Browse Source

Add LBA48 support, now we can use large capacity disk , increase from 137G to 549G.

Before: We can not use large capacity disk.
Now: We can use large capacity disk.
Test: In pmon, you can observe wether we can use large capacity disk by load.

Targets: all
master
zhengxingwang 13 years ago
committed by wanghongmei
parent
commit
70acb14c11
  1. 138
      sys/dev/ata/ata_wdc.c
  2. 1
      sys/dev/ata/atavar.h
  3. 10
      sys/dev/ata/wd.c
  4. 2
      sys/dev/ic/wdc.c
  5. 12
      sys/dev/ic/wdcreg.h

138
sys/dev/ata/ata_wdc.c

@ -286,30 +286,35 @@ _wdc_ata_bio_start(chp, xfer)
#ifdef DEBUG_IDE
printf("mov right\n");
#endif
sect = (ata_bio->blkno >> 0) & 0xff;
cyl = (ata_bio->blkno >> 8) & 0xffff;
head = (ata_bio->blkno >> 24) & 0x0f;
head |= WDSD_LBA;
#ifdef DEBUG_IDE
printf("ata_bio->blkno=%llx\n",ata_bio->blkno);
#endif
/* LBA1 = (ata_bio->blkno >> 0) & 0xff;
LBA2 = (ata_bio->blkno >> 8) & 0xff;
LBA3 = (ata_bio->blkno >> 16) & 0xff;
LBA4 = (ata_bio->blkno >> 24) & 0xff;
LBA5 = (ata_bio->blkno >> 32) & 0xff;
LBA6 = (ata_bio->blkno >> 40) & 0xff;
head1 = (ata_bio->blkno >> 44) & 0x0f;
head1 |= WDSD_LBA;*/
if(!(drvp->drive_flags & DRIVE_LBA48)){
sect = (ata_bio->blkno >> 0) & 0xff;
cyl = (ata_bio->blkno >> 8) & 0xffff;
head = (ata_bio->blkno >> 24) & 0x0f;
head |= WDSD_LBA;
}
else
{
LBA1 = (ata_bio->blkno >> 0) & 0xff;
LBA2 = (ata_bio->blkno >> 8) & 0xff;
LBA3 = (ata_bio->blkno >> 16) & 0xff;
LBA4 = (ata_bio->blkno >> 24) & 0xff;
LBA5 = (ata_bio->blkno >> 32) & 0xff;
LBA6 = (ata_bio->blkno >> 40) & 0xff;
head1 = (ata_bio->blkno >> 44) & 0x0f;
head1 |= WDSD_LBA;
#ifdef DEBUG_IDE
printf("LBA1=%x\n",LBA1);
printf("LBA2=%x\n",LBA2);
printf("LBA3=%x\n",LBA3);
printf("LBA4=%x\n",LBA4);
printf("LBA5=%x\n",LBA5);
printf("LBA6=%x\n",LBA6);
printf("head1=%x\n",head1);
printf("LBA1=%x\n",LBA1);
printf("LBA2=%x\n",LBA2);
printf("LBA3=%x\n",LBA3);
printf("LBA4=%x\n",LBA4);
printf("LBA5=%x\n",LBA5);
printf("LBA6=%x\n",LBA6);
printf("head1=%x\n",head1);
#endif
}
} else {
int blkno = ata_bio->blkno;
#ifdef DEBUG_IDE
@ -333,8 +338,10 @@ _wdc_ata_bio_start(chp, xfer)
#ifdef DEBUG_IDE
printf("ata_bio->nbytes=%d\n",ata_bio->nbytes);
#endif
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READDMA : WDCC_WRITEDMA;
if(drvp->drive_flags & DRIVE_LBA48)
cmd = (ata_bio->flags & ATA_READ) ? WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT;
else
cmd = (ata_bio->flags & ATA_READ) ? WDCC_READDMA : WDCC_WRITEDMA;
nblks = ata_bio->nblks;
#ifdef DEBUG_IDE
printf("2.ata_bio->nblks=%d,nblks=%d\n",ata_bio->nblks,nblks);
@ -354,27 +361,27 @@ _wdc_ata_bio_start(chp, xfer)
WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
goto timeout;
/*
#ifdef IDE_DMA
precomp=(ata_bio->lp->d_type == DTYPE_ST506)?ata_bio->lp->d_precompcyl/4:0;
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_seccnt, 0);
CHP_WRITE_REG(chp, wdr_sector, LBA4);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA5);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA6);
DELAY(3);
CHP_WRITE_REG(chp, wdr_precomp, 0);
CHP_WRITE_REG(chp, wdr_seccnt, nblks);
CHP_WRITE_REG(chp, wdr_sector, LBA1);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA2);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA3);
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_command, cmd);
#else
*/
wdccommand(chp, xfer->drive, cmd, cyl,
head, sect, nblks, 0);
//#endif
if(drvp->drive_flags & DRIVE_LBA48){
precomp=(ata_bio->lp->d_type == DTYPE_ST506)?ata_bio->lp->d_precompcyl/4:0;
CHP_WRITE_REG(chp, 1, 0);
CHP_WRITE_REG(chp, wdr_seccnt, 0);
CHP_WRITE_REG(chp, wdr_sector, LBA4);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA5);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA6);
DELAY(10);
CHP_WRITE_REG(chp, 1, 0);
CHP_WRITE_REG(chp, wdr_seccnt, nblks);
CHP_WRITE_REG(chp, wdr_sector, LBA1);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA2);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA3);
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
DELAY(10);
CHP_WRITE_REG(chp, wdr_command, cmd);
}
else
wdccommand(chp, xfer->drive, cmd, cyl, head, sect, nblks, 0);
/* start the DMA channel */
(*chp->wdc->dma_start)(chp->wdc->dma_arg,
chp->channel, xfer->drive, dma_flags);
@ -394,31 +401,38 @@ _wdc_ata_bio_start(chp, xfer)
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READMULTI : WDCC_WRITEMULTI;
} else {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READ : WDCC_WRITE;
if(!(drvp->drive_flags & DRIVE_LBA48))
cmd = (ata_bio->flags & ATA_READ) ? WDCC_READ : WDCC_WRITE;
else
cmd = (ata_bio->flags & ATA_READ) ? WDCC_READ_EXT : WDCC_WRITE_EXT;
}
/* Initiate command! */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
goto timeout;
wdccommand(chp, xfer->drive, cmd, cyl,
head, sect, nblks,
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
/* precomp=(ata_bio->lp->d_type == DTYPE_ST506)?ata_bio->lp->d_precompcyl/4:0;
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_seccnt, 0);
CHP_WRITE_REG(chp, wdr_sector, LBA4);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA5);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA6);
DELAY(1);
CHP_WRITE_REG(chp, wdr_precomp, precomp);
CHP_WRITE_REG(chp, wdr_seccnt, nblks);
CHP_WRITE_REG(chp, wdr_sector, LBA1);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA2);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA3);
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_command, cmd);*/
if(!(drvp->drive_flags & DRIVE_LBA48)){
wdccommand(chp, xfer->drive, cmd, cyl,
head, sect, nblks,
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
}
else{
precomp=(ata_bio->lp->d_type == DTYPE_ST506)?ata_bio->lp->d_precompcyl/4:0;
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_seccnt, 0);
CHP_WRITE_REG(chp, wdr_sector, LBA4);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA5);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA6);
DELAY(1);
CHP_WRITE_REG(chp, wdr_precomp, precomp);
CHP_WRITE_REG(chp, wdr_seccnt, nblks);
CHP_WRITE_REG(chp, wdr_sector, LBA1);
CHP_WRITE_REG(chp, wdr_cyl_lo, LBA2);
CHP_WRITE_REG(chp, wdr_cyl_hi, LBA3);
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4) | head1);
CHP_WRITE_REG(chp, wdr_command, cmd);
}
#ifdef DEBUG_IDE
printf("cmd=%x\n",cmd);
#endif

