diff options
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 | ||
