Merge HEAD from ../scsi-misc-2.6-old
[pandora-kernel.git] / drivers / scsi / aacraid / aachba.c
index 44dbbe3..a913196 100644 (file)
@@ -313,18 +313,37 @@ int aac_get_containers(struct aac_dev *dev)
                }
                dresp = (struct aac_mount *)fib_data(fibptr);
 
+               if ((le32_to_cpu(dresp->status) == ST_OK) &&
+                   (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) {
+                       dinfo->command = cpu_to_le32(VM_NameServe64);
+                       dinfo->count = cpu_to_le32(index);
+                       dinfo->type = cpu_to_le32(FT_FILESYS);
+
+                       if (fib_send(ContainerCommand,
+                                   fibptr,
+                                   sizeof(struct aac_query_mount),
+                                   FsaNormal,
+                                   1, 1,
+                                   NULL, NULL) < 0)
+                               continue;
+               } else
+                       dresp->mnt[0].capacityhigh = 0;
+
                dprintk ((KERN_DEBUG
-                 "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%u\n",
+                 "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n",
                  (int)index, (int)le32_to_cpu(dresp->status),
                  (int)le32_to_cpu(dresp->mnt[0].vol),
                  (int)le32_to_cpu(dresp->mnt[0].state),
-                 (unsigned)le32_to_cpu(dresp->mnt[0].capacity)));
+                 ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+                   (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32)));
                if ((le32_to_cpu(dresp->status) == ST_OK) &&
                    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
                    (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
                        fsa_dev_ptr[index].valid = 1;
                        fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol);
-                       fsa_dev_ptr[index].size = le32_to_cpu(dresp->mnt[0].capacity);
+                       fsa_dev_ptr[index].size
+                         = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+                           (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);
                        if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
                                    fsa_dev_ptr[index].ro = 1;
                }
@@ -460,7 +479,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
  *     is updated in the struct fsa_dev_info structure rather than returned.
  */
  
