aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-06-17 05:10:56 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:34 -0400
commitb68bf096d4211bb6490955f86842d8291e8ae218 (patch)
treec512c93f8effded33b4318e3d7e25217a86897a5 /drivers/message
parent51106ab5306b752cd53d40626f78774276bb1368 (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/message')
-rw-r--r--drivers/message/fusion/mptbase.h2
-rw-r--r--drivers/message/fusion/mptctl.c14
-rw-r--r--drivers/message/fusion/mptsas.c59
-rw-r--r--drivers/message/fusion/mptscsih.c2
4 files changed, 56 insertions, 21 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 453bcb7d6b5e..a2a620c3e073 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -580,6 +580,7 @@ struct mptfc_rport_info
580typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); 580typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
581typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, 581typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
582 dma_addr_t dma_addr); 582 dma_addr_t dma_addr);
583typedef 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 f06b29193b4e..9bd89cebb5a9 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 8963f5c44c23..a94655162347 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);
126static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event); 126static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
127static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); 127static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
128static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); 128static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
129void mptsas_schedule_target_reset(void *ioc);
129 130
130static void mptsas_print_phy_data(MPT_ADAPTER *ioc, 131static 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
1151void
1152mptsas_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 5a3c10e72e40..c5c8fb811f54 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;