aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
authorSalyzyn, Mark <Mark_Salyzyn@adaptec.com>2008-01-11 14:56:07 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 12:29:26 -0500
commit0995ad382df77b438d0c1e4f93ff349aa2eb9caf (patch)
tree84125251a9f45d5c3d7d262900a572f62ad4d11b /drivers/scsi/aacraid/commsup.c
parentd9aa3af09cdc5d3ae0e67bed4107bcf7e25b9f31 (diff)
[SCSI] aacraid: respond to enclosure service events
Added support to respond to enclosure service events (controller AIFs) to add, online or offline physical targets reported to sg. Also added online and offlining of arrays. Removed an automatic variable definition in a sub block that hid an earlier definition, determined to be inert as the sub-block use did not interfere. Bumped the driver versioning to stamp the addition of this feature. Signed-off-by: Mark Salyzyn <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
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