version 1.79.2.1, 2005/07/06 22:03:02 |
version 1.80, 2005/05/29 22:11:28 |
Line 183 wdc_ata_bio_start(struct ata_channel *ch |
|
Line 183 wdc_ata_bio_start(struct ata_channel *ch |
|
struct ata_bio *ata_bio = xfer->c_cmd; |
struct ata_bio *ata_bio = xfer->c_cmd; |
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; |
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; |
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; |
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; |
char *errstring; |
const char *errstring; |
|
|
ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", |
ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", |
atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive), |
atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive), |
Line 323 _wdc_ata_bio_start(struct ata_channel *c |
|
Line 323 _wdc_ata_bio_start(struct ata_channel *c |
|
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; |
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; |
u_int16_t cyl; |
u_int16_t cyl; |
u_int8_t head, sect, cmd = 0; |
u_int8_t head, sect, cmd = 0; |
int nblks, error; |
int nblks; |
int dma_flags = 0; |
int dma_flags = 0; |
|
|
ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", |
ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", |
|
|
cmd = (ata_bio->flags & ATA_READ) ? |
cmd = (ata_bio->flags & ATA_READ) ? |
WDCC_READDMA : WDCC_WRITEDMA; |
WDCC_READDMA : WDCC_WRITEDMA; |
/* Init the DMA channel. */ |
/* Init the DMA channel. */ |
error = (*wdc->dma_init)(wdc->dma_arg, |
if ((*wdc->dma_init)(wdc->dma_arg, |
chp->ch_channel, xfer->c_drive, |
chp->ch_channel, xfer->c_drive, |
(char *)xfer->c_databuf + xfer->c_skip, |
(char *)xfer->c_databuf + xfer->c_skip, |
ata_bio->nbytes, dma_flags); |
ata_bio->nbytes, dma_flags) != 0) { |
if (error) { |
|
if (error == EINVAL) { |
|
/* |
|
* We can't do DMA on this transfer |
|
* for some reason. Fall back to |
|
* PIO. |
|
*/ |
|
xfer->c_flags &= ~C_DMA; |
|
error = 0; |
|
goto do_pio; |
|
} |
|
ata_bio->error = ERR_DMA; |
ata_bio->error = ERR_DMA; |
ata_bio->r_error = 0; |
ata_bio->r_error = 0; |
wdc_ata_bio_done(chp, xfer); |
wdc_ata_bio_done(chp, xfer); |
|
|
/* wait for irq */ |
/* wait for irq */ |
goto intr; |
goto intr; |
} /* else not DMA */ |
} /* else not DMA */ |
do_pio: |
|
ata_bio->nblks = min(nblks, ata_bio->multi); |
ata_bio->nblks = min(nblks, ata_bio->multi); |
ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize; |
ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize; |
KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0); |
KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0); |