-static int probe_container(struct aac_dev *dev, int cid)
+int probe_container(struct aac_dev *dev, int cid)
 {
        struct fsa_dev_info *fsa_dev_ptr;
        int status;
@@ -496,12 +515,30 @@ static int probe_container(struct aac_dev *dev, int cid)
 
        dresp = (struct aac_mount *) fib_data(fibptr);
 
+       if ((le32_to_cpu(dresp->status) == ST_OK) &&
+           (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) {
+               dinfo->command = cpu_to_le32(VM_NameServe64);
+               dinfo->count = cpu_to_le32(cid);
+               dinfo->type = cpu_to_le32(FT_FILESYS);
+
+               if (fib_send(ContainerCommand,
+                           fibptr,
+                           sizeof(struct aac_query_mount),
+                           FsaNormal,
+                           1, 1,
+                           NULL, NULL) < 0)
+                       goto error;
+       } else
+               dresp->mnt[0].capacityhigh = 0;
+
        if ((le32_to_cpu(dresp->status) == ST_OK) &&
            (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
            (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
                fsa_dev_ptr[cid].valid = 1;
                fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol);
-               fsa_dev_ptr[cid].size = le32_to_cpu(dresp->mnt[0].capacity);
+               fsa_dev_ptr[cid].size
+                 = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
+                   (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);
                if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
                        fsa_dev_ptr[cid].ro = 1;
        }
@@ -683,7 +720,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
                         fibptr, 
                         sizeof(*info),
                         FsaNormal, 
-                        1, 1, 
+                        -1, 1, /* First `interrupt' command uses special wait */
                         NULL, 
                         NULL);
 
@@ -834,8 +871,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
        if (!(dev->raw_io_interface)) {
                dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
                        sizeof(struct aac_fibhdr) -
-                       sizeof(struct aac_write) + sizeof(struct sgmap)) /
-                               sizeof(struct sgmap);
+                       sizeof(struct aac_write) + sizeof(struct sgentry)) /
+                               sizeof(struct sgentry);
                if (dev->dac_support) {
                        /* 
                         * 38 scatter gather elements 
@@ -844,8 +881,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
                                (dev->max_fib_size -
                                sizeof(struct aac_fibhdr) -
                                sizeof(struct aac_write64) +
-                               sizeof(struct sgmap64)) /
-                                       sizeof(struct sgmap64);
+                               sizeof(struct sgentry64)) /
+                                       sizeof(struct sgentry64);
                }
                dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
                if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
@@ -882,7 +919,40 @@ static void io_callback(void *context, struct fib * fibptr)
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
        cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
-       dprintk((KERN_DEBUG "io_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3], jiffies));
+       if (nblank(dprintk(x))) {
+               u64 lba;
+               switch (scsicmd->cmnd[0]) {
+               case WRITE_6:
+               case READ_6:
+                       lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
+                           (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+                       break;
+               case WRITE_16:
+               case READ_16:
+                       lba = ((u64)scsicmd->cmnd[2] << 56) |
+                             ((u64)scsicmd->cmnd[3] << 48) |
+                             ((u64)scsicmd->cmnd[4] << 40) |
+                             ((u64)scsicmd->cmnd[5] << 32) |
+                             ((u64)scsicmd->cmnd[6] << 24) |
+                             (scsicmd->cmnd[7] << 16) |
+                             (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+                       break;
+               case WRITE_12:
+               case READ_12:
+                       lba = ((u64)scsicmd->cmnd[2] << 24) |
+                             (scsicmd->cmnd[3] << 16) |
+                             (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+                       break;
+               default:
+                       lba = ((u64)scsicmd->cmnd[2] << 24) |
+                              (scsicmd->cmnd[3] << 16) |
+                              (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+                       break;
+               }
+               printk(KERN_DEBUG
+                 "io_callback[cpu %d]: lba = %llu, t = %ld.\n",
+                 smp_processor_id(), (unsigned long long)lba, jiffies);
+       }
 
        if (fibptr == NULL)
                BUG();
@@ -923,7 +993,7 @@ static void io_callback(void *context, struct fib * fibptr)
 
 static int aac_read(struct scsi_cmnd * scsicmd, int cid)
 {
-       u32 lba;
+       u64 lba;
        u32 count;
        int status;
 
@@ -935,23 +1005,69 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Get block address and transfer length
         */
-       if (scsicmd->cmnd[0] == READ_6) /* 6 byte command */
-       {
+       switch (scsicmd->cmnd[0]) {
+       case READ_6:
                dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid));
 
-               lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+               lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | 
+                       (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
                count = scsicmd->cmnd[4];
 
                if (count == 0)
                        count = 256;
-       } else {
+               break;
+       case READ_16:
+               dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid));
+
+               lba =   ((u64)scsicmd->cmnd[2] << 56) |
+                       ((u64)scsicmd->cmnd[3] << 48) |
+                       ((u64)scsicmd->cmnd[4] << 40) |
+                       ((u64)scsicmd->cmnd[5] << 32) |
+                       ((u64)scsicmd->cmnd[6] << 24) | 
+                       (scsicmd->cmnd[7] << 16) |
+                       (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+               count = (scsicmd->cmnd[10] << 24) | 
+                       (scsicmd->cmnd[11] << 16) |
+                       (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
+               break;
+       case READ_12:
+               dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid));
+
+               lba = ((u64)scsicmd->cmnd[2] << 24) | 
+                       (scsicmd->cmnd[3] << 16) |
+                       (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+               count = (scsicmd->cmnd[6] << 24) | 
+                       (scsicmd->cmnd[7] << 16) |
+                       (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+               break;
+       default:
                dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid));
 
-               lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+               lba = ((u64)scsicmd->cmnd[2] << 24) | 
+                       (scsicmd->cmnd[3] << 16) | 
+                       (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
+               break;
        }
-       dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n",
+       dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
          smp_processor_id(), (unsigned long long)lba, jiffies));
+       if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) &&
+               (lba & 0xffffffff00000000LL)) {
+               dprintk((KERN_DEBUG "aac_read: Illegal lba\n"));
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | 
+                       SAM_STAT_CHECK_CONDITION;
+               set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+                           HARDWARE_ERROR,
+                           SENCODE_INTERNAL_TARGET_FAILURE,
+                           ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+                           0, 0);
+               memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+                 (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+                   ? sizeof(scsicmd->sense_buffer)
+                   : sizeof(dev->fsa_dev[cid].sense_data));
+               scsicmd->scsi_done(scsicmd);
+               return 0;
+       }
        /*
         *      Alocate and initialize a Fib
         */
