Skip to content

Commit 9f4c887

Browse files
Merge patch series "scsi: EH rework prep patches, part 1"
Hannes Reinecke <[email protected]> says: Hi all, (taking up an old thread:) here's the first batch of patches for my EH rework. It modifies the reset callbacks for SCSI drivers such that the final conversion to drop the 'struct scsi_cmnd' argument and use the entity in question (host, bus, target, device) as the argument to the SCSI EH callbacks becomes possible. The first part covers drivers which just requires minor tweaks. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
2 parents 78882c7 + 82b2fb5 commit 9f4c887

File tree

18 files changed

+572
-395
lines changed

18 files changed

+572
-395
lines changed

drivers/message/fusion/mptfc.c

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -183,73 +183,109 @@ static struct fc_function_template mptfc_transport_functions = {
183183
};
184184

185185
static int
186-
mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
187-
int (*func)(struct scsi_cmnd *SCpnt),
188-
const char *caller)
186+
mptfc_block_error_handler(struct fc_rport *rport)
189187
{
190188
MPT_SCSI_HOST *hd;
191-
struct scsi_device *sdev = SCpnt->device;
192-
struct Scsi_Host *shost = sdev->host;
193-
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
189+
struct Scsi_Host *shost = rport_to_shost(rport);
194190
unsigned long flags;
195191
int ready;
196-
MPT_ADAPTER *ioc;
192+
MPT_ADAPTER *ioc;
197193
int loops = 40; /* seconds */
198194

199-
hd = shost_priv(SCpnt->device->host);
195+
hd = shost_priv(shost);
200196
ioc = hd->ioc;
201197
spin_lock_irqsave(shost->host_lock, flags);
202198
while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
203199
|| (loops > 0 && ioc->active == 0)) {
204200
spin_unlock_irqrestore(shost->host_lock, flags);
205201
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
206-
"mptfc_block_error_handler.%d: %d:%llu, port status is "
207-
"%x, active flag %d, deferring %s recovery.\n",
202+
"mptfc_block_error_handler.%d: %s, port status is "
203+
"%x, active flag %d, deferring recovery.\n",
208204
ioc->name, ioc->sh->host_no,
209-
SCpnt->device->id, SCpnt->device->lun,
210-
ready, ioc->active, caller));
205+
dev_name(&rport->dev), ready, ioc->active));
211206
msleep(1000);
212207
spin_lock_irqsave(shost->host_lock, flags);
213208
loops --;
214209
}
215210
spin_unlock_irqrestore(shost->host_lock, flags);
216211

217-
if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
218-
|| ioc->active == 0) {
212+
if (ready == DID_NO_CONNECT || ioc->active == 0) {
219213
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
220-
"%s.%d: %d:%llu, failing recovery, "
221-
"port state %x, active %d, vdevice %p.\n", caller,
214+
"mpt_block_error_handler.%d: %s, failing recovery, "
215+
"port state %x, active %d.\n",
222216
ioc->name, ioc->sh->host_no,
223-
SCpnt->device->id, SCpnt->device->lun, ready,
224-
ioc->active, SCpnt->device->hostdata));
217+
dev_name(&rport->dev), ready, ioc->active));
225218
return FAILED;
226219
}
227-
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
228-
"%s.%d: %d:%llu, executing recovery.\n", caller,
229-
ioc->name, ioc->sh->host_no,
230-
SCpnt->device->id, SCpnt->device->lun));
231-
return (*func)(SCpnt);
220+
return SUCCESS;
232221
}
233222

234223
static int
235224
mptfc_abort(struct scsi_cmnd *SCpnt)
236225
{
237-
return
238-
mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
226+
struct Scsi_Host *shost = SCpnt->device->host;
227+
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
228+
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
229+
int rtn;
230+
231+
rtn = mptfc_block_error_handler(rport);
232+
if (rtn == SUCCESS) {
233+
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
234+
"%s.%d: %d:%llu, executing recovery.\n", __func__,
235+
hd->ioc->name, shost->host_no,
236+
SCpnt->device->id, SCpnt->device->lun));
237+
rtn = mptscsih_abort(SCpnt);
238+
}
239+
return rtn;
239240
}
240241