1
sys/dev/ata/atavar.h

@ -55,6 +55,7 @@ struct ata_drive_datas {
#define DRIVE_DMAERR 0x0100 /* Udma transfer had crc error, don't try DMA */
#define DRIVE_DSCBA 0x0200 /* DSC in buffer availability mode */
#define DRIVE_DSCWAIT 0x0400 /* In wait for DSC to be asserted */
#define DRIVE_LBA48 0x8000 /* for LBA48 */
/*
* Current setting of drive's PIO, DMA and UDMA modes.

10
sys/dev/ata/wd.c

@ -174,7 +174,7 @@ struct wd_softc {
#ifdef INTERFACE_3A780E
unsigned long sc_capacity; /* disk size Lc modify */
#else
int sc_capacity;
unsigned long sc_capacity;
#endif
int cyl; /* actual drive parameters */
@ -392,6 +392,10 @@ wdattach(parent, self, aux)
wd->sc_capacity =
(wd->sc_params.atap_capacity[1] << 16) |
wd->sc_params.atap_capacity[0];
if(wd->sc_capacity >= 0xFFFFFFF)
wd->drvp->drive_flags |= DRIVE_LBA48;
printf(" LBA, %dMB, %d cyl, %d head, %d sec, %d sectors\n",
wd->sc_capacity / (1048576 / DEV_BSIZE),
wd->sc_params.atap_cylinders,
@ -629,7 +633,11 @@ __wdstart(wd, bp)
* the sector number of the problem, and will eventually allow the
* transfer to succeed.
*/
#ifdef IDE_DMA
if (wd->sc_multi == 1 || wd->retries >= WDIORETRIES_SINGLE)
#else
if (wd->sc_multi != 1 || wd->retries >= WDIORETRIES_SINGLE)
#endif
wd->sc_wdc_bio.flags = ATA_SINGLE | ATA_POLL;
else
wd->sc_wdc_bio.flags = ATA_POLL;

2
sys/dev/ic/wdc.c

@ -1071,7 +1071,7 @@ wdc_probe_caps(drvp, params)
struct wdc_softc *wdc = chp->wdc;
int i, printed;
int cf_flags = drvp->cf_flags;
if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
(WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
struct ataparams params2;

12
sys/dev/ic/wdcreg.h

@ -81,8 +81,10 @@
#define WDCC_NOP 0x00 /* NOP - Always fail with "aborted command" */
#define WDCC_RECAL 0x10 /* disk restore code -- resets cntlr */
#define WDCC_READ 0x29 /* disk read code */
#define WDCC_WRITE 0x39 /* disk write code */
#define WDCC_READ 0x20 /* disk read code */
#define WDCC_READ_EXT 0x24 /* disk read code */
#define WDCC_WRITE 0x30 /* disk write code */
#define WDCC_WRITE_EXT 0x34 /* disk write code */
#define WDCC__LONG 0x02 /* modifier -- access ecc bytes */
#define WDCC__NORETRY 0x01 /* modifier -- no retrys */
@ -94,8 +96,10 @@
#define WDCC_WRITEMULTI 0x39 // 0xc5 /* write multiple */
#define WDCC_SETMULTI 0xc6 /* set multiple mode */
#define WDCC_READDMA 0xc8 /* read with DMA */
#define WDCC_WRITEDMA 0xca /* write with DMA */
#define WDCC_READDMA 0xc8 /* read with DMA */
#define WDCC_READDMA_EXT 0x25 /* read with DMA */
#define WDCC_WRITEDMA 0xca /* write with DMA */
#define WDCC_WRITEDMA_EXT 0x35 /* write with DMA */
#define WDCC_ACKMC 0xdb /* acknowledge media change */
#define WDCC_LOCK 0xde /* lock drawer */

Loading…
Cancel
Save