diff options
author | Yang, Bo <Bo.Yang@lsi.com> | 2009-12-06 10:39:25 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-17 14:12:40 -0500 |
commit | c978684254d11e3768c5a0b2780302fb0cada29c (patch) | |
tree | 174dbe555a241222216dc2b180b96406469757ef /drivers/scsi | |
parent | bdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7db (diff) |
[SCSI] megaraid_sas: driver fixed the device update issue
driver fixed the device update issue after get the AEN PD delete/ADD
and LD add/delete from FW.
Signed-off-by Bo Yang<bo.yang@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a92998fe2468..9ad274cf73a2 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -4072,6 +4072,7 @@ megasas_aen_polling(struct work_struct *work) | |||
4072 | struct Scsi_Host *host; | 4072 | struct Scsi_Host *host; |
4073 | struct scsi_device *sdev1; | 4073 | struct scsi_device *sdev1; |
4074 | u16 pd_index = 0; | 4074 | u16 pd_index = 0; |
4075 | u16 ld_index = 0; | ||
4075 | int i, j, doscan = 0; | 4076 | int i, j, doscan = 0; |
4076 | u32 seq_num; | 4077 | u32 seq_num; |
4077 | int error; | 4078 | int error; |
@@ -4087,8 +4088,124 @@ megasas_aen_polling(struct work_struct *work) | |||
4087 | 4088 | ||
4088 | switch (instance->evt_detail->code) { | 4089 | switch (instance->evt_detail->code) { |
4089 | case MR_EVT_PD_INSERTED: | 4090 | case MR_EVT_PD_INSERTED: |
4091 | if (megasas_get_pd_list(instance) == 0) { | ||
4092 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { | ||
4093 | for (j = 0; | ||
4094 | j < MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4095 | j++) { | ||
4096 | |||
4097 | pd_index = | ||
4098 | (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; | ||
4099 | |||
4100 | sdev1 = | ||
4101 | scsi_device_lookup(host, i, j, 0); | ||
4102 | |||
4103 | if (instance->pd_list[pd_index].driveState | ||
4104 | == MR_PD_STATE_SYSTEM) { | ||
4105 | if (!sdev1) { | ||
4106 | scsi_add_device(host, i, j, 0); | ||
4107 | } | ||
4108 | |||
4109 | if (sdev1) | ||
4110 | scsi_device_put(sdev1); | ||
4111 | } | ||
4112 | } | ||
4113 | } | ||
4114 | } | ||
4115 | doscan = 0; | ||
4116 | break; | ||
4117 | |||
4090 | case MR_EVT_PD_REMOVED: | 4118 | case MR_EVT_PD_REMOVED: |
4119 | if (megasas_get_pd_list(instance) == 0) { | ||
4120 | megasas_get_pd_list(instance); | ||
4121 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { | ||
4122 | for (j = 0; | ||
4123 | j < MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4124 | j++) { | ||
4125 | |||
4126 | pd_index = | ||
4127 | (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; | ||
4128 | |||
4129 | sdev1 = | ||
4130 | scsi_device_lookup(host, i, j, 0); | ||
4131 | |||
4132 | if (instance->pd_list[pd_index].driveState | ||
4133 | == MR_PD_STATE_SYSTEM) { | ||
4134 | if (sdev1) { | ||
4135 | scsi_device_put(sdev1); | ||
4136 | } | ||
4137 | } else { | ||
4138 | if (sdev1) { | ||
4139 | scsi_remove_device(sdev1); | ||
4140 | scsi_device_put(sdev1); | ||
4141 | } | ||
4142 | } | ||
4143 | } | ||
4144 | } | ||
4145 | } | ||
4146 | doscan = 0; | ||
4147 | break; | ||
4148 | |||
4149 | case MR_EVT_LD_OFFLINE: | ||
4150 | case MR_EVT_LD_DELETED: | ||
4151 | megasas_get_ld_list(instance); | ||
4152 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { | ||
4153 | for (j = 0; | ||
4154 | j < MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4155 | j++) { | ||
4156 | |||
4157 | ld_index = | ||
4158 | (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; | ||
4159 | |||
4160 | sdev1 = scsi_device_lookup(host, | ||
4161 | i + MEGASAS_MAX_LD_CHANNELS, | ||
4162 | j, | ||
4163 | 0); | ||
4164 | |||
4165 | if (instance->ld_ids[ld_index] != 0xff) { | ||
4166 | if (sdev1) { | ||
4167 | scsi_device_put(sdev1); | ||
4168 | } | ||
4169 | } else { | ||
4170 | if (sdev1) { | ||
4171 | scsi_remove_device(sdev1); | ||
4172 | scsi_device_put(sdev1); | ||
4173 | } | ||
4174 | } | ||
4175 | } | ||
4176 | } | ||
4177 | doscan = 0; | ||
4178 | break; | ||
4179 | case MR_EVT_LD_CREATED: | ||
4180 | megasas_get_ld_list(instance); | ||
4181 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { | ||
4182 | for (j = 0; | ||
4183 | j < MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4184 | j++) { | ||
4185 | ld_index = | ||
4186 | (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; | ||
4187 | |||
4188 | sdev1 = scsi_device_lookup(host, | ||
4189 | i+MEGASAS_MAX_LD_CHANNELS, | ||
4190 | j, 0); | ||
4191 | |||
4192 | if (instance->ld_ids[ld_index] != | ||
4193 | 0xff) { | ||
4194 | if (!sdev1) { | ||
4195 | scsi_add_device(host, | ||
4196 | i + 2, | ||
4197 | j, 0); | ||
4198 | } | ||
4199 | } | ||
4200 | if (sdev1) { | ||
4201 | scsi_device_put(sdev1); | ||
4202 | } | ||
4203 | } | ||
4204 | } | ||
4205 | doscan = 0; | ||
4206 | break; | ||
4091 | case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: | 4207 | case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: |
4208 | case MR_EVT_FOREIGN_CFG_IMPORTED: | ||
4092 | doscan = 1; | 4209 | doscan = 1; |
4093 | break; | 4210 | break; |
4094 | default: | 4211 | default: |
@@ -4123,6 +4240,31 @@ megasas_aen_polling(struct work_struct *work) | |||
4123 | } | 4240 | } |
4124 | } | 4241 | } |
4125 | } | 4242 | } |
4243 | |||
4244 | megasas_get_ld_list(instance); | ||
4245 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { | ||
4246 | for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) { | ||
4247 | ld_index = | ||
4248 | (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j; | ||
4249 | |||
4250 | sdev1 = scsi_device_lookup(host, | ||
4251 | i+MEGASAS_MAX_LD_CHANNELS, j, 0); | ||
4252 | if (instance->ld_ids[ld_index] != 0xff) { | ||
4253 | if (!sdev1) { | ||
4254 | scsi_add_device(host, | ||
4255 | i+2, | ||
4256 | j, 0); | ||
4257 | } else { | ||
4258 | scsi_device_put(sdev1); | ||
4259 | } | ||
4260 | } else { | ||
4261 | if (sdev1) { | ||
4262 | scsi_remove_device(sdev1); | ||
4263 | scsi_device_put(sdev1); | ||
4264 | } | ||
4265 | } | ||
4266 | } | ||
4267 | } | ||
4126 | } | 4268 | } |
4127 | 4269 | ||
4128 | if ( instance->aen_cmd != NULL ) { | 4270 | if ( instance->aen_cmd != NULL ) { |