Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block
[sfrench/cifs-2.6.git] / drivers / ata / libata-scsi.c
index 79550908adccfadab22e70eb6f4165bb91aaa94d..9fbb39cd0f5892414a6cb72d4378de8c99da960f 100644 (file)
@@ -71,11 +71,10 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
 #define ALL_SUB_MPAGES 0xff
 
 
-static const u8 def_rw_recovery_mpage[] = {
+static const u8 def_rw_recovery_mpage[RW_RECOVERY_MPAGE_LEN] = {
        RW_RECOVERY_MPAGE,
        RW_RECOVERY_MPAGE_LEN - 2,
-       (1 << 7) |      /* AWRE, sat-r06 say it shall be 0 */
-           (1 << 6),   /* ARRE (auto read reallocation) */
+       (1 << 7),       /* AWRE */
        0,              /* read retry count */
        0, 0, 0, 0,
        0,              /* write retry count */
@@ -750,6 +749,13 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
+
+       /* Schedule policy is determined by ->qc_defer() callback and
+        * it needs to see every deferred qc.  Set dev_blocked to 1 to
+        * prevent SCSI midlayer from automatically deferring
+        * requests.
+        */
+       sdev->max_device_blocked = 1;
 }
 
 static void ata_scsi_dev_config(struct scsi_device *sdev,
@@ -795,8 +801,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 
        ata_scsi_sdev_config(sdev);
 
-       blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
-
        sdev->manage_start_stop = 1;
 
        if (dev)
@@ -938,6 +942,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
                goto invalid_fld;       /* LOEJ bit set not supported */
        if (((cdb[4] >> 4) & 0xf) != 0)
                goto invalid_fld;       /* power conditions not supported */
+
+       if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) {
+               /* the device lacks PM support, finish without doing anything */
+               scmd->result = SAM_STAT_GOOD;
+               return 1;
+       }
+
        if (cdb[4] & 0x1) {
                tf->nsect = 1;  /* 1 sector, lba=0 */
 
@@ -1350,6 +1361,7 @@ nothing_to_do:
 static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       struct ata_eh_info *ehi = &qc->dev->link->eh_info;
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
        int need_sense = (qc->err_mask != 0);
@@ -1363,14 +1375,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
                case ATA_CMD_SET_FEATURES:
                        if ((qc->tf.feature == SETFEATURES_WC_ON) ||
                            (qc->tf.feature == SETFEATURES_WC_OFF)) {
-                               ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+                               ehi->action |= ATA_EH_REVALIDATE;
                                ata_port_schedule_eh(ap);
                        }
                        break;
 
                case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
                case ATA_CMD_SET_MULTI: /* multi_count changed */
-                       ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+                       ehi->action |= ATA_EH_REVALIDATE;
                        ata_port_schedule_eh(ap);
                        break;
                }
@@ -1416,37 +1428,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
        ata_qc_free(qc);
 }
 
-/**
- *     ata_scmd_need_defer - Check whether we need to defer scmd
- *     @dev: ATA device to which the command is addressed
- *     @is_io: Is the command IO (and thus possibly NCQ)?
- *
- *     NCQ and non-NCQ commands cannot run together.  As upper layer
- *     only knows the queue depth, we are responsible for maintaining
- *     exclusion.  This function checks whether a new command can be
- *     issued to @dev.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- *
- *     RETURNS:
- *     1 if deferring is needed, 0 otherwise.
- */
-static int ata_scmd_need_defer(struct ata_device *dev, int is_io)
-{
-       struct ata_link *link = dev->link;
-       int is_ncq = is_io && ata_ncq_enabled(dev);
-
-       if (is_ncq) {
-               if (!ata_tag_valid(link->active_tag))
-                       return 0;
-       } else {
-               if (!ata_tag_valid(link->active_tag) && !link->sactive)
-                       return 0;
-       }
-       return 1;
-}
-
 /**
  *     ata_scsi_translate - Translate then issue SCSI command to ATA device
  *     @dev: ATA device to which the command is addressed
@@ -1478,14 +1459,12 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *),
                              ata_xlat_func_t xlat_func)
 {
+       struct ata_port *ap = dev->link->ap;
        struct ata_queued_cmd *qc;
-       int is_io = xlat_func == ata_scsi_rw_xlat;
+       int rc;
 
        VPRINTK("ENTER\n");
 
-       if (unlikely(ata_scmd_need_defer(dev, is_io)))
-               goto defer;
-
        qc = ata_scsi_qc_new(dev, cmd, done);
        if (!qc)
                goto err_mem;
@@ -1509,6 +1488,11 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
        if (xlat_func(qc))
                goto early_finish;
 
+       if (ap->ops->qc_defer) {
+               if ((rc = ap->ops->qc_defer(qc)))
+                       goto defer;
+       }
+
        /* select device, send command to hardware */
        ata_qc_issue(qc);
 
@@ -1530,8 +1514,12 @@ err_mem:
        return 0;
 
 defer:
+       ata_qc_free(qc);
        DPRINTK("EXIT - defer\n");
