X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Flibata-scsi.c;h=59503c9ccac9ff794a66d29c358f4d98c4b33ed0;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=b405acf1169310fa77659795f5bbe134938f6083;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index b405acf11..59503c9cc 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -53,8 +52,6 @@ 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 #define RW_RECOVERY_MPAGE_LEN 12 @@ -95,15 +92,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { 0, 30 /* extended self test time, see 05-359r1 */ }; -/* - * libata transport template. libata doesn't do real transport stuff. - * 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, -}; - static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) @@ -163,7 +151,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; enum dma_data_direction data_dir; - if (arg == NULL) + if (NULL == (void *)arg) return -EINVAL; if (copy_from_user(args, arg, sizeof(args))) @@ -213,7 +201,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) /* Need code to retrieve data from check condition? */ if ((argbuf) - && copy_to_user(arg + sizeof(args), argbuf, argsize)) + && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize)) rc = -EFAULT; error: if (argbuf) @@ -240,7 +228,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) u8 args[7]; struct scsi_sense_hdr sshdr; - if (arg == NULL) + if (NULL == (void *)arg) return -EINVAL; if (copy_from_user(args, arg, sizeof(args))) @@ -258,7 +246,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[14] = args[0]; /* Good values for timeout and retries? Values below - from scsi_ioctl_send_command() for default case... */ + from scsi_ioctl_send_command() for default case... */ if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, (10*HZ), 5)) rc = -EIO; @@ -269,8 +257,20 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) 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; @@ -299,6 +299,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) break; } +out: return rc; } @@ -403,12 +404,12 @@ int ata_scsi_device_resume(struct scsi_device *sdev) return ata_device_resume(ap, dev); } -int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) +int ata_scsi_device_suspend(struct scsi_device *sdev) { struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; struct ata_device *dev = &ap->device[sdev->id]; - return ata_device_suspend(ap, dev, state); + return ata_device_suspend(ap, dev); } /** @@ -427,7 +428,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) * LOCKING: * spin_lock_irqsave(host_set lock) */ -void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, +void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, u8 *ascq) { int i; @@ -484,7 +485,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, /* Look for drv_err */ for (i = 0; sense_table[i][0] != 0xFF; i++) { /* Look for best matches first */ - if ((sense_table[i][0] & drv_err) == + if ((sense_table[i][0] & drv_err) == sense_table[i][0]) { *sk = sense_table[i][1]; *asc = sense_table[i][2]; @@ -507,16 +508,21 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, } } /* No error? Undecoded? */ - printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", + printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", id, drv_stat); - /* We need a sensible error return here, which is tricky, and one - that won't cause people to do things like return a disk wrongly */ - *sk = ABORTED_COMMAND; - *asc = 0x00; - *ascq = 0x00; + /* For our last chance pick, use medium read error because + * it's much more common than an ATA drive telling you a write + * has failed. + */ + *sk = MEDIUM_ERROR; + *asc = 0x11; /* "unrecovered read error" */ + *ascq = 0x04; /* "auto-reallocation failed" */ translate_done: + printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to " + "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err, + *sk, *asc, *ascq); return; } @@ -547,7 +553,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) /* * Read the controller registers. */ - WARN_ON(qc->ap->ops->tf_read == NULL); + assert(NULL != qc->ap->ops->tf_read); qc->ap->ops->tf_read(qc->ap, tf); /* @@ -622,7 +628,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) /* * Read the controller registers. */ - WARN_ON(qc->ap->ops->tf_read == NULL); + assert(NULL != qc->ap->ops->tf_read); qc->ap->ops->tf_read(qc->ap, tf); /* @@ -656,41 +662,6 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) } } -static void ata_scsi_sdev_config(struct scsi_device *sdev) -{ - sdev->use_10_for_rw = 1; - sdev->use_10_for_ms = 1; -} - -static void ata_scsi_dev_config(struct scsi_device *sdev, - struct ata_device *dev) -{ - unsigned int max_sectors; - - /* TODO: 2048 is an arbitrary number, not the - * hardware maximum. This should be increased to - * 65534 when Jens Axboe's patch for dynamically - * determining max_sectors is merged. - */ - max_sectors = ATA_MAX_SECTORS; - if (dev->flags & ATA_DFLAG_LBA48) - max_sectors = 2048; - if (dev->max_sectors) - max_sectors = dev->max_sectors; - - blk_queue_max_sectors(sdev->request_queue, max_sectors); - - /* - * SATA DMA transfers must be multiples of 4 byte, so - * we need to pad ATAPI transfers using an extra sg. - * Decrement max hw segments accordingly. - */ - if (dev->class == ATA_DEV_ATAPI) { - request_queue_t *q = sdev->request_queue; - blk_queue_max_hw_segments(q, q->max_hw_segments - 1); - } -} - /** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine @@ -705,7 +676,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, int ata_scsi_slave_config(struct scsi_device *sdev) { - ata_scsi_sdev_config(sdev); + sdev->use_10_for_rw = 1; + sdev->use_10_for_ms = 1; blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); @@ -716,51 +688,32 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ap = (struct ata_port *) &sdev->host->hostdata[0]; dev = &ap->device[sdev->id]; - ata_scsi_dev_config(sdev, dev); - } - - return 0; /* scsi layer doesn't check return value, sigh */ -} - -/** - * ata_scsi_timed_out - SCSI layer time out callback - * @cmd: timed out SCSI command - * - * Handles SCSI layer timeout. We race with normal completion of - * the qc for @cmd. If the qc is already gone, we lose and let - * the scsi command finish (EH_HANDLED). Otherwise, the qc has - * timed out and EH should be invoked. Prevent ata_qc_complete() - * from finishing it by setting EH_SCHEDULED and return - * EH_NOT_HANDLED. - * - * LOCKING: - * Called from timer context - * - * RETURNS: - * EH_HANDLED or EH_NOT_HANDLED - */ -enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host = cmd->device->host; - struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; - unsigned long flags; - struct ata_queued_cmd *qc; - enum scsi_eh_timer_return ret = EH_HANDLED; - - DPRINTK("ENTER\n"); + /* TODO: 1024 is an arbitrary number, not the + * hardware maximum. This should be increased to + * 65534 when Jens Axboe's patch for dynamically + * determining max_sectors is merged. + */ + if ((dev->flags & ATA_DFLAG_LBA48) && + ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { + /* + * do not overwrite sdev->host->max_sectors, since + * other drives on this host may not support LBA48 + */ + blk_queue_max_sectors(sdev->request_queue, 2048); + } - spin_lock_irqsave(&ap->host_set->lock, flags); - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc) { - WARN_ON(qc->scsicmd != cmd); - qc->flags |= ATA_QCFLAG_EH_SCHEDULED; - qc->err_mask |= AC_ERR_TIMEOUT; - ret = EH_NOT_HANDLED; + /* + * SATA DMA transfers must be multiples of 4 byte, so + * we need to pad ATAPI transfers using an extra sg. + * Decrement max hw segments accordingly. + */ + if (dev->class == ATA_DEV_ATAPI) { + request_queue_t *q = sdev->request_queue; + blk_queue_max_hw_segments(q, q->max_hw_segments - 1); + } } - spin_unlock_irqrestore(&ap->host_set->lock, flags); - DPRINTK("EXIT, ret=%d\n", ret); - return ret; + return 0; /* scsi layer doesn't check return value, sigh */ } /** @@ -771,86 +724,29 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) * * LOCKING: * Inherited from SCSI layer (none, can sleep) + * + * RETURNS: + * Zero. */ -static void ata_scsi_error(struct Scsi_Host *host) +int ata_scsi_error(struct Scsi_Host *host) { struct ata_port *ap; - unsigned long flags; DPRINTK("ENTER\n"); ap = (struct ata_port *) &host->hostdata[0]; - - spin_lock_irqsave(&ap->host_set->lock, flags); - WARN_ON(ap->flags & ATA_FLAG_IN_EH); - ap->flags |= ATA_FLAG_IN_EH; - WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - ata_port_flush_task(ap); - ap->ops->eng_timeout(ap); - WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); - - scsi_eh_flush_done_q(&ap->eh_done_q); - - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_IN_EH; - spin_unlock_irqrestore(&ap->host_set->lock, flags); + /* TODO: this is per-command; when queueing is supported + * this code will either change or move to a more + * appropriate place + */ + host->host_failed--; + INIT_LIST_HEAD(&host->eh_cmd_q); DPRINTK("EXIT\n"); -} - -static void ata_eh_scsidone(struct scsi_cmnd *scmd) -{ - /* nada */ -} - -static void __ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct scsi_cmnd *scmd = qc->scsicmd; - unsigned long flags; - - spin_lock_irqsave(&ap->host_set->lock, flags); - qc->scsidone = ata_eh_scsidone; - __ata_qc_complete(qc); - WARN_ON(ata_tag_valid(qc->tag)); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - scsi_eh_finish_cmd(scmd, &ap->eh_done_q); -} - -/** - * ata_eh_qc_complete - Complete an active ATA command from EH - * @qc: Command to complete - * - * Indicate to the mid and upper layers that an ATA command has - * completed. To be used from EH. - */ -void ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct scsi_cmnd *scmd = qc->scsicmd; - scmd->retries = scmd->allowed; - __ata_eh_qc_complete(qc); -} - -/** - * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH - * @qc: Command to retry - * - * Indicate to the mid and upper layers that an ATA command - * should be retried. To be used from EH. - * - * SCSI midlayer limits the number of retries to scmd->allowed. - * This function might need to adjust scmd->retries for commands - * which get retried due to unrelated NCQ failures. - */ -void ata_eh_qc_retry(struct ata_queued_cmd *qc) -{ - __ata_eh_qc_complete(qc); + return 0; } /** @@ -1089,13 +985,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; - if (lba_28_ok(block, n_block)) { - /* use LBA28 */ - tf->command = ATA_CMD_VERIFY; - tf->device |= (block >> 24) & 0xf; - } else if (lba_48_ok(block, n_block)) { - if (!(dev->flags & ATA_DFLAG_LBA48)) - goto out_of_range; + if (dev->flags & ATA_DFLAG_LBA48) { + if (n_block > (64 * 1024)) + goto invalid_fld; /* use LBA48 */ tf->flags |= ATA_TFLAG_LBA48; @@ -1106,9 +998,15 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc tf->hob_lbah = (block >> 40) & 0xff; tf->hob_lbam = (block >> 32) & 0xff; tf->hob_lbal = (block >> 24) & 0xff; - } else - /* request too large even for LBA48 */ - goto out_of_range; + } else { + if (n_block > 256) + goto invalid_fld; + + /* use LBA28 */ + tf->command = ATA_CMD_VERIFY; + + tf->device |= (block >> 24) & 0xf; + } tf->nsect = n_block & 0xff; @@ -1121,8 +1019,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc /* CHS */ u32 sect, head, cyl, track; - if (!lba_28_ok(block, n_block)) - goto out_of_range; + if (n_block > 256) + goto invalid_fld; /* Convert LBA to CHS */ track = (u32)block / dev->sectors; @@ -1132,14 +1030,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc DPRINTK("block %u track %u cyl %u head %u sect %u\n", (u32)block, track, cyl, head, sect); - - /* Check whether the converted CHS can fit. - Cylinder: 0-65535 + + /* Check whether the converted CHS can fit. + Cylinder: 0-65535 Head: 0-15 Sector: 1-255*/ - if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) + if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) goto out_of_range; - + tf->command = ATA_CMD_VERIFY; tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ tf->lbal = sect; @@ -1241,11 +1139,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; - if (lba_28_ok(block, n_block)) { - /* use LBA28 */ - tf->device |= (block >> 24) & 0xf; - } else if (lba_48_ok(block, n_block)) { - if (!(dev->flags & ATA_DFLAG_LBA48)) + if (dev->flags & ATA_DFLAG_LBA48) { + /* The request -may- be too large for LBA48. */ + if ((block >> 48) || (n_block > 65536)) goto out_of_range; /* use LBA48 */ @@ -1256,9 +1152,15 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm tf->hob_lbah = (block >> 40) & 0xff; tf->hob_lbam = (block >> 32) & 0xff; tf->hob_lbal = (block >> 24) & 0xff; - } else - /* request too large even for LBA48 */ - goto out_of_range; + } else { + /* use LBA28 */ + + /* The request -may- be too large for LBA28. */ + if ((block >> 28) || (n_block > 256)) + goto out_of_range; + + tf->device |= (block >> 24) & 0xf; + } if (unlikely(ata_rwcmd_protocol(qc) < 0)) goto invalid_fld; @@ -1271,12 +1173,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm tf->lbal = block & 0xff; tf->device |= ATA_LBA; - } else { + } else { /* CHS */ u32 sect, head, cyl, track; /* The request -may- be too large for CHS addressing. */ - if (!lba_28_ok(block, n_block)) + if ((block >> 28) || (n_block > 256)) goto out_of_range; if (unlikely(ata_rwcmd_protocol(qc) < 0)) @@ -1291,8 +1193,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm DPRINTK("block %u track %u cyl %u head %u sect %u\n", (u32)block, track, cyl, head, sect); - /* Check whether the converted CHS can fit. - Cylinder: 0-65535 + /* Check whether the converted CHS can fit. + Cylinder: 0-65535 Head: 0-15 Sector: 1-255*/ if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) @@ -1323,7 +1225,7 @@ nothing_to_do: return 1; } -static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) +static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; @@ -1360,7 +1262,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) qc->scsidone(cmd); - ata_qc_free(qc); + return 0; } /** @@ -1426,7 +1328,8 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, goto early_finish; /* select device, send command to hardware */ - ata_qc_issue(qc); + if (ata_qc_issue(qc)) + goto err_did; VPRINTK("EXIT\n"); return; @@ -1542,7 +1445,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, * @buflen: Response buffer length. * * Returns standard device identification data associated - * with non-VPD INQUIRY command output. + * with non-EVPD INQUIRY command output. * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1569,8 +1472,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, if (buflen > 35) { memcpy(&rbuf[8], "ATA ", 8); - ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16); - ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4); + ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16); + ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4); if (rbuf[32] == 0 || rbuf[32] == ' ') memcpy(&rbuf[32], "n/a ", 4); } @@ -1593,12 +1496,12 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages + * ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. * - * Returns list of inquiry VPD pages available. + * Returns list of inquiry EVPD pages available. * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1612,7 +1515,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf, 0x80, /* page 0x80, unit serial no page */ 0x83 /* page 0x83, device ident page */ }; - rbuf[3] = sizeof(pages); /* number of supported VPD pages */ + rbuf[3] = sizeof(pages); /* number of supported EVPD pages */ if (buflen > 6) memcpy(rbuf + 4, pages, sizeof(pages)); @@ -1621,7 +1524,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number + * ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. @@ -1644,22 +1547,22 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, memcpy(rbuf, hdr, sizeof(hdr)); if (buflen > (ATA_SERNO_LEN + 4 - 1)) - ata_id_string(args->id, (unsigned char *) &rbuf[4], - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); + ata_dev_id_string(args->id, (unsigned char *) &rbuf[4], + ATA_ID_SERNO_OFS, ATA_SERNO_LEN); return 0; } +static const char * const inq_83_str = "Linux ATA-SCSI simulator"; + /** - * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity + * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. * - * Yields two logical unit device identification designators: - * - vendor specific ASCII containing the ATA serial number - * - SAT defined "t10 vendor id based" containing ASCII vendor - * name ("ATA "), model and serial numbers. + * Returns device identification. Currently hardcoded to + * return "Linux ATA-SCSI simulator". * * LOCKING: * spin_lock_irqsave(host_set lock) @@ -1668,39 +1571,16 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen) { - int num; - const int sat_model_serial_desc_len = 68; - const int ata_model_byte_len = 40; - rbuf[1] = 0x83; /* this page code */ - num = 4; - - if (buflen > (ATA_SERNO_LEN + num + 3)) { - /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ - rbuf[num + 0] = 2; - rbuf[num + 3] = ATA_SERNO_LEN; - num += 4; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); - num += ATA_SERNO_LEN; - } - if (buflen > (sat_model_serial_desc_len + num + 3)) { - /* SAT defined lu model and serial numbers descriptor */ - /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ - rbuf[num + 0] = 2; - rbuf[num + 1] = 1; - rbuf[num + 3] = sat_model_serial_desc_len; - num += 4; - memcpy(rbuf + num, "ATA ", 8); - num += 8; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_PROD_OFS, ata_model_byte_len); - num += ata_model_byte_len; - ata_id_string(args->id, (unsigned char *) rbuf + num, - ATA_ID_SERNO_OFS, ATA_SERNO_LEN); - num += ATA_SERNO_LEN; + rbuf[3] = 4 + strlen(inq_83_str); /* page len */ + + /* our one and only identification descriptor (vendor-specific) */ + if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) { + rbuf[4 + 0] = 2; /* code set: ASCII */ + rbuf[4 + 3] = strlen(inq_83_str); + memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str)); } - rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ + return 0; } @@ -1833,12 +1713,15 @@ static int ata_dev_supports_fua(u16 *id) if (!ata_id_has_fua(id)) return 0; - ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model)); - ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw)); + model[40] = '\0'; + fw[8] = '\0'; - if (strcmp(model, "Maxtor")) + ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1); + ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1); + + if (strncmp(model, "Maxtor", 6)) return 1; - if (strcmp(fw, "BANC1G10")) + if (strncmp(fw, "BANC1G10", 8)) return 1; return 0; /* blacklisted */ @@ -2132,7 +2015,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 done(cmd); } -static void atapi_sense_complete(struct ata_queued_cmd *qc) +static int atapi_sense_complete(struct ata_queued_cmd *qc) { if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) /* FIXME: not quite right; we don't want the @@ -2143,7 +2026,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc) ata_gen_ata_desc_sense(qc); qc->scsidone(qc->scsicmd); - ata_qc_free(qc); + return 0; } /* is it pointless to prefer PIO for "safety reasons"? */ @@ -2173,7 +2056,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); qc->dma_dir = DMA_FROM_DEVICE; - memset(&qc->cdb, 0, qc->dev->cdb_len); + memset(&qc->cdb, 0, ap->cdb_len); qc->cdb[0] = REQUEST_SENSE; qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; @@ -2192,12 +2075,15 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; - ata_qc_issue(qc); + if (ata_qc_issue(qc)) { + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); + } DPRINTK("EXIT\n"); } -static void atapi_qc_complete(struct ata_queued_cmd *qc) +static int atapi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; unsigned int err_mask = qc->err_mask; @@ -2207,7 +2093,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if (unlikely(err_mask & AC_ERR_DEV)) { cmd->result = SAM_STAT_CHECK_CONDITION; atapi_request_sense(qc); - return; + return 1; } else if (unlikely(err_mask)) @@ -2247,7 +2133,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } qc->scsidone(cmd); - ata_qc_free(qc); + return 0; } /** * atapi_xlat - Initialize PACKET taskfile @@ -2273,7 +2159,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) if (ata_check_atapi_dma(qc)) using_pio = 1; - memcpy(&qc->cdb, scsicmd, dev->cdb_len); + memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len); qc->complete_fn = atapi_qc_complete; @@ -2377,6 +2263,9 @@ ata_scsi_map_proto(u8 byte1) case 4: /* PIO Data-in */ case 5: /* PIO Data-out */ + if (byte1 & 0xe0) { + return ATA_PROT_PIO_MULT; + } return ATA_PROT_PIO; case 10: /* Device Reset */ @@ -2415,10 +2304,6 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) goto invalid_fld; - if (scsicmd[1] & 0xe0) - /* PIO multi not supported yet */ - goto invalid_fld; - /* * 12 and 16 byte CDBs use different offsets to * provide the various register values. @@ -2575,21 +2460,6 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, #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 @@ -2624,13 +2494,24 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) ata_scsi_dump_cdb(ap, cmd); dev = ata_scsi_find_dev(ap, scsidev); - if (likely(dev)) - __ata_scsi_queuecmd(cmd, done, ap, dev); - else { + if (unlikely(!dev)) { 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; @@ -2638,8 +2519,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) /** * ata_scsi_simulate - simulate SCSI command on ATA device - * @ap: port the device is connected to - * @dev: the target device + * @id: current IDENTIFY data for target device. * @cmd: SCSI command being sent to device. * @done: SCSI command completion function. *