241242
static int
242243
mptfc_dev_reset(struct scsi_cmnd *SCpnt)
243244
{
244-
return
245-
mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
245+
struct Scsi_Host *shost = SCpnt->device->host;
246+
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
247+
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
248+
int rtn;
249+
250+
rtn = mptfc_block_error_handler(rport);
251+
if (rtn == SUCCESS) {
252+
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
253+
"%s.%d: %d:%llu, executing recovery.\n", __func__,
254+
hd->ioc->name, shost->host_no,
255+
SCpnt->device->id, SCpnt->device->lun));
256+
rtn = mptscsih_dev_reset(SCpnt);
257+
}
258+
return rtn;
246259
}
247260

248261
static int
249262
mptfc_bus_reset(struct scsi_cmnd *SCpnt)
250263
{
251-
return
252-
mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
264+
struct Scsi_Host *shost = SCpnt->device->host;
265+
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
266+
int channel = SCpnt->device->channel;
267+
struct mptfc_rport_info *ri;
268+
int rtn;
269+
270+
list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
271+
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
272+
VirtTarget *vtarget = ri->starget->hostdata;
273+
274+
if (!vtarget || vtarget->channel != channel)
275+
continue;
276+
rtn = fc_block_rport(ri->rport);
277+
if (rtn != 0)
278+
break;
279+
}
280+
}
281+
if (rtn == 0) {
282+
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
283+
"%s.%d: %d:%llu, executing recovery.\n", __func__,
284+
hd->ioc->name, shost->host_no,
285+
SCpnt->device->id, SCpnt->device->lun));
286+
rtn = mptscsih_bus_reset(SCpnt);
287+
}
288+
return rtn;
253289
}
254290

255291
static void

drivers/message/fusion/mptscsih.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1793,7 +1793,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
17931793

17941794
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
17951795
/**
1796-
* mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1796+
* mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
17971797
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
17981798
*
17991799
* (linux scsi_host_template.eh_dev_reset_handler routine)
@@ -1808,6 +1808,58 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
18081808
VirtDevice *vdevice;
18091809
MPT_ADAPTER *ioc;
18101810

1811+
/* If we can't locate our host adapter structure, return FAILED status.
1812+
*/
1813+
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1814+
printk(KERN_ERR MYNAM ": lun reset: "
1815+
"Can't locate host! (sc=%p)\n", SCpnt);
1816+
return FAILED;
1817+
}
1818+
1819+
ioc = hd->ioc;
1820+
printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
1821+
ioc->name, SCpnt);
1822+
scsi_print_command(SCpnt);
1823+
1824+
vdevice = SCpnt->device->hostdata;
1825+
if (!vdevice || !vdevice->vtarget) {
1826+
retval = 0;
1827+
goto out;
1828+
}
1829+
1830+
retval = mptscsih_IssueTaskMgmt(hd,
1831+
MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET,
1832+
vdevice->vtarget->channel,
1833+
vdevice->vtarget->id, vdevice->lun, 0,
1834+
mptscsih_get_tm_timeout(ioc));
1835+
1836+
out:
1837+
printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
1838+
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1839+
1840+
if (retval == 0)
1841+
return SUCCESS;
1842+
else
1843+
return FAILED;
1844+
}
1845+
1846+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1847+
/**
1848+
* mptscsih_target_reset - Perform a SCSI TARGET_RESET!
1849+
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1850+
*
1851+
* (linux scsi_host_template.eh_target_reset_handler routine)
1852+
*
1853+
* Returns SUCCESS or FAILED.
1854+
**/
1855+
int
1856+
mptscsih_target_reset(struct scsi_cmnd * SCpnt)
1857+
{
1858+
MPT_SCSI_HOST *hd;
1859+
int retval;
1860+
VirtDevice *vdevice;
1861+
MPT_ADAPTER *ioc;
1862+
18111863
/* If we can't locate our host adapter structure, return FAILED status.
18121864
*/
18131865
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
@@ -3256,6 +3308,7 @@ EXPORT_SYMBOL(mptscsih_slave_destroy);
32563308
EXPORT_SYMBOL(mptscsih_slave_configure);
32573309
EXPORT_SYMBOL(mptscsih_abort);
32583310
EXPORT_SYMBOL(mptscsih_dev_reset);
3311+
EXPORT_SYMBOL(mptscsih_target_reset);
32593312
EXPORT_SYMBOL(mptscsih_bus_reset);
32603313
EXPORT_SYMBOL(mptscsih_host_reset);
32613314
EXPORT_SYMBOL(mptscsih_bios_param);

drivers/message/fusion/mptscsih.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ extern void mptscsih_slave_destroy(struct scsi_device *device);
120120
extern int mptscsih_slave_configure(struct scsi_device *device);
121121
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
122122
extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
123+
extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
123124
extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
124125
extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
125126
extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);

