Commit b68bf096d4211bb6490955f86842d8291e8ae218

Authored by Kashyap, Desai
Committed by James Bottomley
1 parent 51106ab530

[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>

Showing 4 changed files with 56 additions and 21 deletions Side-by-side Diff

drivers/message/fusion/mptbase.h
... ... @@ -580,6 +580,7 @@
580 580 typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
581 581 typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
582 582 dma_addr_t dma_addr);
  583 +typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc);
583 584  
584 585 /*
585 586 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
... ... @@ -738,6 +739,7 @@
738 739 int taskmgmt_in_progress;
739 740 u8 taskmgmt_quiesce_io;
740 741 u8 ioc_reset_in_progress;
  742 + MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
741 743 struct work_struct sas_persist_task;
742 744  
743 745 struct work_struct fc_setup_reset_work;
drivers/message/fusion/mptctl.c
... ... @@ -261,10 +261,16 @@
261 261 /* We are done, issue wake up
262 262 */
263 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 265 mpt_clear_taskmgmt_in_progress_flag(ioc);
266   - ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
267   - complete(&ioc->ioctl_cmds.done);
  266 + ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
  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 276 out_continuation:
... ... @@ -298,6 +304,8 @@
298 304 mpt_clear_taskmgmt_in_progress_flag(ioc);
299 305 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
300 306 complete(&ioc->taskmgmt_cmds.done);
  307 + if (ioc->bus_type == SAS)
  308 + ioc->schedule_target_reset(ioc);
301 309 return 1;
302 310 }
303 311 return 0;
drivers/message/fusion/mptsas.c
... ... @@ -126,6 +126,7 @@
126 126 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
127 127 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
128 128 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
  129 +void mptsas_schedule_target_reset(void *ioc);
129 130  
130 131 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
131 132 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
... ... @@ -1139,6 +1140,44 @@
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 1181 * mptsas_taskmgmt_complete - complete SAS task management function
1143 1182 * @ioc: Pointer to MPT_ADAPTER structure
1144 1183 *
1145 1184  
... ... @@ -1227,24 +1266,8 @@
1227 1266 &target_reset_list->sas_event_data);
1228 1267  
1229 1268  
1230   - /*
1231   - * issue target reset to next device in the queue
1232   - */
  1269 + ioc->schedule_target_reset(ioc);
1233 1270  
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   -
1248 1271 return 1;
1249 1272 }
1250 1273  
... ... @@ -4961,7 +4984,7 @@
4961 4984 ioc->DoneCtx = mptsasDoneCtx;
4962 4985 ioc->TaskCtx = mptsasTaskCtx;
4963 4986 ioc->InternalCtx = mptsasInternalCtx;
4964   -
  4987 + ioc->schedule_target_reset = &mptsas_schedule_target_reset;
4965 4988 /* Added sanity check on readiness of the MPT adapter.
4966 4989 */
4967 4990 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
drivers/message/fusion/mptscsih.c
... ... @@ -2134,6 +2134,8 @@
2134 2134 mpt_clear_taskmgmt_in_progress_flag(ioc);
2135 2135 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2136 2136 complete(&ioc->taskmgmt_cmds.done);
  2137 + if (ioc->bus_type == SAS)
  2138 + ioc->schedule_target_reset(ioc);
2137 2139 return 1;
2138 2140 }
2139 2141 return 0;