@@ -964,8 +1080,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
        if (dev->raw_io_interface) {
                struct aac_raw_io *readcmd;
                readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
-               readcmd->block[0] = cpu_to_le32(lba);
-               readcmd->block[1] = 0;
+               readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+               readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
                readcmd->count = cpu_to_le32(count<<9);
                readcmd->cid = cpu_to_le16(cid);
                readcmd->flags = cpu_to_le16(1);
@@ -992,7 +1108,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                readcmd->command = cpu_to_le32(VM_CtHostRead64);
                readcmd->cid = cpu_to_le16(cid);
                readcmd->sector_count = cpu_to_le16(count);
-               readcmd->block = cpu_to_le32(lba);
+               readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
                readcmd->pad   = 0;
                readcmd->flags = 0; 
 
@@ -1017,7 +1133,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
                readcmd->command = cpu_to_le32(VM_CtBlockRead);
                readcmd->cid = cpu_to_le32(cid);
-               readcmd->block = cpu_to_le32(lba);
+               readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
                readcmd->count = cpu_to_le32(count * 512);
 
                aac_build_sg(scsicmd, &readcmd->sg);
@@ -1059,7 +1175,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
 
 static int aac_write(struct scsi_cmnd * scsicmd, int cid)
 {
-       u32 lba;
+       u64 lba;
        u32 count;
        int status;
        u16 fibsize;
@@ -1076,13 +1192,48 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                count = scsicmd->cmnd[4];
                if (count == 0)
                        count = 256;
+       } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
+               dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid));
+
+               lba =   ((u64)scsicmd->cmnd[2] << 56) |
+                       ((u64)scsicmd->cmnd[3] << 48) |
+                       ((u64)scsicmd->cmnd[4] << 40) |
+                       ((u64)scsicmd->cmnd[5] << 32) |
+                       ((u64)scsicmd->cmnd[6] << 24) | 
+                       (scsicmd->cmnd[7] << 16) |
+                       (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+               count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
+                       (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
+       } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
+               dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid));
+
+               lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16)
+                   | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+               count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
+                     | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
        } else {
                dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid));
-               lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+               lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
        }
-       dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n",
+       dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
          smp_processor_id(), (unsigned long long)lba, jiffies));
+       if ((!(dev->raw_io_interface) || !(dev->raw_io_64))
+        && (lba & 0xffffffff00000000LL)) {
+               dprintk((KERN_DEBUG "aac_write: Illegal lba\n"));
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+               set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+                           HARDWARE_ERROR,
+                           SENCODE_INTERNAL_TARGET_FAILURE,
+                           ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+                           0, 0);
+               memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+                 (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+                   ? sizeof(scsicmd->sense_buffer)
+                   : sizeof(dev->fsa_dev[cid].sense_data));
+               scsicmd->scsi_done(scsicmd);
+               return 0;
+       }
        /*
         *      Allocate and initialize a Fib then setup a BlockWrite command
         */
