diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-04 10:16:31 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-04 10:16:31 -0400 |
commit | 2ee73cc2d507df7b28050fba5d08bd33dd34848c (patch) | |
tree | af5f33b265318e0f4b61f788691fe4f780ec402c /drivers/scsi/aacraid/aachba.c | |
parent | c1d9728ecc5b560465df3c0c0d3b3825c2710b40 (diff) | |
parent | ed39f731ab2e77e58122232f6e27333331d7793d (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 283 |
1 files changed, 245 insertions, 38 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a8e3dfcd0dc7..93416f760e5a 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -313,18 +313,37 @@ int aac_get_containers(struct aac_dev *dev) | |||
313 | } | 313 | } |
314 | dresp = (struct aac_mount *)fib_data(fibptr); | 314 | dresp = (struct aac_mount *)fib_data(fibptr); |
315 | 315 | ||
316 | if ((le32_to_cpu(dresp->status) == ST_OK) && | ||
317 | (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { | ||
318 | dinfo->command = cpu_to_le32(VM_NameServe64); | ||
319 | dinfo->count = cpu_to_le32(index); | ||
320 | dinfo->type = cpu_to_le32(FT_FILESYS); | ||
321 | |||
322 | if (fib_send(ContainerCommand, | ||
323 | fibptr, | ||
324 | sizeof(struct aac_query_mount), | ||
325 | FsaNormal, | ||
326 | 1, 1, | ||
327 | NULL, NULL) < 0) | ||
328 | continue; | ||
329 | } else | ||
330 | dresp->mnt[0].capacityhigh = 0; | ||
331 | |||
316 | dprintk ((KERN_DEBUG | 332 | dprintk ((KERN_DEBUG |
317 | "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%u\n", | 333 | "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n", |
318 | (int)index, (int)le32_to_cpu(dresp->status), | 334 | (int)index, (int)le32_to_cpu(dresp->status), |
319 | (int)le32_to_cpu(dresp->mnt[0].vol), | 335 | (int)le32_to_cpu(dresp->mnt[0].vol), |
320 | (int)le32_to_cpu(dresp->mnt[0].state), | 336 | (int)le32_to_cpu(dresp->mnt[0].state), |
321 | (unsigned)le32_to_cpu(dresp->mnt[0].capacity))); | 337 | ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + |
338 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32))); | ||
322 | if ((le32_to_cpu(dresp->status) == ST_OK) && | 339 | if ((le32_to_cpu(dresp->status) == ST_OK) && |
323 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && | 340 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && |
324 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { | 341 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { |
325 | fsa_dev_ptr[index].valid = 1; | 342 | fsa_dev_ptr[index].valid = 1; |
326 | fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); | 343 | fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); |
327 | fsa_dev_ptr[index].size = le32_to_cpu(dresp->mnt[0].capacity); | 344 | fsa_dev_ptr[index].size |
345 | = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | ||
346 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); | ||
328 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) | 347 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) |
329 | fsa_dev_ptr[index].ro = 1; | 348 | fsa_dev_ptr[index].ro = 1; |
330 | } | 349 | } |
@@ -460,7 +479,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
460 | * is updated in the struct fsa_dev_info structure rather than returned. | 479 | * is updated in the struct fsa_dev_info structure rather than returned. |
461 | */ | 480 | */ |
462 | 481 | ||
463 | static int probe_container(struct aac_dev *dev, int cid) | 482 | int probe_container(struct aac_dev *dev, int cid) |
464 | { | 483 | { |
465 | struct fsa_dev_info *fsa_dev_ptr; | 484 | struct fsa_dev_info *fsa_dev_ptr; |
466 | int status; | 485 | int status; |
@@ -497,11 +516,29 @@ static int probe_container(struct aac_dev *dev, int cid) | |||
497 | dresp = (struct aac_mount *) fib_data(fibptr); | 516 | dresp = (struct aac_mount *) fib_data(fibptr); |
498 | 517 | ||
499 | if ((le32_to_cpu(dresp->status) == ST_OK) && | 518 | if ((le32_to_cpu(dresp->status) == ST_OK) && |
519 | (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { | ||
520 | dinfo->command = cpu_to_le32(VM_NameServe64); | ||
521 | dinfo->count = cpu_to_le32(cid); | ||
522 | dinfo->type = cpu_to_le32(FT_FILESYS); | ||
523 | |||
524 | if (fib_send(ContainerCommand, | ||
525 | fibptr, | ||
526 | sizeof(struct aac_query_mount), | ||
527 | FsaNormal, | ||
528 | 1, 1, | ||
529 | NULL, NULL) < 0) | ||
530 | goto error; | ||
531 | } else | ||
532 | dresp->mnt[0].capacityhigh = 0; | ||
533 | |||
534 | if ((le32_to_cpu(dresp->status) == ST_OK) && | ||
500 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && | 535 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && |
501 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { | 536 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { |
502 | fsa_dev_ptr[cid].valid = 1; | 537 | fsa_dev_ptr[cid].valid = 1; |
503 | fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); | 538 | fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); |
504 | fsa_dev_ptr[cid].size = le32_to_cpu(dresp->mnt[0].capacity); | 539 | fsa_dev_ptr[cid].size |
540 | = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | ||
541 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); | ||
505 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) | 542 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) |
506 | fsa_dev_ptr[cid].ro = 1; | 543 | fsa_dev_ptr[cid].ro = 1; |
507 | } | 544 | } |
@@ -655,7 +692,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
655 | fibptr, | 692 | fibptr, |
656 | sizeof(*info), | 693 | sizeof(*info), |
657 | FsaNormal, | 694 | FsaNormal, |
658 | 1, 1, | 695 | -1, 1, /* First `interrupt' command uses special wait */ |
659 | NULL, | 696 | NULL, |
660 | NULL); | 697 | NULL); |
661 | 698 | ||
@@ -806,8 +843,8 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
806 | if (!(dev->raw_io_interface)) { | 843 | if (!(dev->raw_io_interface)) { |
807 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - | 844 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - |
808 | sizeof(struct aac_fibhdr) - | 845 | sizeof(struct aac_fibhdr) - |
809 | sizeof(struct aac_write) + sizeof(struct sgmap)) / | 846 | sizeof(struct aac_write) + sizeof(struct sgentry)) / |
810 | sizeof(struct sgmap); | 847 | sizeof(struct sgentry); |
811 | if (dev->dac_support) { | 848 | if (dev->dac_support) { |
812 | /* | 849 | /* |
813 | * 38 scatter gather elements | 850 | * 38 scatter gather elements |
@@ -816,8 +853,8 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
816 | (dev->max_fib_size - | 853 | (dev->max_fib_size - |
817 | sizeof(struct aac_fibhdr) - | 854 | sizeof(struct aac_fibhdr) - |
818 | sizeof(struct aac_write64) + | 855 | sizeof(struct aac_write64) + |
819 | sizeof(struct sgmap64)) / | 856 | sizeof(struct sgentry64)) / |
820 | sizeof(struct sgmap64); | 857 | sizeof(struct sgentry64); |
821 | } | 858 | } |
822 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | 859 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; |
823 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | 860 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { |
@@ -854,7 +891,40 @@ static void io_callback(void *context, struct fib * fibptr) | |||
854 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 891 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
855 | cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); | 892 | cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); |
856 | 893 | ||
857 | 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)); | 894 | if (nblank(dprintk(x))) { |
895 | u64 lba; | ||
896 | switch (scsicmd->cmnd[0]) { | ||
897 | case WRITE_6: | ||
898 | case READ_6: | ||
899 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | | ||
900 | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | ||
901 | break; | ||
902 | case WRITE_16: | ||
903 | case READ_16: | ||
904 | lba = ((u64)scsicmd->cmnd[2] << 56) | | ||
905 | ((u64)scsicmd->cmnd[3] << 48) | | ||
906 | ((u64)scsicmd->cmnd[4] << 40) | | ||
907 | ((u64)scsicmd->cmnd[5] << 32) | | ||
908 | ((u64)scsicmd->cmnd[6] << 24) | | ||
909 | (scsicmd->cmnd[7] << 16) | | ||
910 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | ||
911 | break; | ||
912 | case WRITE_12: | ||
913 | case READ_12: | ||
914 | lba = ((u64)scsicmd->cmnd[2] << 24) | | ||
915 | (scsicmd->cmnd[3] << 16) | | ||
916 | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | ||
917 | break; | ||
918 | default: | ||
919 | lba = ((u64)scsicmd->cmnd[2] << 24) | | ||
920 | (scsicmd->cmnd[3] << 16) | | ||
921 | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | ||
922 | break; | ||
923 | } | ||
924 | printk(KERN_DEBUG | ||
925 | "io_callback[cpu %d]: lba = %llu, t = %ld.\n", | ||
926 | smp_processor_id(), (unsigned long long)lba, jiffies); | ||
927 | } | ||
858 | 928 | ||
859 | if (fibptr == NULL) | 929 | if (fibptr == NULL) |
860 | BUG(); | 930 | BUG(); |
@@ -895,7 +965,7 @@ static void io_callback(void *context, struct fib * fibptr) | |||
895 | 965 | ||
896 | static int aac_read(struct scsi_cmnd * scsicmd, int cid) | 966 | static int aac_read(struct scsi_cmnd * scsicmd, int cid) |
897 | { | 967 | { |
898 | u32 lba; | 968 | u64 lba; |
899 | u32 count; | 969 | u32 count; |
900 | int status; | 970 | int status; |
901 | 971 | ||
@@ -907,23 +977,69 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
907 | /* | 977 | /* |
908 | * Get block address and transfer length | 978 | * Get block address and transfer length |
909 | */ | 979 | */ |
910 | if (scsicmd->cmnd[0] == READ_6) /* 6 byte command */ | 980 | switch (scsicmd->cmnd[0]) { |
911 | { | 981 | case READ_6: |
912 | dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); | 982 | dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); |
913 | 983 | ||
914 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | 984 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | |
985 | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | ||
915 | count = scsicmd->cmnd[4]; | 986 | count = scsicmd->cmnd[4]; |
916 | 987 | ||
917 | if (count == 0) | 988 | if (count == 0) |
918 | count = 256; | 989 | count = 256; |
919 | } else { | 990 | break; |
991 | case READ_16: | ||
992 | dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); | ||
993 | |||
994 | lba = ((u64)scsicmd->cmnd[2] << 56) | | ||
995 | ((u64)scsicmd->cmnd[3] << 48) | | ||
996 | ((u64)scsicmd->cmnd[4] << 40) | | ||
997 | ((u64)scsicmd->cmnd[5] << 32) | | ||
998 | ((u64)scsicmd->cmnd[6] << 24) | | ||
999 | (scsicmd->cmnd[7] << 16) | | ||
1000 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | ||
1001 | count = (scsicmd->cmnd[10] << 24) | | ||
1002 | (scsicmd->cmnd[11] << 16) | | ||
1003 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; | ||
1004 | break; | ||
1005 | case READ_12: | ||
1006 | dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); | ||
1007 | |||
1008 | lba = ((u64)scsicmd->cmnd[2] << 24) | | ||
1009 | (scsicmd->cmnd[3] << 16) | | ||
1010 | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | ||
1011 | count = (scsicmd->cmnd[6] << 24) | | ||
1012 | (scsicmd->cmnd[7] << 16) | | ||
1013 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | ||
1014 | break; | ||
1015 | default: | ||
920 | dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); | 1016 | dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); |
921 | 1017 | ||
922 | lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | 1018 | lba = ((u64)scsicmd->cmnd[2] << 24) | |
1019 | (scsicmd->cmnd[3] << 16) | | ||
1020 | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | ||
923 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 1021 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
1022 | break; | ||
924 | } | 1023 | } |
925 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", | 1024 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", |
926 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1025 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1026 | if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) && | ||
1027 | (lba & 0xffffffff00000000LL)) { | ||
1028 | dprintk((KERN_DEBUG "aac_read: Illegal lba\n")); | ||
1029 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | | ||
1030 | SAM_STAT_CHECK_CONDITION; | ||
1031 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
1032 | HARDWARE_ERROR, | ||
1033 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
1034 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
1035 | 0, 0); | ||
1036 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1037 | (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) | ||
1038 | ? sizeof(scsicmd->sense_buffer) | ||
1039 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
1040 | scsicmd->scsi_done(scsicmd); | ||
1041 | return 0; | ||
1042 | } | ||
927 | /* | 1043 | /* |
928 | * Alocate and initialize a Fib | 1044 | * Alocate and initialize a Fib |
929 | */ | 1045 | */ |
@@ -936,8 +1052,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
936 | if (dev->raw_io_interface) { | 1052 | if (dev->raw_io_interface) { |
937 | struct aac_raw_io *readcmd; | 1053 | struct aac_raw_io *readcmd; |
938 | readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | 1054 | readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); |
939 | readcmd->block[0] = cpu_to_le32(lba); | 1055 | readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); |
940 | readcmd->block[1] = 0; | 1056 | readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); |
941 | readcmd->count = cpu_to_le32(count<<9); | 1057 | readcmd->count = cpu_to_le32(count<<9); |
942 | readcmd->cid = cpu_to_le16(cid); | 1058 | readcmd->cid = cpu_to_le16(cid); |
943 | readcmd->flags = cpu_to_le16(1); | 1059 | readcmd->flags = cpu_to_le16(1); |
@@ -964,7 +1080,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
964 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | 1080 | readcmd->command = cpu_to_le32(VM_CtHostRead64); |
965 | readcmd->cid = cpu_to_le16(cid); | 1081 | readcmd->cid = cpu_to_le16(cid); |
966 | readcmd->sector_count = cpu_to_le16(count); | 1082 | readcmd->sector_count = cpu_to_le16(count); |
967 | readcmd->block = cpu_to_le32(lba); | 1083 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); |
968 | readcmd->pad = 0; | 1084 | readcmd->pad = 0; |
969 | readcmd->flags = 0; | 1085 | readcmd->flags = 0; |
970 | 1086 | ||
@@ -989,7 +1105,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
989 | readcmd = (struct aac_read *) fib_data(cmd_fibcontext); | 1105 | readcmd = (struct aac_read *) fib_data(cmd_fibcontext); |
990 | readcmd->command = cpu_to_le32(VM_CtBlockRead); | 1106 | readcmd->command = cpu_to_le32(VM_CtBlockRead); |
991 | readcmd->cid = cpu_to_le32(cid); | 1107 | readcmd->cid = cpu_to_le32(cid); |
992 | readcmd->block = cpu_to_le32(lba); | 1108 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); |
993 | readcmd->count = cpu_to_le32(count * 512); | 1109 | readcmd->count = cpu_to_le32(count * 512); |
994 | 1110 | ||
995 | aac_build_sg(scsicmd, &readcmd->sg); | 1111 | aac_build_sg(scsicmd, &readcmd->sg); |
@@ -1031,7 +1147,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1031 | 1147 | ||
1032 | static int aac_write(struct scsi_cmnd * scsicmd, int cid) | 1148 | static int aac_write(struct scsi_cmnd * scsicmd, int cid) |
1033 | { | 1149 | { |
1034 | u32 lba; | 1150 | u64 lba; |
1035 | u32 count; | 1151 | u32 count; |
1036 | int status; | 1152 | int status; |
1037 | u16 fibsize; | 1153 | u16 fibsize; |
@@ -1048,13 +1164,48 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1048 | count = scsicmd->cmnd[4]; | 1164 | count = scsicmd->cmnd[4]; |
1049 | if (count == 0) | 1165 | if (count == 0) |
1050 | count = 256; | 1166 | count = 256; |
1167 | } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ | ||
1168 | dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid)); | ||
1169 | |||
1170 | lba = ((u64)scsicmd->cmnd[2] << 56) | | ||
1171 | ((u64)scsicmd->cmnd[3] << 48) | | ||
1172 | ((u64)scsicmd->cmnd[4] << 40) | | ||
1173 | ((u64)scsicmd->cmnd[5] << 32) | | ||
1174 | ((u64)scsicmd->cmnd[6] << 24) | | ||
1175 | (scsicmd->cmnd[7] << 16) | | ||
1176 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | ||
1177 | count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | | ||
1178 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; | ||
1179 | } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ | ||
1180 | dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid)); | ||
1181 | |||
1182 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | ||
1183 | | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | ||
1184 | count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | ||
1185 | | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | ||
1051 | } else { | 1186 | } else { |
1052 | dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); | 1187 | dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); |
1053 | lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | 1188 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; |
1054 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 1189 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
1055 | } | 1190 | } |
1056 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n", | 1191 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", |
1057 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1192 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1193 | if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) | ||
1194 | && (lba & 0xffffffff00000000LL)) { | ||
1195 | dprintk((KERN_DEBUG "aac_write: Illegal lba\n")); | ||
1196 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | ||
1197 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
1198 | HARDWARE_ERROR, | ||
1199 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
1200 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
1201 | 0, 0); | ||
1202 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1203 | (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) | ||
1204 | ? sizeof(scsicmd->sense_buffer) | ||
1205 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
1206 | scsicmd->scsi_done(scsicmd); | ||
1207 | return 0; | ||
1208 | } | ||
1058 | /* | 1209 | /* |
1059 | * Allocate and initialize a Fib then setup a BlockWrite command | 1210 | * Allocate and initialize a Fib then setup a BlockWrite command |
1060 | */ | 1211 | */ |
@@ -1068,8 +1219,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1068 | if (dev->raw_io_interface) { | 1219 | if (dev->raw_io_interface) { |
1069 | struct aac_raw_io *writecmd; | 1220 | struct aac_raw_io *writecmd; |
1070 | writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | 1221 | writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); |
1071 | writecmd->block[0] = cpu_to_le32(lba); | 1222 | writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); |
1072 | writecmd->block[1] = 0; | 1223 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); |
1073 | writecmd->count = cpu_to_le32(count<<9); | 1224 | writecmd->count = cpu_to_le32(count<<9); |
1074 | writecmd->cid = cpu_to_le16(cid); | 1225 | writecmd->cid = cpu_to_le16(cid); |
1075 | writecmd->flags = 0; | 1226 | writecmd->flags = 0; |
@@ -1096,7 +1247,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1096 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); | 1247 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); |
1097 | writecmd->cid = cpu_to_le16(cid); | 1248 | writecmd->cid = cpu_to_le16(cid); |
1098 | writecmd->sector_count = cpu_to_le16(count); | 1249 | writecmd->sector_count = cpu_to_le16(count); |
1099 | writecmd->block = cpu_to_le32(lba); | 1250 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); |
1100 | writecmd->pad = 0; | 1251 | writecmd->pad = 0; |
1101 | writecmd->flags = 0; | 1252 | writecmd->flags = 0; |
1102 | 1253 | ||
@@ -1121,7 +1272,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1121 | writecmd = (struct aac_write *) fib_data(cmd_fibcontext); | 1272 | writecmd = (struct aac_write *) fib_data(cmd_fibcontext); |
1122 | writecmd->command = cpu_to_le32(VM_CtBlockWrite); | 1273 | writecmd->command = cpu_to_le32(VM_CtBlockWrite); |
1123 | writecmd->cid = cpu_to_le32(cid); | 1274 | writecmd->cid = cpu_to_le32(cid); |
1124 | writecmd->block = cpu_to_le32(lba); | 1275 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); |
1125 | writecmd->count = cpu_to_le32(count * 512); | 1276 | writecmd->count = cpu_to_le32(count * 512); |
1126 | writecmd->sg.count = cpu_to_le32(1); | 1277 | writecmd->sg.count = cpu_to_le32(1); |
1127 | /* ->stable is not used - it did mean which type of write */ | 1278 | /* ->stable is not used - it did mean which type of write */ |
@@ -1310,11 +1461,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1310 | */ | 1461 | */ |
1311 | if ((fsa_dev_ptr[cid].valid & 1) == 0) { | 1462 | if ((fsa_dev_ptr[cid].valid & 1) == 0) { |
1312 | switch (scsicmd->cmnd[0]) { | 1463 | switch (scsicmd->cmnd[0]) { |
1464 | case SERVICE_ACTION_IN: | ||
1465 | if (!(dev->raw_io_interface) || | ||
1466 | !(dev->raw_io_64) || | ||
1467 | ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) | ||
1468 | break; | ||
1313 | case INQUIRY: | 1469 | case INQUIRY: |
1314 | case READ_CAPACITY: | 1470 | case READ_CAPACITY: |
1315 | case TEST_UNIT_READY: | 1471 | case TEST_UNIT_READY: |
1316 | spin_unlock_irq(host->host_lock); | 1472 | spin_unlock_irq(host->host_lock); |
1317 | probe_container(dev, cid); | 1473 | probe_container(dev, cid); |
1474 | if ((fsa_dev_ptr[cid].valid & 1) == 0) | ||
1475 | fsa_dev_ptr[cid].valid = 0; | ||
1318 | spin_lock_irq(host->host_lock); | 1476 | spin_lock_irq(host->host_lock); |
1319 | if (fsa_dev_ptr[cid].valid == 0) { | 1477 | if (fsa_dev_ptr[cid].valid == 0) { |
1320 | scsicmd->result = DID_NO_CONNECT << 16; | 1478 | scsicmd->result = DID_NO_CONNECT << 16; |
@@ -1375,7 +1533,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1375 | memset(&inq_data, 0, sizeof (struct inquiry_data)); | 1533 | memset(&inq_data, 0, sizeof (struct inquiry_data)); |
1376 | 1534 | ||
1377 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ | 1535 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ |
1378 | inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ | ||
1379 | 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 */ | 1536 | 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 */ |
1380 | inq_data.inqd_len = 31; | 1537 | inq_data.inqd_len = 31; |
1381 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ | 1538 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ |
@@ -1397,13 +1554,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1397 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 1554 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); |
1398 | return aac_get_container_name(scsicmd, cid); | 1555 | return aac_get_container_name(scsicmd, cid); |
1399 | } | 1556 | } |
1557 | case SERVICE_ACTION_IN: | ||
1558 | if (!(dev->raw_io_interface) || | ||
1559 | !(dev->raw_io_64) || | ||
1560 | ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) | ||
1561 | break; | ||
1562 | { | ||
1563 | u64 capacity; | ||
1564 | char cp[12]; | ||
1565 | unsigned int offset = 0; | ||
1566 | |||
1567 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); | ||
1568 | capacity = fsa_dev_ptr[cid].size - 1; | ||
1569 | if (scsicmd->cmnd[13] > 12) { | ||
1570 | offset = scsicmd->cmnd[13] - 12; | ||
1571 | if (offset > sizeof(cp)) | ||
1572 | break; | ||
1573 | memset(cp, 0, offset); | ||
1574 | aac_internal_transfer(scsicmd, cp, 0, offset); | ||
1575 | } | ||
1576 | cp[0] = (capacity >> 56) & 0xff; | ||
1577 | cp[1] = (capacity >> 48) & 0xff; | ||
1578 | cp[2] = (capacity >> 40) & 0xff; | ||
1579 | cp[3] = (capacity >> 32) & 0xff; | ||
1580 | cp[4] = (capacity >> 24) & 0xff; | ||
1581 | cp[5] = (capacity >> 16) & 0xff; | ||
1582 | cp[6] = (capacity >> 8) & 0xff; | ||
1583 | cp[7] = (capacity >> 0) & 0xff; | ||
1584 | cp[8] = 0; | ||
1585 | cp[9] = 0; | ||
1586 | cp[10] = 2; | ||
1587 | cp[11] = 0; | ||
1588 | aac_internal_transfer(scsicmd, cp, offset, sizeof(cp)); | ||
1589 | |||
1590 | /* Do not cache partition table for arrays */ | ||
1591 | scsicmd->device->removable = 1; | ||
1592 | |||
1593 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||
1594 | scsicmd->scsi_done(scsicmd); | ||
1595 | |||
1596 | return 0; | ||
1597 | } | ||
1598 | |||
1400 | case READ_CAPACITY: | 1599 | case READ_CAPACITY: |
1401 | { | 1600 | { |
1402 | u32 capacity; | 1601 | u32 capacity; |
1403 | char cp[8]; | 1602 | char cp[8]; |
1404 | 1603 | ||
1405 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); | 1604 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); |
1406 | if (fsa_dev_ptr[cid].size <= 0x100000000LL) | 1605 | if (fsa_dev_ptr[cid].size <= 0x100000000ULL) |
1407 | capacity = fsa_dev_ptr[cid].size - 1; | 1606 | capacity = fsa_dev_ptr[cid].size - 1; |
1408 | else | 1607 | else |
1409 | capacity = (u32)-1; | 1608 | capacity = (u32)-1; |
@@ -1417,6 +1616,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1417 | cp[6] = 2; | 1616 | cp[6] = 2; |
1418 | cp[7] = 0; | 1617 | cp[7] = 0; |
1419 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | 1618 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); |
1619 | /* Do not cache partition table for arrays */ | ||
1620 | scsicmd->device->removable = 1; | ||
1420 | 1621 | ||
1421 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1622 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1422 | scsicmd->scsi_done(scsicmd); | 1623 | scsicmd->scsi_done(scsicmd); |
@@ -1497,6 +1698,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1497 | { | 1698 | { |
1498 | case READ_6: | 1699 | case READ_6: |
1499 | case READ_10: | 1700 | case READ_10: |
1701 | case READ_12: | ||
1702 | case READ_16: | ||
1500 | /* | 1703 | /* |
1501 | * Hack to keep track of ordinal number of the device that | 1704 | * Hack to keep track of ordinal number of the device that |
1502 | * corresponds to a container. Needed to convert | 1705 | * corresponds to a container. Needed to convert |
@@ -1504,17 +1707,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1504 | */ | 1707 | */ |
1505 | 1708 | ||
1506 | spin_unlock_irq(host->host_lock); | 1709 | spin_unlock_irq(host->host_lock); |
1507 | if (scsicmd->request->rq_disk) | 1710 | if (scsicmd->request->rq_disk) |
1508 | memcpy(fsa_dev_ptr[cid].devname, | 1711 | strlcpy(fsa_dev_ptr[cid].devname, |
1509 | scsicmd->request->rq_disk->disk_name, | 1712 | scsicmd->request->rq_disk->disk_name, |
1510 | 8); | 1713 | min(sizeof(fsa_dev_ptr[cid].devname), |
1511 | 1714 | sizeof(scsicmd->request->rq_disk->disk_name) + 1)); | |
1512 | ret = aac_read(scsicmd, cid); | 1715 | ret = aac_read(scsicmd, cid); |
1513 | spin_lock_irq(host->host_lock); | 1716 | spin_lock_irq(host->host_lock); |
1514 | return ret; | 1717 | return ret; |
1515 | 1718 | ||
1516 | case WRITE_6: | 1719 | case WRITE_6: |
1517 | case WRITE_10: | 1720 | case WRITE_10: |
1721 | case WRITE_12: | ||
1722 | case WRITE_16: | ||
1518 | spin_unlock_irq(host->host_lock); | 1723 | spin_unlock_irq(host->host_lock); |
1519 | ret = aac_write(scsicmd, cid); | 1724 | ret = aac_write(scsicmd, cid); |
1520 | spin_lock_irq(host->host_lock); | 1725 | spin_lock_irq(host->host_lock); |
@@ -1745,6 +1950,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
1745 | case WRITE_10: | 1950 | case WRITE_10: |
1746 | case READ_12: | 1951 | case READ_12: |
1747 | case WRITE_12: | 1952 | case WRITE_12: |
1953 | case READ_16: | ||
1954 | case WRITE_16: | ||
1748 | if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) { | 1955 | if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) { |
1749 | printk(KERN_WARNING"aacraid: SCSI CMD underflow\n"); | 1956 | printk(KERN_WARNING"aacraid: SCSI CMD underflow\n"); |
1750 | } else { | 1957 | } else { |
@@ -1850,8 +2057,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
1850 | sizeof(scsicmd->sense_buffer) : | 2057 | sizeof(scsicmd->sense_buffer) : |
1851 | le32_to_cpu(srbreply->sense_data_size); | 2058 | le32_to_cpu(srbreply->sense_data_size); |
1852 | #ifdef AAC_DETAILED_STATUS_INFO | 2059 | #ifdef AAC_DETAILED_STATUS_INFO |
1853 | dprintk((KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", | 2060 | printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", |
1854 | le32_to_cpu(srbreply->status), len)); | 2061 | le32_to_cpu(srbreply->status), len); |
1855 | #endif | 2062 | #endif |
1856 | memcpy(scsicmd->sense_buffer, srbreply->sense_data, len); | 2063 | memcpy(scsicmd->sense_buffer, srbreply->sense_data, len); |
1857 | 2064 | ||