Commit 80e00375 authored by Jeff Garzik's avatar Jeff Garzik

[libata] handle non-data ATAPI commands via interrupt

It's easier to do it this way, than polling, at the moment.

Also, fix a test in ata_scsi_translate that was incorrectly
erroring-out non-data commands.
parent 96b2b4d7
...@@ -2677,6 +2677,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ...@@ -2677,6 +2677,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
handled = 1; handled = 1;
break; break;
case ATA_PROT_ATAPI:
case ATA_PROT_NODATA: /* command completion, but no data xfer */ case ATA_PROT_NODATA: /* command completion, but no data xfer */
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
...@@ -2837,9 +2838,16 @@ static void atapi_packet_task(void *_data) ...@@ -2837,9 +2838,16 @@ static void atapi_packet_task(void *_data)
qc->scsicmd->cmnd, ap->host->max_cmd_len / 4); qc->scsicmd->cmnd, ap->host->max_cmd_len / 4);
/* if we are DMA'ing, irq handler takes over from here */ /* if we are DMA'ing, irq handler takes over from here */
if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) { if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
ap->ops->bmdma_start(qc); /* initiate bmdma */ ap->ops->bmdma_start(qc); /* initiate bmdma */
} else {
/* non-data commands are also handled via irq */
else if (qc->scsicmd->sc_data_direction == SCSI_DATA_NONE) {
/* do nothing */
}
/* PIO commands are handled by polling */
else {
ap->pio_task_state = PIO_ST; ap->pio_task_state = PIO_ST;
queue_work(ata_wq, &ap->pio_task); queue_work(ata_wq, &ap->pio_task);
} }
......
...@@ -46,8 +46,8 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, ...@@ -46,8 +46,8 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
* @geom: location to which geometry will be output * @geom: location to which geometry will be output
* *
* Generic bios head/sector/cylinder calculator * Generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS) * used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not * mapping. Some situations may arise where the disk is not
* bootable if this is not used. * bootable if this is not used.
* *
* LOCKING: * LOCKING:
...@@ -57,7 +57,7 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, ...@@ -57,7 +57,7 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
* Zero. * Zero.
*/ */
int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[]) sector_t capacity, int geom[])
{ {
geom[0] = 255; geom[0] = 255;
geom[1] = 63; geom[1] = 63;
...@@ -362,19 +362,20 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, ...@@ -362,19 +362,20 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
VPRINTK("ENTER\n"); VPRINTK("ENTER\n");
if (unlikely(cmd->request_bufflen < 1)) {
printk(KERN_WARNING "ata%u(%u): empty request buffer\n",
ap->id, dev->devno);
goto err_out;
}
qc = ata_scsi_qc_new(ap, dev, cmd, done); qc = ata_scsi_qc_new(ap, dev, cmd, done);
if (!qc) if (!qc)
return; return;
if (cmd->sc_data_direction == SCSI_DATA_READ || if (cmd->sc_data_direction == SCSI_DATA_READ ||
cmd->sc_data_direction == SCSI_DATA_WRITE) cmd->sc_data_direction == SCSI_DATA_WRITE) {
if (unlikely(cmd->request_bufflen < 1)) {
printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n",
ap->id, dev->devno);
goto err_out;
}
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
}
if (xlat_func(qc, scsicmd)) if (xlat_func(qc, scsicmd))
goto err_out; goto err_out;
...@@ -910,12 +911,18 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) ...@@ -910,12 +911,18 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
qc->tf.command = ATA_CMD_PACKET; qc->tf.command = ATA_CMD_PACKET;
if ((cmd->sc_data_direction == SCSI_DATA_NONE) || /* no data - interrupt-driven */
((qc->flags & ATA_QCFLAG_DMA) == 0)) { if (cmd->sc_data_direction == SCSI_DATA_NONE)
qc->tf.protocol = ATA_PROT_ATAPI;
/* PIO data xfer - polling */
else if ((qc->flags & ATA_QCFLAG_DMA) == 0) {
ata_qc_set_polling(qc); ata_qc_set_polling(qc);
qc->tf.protocol = ATA_PROT_ATAPI; qc->tf.protocol = ATA_PROT_ATAPI;
qc->tf.lbam = (8 * 1024) & 0xff; qc->tf.lbam = (8 * 1024) & 0xff;
qc->tf.lbah = (8 * 1024) >> 8; qc->tf.lbah = (8 * 1024) >> 8;
/* DMA data xfer - interrupt-driven */
} else { } else {
qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */
qc->tf.protocol = ATA_PROT_ATAPI_DMA; qc->tf.protocol = ATA_PROT_ATAPI_DMA;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment