diff options
| author | Jeff Garzik <jgarzik@redhat.com> | 2004-05-13 13:26:59 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2004-05-13 13:26:59 -0400 |
| commit | 2e0b05720b394ba2c6bb36364ff963d07d9ccb05 (patch) | |
| tree | b303520f79f0342bbf8af6eafee17ea66f3ea1c2 | |
| parent | 4801224e03f98cc2cfcf154767aff46617365046 (diff) | |
[libata] more ATAPI work - translate SCSI CDB to ATA PACKET
Now that we can specify ATAPI as a taskfile protocol, we can utilize
the existing SCSI->ATA translation infrastructure to build an ATA
PACKET command quickly and easily.
| -rw-r--r-- | drivers/scsi/libata-core.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/libata-scsi.c | 62 | ||||
| -rw-r--r-- | drivers/scsi/libata.h | 1 |
3 files changed, 16 insertions, 61 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index c22d1d199358..0758649eaec6 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2794,20 +2794,6 @@ static unsigned long ata_thread_iter(struct ata_port *ap) return timeout; } -void atapi_start(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - qc->flags |= ATA_QCFLAG_ACTIVE; - ap->active_tag = qc->tag; - - ata_dev_select(ap, qc->dev->devno, 1, 0); - ata_tf_to_host_nolock(ap, &qc->tf); - queue_work(ata_wq, &ap->packet_task); - - VPRINTK("EXIT\n"); -} - /** * atapi_packet_task - Write CDB bytes to hardware * @_data: Port to which ATAPI device is attached. diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index ef152830ea67..a8f1b72aa0e9 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -885,53 +885,20 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 } /** - * atapi_scsi_queuecmd - Send CDB to ATAPI device - * @ap: Port to which ATAPI device is attached. - * @dev: Target device for CDB. - * @cmd: SCSI command being sent to device. - * @done: SCSI command completion function. - * - * Sends CDB to ATAPI device. If the Linux SCSI layer sends a - * non-data command, then this function handles the command - * directly, via polling. Otherwise, the bmdma engine is started. + * atapi_xlat - Initialize PACKET taskfile + * @qc: command structure to be initialized + * @scsicmd: SCSI CDB associated with this PACKET command * * LOCKING: * spin_lock_irqsave(host_set lock) + * + * RETURNS: + * Zero on success, non-zero on failure. */ -static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) { - struct ata_queued_cmd *qc; - u8 *scsicmd = cmd->cmnd; - - VPRINTK("ENTER, drv_stat = 0x%x\n", ata_chk_status(ap)); - - if (cmd->sc_data_direction == SCSI_DATA_UNKNOWN) { - DPRINTK("unknown data, scsicmd 0x%x\n", scsicmd[0]); - ata_bad_cdb(cmd, done); - return; - } - - switch(scsicmd[0]) { - case READ_6: - case WRITE_6: - case MODE_SELECT: - case MODE_SENSE: - DPRINTK("read6/write6/modesel/modesense trap\n"); - ata_bad_scsiop(cmd, done); - return; - - default: - /* do nothing */ - break; - } - - qc = ata_scsi_qc_new(ap, dev, cmd, done); - if (!qc) { - printk(KERN_ERR "ata%u: command queue empty\n", ap->id); - return; - } + struct scsi_cmnd *cmd = qc->scsicmd; qc->flags |= ATA_QCFLAG_ATAPI; @@ -943,17 +910,20 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev, qc->tf.command = ATA_CMD_PACKET; - if (cmd->sc_data_direction == SCSI_DATA_NONE) { - qc->tf.protocol = ATA_PROT_ATAPI; + if ((cmd->sc_data_direction == SCSI_DATA_NONE) || + ((qc->flags & ATA_QCFLAG_DMA) == 0)) { qc->flags |= ATA_QCFLAG_POLL; + qc->tf.protocol = ATA_PROT_ATAPI; qc->tf.ctl |= ATA_NIEN; /* disable interrupts */ + qc->tf.lbam = (8 * 1024) & 0xff; + qc->tf.lbah = (8 * 1024) >> 8; } else { - qc->tf.protocol = ATA_PROT_ATAPI_DMA; qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ + qc->tf.protocol = ATA_PROT_ATAPI_DMA; qc->tf.feature |= ATAPI_PKT_DMA; } - atapi_start(qc); + return 0; } /** @@ -1092,7 +1062,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) else ata_scsi_simulate(ap, dev, cmd, done); } else - atapi_scsi_queuecmd(ap, dev, cmd, done); + ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); out_unlock: return 0; diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 3f14bfe509b8..cf7bb8d6116b 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -44,7 +44,6 @@ extern int ata_qc_issue(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf); -extern void atapi_start(struct ata_queued_cmd *qc); /* libata-scsi.c */ |