-       return SCSI_MLQUEUE_DEVICE_BUSY;
+       if (rc == ATA_DEFER_LINK)
+               return SCSI_MLQUEUE_DEVICE_BUSY;
+       else
+               return SCSI_MLQUEUE_HOST_BUSY;
 }
 
 /**
@@ -1832,8 +1820,9 @@ unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
        pbuf[2] = (0x238 >> 8);         /* page size fixed at 238h */
        pbuf[3] = (0x238 & 0xff);
 
-       memcpy(&pbuf[8], "ATA     ", 8);
-       ata_id_string(args->id, &pbuf[16], ATA_ID_PROD, 16);
+       memcpy(&pbuf[8], "linux   ", 8);
+       memcpy(&pbuf[16], "libata          ", 16);
+       memcpy(&pbuf[32], DRV_VERSION, 4);
        ata_id_string(args->id, &pbuf[32], ATA_ID_FW_REV, 4);
 
        /* we don't store the ATA device signature, so we fake it */
@@ -2315,8 +2304,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
                qc->tf.feature |= ATAPI_PKT_DMA;
        } else {
                qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
+               qc->tf.lbam = SCSI_SENSE_BUFFERSIZE;
+               qc->tf.lbah = 0;
        }
        qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
@@ -2425,6 +2414,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        struct ata_device *dev = qc->dev;
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
+       unsigned int nbytes;
 
        memset(qc->cdb, 0, dev->cdb_len);
        memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
@@ -2444,14 +2434,20 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        if (!using_pio && ata_check_atapi_dma(qc))
                using_pio = 1;
 
+       /* Some controller variants snoop this value for Packet transfers
+          to do state machine and FIFO management. Thus we want to set it
+          properly, and for DMA where it is effectively meaningless */
+       nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
+
+       qc->tf.lbam = (nbytes & 0xFF);
+       qc->tf.lbah = (nbytes >> 8);
+
        if (using_pio || nodata) {
                /* no data, or PIO data xfer */
                if (nodata)
                        qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
                else
                        qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
        } else {
                /* DMA data xfer */
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
@@ -2462,6 +2458,9 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
                        qc->tf.feature |= ATAPI_DMADIR;
        }
 
+
+       /* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE
+          as ATAPI tape drives don't get this right otherwise */
        return 0;
 }
 
@@ -2920,14 +2919,9 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
        args.done = done;
 
        switch(scsicmd[0]) {
-               /* no-op's, complete with success */
-               case SYNCHRONIZE_CACHE:
-               case REZERO_UNIT:
-               case SEEK_6:
-               case SEEK_10:
-               case TEST_UNIT_READY:
-               case FORMAT_UNIT:               /* FIXME: correct? */
-                       ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
+               /* TODO: worth improving? */
+               case FORMAT_UNIT:
+                       ata_scsi_invalid_field(cmd, done);
                        break;
 
                case INQUIRY:
@@ -2985,6 +2979,20 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
                        done(cmd);
                        break;
 
+               /* if we reach this, then writeback caching is disabled,
+                * turning this into a no-op.
+                */
+               case SYNCHRONIZE_CACHE:
+                       /* fall through */
+
+               /* no-op's, complete with success */
+               case REZERO_UNIT:
+               case SEEK_6:
+               case SEEK_10:
+               case TEST_UNIT_READY:
+                       ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
+                       break;
+
                case SEND_DIAGNOSTIC:
                        tmp8 = scsicmd[1] & ~(1 << 3);
                        if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
@@ -3025,6 +3033,13 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                shost->max_channel = 1;
                shost->max_cmd_len = 16;
 
+               /* Schedule policy is determined by ->qc_defer()
+                * callback and it needs to see every deferred qc.
+                * Set host_blocked to 1 to prevent SCSI midlayer from
+                * automatically deferring requests.
+                */
+               shost->max_host_blocked = 1;
+
                rc = scsi_add_host(ap->scsi_host, ap->host->dev);
                if (rc)
                        goto err_add;
@@ -3223,21 +3238,21 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
 
 /**
  *     ata_scsi_media_change_notify - send media change event
- *     @atadev: Pointer to the disk device with media change event
+ *     @dev: Pointer to the disk device with media change event
  *
  *     Tell the block layer to send a media change notification
  *     event.
  *
  *     LOCKING:
- *     interrupt context, may not sleep.
+ *     spin_lock_irqsave(host lock)
  */
-void ata_scsi_media_change_notify(struct ata_device *atadev)
+void ata_scsi_media_change_notify(struct ata_device *dev)
 {
 #ifdef OTHER_AN_PATCHES_HAVE_BEEN_APPLIED
-       scsi_device_event_notify(atadev->sdev, SDEV_MEDIA_CHANGE);
+       if (dev->sdev)
+               scsi_device_event_notify(dev->sdev, SDEV_MEDIA_CHANGE);
 #endif
 }
-EXPORT_SYMBOL_GPL(ata_scsi_media_change_notify);
 
 /**
  *     ata_scsi_hotplug - SCSI part of hotplug