@@ -1096,8 +1247,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
        if (dev->raw_io_interface) {
                struct aac_raw_io *writecmd;
                writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
-               writecmd->block[0] = cpu_to_le32(lba);
-               writecmd->block[1] = 0;
+               writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+               writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
                writecmd->count = cpu_to_le32(count<<9);
                writecmd->cid = cpu_to_le16(cid);
                writecmd->flags = 0; 
@@ -1124,7 +1275,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                writecmd->command = cpu_to_le32(VM_CtHostWrite64);
                writecmd->cid = cpu_to_le16(cid);
                writecmd->sector_count = cpu_to_le16(count); 
-               writecmd->block = cpu_to_le32(lba);
+               writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
                writecmd->pad   = 0;
                writecmd->flags = 0;
 
@@ -1149,7 +1300,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
                writecmd->command = cpu_to_le32(VM_CtBlockWrite);
                writecmd->cid = cpu_to_le32(cid);
-               writecmd->block = cpu_to_le32(lba);
+               writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
                writecmd->count = cpu_to_le32(count * 512);
                writecmd->sg.count = cpu_to_le32(1);
                /* ->stable is not used - it did mean which type of write */
@@ -1337,11 +1488,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                         */
                        if ((fsa_dev_ptr[cid].valid & 1) == 0) {
                                switch (scsicmd->cmnd[0]) {
+                               case SERVICE_ACTION_IN:
+                                       if (!(dev->raw_io_interface) ||
+                                           !(dev->raw_io_64) ||
+                                           ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+                                               break;
                                case INQUIRY:
                                case READ_CAPACITY:
                                case TEST_UNIT_READY:
                                        spin_unlock_irq(host->host_lock);
                                        probe_container(dev, cid);
+                                       if ((fsa_dev_ptr[cid].valid & 1) == 0)
+                                               fsa_dev_ptr[cid].valid = 0;
                                        spin_lock_irq(host->host_lock);
                                        if (fsa_dev_ptr[cid].valid == 0) {
                                                scsicmd->result = DID_NO_CONNECT << 16;
@@ -1402,7 +1560,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                memset(&inq_data, 0, sizeof (struct inquiry_data));
 
                inq_data.inqd_ver = 2;  /* claim compliance to SCSI-2 */
-               inq_data.inqd_dtq = 0x80;       /* set RMB bit to one indicating that the medium is removable */
                inq_data.inqd_rdf = 2;  /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
                inq_data.inqd_len = 31;
                /*Format for "pad2" is  RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
@@ -1424,13 +1581,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
                return aac_get_container_name(scsicmd, cid);
        }
+       case SERVICE_ACTION_IN:
+               if (!(dev->raw_io_interface) ||
+                   !(dev->raw_io_64) ||
+                   ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+                       break;
+       {
+               u64 capacity;
+               char cp[12];
+               unsigned int offset = 0;
+
+               dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
+               capacity = fsa_dev_ptr[cid].size - 1;
+               if (scsicmd->cmnd[13] > 12) {
+                       offset = scsicmd->cmnd[13] - 12;
+                       if (offset > sizeof(cp))
+                               break;
+                       memset(cp, 0, offset);
+                       aac_internal_transfer(scsicmd, cp, 0, offset);
+               }
+               cp[0] = (capacity >> 56) & 0xff;
+               cp[1] = (capacity >> 48) & 0xff;
+               cp[2] = (capacity >> 40) & 0xff;
+               cp[3] = (capacity >> 32) & 0xff;
+               cp[4] = (capacity >> 24) & 0xff;
+               cp[5] = (capacity >> 16) & 0xff;
+               cp[6] = (capacity >> 8) & 0xff;
+               cp[7] = (capacity >> 0) & 0xff;
+               cp[8] = 0;
+               cp[9] = 0;
+               cp[10] = 2;
+               cp[11] = 0;
+               aac_internal_transfer(scsicmd, cp, offset, sizeof(cp));
+
+               /* Do not cache partition table for arrays */
+               scsicmd->device->removable = 1;
+
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+               scsicmd->scsi_done(scsicmd);
+
+               return 0;
+       }
+
        case READ_CAPACITY:
        {
                u32 capacity;
                char cp[8];
 
                dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
-               if (fsa_dev_ptr[cid].size <= 0x100000000LL)
+               if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
                        capacity = fsa_dev_ptr[cid].size - 1;
                else
                        capacity = (u32)-1;
@@ -1444,6 +1643,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                cp[6] = 2;
                cp[7] = 0;
                aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
+               /* Do not cache partition table for arrays */
+               scsicmd->device->removable = 1;
 
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
@@ -1524,6 +1725,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
        {
                case READ_6:
                case READ_10:
+               case READ_12:
+               case READ_16:
                        /*
                         *      Hack to keep track of ordinal number of the device that
                         *      corresponds to a container. Needed to convert
@@ -1531,17 +1734,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                         */
                         
                        spin_unlock_irq(host->host_lock);
-                       if  (scsicmd->request->rq_disk)
-                               memcpy(fsa_dev_ptr[cid].devname,
-                                       scsicmd->request->rq_disk->disk_name,
-                                       8);
-
+                       if (scsicmd->request->rq_disk)
+                               strlcpy(fsa_dev_ptr[cid].devname,
+                               scsicmd->request->rq_disk->disk_name,
+                               min(sizeof(fsa_dev_ptr[cid].devname),
+                               sizeof(scsicmd->request->rq_disk->disk_name) + 1));
                        ret = aac_read(scsicmd, cid);
                        spin_lock_irq(host->host_lock);
                        return ret;
 
                case WRITE_6:
                case WRITE_10:
+               case WRITE_12:
+               case WRITE_16:
                        spin_unlock_irq(host->host_lock);
                        ret = aac_write(scsicmd, cid);
                        spin_lock_irq(host->host_lock);
@@ -1772,6 +1977,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
                case  WRITE_10:
                case  READ_12:
                case  WRITE_12:
+               case  READ_16:
+               case  WRITE_16:
                        if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) {
                                printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
                        } else {
@@ -1877,8 +2084,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
                                sizeof(scsicmd->sense_buffer) :
                                le32_to_cpu(srbreply->sense_data_size);
 #ifdef AAC_DETAILED_STATUS_INFO
-               dprintk((KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", 
-                                       le32_to_cpu(srbreply->status), len));
+               printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
+                                       le32_to_cpu(srbreply->status), len);
 #endif
                memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);