aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c96
1 files changed, 75 insertions, 21 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3a3017d8dc65..6d88f30296e1 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -775,20 +775,20 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
775{ 775{
776 struct hw_fib * hw_fib = fibptr->hw_fib_va; 776 struct hw_fib * hw_fib = fibptr->hw_fib_va;
777 struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; 777 struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
778 u32 container; 778 u32 channel, id, lun, container;
779 struct scsi_device *device; 779 struct scsi_device *device;
780 enum { 780 enum {
781 NOTHING, 781 NOTHING,
782 DELETE, 782 DELETE,
783 ADD, 783 ADD,
784 CHANGE 784 CHANGE
785 } device_config_needed; 785 } device_config_needed = NOTHING;
786 786
787 /* Sniff for container changes */ 787 /* Sniff for container changes */
788 788
789 if (!dev || !dev->fsa_dev) 789 if (!dev || !dev->fsa_dev)
790 return; 790 return;
791 container = (u32)-1; 791 container = channel = id = lun = (u32)-1;
792 792
793 /* 793 /*
794 * We have set this up to try and minimize the number of 794 * We have set this up to try and minimize the number of
@@ -901,6 +901,36 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
901 case AifEnConfigChange: 901 case AifEnConfigChange:
902 break; 902 break;
903 903
904 case AifEnEnclosureManagement:
905 switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
906 case EM_DRIVE_INSERTION:
907 case EM_DRIVE_REMOVAL:
908 container = le32_to_cpu(
909 ((__le32 *)aifcmd->data)[2]);
910 if ((container >> 28))
911 break;
912 channel = (container >> 24) & 0xF;
913 if (channel >= dev->maximum_num_channels)
914 break;
915 id = container & 0xFFFF;
916 lun = (container >> 16) & 0xFF;
917 if (id >= dev->maximum_num_physicals) {
918 /* legacy dev_t ? */
919 if ((0x2000 <= id) || lun || channel ||
920 ((channel = (id >> 7) & 0x3F) >=
921 dev->maximum_num_channels))
922 break;
923 lun = (id >> 4) & 7;
924 id &= 0xF;
925 }
926 channel = aac_phys_to_logical(channel);
927 device_config_needed =
928 (((__le32 *)aifcmd->data)[3]
929 == cpu_to_le32(EM_DRIVE_INSERTION)) ?
930 ADD : DELETE;
931 break;
932 }
933 break;
904 } 934 }
905 935
906 /* 936 /*
@@ -969,7 +999,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
969 break; 999 break;
970 } 1000 }
971 1001
972 device_config_needed = NOTHING; 1002 if (device_config_needed == NOTHING)
973 for (container = 0; container < dev->maximum_num_containers; 1003 for (container = 0; container < dev->maximum_num_containers;
974 ++container) { 1004 ++container) {
975 if ((dev->fsa_dev[container].config_waiting_on == 0) && 1005 if ((dev->fsa_dev[container].config_waiting_on == 0) &&
@@ -978,6 +1008,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
978 device_config_needed = 1008 device_config_needed =
979 dev->fsa_dev[container].config_needed; 1009 dev->fsa_dev[container].config_needed;
980 dev->fsa_dev[container].config_needed = NOTHING; 1010 dev->fsa_dev[container].config_needed = NOTHING;
1011 channel = CONTAINER_TO_CHANNEL(container);
1012 id = CONTAINER_TO_ID(container);
1013 lun = CONTAINER_TO_LUN(container);
981 break; 1014 break;
982 } 1015 }
983 } 1016 }
@@ -1001,34 +1034,56 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
1001 /* 1034 /*
1002 * force reload of disk info via aac_probe_container 1035 * force reload of disk info via aac_probe_container
1003 */ 1036 */
1004 if ((device_config_needed == CHANGE) 1037 if ((channel == CONTAINER_CHANNEL) &&
1005 && (dev->fsa_dev[container].valid == 1)) 1038 (device_config_needed != NOTHING)) {
1006 dev->fsa_dev[container].valid = 2; 1039 if (dev->fsa_dev[container].valid == 1)
1007 if ((device_config_needed == CHANGE) || 1040 dev->fsa_dev[container].valid = 2;
1008 (device_config_needed == ADD))
1009 aac_probe_container(dev, container); 1041 aac_probe_container(dev, container);
1010 device = scsi_device_lookup(dev->scsi_host_ptr, 1042 }
1011 CONTAINER_TO_CHANNEL(container), 1043 device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
1012 CONTAINER_TO_ID(container),
1013 CONTAINER_TO_LUN(container));
1014 if (device) { 1044 if (device) {
1015 switch (device_config_needed) { 1045 switch (device_config_needed) {
1016 case DELETE: 1046 case DELETE:
1047 if (scsi_device_online(device)) {
1048 scsi_device_set_state(device, SDEV_OFFLINE);
1049 sdev_printk(KERN_INFO, device,
1050 "Device offlined - %s\n",
1051 (channel == CONTAINER_CHANNEL) ?
1052 "array deleted" :
1053 "enclosure services event");
1054 }
1055 break;
1056 case ADD:
1057 if (!scsi_device_online(device)) {
1058 sdev_printk(KERN_INFO, device,
1059 "Device online - %s\n",
1060 (channel == CONTAINER_CHANNEL) ?
1061 "array created" :
1062 "enclosure services event");
1063 scsi_device_set_state(device, SDEV_RUNNING);
1064 }
1065 /* FALLTHRU */
1017 case CHANGE: 1066 case CHANGE:
1067 if ((channel == CONTAINER_CHANNEL)
1068 && (!dev->fsa_dev[container].valid)) {
1069 if (!scsi_device_online(device))
1070 break;
1071 scsi_device_set_state(device, SDEV_OFFLINE);
1072 sdev_printk(KERN_INFO, device,
1073 "Device offlined - %s\n",
1074 "array failed");
1075 break;
1076 }
1018 scsi_rescan_device(&device->sdev_gendev); 1077 scsi_rescan_device(&device->sdev_gendev);
1019 1078
1020 default: 1079 default:
1021 break; 1080 break;
1022 } 1081 }
1023 scsi_device_put(device); 1082 scsi_device_put(device);
1083 device_config_needed = NOTHING;
1024 } 1084 }
1025 if (device_config_needed == ADD) { 1085 if (device_config_needed == ADD)
1026 scsi_add_device(dev->scsi_host_ptr, 1086 scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
1027 CONTAINER_TO_CHANNEL(container),
1028 CONTAINER_TO_ID(container),
1029 CONTAINER_TO_LUN(container));
1030 }
1031
1032} 1087}
1033 1088
1034static int _aac_reset_adapter(struct aac_dev *aac, int forced) 1089static int _aac_reset_adapter(struct aac_dev *aac, int forced)
@@ -1469,7 +1524,6 @@ int aac_command_thread(void *data)
1469 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); 1524 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
1470 aac_fib_adapter_complete(fib, (u16)sizeof(u32)); 1525 aac_fib_adapter_complete(fib, (u16)sizeof(u32));
1471 } else { 1526 } else {
1472 struct list_head *entry;
1473 /* The u32 here is important and intended. We are using 1527 /* The u32 here is important and intended. We are using
1474 32bit wrapping time to fit the adapter field */ 1528 32bit wrapping time to fit the adapter field */
1475 1529