[libata] SCSI VPD page 0x83 fixes
[sfrench/cifs-2.6.git] / drivers / scsi / libata-scsi.c
index 9d67c6768335689747a3b8663092a9da0cb6c437..3aaa74cbef1d2b0b14acdcb363eb8e140298040a 100644 (file)
@@ -553,7 +553,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
        /*
         * Read the controller registers.
         */
-       assert(NULL != qc->ap->ops->tf_read);
+       WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
 
        /*
@@ -628,7 +628,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
        /*
         * Read the controller registers.
         */
-       assert(NULL != qc->ap->ops->tf_read);
+       WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
 
        /*
@@ -684,23 +684,23 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
        if (sdev->id < ATA_MAX_DEVICES) {
                struct ata_port *ap;
                struct ata_device *dev;
+               unsigned int max_sectors;
 
                ap = (struct ata_port *) &sdev->host->hostdata[0];
                dev = &ap->device[sdev->id];
 
-               /* TODO: 1024 is an arbitrary number, not the
+               /* 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.
                 */
-               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);
-               }
+               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
@@ -746,7 +746,7 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        qc = ata_qc_from_tag(ap, ap->active_tag);
        if (qc) {
-               assert(qc->scsicmd == cmd);
+               WARN_ON(qc->scsicmd != cmd);
                qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
                qc->err_mask |= AC_ERR_TIMEOUT;
                ret = EH_NOT_HANDLED;
@@ -780,14 +780,16 @@ int ata_scsi_error(struct Scsi_Host *host)
        ap = (struct ata_port *) &host->hostdata[0];
 
        spin_lock_irqsave(&ap->host_set->lock, flags);
-       assert(!(ap->flags & ATA_FLAG_IN_EH));
+       WARN_ON(ap->flags & ATA_FLAG_IN_EH);
        ap->flags |= ATA_FLAG_IN_EH;
-       assert(ata_qc_from_tag(ap, ap->active_tag) != NULL);
+       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);
 
-       assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q));
+       WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
 
        scsi_eh_flush_done_q(&ap->eh_done_q);
 
@@ -813,7 +815,7 @@ static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        qc->scsidone = ata_eh_scsidone;
        __ata_qc_complete(qc);
-       assert(!ata_tag_valid(qc->tag));
+       WARN_ON(ata_tag_valid(qc->tag));
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
        scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
@@ -1540,7 +1542,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
  *     @buflen: Response buffer length.
  *
  *     Returns standard device identification data associated
- *     with non-EVPD INQUIRY command output.
+ *     with non-VPD INQUIRY command output.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
@@ -1567,8 +1569,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
 
        if (buflen > 35) {
                memcpy(&rbuf[8], "ATA     ", 8);
-               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);
+               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);
                if (rbuf[32] == 0 || rbuf[32] == ' ')
                        memcpy(&rbuf[32], "n/a ", 4);
        }
@@ -1591,12 +1593,12 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
- *     ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages
+ *     ata_scsiop_inq_00 - Simulate INQUIRY VPD 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 EVPD pages available.
+ *     Returns list of inquiry VPD pages available.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
@@ -1610,7 +1612,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 EVPD pages */
+       rbuf[3] = sizeof(pages);        /* number of supported VPD pages */
 
        if (buflen > 6)
                memcpy(rbuf + 4, pages, sizeof(pages));
@@ -1619,7 +1621,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
- *     ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number
+ *     ata_scsiop_inq_80 - Simulate INQUIRY VPD 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.
@@ -1642,22 +1644,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_dev_id_string(args->id, (unsigned char *) &rbuf[4],
-                                 ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
+               ata_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 EVPD page 83, device identity
+ *     ata_scsiop_inq_83 - Simulate INQUIRY VPD 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.
  *
- *     Returns device identification.  Currently hardcoded to
- *     return "Linux ATA-SCSI simulator".
+ *     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.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
@@ -1666,16 +1668,39 @@ static const char * const inq_83_str = "Linux ATA-SCSI simulator";
 unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
                              unsigned int buflen)
 {
-       rbuf[1] = 0x83;                 /* this page code */
-       rbuf[3] = 4 + strlen(inq_83_str);       /* page len */
+       int num;
+       const int sat_model_serial_desc_len = 68;
+       const int ata_model_byte_len = 40;
 
-       /* 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[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] = num - 4;    /* page len (assume less than 256 bytes) */
        return 0;
 }
 
@@ -1803,18 +1828,17 @@ static int ata_dev_supports_fua(u16 *id)
 {
        unsigned char model[41], fw[9];
 
+       if (!libata_fua)
+               return 0;
        if (!ata_id_has_fua(id))
                return 0;
 
-       model[40] = '\0';
-       fw[8] = '\0';
-
-       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);
+       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));
 
-       if (strncmp(model, "Maxtor", 6))
+       if (strcmp(model, "Maxtor"))
                return 1;
-       if (strncmp(fw, "BANC1G10", 8))
+       if (strcmp(fw, "BANC1G10"))
                return 1;
 
        return 0; /* blacklisted */
@@ -2149,7 +2173,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, ap->cdb_len);
+       memset(&qc->cdb, 0, qc->dev->cdb_len);
        qc->cdb[0] = REQUEST_SENSE;
        qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
 
@@ -2251,7 +2275,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, qc->ap->cdb_len);
+       memcpy(&qc->cdb, scsicmd, dev->cdb_len);
 
        qc->complete_fn = atapi_qc_complete;