diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2010-06-17 05:10:56 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-27 13:02:34 -0400 |
commit | b68bf096d4211bb6490955f86842d8291e8ae218 (patch) | |
tree | c512c93f8effded33b4318e3d7e25217a86897a5 /drivers | |
parent | 51106ab5306b752cd53d40626f78774276bb1368 (diff) |
[SCSI] mptfusion: schedule_target_reset from all Reset context
Issue:
target reset will be queued to driver's internal queue to get schedule
later. When driver add target into internal target_reset queue we will block IOs
on those target using scsi midlayer API. Now due to some cause driver is not
executing those target_reset list and it is always in block state.
Changes:
now we are clearing target_reset queue from all other Callback context
instead of only DeviceReset context.Now wherever driver is clearing
taskmgmt_in_progress flag it is considering target_reset queue cleanup
also.
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/message/fusion/mptbase.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 14 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 59 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 2 |
4 files changed, 56 insertions, 21 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 453bcb7d6b5..a2a620c3e07 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -580,6 +580,7 @@ struct mptfc_rport_info | |||
580 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); | 580 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); |
581 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, | 581 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, |
582 | dma_addr_t dma_addr); | 582 | dma_addr_t dma_addr); |
583 | typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc); | ||
583 | 584 | ||
584 | /* | 585 | /* |
585 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS | 586 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS |
@@ -738,6 +739,7 @@ typedef struct _MPT_ADAPTER | |||
738 | int taskmgmt_in_progress; | 739 | int taskmgmt_in_progress; |
739 | u8 taskmgmt_quiesce_io; | 740 | u8 taskmgmt_quiesce_io; |
740 | u8 ioc_reset_in_progress; | 741 | u8 ioc_reset_in_progress; |
742 | MPT_SCHEDULE_TARGET_RESET schedule_target_reset; | ||
741 | struct work_struct sas_persist_task; | 743 | struct work_struct sas_persist_task; |
742 | 744 | ||
743 | struct work_struct fc_setup_reset_work; | 745 | struct work_struct fc_setup_reset_work; |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index f06b29193b4..9bd89cebb5a 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -261,10 +261,16 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) | |||
261 | /* We are done, issue wake up | 261 | /* We are done, issue wake up |
262 | */ | 262 | */ |
263 | if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { | 263 | if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { |
264 | if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) | 264 | if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) { |
265 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 265 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
266 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 266 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
267 | complete(&ioc->ioctl_cmds.done); | 267 | complete(&ioc->ioctl_cmds.done); |
268 | if (ioc->bus_type == SAS) | ||
269 | ioc->schedule_target_reset(ioc); | ||
270 | } else { | ||
271 | ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | ||
272 | complete(&ioc->ioctl_cmds.done); | ||
273 | } | ||
268 | } | 274 | } |
269 | 275 | ||
270 | out_continuation: | 276 | out_continuation: |
@@ -298,6 +304,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
298 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 304 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
299 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 305 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
300 | complete(&ioc->taskmgmt_cmds.done); | 306 | complete(&ioc->taskmgmt_cmds.done); |
307 | if (ioc->bus_type == SAS) | ||
308 | ioc->schedule_target_reset(ioc); | ||
301 | return 1; | 309 | return 1; |
302 | } | 310 | } |
303 | return 0; | 311 | return 0; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 8963f5c44c2..a9465516234 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -126,6 +126,7 @@ static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); | |||
126 | static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); | 126 | static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); |
127 | static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); | 127 | static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); |
128 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); | 128 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); |
129 | void mptsas_schedule_target_reset(void *ioc); | ||
129 | 130 | ||
130 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, | 131 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, |
131 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) | 132 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) |
@@ -1139,6 +1140,44 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, | |||
1139 | } | 1140 | } |
1140 | 1141 | ||
1141 | /** | 1142 | /** |
1143 | * mptsas_schedule_target_reset- send pending target reset | ||
1144 | * @iocp: per adapter object | ||
1145 | * | ||
1146 | * This function will delete scheduled target reset from the list and | ||
1147 | * try to send next target reset. This will be called from completion | ||
1148 | * context of any Task managment command. | ||
1149 | */ | ||
1150 | |||
1151 | void | ||
1152 | mptsas_schedule_target_reset(void *iocp) | ||
1153 | { | ||
1154 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp); | ||
1155 | MPT_SCSI_HOST *hd = shost_priv(ioc->sh); | ||
1156 | struct list_head *head = &hd->target_reset_list; | ||
1157 | struct mptsas_target_reset_event *target_reset_list; | ||
1158 | u8 id, channel; | ||
1159 | /* | ||
1160 | * issue target reset to next device in the queue | ||
1161 | */ | ||
1162 | |||
1163 | head = &hd->target_reset_list; | ||
1164 | if (list_empty(head)) | ||
1165 | return; | ||
1166 | |||
1167 | target_reset_list = list_entry(head->next, | ||
1168 | struct mptsas_target_reset_event, list); | ||
1169 | |||
1170 | id = target_reset_list->sas_event_data.TargetID; | ||
1171 | channel = target_reset_list->sas_event_data.Bus; | ||
1172 | target_reset_list->time_count = jiffies; | ||
1173 | |||
1174 | if (mptsas_target_reset(ioc, channel, id)) | ||
1175 | target_reset_list->target_reset_issued = 1; | ||
1176 | return; | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | /** | ||
1142 | * mptsas_taskmgmt_complete - complete SAS task management function | 1181 | * mptsas_taskmgmt_complete - complete SAS task management function |
1143 | * @ioc: Pointer to MPT_ADAPTER structure | 1182 | * @ioc: Pointer to MPT_ADAPTER structure |
1144 | * | 1183 | * |
@@ -1227,23 +1266,7 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
1227 | &target_reset_list->sas_event_data); | 1266 | &target_reset_list->sas_event_data); |
1228 | 1267 | ||
1229 | 1268 | ||
1230 | /* | 1269 | ioc->schedule_target_reset(ioc); |
1231 | * issue target reset to next device in the queue | ||
1232 | */ | ||
1233 | |||
1234 | head = &hd->target_reset_list; | ||
1235 | if (list_empty(head)) | ||
1236 | return 1; | ||
1237 | |||
1238 | target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, | ||
1239 | list); | ||
1240 | |||
1241 | id = target_reset_list->sas_event_data.TargetID; | ||
1242 | channel = target_reset_list->sas_event_data.Bus; | ||
1243 | target_reset_list->time_count = jiffies; | ||
1244 | |||
1245 | if (mptsas_target_reset(ioc, channel, id)) | ||
1246 | target_reset_list->target_reset_issued = 1; | ||
1247 | 1270 | ||
1248 | return 1; | 1271 | return 1; |
1249 | } | 1272 | } |
@@ -4961,7 +4984,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4961 | ioc->DoneCtx = mptsasDoneCtx; | 4984 | ioc->DoneCtx = mptsasDoneCtx; |
4962 | ioc->TaskCtx = mptsasTaskCtx; | 4985 | ioc->TaskCtx = mptsasTaskCtx; |
4963 | ioc->InternalCtx = mptsasInternalCtx; | 4986 | ioc->InternalCtx = mptsasInternalCtx; |
4964 | 4987 | ioc->schedule_target_reset = &mptsas_schedule_target_reset; | |
4965 | /* Added sanity check on readiness of the MPT adapter. | 4988 | /* Added sanity check on readiness of the MPT adapter. |
4966 | */ | 4989 | */ |
4967 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { | 4990 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 5a3c10e72e4..c5c8fb811f5 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -2134,6 +2134,8 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, | |||
2134 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 2134 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
2135 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; | 2135 | ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; |
2136 | complete(&ioc->taskmgmt_cmds.done); | 2136 | complete(&ioc->taskmgmt_cmds.done); |
2137 | if (ioc->bus_type == SAS) | ||
2138 | ioc->schedule_target_reset(ioc); | ||
2137 | return 1; | 2139 | return 1; |
2138 | } | 2140 | } |
2139 | return 0; | 2141 | return 0; |