typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
+static void ata_scsi_error(struct Scsi_Host *host);
enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
#define RW_RECOVERY_MPAGE 0x1
* It just needs the eh_timed_out hook.
*/
struct scsi_transport_template ata_scsi_transport_template = {
+ .eh_strategy_handler = ata_scsi_error,
.eh_timed_out = ata_scsi_timed_out,
};
int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
{
- struct ata_port *ap;
- struct ata_device *dev;
int val = -EINVAL, rc = -EINVAL;
- ap = (struct ata_port *) &scsidev->host->hostdata[0];
- if (!ap)
- goto out;
-
- dev = ata_scsi_find_dev(ap, scsidev);
- if (!dev) {
- rc = -ENODEV;
- goto out;
- }
-
switch (cmd) {
case ATA_IOC_GET_IO32:
val = 0;
break;
}
-out:
return rc;
}
*
* LOCKING:
* Inherited from SCSI layer (none, can sleep)
- *
- * RETURNS:
- * Zero.
*/
-int ata_scsi_error(struct Scsi_Host *host)
+static void ata_scsi_error(struct Scsi_Host *host)
{
struct ata_port *ap;
unsigned long flags;
spin_unlock_irqrestore(&ap->host_set->lock, flags);
DPRINTK("EXIT\n");
- return 0;
}
static void ata_eh_scsidone(struct scsi_cmnd *scmd)
goto early_finish;
/* select device, send command to hardware */
- qc->err_mask = ata_qc_issue(qc);
- if (qc->err_mask)
- ata_qc_complete(qc);
+ ata_qc_issue(qc);
VPRINTK("EXIT\n");
return;
qc->complete_fn = atapi_sense_complete;
- qc->err_mask = ata_qc_issue(qc);
- if (qc->err_mask)
- ata_qc_complete(qc);
+ ata_qc_issue(qc);
DPRINTK("EXIT\n");
}
#endif
}
+static inline void __ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
+ struct ata_port *ap, struct ata_device *dev)
+{
+ if (dev->class == ATA_DEV_ATA) {
+ ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
+ cmd->cmnd[0]);
+
+ if (xlat_func)
+ ata_scsi_translate(ap, dev, cmd, done, xlat_func);
+ else
+ ata_scsi_simulate(ap, dev, cmd, done);
+ } else
+ ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+}
+
/**
* ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent
ata_scsi_dump_cdb(ap, cmd);
dev = ata_scsi_find_dev(ap, scsidev);
- if (unlikely(!dev)) {
+ if (likely(dev))
+ __ata_scsi_queuecmd(cmd, done, ap, dev);
+ else {
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
- goto out_unlock;
}
- if (dev->class == ATA_DEV_ATA) {
- ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
- cmd->cmnd[0]);
-
- if (xlat_func)
- ata_scsi_translate(ap, dev, cmd, done, xlat_func);
- else
- ata_scsi_simulate(ap, dev, cmd, done);
- } else
- ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
-
-out_unlock:
spin_unlock(&ap->host_set->lock);
spin_lock(shost->host_lock);
return 0;