[PATCH] Centralise definitions of sector_t and blkcnt_t
[sfrench/cifs-2.6.git] / drivers / ata / libata-scsi.c
index 56d7e1ea9d7226a403ab8c11ca5be8dd15869a99..8eaace94d9631e9e2b64fdc3443ca26d0d41bf66 100644 (file)
@@ -1265,17 +1265,14 @@ nothing_to_do:
 
 static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
 {
-       struct ata_taskfile *tf = &qc->tf;
-       struct ata_device *dev = qc->dev;
+       unsigned int tf_flags = 0;
        u64 block;
        u32 n_block;
-
-       qc->flags |= ATA_QCFLAG_IO;
-       tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       int rc;
 
        if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
            scsicmd[0] == WRITE_16)
-               tf->flags |= ATA_TFLAG_WRITE;
+               tf_flags |= ATA_TFLAG_WRITE;
 
        /* Calculate the SCSI LBA, transfer length and FUA. */
        switch (scsicmd[0]) {
@@ -1283,7 +1280,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
        case WRITE_10:
                scsi_10_lba_len(scsicmd, &block, &n_block);
                if (unlikely(scsicmd[1] & (1 << 3)))
-                       tf->flags |= ATA_TFLAG_FUA;
+                       tf_flags |= ATA_TFLAG_FUA;
                break;
        case READ_6:
        case WRITE_6:
@@ -1299,7 +1296,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
        case WRITE_16:
                scsi_16_lba_len(scsicmd, &block, &n_block);
                if (unlikely(scsicmd[1] & (1 << 3)))
-                       tf->flags |= ATA_TFLAG_FUA;
+                       tf_flags |= ATA_TFLAG_FUA;
                break;
        default:
                DPRINTK("no-byte command\n");
@@ -1317,106 +1314,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                 */
                goto nothing_to_do;
 
-       if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
-                          ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
-               /* yay, NCQ */
-               if (!lba_48_ok(block, n_block))
-                       goto out_of_range;
-
-               tf->protocol = ATA_PROT_NCQ;
-               tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
-
-               if (tf->flags & ATA_TFLAG_WRITE)
-                       tf->command = ATA_CMD_FPDMA_WRITE;
-               else
-                       tf->command = ATA_CMD_FPDMA_READ;
-
-               qc->nsect = n_block;
-
-               tf->nsect = qc->tag << 3;
-               tf->hob_feature = (n_block >> 8) & 0xff;
-               tf->feature = n_block & 0xff;
-
-               tf->hob_lbah = (block >> 40) & 0xff;
-               tf->hob_lbam = (block >> 32) & 0xff;
-               tf->hob_lbal = (block >> 24) & 0xff;
-               tf->lbah = (block >> 16) & 0xff;
-               tf->lbam = (block >> 8) & 0xff;
-               tf->lbal = block & 0xff;
-
-               tf->device = 1 << 6;
-               if (tf->flags & ATA_TFLAG_FUA)
-                       tf->device |= 1 << 7;
-       } else 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))
-                               goto out_of_range;
-
-                       /* use LBA48 */
-                       tf->flags |= ATA_TFLAG_LBA48;
-
-                       tf->hob_nsect = (n_block >> 8) & 0xff;
-
-                       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;
-
-               if (unlikely(ata_rwcmd_protocol(qc) < 0))
-                       goto invalid_fld;
-
-               qc->nsect = n_block;
-               tf->nsect = n_block & 0xff;
-
-               tf->lbah = (block >> 16) & 0xff;
-               tf->lbam = (block >> 8) & 0xff;
-               tf->lbal = block & 0xff;
-
-               tf->device |= ATA_LBA;
-       } else {
-               /* CHS */
-               u32 sect, head, cyl, track;
-
-               /* The request -may- be too large for CHS addressing. */
-               if (!lba_28_ok(block, n_block))
-                       goto out_of_range;
-
-               if (unlikely(ata_rwcmd_protocol(qc) < 0))
-                       goto invalid_fld;
-
-               /* Convert LBA to CHS */
-               track = (u32)block / dev->sectors;
-               cyl   = track / dev->heads;
-               head  = track % dev->heads;
-               sect  = (u32)block % dev->sectors + 1;
-
-               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
-                  Head: 0-15
-                  Sector: 1-255*/
-               if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
-                       goto out_of_range;
-
-               qc->nsect = n_block;
-               tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
-               tf->lbal = sect;
-               tf->lbam = cyl;
-               tf->lbah = cyl >> 8;
-               tf->device |= head;
-       }
+       qc->flags |= ATA_QCFLAG_IO;
+       qc->nsect = n_block;
 
-       return 0;
+       rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
+                            qc->tag);
+       if (likely(rc == 0))
+               return 0;
 
+       if (rc == -ERANGE)
+               goto out_of_range;
+       /* treat all other errors as -EINVAL, fall through */
 invalid_fld:
        ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
        /* "Invalid field in cbd" */
@@ -1697,6 +1605,22 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
        args->done(cmd);
 }
 