drivers/scsi/aic7xxx/aic79xx_osm.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -536,13 +536,18 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
536536
struct scsi_cmnd *cmd;
537537

538538
cmd = scb->io_ctx;
539-
ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
540-
scsi_dma_unmap(cmd);
539+
if (cmd) {
540+
ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
541+
scsi_dma_unmap(cmd);
542+
}
541543
}
542544

543545
/******************************** Macros **************************************/
544-
#define BUILD_SCSIID(ahd, cmd) \
545-
(((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
546+
static inline unsigned int ahd_build_scsiid(struct ahd_softc *ahd,
547+
struct scsi_device *sdev)
548+
{
549+
return ((sdev_id(sdev) << TID_SHIFT) & TID) | (ahd)->our_id;
550+
}
546551

547552
/*
548553
* Return a string describing the driver.
@@ -811,14 +816,14 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)
811816

812817
tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
813818
cmd->device->id, &tstate);
814-
reset_scb->io_ctx = cmd;
819+
reset_scb->io_ctx = NULL;
815820
reset_scb->platform_data->dev = dev;
816821
reset_scb->sg_count = 0;
817822
ahd_set_residual(reset_scb, 0);
818823
ahd_set_sense_residual(reset_scb, 0);
819824
reset_scb->platform_data->xfer_len = 0;
820825
reset_scb->hscb->control = 0;
821-
reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
826+
reset_scb->hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
822827
reset_scb->hscb->lun = cmd->device->lun;
823828
reset_scb->hscb->cdb_len = 0;
824829
reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
@@ -1577,7 +1582,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
15771582
* Fill out basics of the HSCB.
15781583
*/
15791584
hscb->control = 0;
1580-
hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1585+
hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
15811586
hscb->lun = cmd->device->lun;
15821587
scb->hscb->task_management = 0;
15831588
mask = SCB_GET_TARGET_MASK(ahd, scb);
@@ -1766,9 +1771,16 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
17661771
dev = scb->platform_data->dev;
17671772
dev->active--;
17681773
dev->openings++;
1769-
if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1770-
cmd->result &= ~(CAM_DEV_QFRZN << 16);
1771-
dev->qfrozen--;
1774+
if (cmd) {
1775+
if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1776+
cmd->result &= ~(CAM_DEV_QFRZN << 16);
1777+
dev->qfrozen--;
1778+
}
1779+
} else if (scb->flags & SCB_DEVICE_RESET) {
1780+
if (ahd->platform_data->eh_done)
1781+
complete(ahd->platform_data->eh_done);
1782+
ahd_free_scb(ahd, scb);
1783+
return;
17721784
}
17731785
ahd_linux_unmap_scb(ahd, scb);
17741786

0 commit comments

Comments
 (0)