+/**
+ *     ATA_SCSI_RBUF_SET - helper to set values in SCSI response buffer
+ *     @idx: byte index into SCSI response buffer
+ *     @val: value to set
+ *
+ *     To be used by SCSI command simulator functions.  This macros
+ *     expects two local variables, u8 *rbuf and unsigned int buflen,
+ *     are in scope.
+ *
+ *     LOCKING:
+ *     None.
+ */
+#define ATA_SCSI_RBUF_SET(idx, val) do { \
+               if ((idx) < buflen) rbuf[(idx)] = (u8)(val); \
+       } while (0)
+
 /**
  *     ata_scsiop_inq_std - Simulate INQUIRY command
  *     @args: device IDENTIFY data / SCSI command of interest.
@@ -2156,67 +2080,42 @@ saving_not_supp:
  *     Simulate READ CAPACITY commands.
  *
  *     LOCKING:
- *     spin_lock_irqsave(host lock)
+ *     None.
  */
-
 unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
                                unsigned int buflen)
 {
-       u64 n_sectors;
-       u32 tmp;
+       u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
 
        VPRINTK("ENTER\n");
 
-       if (ata_id_has_lba(args->id)) {
-               if (ata_id_has_lba48(args->id))
-                       n_sectors = ata_id_u64(args->id, 100);
-               else
-                       n_sectors = ata_id_u32(args->id, 60);
-       } else {
-               /* CHS default translation */
-               n_sectors = args->id[1] * args->id[3] * args->id[6];
-
-               if (ata_id_current_chs_valid(args->id))
-                       /* CHS current translation */
-                       n_sectors = ata_id_u32(args->id, 57);
-       }
-
-       n_sectors--;            /* ATA TotalUserSectors - 1 */
-
        if (args->cmd->cmnd[0] == READ_CAPACITY) {
-               if( n_sectors >= 0xffffffffULL )
-                       tmp = 0xffffffff ;  /* Return max count on overflow */
-               else
-                       tmp = n_sectors ;
+               if (last_lba >= 0xffffffffULL)
+                       last_lba = 0xffffffff;
 
                /* sector count, 32-bit */
-               rbuf[0] = tmp >> (8 * 3);
-               rbuf[1] = tmp >> (8 * 2);
-               rbuf[2] = tmp >> (8 * 1);
-               rbuf[3] = tmp;
+               ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 3));
+               ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 2));
+               ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 1));
+               ATA_SCSI_RBUF_SET(3, last_lba);
 
                /* sector size */
-               tmp = ATA_SECT_SIZE;
-               rbuf[6] = tmp >> 8;
-               rbuf[7] = tmp;
-
+               ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8);
+               ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE);
        } else {
                /* sector count, 64-bit */
-               tmp = n_sectors >> (8 * 4);
-               rbuf[2] = tmp >> (8 * 3);
-               rbuf[3] = tmp >> (8 * 2);
-               rbuf[4] = tmp >> (8 * 1);
-               rbuf[5] = tmp;
-               tmp = n_sectors;
-               rbuf[6] = tmp >> (8 * 3);
-               rbuf[7] = tmp >> (8 * 2);
-               rbuf[8] = tmp >> (8 * 1);
-               rbuf[9] = tmp;
+               ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7));
+               ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 6));
+               ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 5));
+               ATA_SCSI_RBUF_SET(3, last_lba >> (8 * 4));
+               ATA_SCSI_RBUF_SET(4, last_lba >> (8 * 3));
+               ATA_SCSI_RBUF_SET(5, last_lba >> (8 * 2));
+               ATA_SCSI_RBUF_SET(6, last_lba >> (8 * 1));
+               ATA_SCSI_RBUF_SET(7, last_lba);
 
                /* sector size */
-               tmp = ATA_SECT_SIZE;
-               rbuf[12] = tmp >> 8;
-               rbuf[13] = tmp;
+               ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8);
+               ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE);
        }
 
        return 0;
@@ -3190,15 +3089,27 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
 void ata_scsi_dev_rescan(void *data)
 {
        struct ata_port *ap = data;
-       struct ata_device *dev;
+       unsigned long flags;
        unsigned int i;
 
+       spin_lock_irqsave(ap->lock, flags);
+
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               dev = &ap->device[i];
+               struct ata_device *dev = &ap->device[i];
+               struct scsi_device *sdev = dev->sdev;
 
-               if (ata_dev_enabled(dev) && dev->sdev)
-                       scsi_rescan_device(&(dev->sdev->sdev_gendev));
+               if (!ata_dev_enabled(dev) || !sdev)
+                       continue;
+               if (scsi_device_get(sdev))
+                       continue;
+
+               spin_unlock_irqrestore(ap->lock, flags);
+               scsi_rescan_device(&(sdev->sdev_gendev));
+               scsi_device_put(sdev);
+               spin_lock_irqsave(ap->lock, flags);
        }
+
+       spin_unlock_irqrestore(ap->lock, flags);
 }
 
 /**