mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "Updates to the usual drivers (ufs, megaraid_sas, lpfc, target, ibmvfc, scsi_debug) plus the usual assorted minor fixes and updates. The major change this time around is a prep patch for rethreading of the driver reset handler API not to take a scsi_cmd structure which starts to reduce various drivers' dependence on scsi_cmd in error handling" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (132 commits) scsi: ufs: core: Leave space for '\0' in utf8 desc string scsi: ufs: core: Conversion to bool not necessary scsi: ufs: core: Fix race between force complete and ISR scsi: megaraid: Fix up debug message in megaraid_abort_and_reset() scsi: aic79xx: Fix up NULL command in ahd_done() scsi: message: fusion: Initialize return value in mptfc_bus_reset() scsi: mpt3sas: Fix loop logic scsi: snic: Remove useless code in snic_dr_clean_pending_req() scsi: core: Add comment to target_destroy in scsi_host_template scsi: core: Clean up scsi_dev_queue_ready() scsi: pmcraid: Add missing scsi_device_put() in pmcraid_eh_target_reset_handler() scsi: target: core: Fix kernel-doc comment scsi: pmcraid: Fix kernel-doc comment scsi: core: Handle depopulation and restoration in progress scsi: ufs: core: Add support for parsing OPP scsi: ufs: core: Add OPP support for scaling clocks and regulators scsi: ufs: dt-bindings: common: Add OPP table scsi: scsi_debug: Add param to control sdev's allow_restart scsi: scsi_debug: Add debugfs interface to fail target reset scsi: scsi_debug: Add new error injection type: Reset LUN failed ...
This commit is contained in:
@@ -20,11 +20,25 @@ properties:
|
||||
items:
|
||||
- description: Minimum frequency for given clock in Hz
|
||||
- description: Maximum frequency for given clock in Hz
|
||||
deprecated: true
|
||||
description: |
|
||||
Preferred is operating-points-v2.
|
||||
|
||||
Array of <min max> operating frequencies in Hz stored in the same order
|
||||
as the clocks property. If this property is not defined or a value in the
|
||||
array is "0" then it is assumed that the frequency is set by the parent
|
||||
clock or a fixed rate clock source.
|
||||
as the clocks property. If either this property or operating-points-v2 is
|
||||
not defined or a value in the array is "0" then it is assumed that the
|
||||
frequency is set by the parent clock or a fixed rate clock source.
|
||||
|
||||
operating-points-v2:
|
||||
description:
|
||||
Preferred over freq-table-hz.
|
||||
If present, each OPP must contain array of frequencies stored in the same
|
||||
order for each clock. If clock frequency in the array is "0" then it is
|
||||
assumed that the frequency is set by the parent clock or a fixed rate
|
||||
clock source.
|
||||
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
@@ -75,8 +89,23 @@ properties:
|
||||
|
||||
dependencies:
|
||||
freq-table-hz: [ clocks ]
|
||||
operating-points-v2: [ clocks, clock-names ]
|
||||
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
required:
|
||||
- freq-table-hz
|
||||
then:
|
||||
properties:
|
||||
operating-points-v2: false
|
||||
- if:
|
||||
required:
|
||||
- operating-points-v2
|
||||
then:
|
||||
properties:
|
||||
freq-table-hz: false
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
@@ -11221,7 +11221,6 @@ M: Sagi Grimberg <sagi@grimberg.me>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
L: target-devel@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.linux-iscsi.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
|
||||
F: drivers/infiniband/ulp/isert
|
||||
|
||||
@@ -13623,6 +13622,7 @@ MEGARAID SCSI/SAS DRIVERS
|
||||
M: Kashyap Desai <kashyap.desai@broadcom.com>
|
||||
M: Sumit Saxena <sumit.saxena@broadcom.com>
|
||||
M: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
|
||||
M: Chandrakanth patil <chandrakanth.patil@broadcom.com>
|
||||
L: megaraidlinux.pdl@broadcom.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
@@ -19275,7 +19275,6 @@ M: "Martin K. Petersen" <martin.petersen@oracle.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
L: target-devel@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.linux-iscsi.org
|
||||
Q: https://patchwork.kernel.org/project/target-devel/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
|
||||
F: Documentation/target/
|
||||
|
||||
@@ -3867,6 +3867,9 @@ static const struct target_core_fabric_ops srpt_template = {
|
||||
.tfc_discovery_attrs = srpt_da_attrs,
|
||||
.tfc_wwn_attrs = srpt_wwn_attrs,
|
||||
.tfc_tpg_attrib_attrs = srpt_tpg_attrib_attrs,
|
||||
|
||||
.default_submit_type = TARGET_DIRECT_SUBMIT,
|
||||
.direct_submit_supp = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1328,8 +1328,8 @@ mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
|
||||
|
||||
/* Set the Version Strings.
|
||||
*/
|
||||
strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
|
||||
karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
|
||||
strscpy_pad(karg->driverVersion, MPT_LINUX_PACKAGE_NAME,
|
||||
sizeof(karg->driverVersion));
|
||||
|
||||
karg->busChangeEvent = 0;
|
||||
karg->hostId = ioc->pfacts[port].PortSCSIID;
|
||||
@@ -1493,10 +1493,8 @@ mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
|
||||
#else
|
||||
karg.chip_type = ioc->pcidev->device;
|
||||
#endif
|
||||
strncpy (karg.name, ioc->name, MPT_MAX_NAME);
|
||||
karg.name[MPT_MAX_NAME-1]='\0';
|
||||
strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
|
||||
karg.product[MPT_PRODUCT_LENGTH-1]='\0';
|
||||
strscpy_pad(karg.name, ioc->name, sizeof(karg.name));
|
||||
strscpy_pad(karg.product, ioc->prod_name, sizeof(karg.product));
|
||||
|
||||
/* Copy the data from kernel memory to user memory
|
||||
*/
|
||||
@@ -2394,7 +2392,7 @@ mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
|
||||
cfg.dir = 0; /* read */
|
||||
cfg.timeout = 10;
|
||||
|
||||
strncpy(karg.serial_number, " ", 24);
|
||||
strscpy_pad(karg.serial_number, " ", sizeof(karg.serial_number));
|
||||
if (mpt_config(ioc, &cfg) == 0) {
|
||||
if (cfg.cfghdr.hdr->PageLength > 0) {
|
||||
/* Issue the second config page request */
|
||||
@@ -2408,8 +2406,9 @@ mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
|
||||
if (mpt_config(ioc, &cfg) == 0) {
|
||||
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
|
||||
if (strlen(pdata->BoardTracerNumber) > 1) {
|
||||
strscpy(karg.serial_number,
|
||||
pdata->BoardTracerNumber, 24);
|
||||
strscpy_pad(karg.serial_number,
|
||||
pdata->BoardTracerNumber,
|
||||
sizeof(karg.serial_number));
|
||||
}
|
||||
}
|
||||
dma_free_coherent(&ioc->pcidev->dev,
|
||||
@@ -2456,7 +2455,7 @@ mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Gather ISTWI(Industry Standard Two Wire Interface) Data
|
||||
*/
|
||||
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
|
||||
|
||||
@@ -183,73 +183,109 @@ static struct fc_function_template mptfc_transport_functions = {
|
||||
};
|
||||
|
||||
static int
|
||||
mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
|
||||
int (*func)(struct scsi_cmnd *SCpnt),
|
||||
const char *caller)
|
||||
mptfc_block_error_handler(struct fc_rport *rport)
|
||||
{
|
||||
MPT_SCSI_HOST *hd;
|
||||
struct scsi_device *sdev = SCpnt->device;
|
||||
struct Scsi_Host *shost = sdev->host;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
|
||||
struct Scsi_Host *shost = rport_to_shost(rport);
|
||||
unsigned long flags;
|
||||
int ready;
|
||||
MPT_ADAPTER *ioc;
|
||||
MPT_ADAPTER *ioc;
|
||||
int loops = 40; /* seconds */
|
||||
|
||||
hd = shost_priv(SCpnt->device->host);
|
||||
hd = shost_priv(shost);
|
||||
ioc = hd->ioc;
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
|
||||
|| (loops > 0 && ioc->active == 0)) {
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"mptfc_block_error_handler.%d: %d:%llu, port status is "
|
||||
"%x, active flag %d, deferring %s recovery.\n",
|
||||
"mptfc_block_error_handler.%d: %s, port status is "
|
||||
"%x, active flag %d, deferring recovery.\n",
|
||||
ioc->name, ioc->sh->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun,
|
||||
ready, ioc->active, caller));
|
||||
dev_name(&rport->dev), ready, ioc->active));
|
||||
msleep(1000);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
loops --;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
|
||||
|| ioc->active == 0) {
|
||||
if (ready == DID_NO_CONNECT || ioc->active == 0) {
|
||||
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"%s.%d: %d:%llu, failing recovery, "
|
||||
"port state %x, active %d, vdevice %p.\n", caller,
|
||||
"mpt_block_error_handler.%d: %s, failing recovery, "
|
||||
"port state %x, active %d.\n",
|
||||
ioc->name, ioc->sh->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun, ready,
|
||||
ioc->active, SCpnt->device->hostdata));
|
||||
dev_name(&rport->dev), ready, ioc->active));
|
||||
return FAILED;
|
||||
}
|
||||
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"%s.%d: %d:%llu, executing recovery.\n", caller,
|
||||
ioc->name, ioc->sh->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun));
|
||||
return (*func)(SCpnt);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_abort(struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
return
|
||||
mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
|
||||
struct Scsi_Host *shost = SCpnt->device->host;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
|
||||
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
|
||||
int rtn;
|
||||
|
||||
rtn = mptfc_block_error_handler(rport);
|
||||
if (rtn == SUCCESS) {
|
||||
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"%s.%d: %d:%llu, executing recovery.\n", __func__,
|
||||
hd->ioc->name, shost->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun));
|
||||
rtn = mptscsih_abort(SCpnt);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_dev_reset(struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
return
|
||||
mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
|
||||
struct Scsi_Host *shost = SCpnt->device->host;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
|
||||
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
|
||||
int rtn;
|
||||
|
||||
rtn = mptfc_block_error_handler(rport);
|
||||
if (rtn == SUCCESS) {
|
||||
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"%s.%d: %d:%llu, executing recovery.\n", __func__,
|
||||
hd->ioc->name, shost->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun));
|
||||
rtn = mptscsih_dev_reset(SCpnt);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_bus_reset(struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
return
|
||||
mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
|
||||
struct Scsi_Host *shost = SCpnt->device->host;
|
||||
MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
|
||||
int channel = SCpnt->device->channel;
|
||||
struct mptfc_rport_info *ri;
|
||||
int rtn = FAILED;
|
||||
|
||||
list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
|
||||
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
|
||||
VirtTarget *vtarget = ri->starget->hostdata;
|
||||
|
||||
if (!vtarget || vtarget->channel != channel)
|
||||
continue;
|
||||
rtn = fc_block_rport(ri->rport);
|
||||
if (rtn != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rtn == 0) {
|
||||
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
"%s.%d: %d:%llu, executing recovery.\n", __func__,
|
||||
hd->ioc->name, shost->host_no,
|
||||
SCpnt->device->id, SCpnt->device->lun));
|
||||
rtn = mptscsih_bus_reset(SCpnt);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -2964,17 +2964,17 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
|
||||
goto out_free;
|
||||
|
||||
manufacture_reply = data_out + sizeof(struct rep_manu_request);
|
||||
strncpy(edev->vendor_id, manufacture_reply->vendor_id,
|
||||
SAS_EXPANDER_VENDOR_ID_LEN);
|
||||
strncpy(edev->product_id, manufacture_reply->product_id,
|
||||
SAS_EXPANDER_PRODUCT_ID_LEN);
|
||||
strncpy(edev->product_rev, manufacture_reply->product_rev,
|
||||
SAS_EXPANDER_PRODUCT_REV_LEN);
|
||||
strscpy(edev->vendor_id, manufacture_reply->vendor_id,
|
||||
sizeof(edev->vendor_id));
|
||||
strscpy(edev->product_id, manufacture_reply->product_id,
|
||||
sizeof(edev->product_id));
|
||||
strscpy(edev->product_rev, manufacture_reply->product_rev,
|
||||
sizeof(edev->product_rev));
|
||||
edev->level = manufacture_reply->sas_format;
|
||||
if (manufacture_reply->sas_format) {
|
||||
strncpy(edev->component_vendor_id,
|
||||
strscpy(edev->component_vendor_id,
|
||||
manufacture_reply->component_vendor_id,
|
||||
SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
|
||||
sizeof(edev->component_vendor_id));
|
||||
tmp = (u8 *)&manufacture_reply->component_id;
|
||||
edev->component_id = tmp[0] << 8 | tmp[1];
|
||||
edev->component_revision_id =
|
||||
|
||||
@@ -1793,7 +1793,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
|
||||
* mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
|
||||
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
|
||||
*
|
||||
* (linux scsi_host_template.eh_dev_reset_handler routine)
|
||||
@@ -1808,6 +1808,58 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
|
||||
VirtDevice *vdevice;
|
||||
MPT_ADAPTER *ioc;
|
||||
|
||||
/* If we can't locate our host adapter structure, return FAILED status.
|
||||
*/
|
||||
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
|
||||
printk(KERN_ERR MYNAM ": lun reset: "
|
||||
"Can't locate host! (sc=%p)\n", SCpnt);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ioc = hd->ioc;
|
||||
printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
|
||||
ioc->name, SCpnt);
|
||||
scsi_print_command(SCpnt);
|
||||
|
||||
vdevice = SCpnt->device->hostdata;
|
||||
if (!vdevice || !vdevice->vtarget) {
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
retval = mptscsih_IssueTaskMgmt(hd,
|
||||
MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET,
|
||||
vdevice->vtarget->channel,
|
||||
vdevice->vtarget->id, vdevice->lun, 0,
|
||||
mptscsih_get_tm_timeout(ioc));
|
||||
|
||||
out:
|
||||
printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
|
||||
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
|
||||
|
||||
if (retval == 0)
|
||||
return SUCCESS;
|
||||
else
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptscsih_target_reset - Perform a SCSI TARGET_RESET!
|
||||
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
|
||||
*
|
||||
* (linux scsi_host_template.eh_target_reset_handler routine)
|
||||
*
|
||||
* Returns SUCCESS or FAILED.
|
||||
**/
|
||||
int
|
||||
mptscsih_target_reset(struct scsi_cmnd * SCpnt)
|
||||
{
|
||||
MPT_SCSI_HOST *hd;
|
||||
int retval;
|
||||
VirtDevice *vdevice;
|
||||
MPT_ADAPTER *ioc;
|
||||
|
||||
/* If we can't locate our host adapter structure, return FAILED status.
|
||||
*/
|
||||
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
|
||||
@@ -3256,6 +3308,7 @@ EXPORT_SYMBOL(mptscsih_slave_destroy);
|
||||
EXPORT_SYMBOL(mptscsih_slave_configure);
|
||||
EXPORT_SYMBOL(mptscsih_abort);
|
||||
EXPORT_SYMBOL(mptscsih_dev_reset);
|
||||
EXPORT_SYMBOL(mptscsih_target_reset);
|
||||
EXPORT_SYMBOL(mptscsih_bus_reset);
|
||||
EXPORT_SYMBOL(mptscsih_host_reset);
|
||||
EXPORT_SYMBOL(mptscsih_bios_param);
|
||||
|
||||
@@ -120,6 +120,7 @@ extern void mptscsih_slave_destroy(struct scsi_device *device);
|
||||
extern int mptscsih_slave_configure(struct scsi_device *device);
|
||||
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
|
||||
extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
|
||||
|
||||
@@ -834,21 +834,6 @@ config SCSI_IMM
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imm.
|
||||
|
||||
config SCSI_IZIP_EPP16
|
||||
bool "ppa/imm option - Use slow (but safe) EPP-16"
|
||||
depends on SCSI_IMM
|
||||
help
|
||||
EPP (Enhanced Parallel Port) is a standard for parallel ports which
|
||||
allows them to act as expansion buses that can handle up to 64
|
||||
peripheral devices.
|
||||
|
||||
Some parallel port chipsets are slower than their motherboard, and
|
||||
so we have to control the state of the chipset's FIFO queue every
|
||||
now and then to avoid data loss. This will be done if you say Y
|
||||
here.
|
||||
|
||||
Generally, saying Y is the safe option and slows things down a bit.
|
||||
|
||||
config SCSI_IZIP_SLOW_CTR
|
||||
bool "ppa/imm option - Assume slow parport control register"
|
||||
depends on SCSI_PPA || SCSI_IMM
|
||||
|
||||
@@ -536,13 +536,18 @@ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
|
||||
struct scsi_cmnd *cmd;
|
||||
|
||||
cmd = scb->io_ctx;
|
||||
ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
|
||||
scsi_dma_unmap(cmd);
|
||||
if (cmd) {
|
||||
ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
|
||||
scsi_dma_unmap(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************** Macros **************************************/
|
||||
#define BUILD_SCSIID(ahd, cmd) \
|
||||
(((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
|
||||
static inline unsigned int ahd_build_scsiid(struct ahd_softc *ahd,
|
||||
struct scsi_device *sdev)
|
||||
{
|
||||
return ((sdev_id(sdev) << TID_SHIFT) & TID) | (ahd)->our_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string describing the driver.
|
||||
@@ -811,14 +816,14 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)
|
||||
|
||||
tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
|
||||
cmd->device->id, &tstate);
|
||||
reset_scb->io_ctx = cmd;
|
||||
reset_scb->io_ctx = NULL;
|
||||
reset_scb->platform_data->dev = dev;
|
||||
reset_scb->sg_count = 0;
|
||||
ahd_set_residual(reset_scb, 0);
|
||||
ahd_set_sense_residual(reset_scb, 0);
|
||||
reset_scb->platform_data->xfer_len = 0;
|
||||
reset_scb->hscb->control = 0;
|
||||
reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
|
||||
reset_scb->hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
|
||||
reset_scb->hscb->lun = cmd->device->lun;
|
||||
reset_scb->hscb->cdb_len = 0;
|
||||
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,
|
||||
* Fill out basics of the HSCB.
|
||||
*/
|
||||
hscb->control = 0;
|
||||
hscb->scsiid = BUILD_SCSIID(ahd, cmd);
|
||||
hscb->scsiid = ahd_build_scsiid(ahd, cmd->device);
|
||||
hscb->lun = cmd->device->lun;
|
||||
scb->hscb->task_management = 0;
|
||||
mask = SCB_GET_TARGET_MASK(ahd, scb);
|
||||
@@ -1766,9 +1771,16 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
|
||||
dev = scb->platform_data->dev;
|
||||
dev->active--;
|
||||
dev->openings++;
|
||||
if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
|
||||
cmd->result &= ~(CAM_DEV_QFRZN << 16);
|
||||
dev->qfrozen--;
|
||||
if (cmd) {
|
||||
if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
|
||||
cmd->result &= ~(CAM_DEV_QFRZN << 16);
|
||||
dev->qfrozen--;
|
||||
}
|
||||
} else if (scb->flags & SCB_DEVICE_RESET) {
|
||||
if (ahd->platform_data->eh_done)
|
||||
complete(ahd->platform_data->eh_done);
|
||||
ahd_free_scb(ahd, scb);
|
||||
return;
|
||||
}
|
||||
ahd_linux_unmap_scb(ahd, scb);
|
||||
|
||||
@@ -1822,7 +1834,8 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
|
||||
} else {
|
||||
ahd_set_transaction_status(scb, CAM_REQ_CMP);
|
||||
}
|
||||
} else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
|
||||
} else if (cmd &&
|
||||
ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
|
||||
ahd_linux_handle_scsi_status(ahd, cmd->device, scb);
|
||||
}
|
||||
|
||||
@@ -1856,7 +1869,8 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
|
||||
}
|
||||
|
||||
ahd_free_scb(ahd, scb);
|
||||
ahd_linux_queue_cmd_complete(ahd, cmd);
|
||||
if (cmd)
|
||||
ahd_linux_queue_cmd_complete(ahd, cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -366,7 +366,8 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
|
||||
struct scsi_cmnd *cmd);
|
||||
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
|
||||
static void ahc_linux_release_simq(struct ahc_softc *ahc);
|
||||
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
|
||||
static int ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
|
||||
struct scsi_cmnd *cmd);
|
||||
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
|
||||
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
|
||||
struct ahc_devinfo *devinfo);
|
||||
@@ -728,7 +729,7 @@ ahc_linux_abort(struct scsi_cmnd *cmd)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
|
||||
error = ahc_linux_queue_recovery_cmd(cmd->device, cmd);
|
||||
if (error != SUCCESS)
|
||||
printk("aic7xxx_abort returns 0x%x\n", error);
|
||||
return (error);
|
||||
@@ -742,7 +743,7 @@ ahc_linux_dev_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
|
||||
error = ahc_linux_queue_recovery_cmd(cmd->device, NULL);
|
||||
if (error != SUCCESS)
|
||||
printk("aic7xxx_dev_reset returns 0x%x\n", error);
|
||||
return (error);
|
||||
@@ -798,11 +799,18 @@ struct scsi_host_template aic7xxx_driver_template = {
|
||||
|
||||
/**************************** Tasklet Handler *********************************/
|
||||
|
||||
/******************************** Macros **************************************/
|
||||
#define BUILD_SCSIID(ahc, cmd) \
|
||||
((((cmd)->device->id << TID_SHIFT) & TID) \
|
||||
| (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
|
||||
| (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
|
||||
|
||||
static inline unsigned int ahc_build_scsiid(struct ahc_softc *ahc,
|
||||
struct scsi_device *sdev)
|
||||
{
|
||||
unsigned int scsiid = (sdev->id << TID_SHIFT) & TID;
|
||||
|
||||
if (sdev->channel == 0)
|
||||
scsiid |= ahc->our_id;
|
||||
else
|
||||
scsiid |= ahc->our_id_b | TWIN_CHNLB;
|
||||
return scsiid;
|
||||
}
|
||||
|
||||
/******************************** Bus DMA *************************************/
|
||||
int
|
||||
@@ -1457,7 +1465,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
||||
* Fill out basics of the HSCB.
|
||||
*/
|
||||
hscb->control = 0;
|
||||
hscb->scsiid = BUILD_SCSIID(ahc, cmd);
|
||||
hscb->scsiid = ahc_build_scsiid(ahc, cmd->device);
|
||||
hscb->lun = cmd->device->lun;
|
||||
mask = SCB_GET_TARGET_MASK(ahc, scb);
|
||||
tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
|
||||
@@ -2029,11 +2037,12 @@ ahc_linux_release_simq(struct ahc_softc *ahc)
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
|
||||
struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct ahc_softc *ahc;
|
||||
struct ahc_linux_device *dev;
|
||||
struct scb *pending_scb;
|
||||
struct scb *pending_scb = NULL, *scb;
|
||||
u_int saved_scbptr;
|
||||
u_int active_scb_index;
|
||||
u_int last_phase;
|
||||
@@ -2046,18 +2055,19 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
int disconnected;
|
||||
unsigned long flags;
|
||||
|
||||
pending_scb = NULL;
|
||||
paused = FALSE;
|
||||
wait = FALSE;
|
||||
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
|
||||
ahc = *(struct ahc_softc **)sdev->host->hostdata;
|
||||
|
||||
scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
|
||||
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
|
||||
sdev_printk(KERN_INFO, sdev, "Attempting to queue a%s message\n",
|
||||
cmd ? "n ABORT" : " TARGET RESET");
|
||||
|
||||
printk("CDB:");
|
||||
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
|
||||
printk(" 0x%x", cmd->cmnd[cdb_byte]);
|
||||
printk("\n");
|
||||
if (cmd) {
|
||||
printk("CDB:");
|
||||
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
|
||||
printk(" 0x%x", cmd->cmnd[cdb_byte]);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
ahc_lock(ahc, &flags);
|
||||
|
||||
@@ -2068,7 +2078,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
* at all, and the system wanted us to just abort the
|
||||
* command, return success.
|
||||
*/
|
||||
dev = scsi_transport_device_data(cmd->device);
|
||||
dev = scsi_transport_device_data(sdev);
|
||||
|
||||
if (dev == NULL) {
|
||||
/*
|
||||
@@ -2076,13 +2086,12 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
* so we must not still own the command.
|
||||
*/
|
||||
printk("%s:%d:%d:%d: Is not an active device\n",
|
||||
ahc_name(ahc), cmd->device->channel, cmd->device->id,
|
||||
(u8)cmd->device->lun);
|
||||
ahc_name(ahc), sdev->channel, sdev->id, (u8)sdev->lun);
|
||||
retval = SUCCESS;
|
||||
goto no_cmd;
|
||||
}
|
||||
|
||||
if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
|
||||
if (cmd && (dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
|
||||
&& ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
|
||||
cmd->device->channel + 'A',
|
||||
(u8)cmd->device->lun,
|
||||
@@ -2097,25 +2106,28 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
/*
|
||||
* See if we can find a matching cmd in the pending list.
|
||||
*/
|
||||
LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
|
||||
if (pending_scb->io_ctx == cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
|
||||
|
||||
/* Any SCB for this device will do for a target reset */
|
||||
LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
|
||||
if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
|
||||
scmd_channel(cmd) + 'A',
|
||||
CAM_LUN_WILDCARD,
|
||||
SCB_LIST_NULL, ROLE_INITIATOR))
|
||||
if (cmd) {
|
||||
LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
|
||||
if (scb->io_ctx == cmd) {
|
||||
pending_scb = scb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Any SCB for this device will do for a target reset */
|
||||
LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
|
||||
if (ahc_match_scb(ahc, scb, sdev->id,
|
||||
sdev->channel + 'A',
|
||||
CAM_LUN_WILDCARD,
|
||||
SCB_LIST_NULL, ROLE_INITIATOR)) {
|
||||
pending_scb = scb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pending_scb == NULL) {
|
||||
scmd_printk(KERN_INFO, cmd, "Command not found\n");
|
||||
sdev_printk(KERN_INFO, sdev, "Command not found\n");
|
||||
goto no_cmd;
|
||||
}
|
||||
|
||||
@@ -2146,22 +2158,22 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
ahc_dump_card_state(ahc);
|
||||
|
||||
disconnected = TRUE;
|
||||
if (flag == SCB_ABORT) {
|
||||
if (ahc_search_qinfifo(ahc, cmd->device->id,
|
||||
cmd->device->channel + 'A',
|
||||
cmd->device->lun,
|
||||
if (cmd) {
|
||||
if (ahc_search_qinfifo(ahc, sdev->id,
|
||||
sdev->channel + 'A',
|
||||
sdev->lun,
|
||||
pending_scb->hscb->tag,
|
||||
ROLE_INITIATOR, CAM_REQ_ABORTED,
|
||||
SEARCH_COMPLETE) > 0) {
|
||||
printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
|
||||
ahc_name(ahc), cmd->device->channel,
|
||||
cmd->device->id, (u8)cmd->device->lun);
|
||||
ahc_name(ahc), sdev->channel,
|
||||
sdev->id, (u8)sdev->lun);
|
||||
retval = SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
} else if (ahc_search_qinfifo(ahc, cmd->device->id,
|
||||
cmd->device->channel + 'A',
|
||||
cmd->device->lun,
|
||||
} else if (ahc_search_qinfifo(ahc, sdev->id,
|
||||
sdev->channel + 'A',
|
||||
sdev->lun,
|
||||
pending_scb->hscb->tag,
|
||||
ROLE_INITIATOR, /*status*/0,
|
||||
SEARCH_COUNT) > 0) {
|
||||
@@ -2174,7 +2186,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
|
||||
if (bus_scb == pending_scb)
|
||||
disconnected = FALSE;
|
||||
else if (flag != SCB_ABORT
|
||||
else if (!cmd
|
||||
&& ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
|
||||
&& ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
|
||||
disconnected = FALSE;
|
||||
@@ -2194,18 +2206,18 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
|
||||
if (last_phase != P_BUSFREE
|
||||
&& (pending_scb->hscb->tag == active_scb_index
|
||||
|| (flag == SCB_DEVICE_RESET
|
||||
&& SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
|
||||
|| (!cmd && SCSIID_TARGET(ahc, saved_scsiid) == sdev->id))) {
|
||||
|
||||
/*
|
||||
* We're active on the bus, so assert ATN
|
||||
* and hope that the target responds.
|
||||
*/
|
||||
pending_scb = ahc_lookup_scb(ahc, active_scb_index);
|
||||
pending_scb->flags |= SCB_RECOVERY_SCB|flag;
|
||||
pending_scb->flags |= SCB_RECOVERY_SCB;
|
||||
pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;
|
||||
ahc_outb(ahc, MSG_OUT, HOST_MSG);
|
||||
ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
|
||||
scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
|
||||
sdev_printk(KERN_INFO, sdev, "Device is active, asserting ATN\n");
|
||||
wait = TRUE;
|
||||
} else if (disconnected) {
|
||||
|
||||
@@ -2226,7 +2238,8 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
* an unsolicited reselection occurred.
|
||||
*/
|
||||
pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
|
||||
pending_scb->flags |= SCB_RECOVERY_SCB|flag;
|
||||
pending_scb->flags |= SCB_RECOVERY_SCB;
|
||||
pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;
|
||||
|
||||
/*
|
||||
* Remove any cached copy of this SCB in the
|
||||
@@ -2235,9 +2248,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
* same element in the SCB, SCB_NEXT, for
|
||||
* both the qinfifo and the disconnected list.
|
||||
*/
|
||||
ahc_search_disc_list(ahc, cmd->device->id,
|
||||
cmd->device->channel + 'A',
|
||||
cmd->device->lun, pending_scb->hscb->tag,
|
||||
ahc_search_disc_list(ahc, sdev->id,
|
||||
sdev->channel + 'A',
|
||||
sdev->lun, pending_scb->hscb->tag,
|
||||
/*stop_on_first*/TRUE,
|
||||
/*remove*/TRUE,
|
||||
/*save_state*/FALSE);
|
||||
@@ -2260,9 +2273,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
* so we are the next SCB for this target
|
||||
* to run.
|
||||
*/
|
||||
ahc_search_qinfifo(ahc, cmd->device->id,
|
||||
cmd->device->channel + 'A',
|
||||
cmd->device->lun, SCB_LIST_NULL,
|
||||
ahc_search_qinfifo(ahc, sdev->id,
|
||||
sdev->channel + 'A',
|
||||
(u8)sdev->lun, SCB_LIST_NULL,
|
||||
ROLE_INITIATOR, CAM_REQUEUE_REQ,
|
||||
SEARCH_COMPLETE);
|
||||
ahc_qinfifo_requeue_tail(ahc, pending_scb);
|
||||
@@ -2271,7 +2284,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
printk("Device is disconnected, re-queuing SCB\n");
|
||||
wait = TRUE;
|
||||
} else {
|
||||
scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
|
||||
sdev_printk(KERN_INFO, sdev, "Unable to deliver message\n");
|
||||
retval = FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -384,6 +384,7 @@ struct bnx2fc_rport {
|
||||
};
|
||||
|
||||
struct bnx2fc_mp_req {
|
||||
u64 tm_lun;
|
||||
u8 tm_flags;
|
||||
|
||||
u32 req_len;
|
||||
|
||||
@@ -1709,7 +1709,8 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
|
||||
struct fcoe_cached_sge_ctx *cached_sge;
|
||||
struct fcoe_ext_mul_sges_ctx *sgl;
|
||||
int dev_type = tgt->dev_type;
|
||||
u64 *fcp_cmnd;
|
||||
struct fcp_cmnd *fcp_cmnd;
|
||||
u64 *raw_fcp_cmnd;
|
||||
u64 tmp_fcp_cmnd[4];
|
||||
u32 context_id;
|
||||
int cnt, i;
|
||||
@@ -1778,16 +1779,19 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
|
||||
task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1;
|
||||
|
||||
/* Fill FCP_CMND IU */
|
||||
fcp_cmnd = (u64 *)
|
||||
fcp_cmnd = (struct fcp_cmnd *)&tmp_fcp_cmnd;
|
||||
bnx2fc_build_fcp_cmnd(io_req, fcp_cmnd);
|
||||
int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
|
||||
memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
|
||||
raw_fcp_cmnd = (u64 *)
|
||||
task->txwr_rxrd.union_ctx.fcp_cmd.opaque;
|
||||
bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)&tmp_fcp_cmnd);
|
||||
|
||||
/* swap fcp_cmnd */
|
||||
cnt = sizeof(struct fcp_cmnd) / sizeof(u64);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
*fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
|
||||
fcp_cmnd++;
|
||||
*raw_fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
|
||||
raw_fcp_cmnd++;
|
||||
}
|
||||
|
||||
/* Rx Write Tx Read */
|
||||
|
||||
@@ -656,10 +656,9 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
|
||||
static int bnx2fc_initiate_tmf(struct fc_lport *lport, struct fc_rport *rport,
|
||||
u64 tm_lun, u8 tm_flags)
|
||||
{
|
||||
struct fc_lport *lport;
|
||||
struct fc_rport *rport;
|
||||
struct fc_rport_libfc_priv *rp;
|
||||
struct fcoe_port *port;
|
||||
struct bnx2fc_interface *interface;
|
||||
@@ -668,7 +667,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
|
||||
struct bnx2fc_mp_req *tm_req;
|
||||
struct fcoe_task_ctx_entry *task;
|
||||
struct fcoe_task_ctx_entry *task_page;
|
||||
struct Scsi_Host *host = sc_cmd->device->host;
|
||||
struct fc_frame_header *fc_hdr;
|
||||
struct fcp_cmnd *fcp_cmnd;
|
||||
int task_idx, index;
|
||||
@@ -677,8 +675,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
|
||||
u32 sid, did;
|
||||
unsigned long start = jiffies;
|
||||
|
||||
lport = shost_priv(host);
|
||||
rport = starget_to_rport(scsi_target(sc_cmd->device));
|
||||
port = lport_priv(lport);
|
||||
interface = port->priv;
|
||||
|
||||
@@ -689,7 +685,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
|
||||
}
|
||||
rp = rport->dd_data;
|
||||
|
||||
rc = fc_block_scsi_eh(sc_cmd);
|
||||
rc = fc_block_rport(rport);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -718,7 +714,7 @@ retry_tmf:
|
||||
goto retry_tmf;
|
||||
}
|
||||
/* Initialize rest of io_req fields */
|
||||
io_req->sc_cmd = sc_cmd;
|
||||
io_req->sc_cmd = NULL;
|
||||
io_req->port = port;
|
||||
io_req->tgt = tgt;
|
||||
|
||||
@@ -736,11 +732,13 @@ retry_tmf:
|
||||
/* Set TM flags */
|
||||
io_req->io_req_flags = 0;
|
||||
tm_req->tm_flags = tm_flags;
|
||||
tm_req->tm_lun = tm_lun;
|
||||
|
||||
/* Fill FCP_CMND */
|
||||
bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tm_req->req_buf);
|
||||
fcp_cmnd = (struct fcp_cmnd *)tm_req->req_buf;
|
||||
memset(fcp_cmnd->fc_cdb, 0, sc_cmd->cmd_len);
|
||||
int_to_scsilun(tm_lun, &fcp_cmnd->fc_lun);
|
||||
memset(fcp_cmnd->fc_cdb, 0, BNX2FC_MAX_CMD_LEN);
|
||||
fcp_cmnd->fc_dl = 0;
|
||||
|
||||
/* Fill FC header */
|
||||
@@ -763,8 +761,6 @@ retry_tmf:
|
||||
task = &(task_page[index]);
|
||||
bnx2fc_init_mp_task(io_req, task);
|
||||
|
||||
bnx2fc_priv(sc_cmd)->io_req = io_req;
|
||||
|
||||
/* Obtain free SQ entry */
|
||||
spin_lock_bh(&tgt->tgt_lock);
|
||||
bnx2fc_add_2_sq(tgt, xid);
|
||||
@@ -1062,7 +1058,10 @@ cleanup_err:
|
||||
*/
|
||||
int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
|
||||
{
|
||||
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET);
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
|
||||
struct fc_lport *lport = shost_priv(rport_to_shost(rport));
|
||||
|
||||
return bnx2fc_initiate_tmf(lport, rport, 0, FCP_TMF_TGT_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1075,7 +1074,11 @@ int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
|
||||
*/
|
||||
int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
|
||||
{
|
||||
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
|
||||
struct fc_lport *lport = shost_priv(rport_to_shost(rport));
|
||||
|
||||
return bnx2fc_initiate_tmf(lport, rport, sc_cmd->device->lun,
|
||||
FCP_TMF_LUN_RESET);
|
||||
}
|
||||
|
||||
static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
|
||||
@@ -1450,10 +1453,9 @@ io_compl:
|
||||
|
||||
static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
|
||||
{
|
||||
struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
|
||||
struct bnx2fc_rport *tgt = io_req->tgt;
|
||||
struct bnx2fc_cmd *cmd, *tmp;
|
||||
u64 tm_lun = sc_cmd->device->lun;
|
||||
struct bnx2fc_mp_req *tm_req = &io_req->mp_req;
|
||||
u64 lun;
|
||||
int rc = 0;
|
||||
|
||||
@@ -1465,8 +1467,10 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
|
||||
*/
|
||||
list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) {
|
||||
BNX2FC_TGT_DBG(tgt, "LUN RST cmpl: scan for pending IOs\n");
|
||||
if (!cmd->sc_cmd)
|
||||
continue;
|
||||
lun = cmd->sc_cmd->device->lun;
|
||||
if (lun == tm_lun) {
|
||||
if (lun == tm_req->tm_lun) {
|
||||
/* Initiate ABTS on this cmd */
|
||||
if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
|
||||
&cmd->req_flags)) {
|
||||
@@ -1570,32 +1574,37 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
|
||||
printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n",
|
||||
fc_hdr->fh_r_ctl);
|
||||
}
|
||||
if (!bnx2fc_priv(sc_cmd)->io_req) {
|
||||
printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
|
||||
return;
|
||||
}
|
||||
switch (io_req->fcp_status) {
|
||||
case FC_GOOD:
|
||||
if (io_req->cdb_status == 0) {
|
||||
/* Good IO completion */
|
||||
sc_cmd->result = DID_OK << 16;
|
||||
} else {
|
||||
/* Transport status is good, SCSI status not good */
|
||||
sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
|
||||
if (sc_cmd) {
|
||||
if (!bnx2fc_priv(sc_cmd)->io_req) {
|
||||
printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
|
||||
return;
|
||||
}
|
||||
if (io_req->fcp_resid)
|
||||
scsi_set_resid(sc_cmd, io_req->fcp_resid);
|
||||
break;
|
||||
switch (io_req->fcp_status) {
|
||||
case FC_GOOD:
|
||||
if (io_req->cdb_status == 0) {
|
||||
/* Good IO completion */
|
||||
sc_cmd->result = DID_OK << 16;
|
||||
} else {
|
||||
/* Transport status is good, SCSI status not good */
|
||||
sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
|
||||
}
|
||||
if (io_req->fcp_resid)
|
||||
scsi_set_resid(sc_cmd, io_req->fcp_resid);
|
||||
break;
|
||||
|
||||
default:
|
||||
BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
|
||||
io_req->fcp_status);
|
||||
break;
|
||||
default:
|
||||
BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
|
||||
io_req->fcp_status);
|
||||
break;
|
||||
}
|
||||
|
||||
sc_cmd = io_req->sc_cmd;
|
||||
io_req->sc_cmd = NULL;
|
||||
|
||||
bnx2fc_priv(sc_cmd)->io_req = NULL;
|
||||
scsi_done(sc_cmd);
|
||||
}
|
||||
|
||||
sc_cmd = io_req->sc_cmd;
|
||||
io_req->sc_cmd = NULL;
|
||||
|
||||
/* check if the io_req exists in tgt's tmf_q */
|
||||
if (io_req->on_tmf_queue) {
|
||||
|
||||
@@ -1607,9 +1616,6 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
|
||||
return;
|
||||
}
|
||||
|
||||
bnx2fc_priv(sc_cmd)->io_req = NULL;
|
||||
scsi_done(sc_cmd);
|
||||
|
||||
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
||||
if (io_req->wait_for_abts_comp) {
|
||||
BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n");
|
||||
@@ -1738,15 +1744,9 @@ static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req)
|
||||
void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,
|
||||
struct fcp_cmnd *fcp_cmnd)
|
||||
{
|
||||
struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
|
||||
|
||||
memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
|
||||
|
||||
int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
|
||||
|
||||
fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
|
||||
memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
|
||||
|
||||
fcp_cmnd->fc_cmdref = 0;
|
||||
fcp_cmnd->fc_pri_ta = 0;
|
||||
fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags;
|
||||
|
||||
@@ -1294,7 +1294,7 @@ static int cxgbi_ddp_reserve(struct cxgbi_conn *cconn,
|
||||
|
||||
/*
|
||||
* the ddp tag will be used for the itt in the outgoing pdu,
|
||||
* the itt genrated by libiscsi is saved in the ppm and can be
|
||||
* the itt generated by libiscsi is saved in the ppm and can be
|
||||
* retrieved via the ddp tag
|
||||
*/
|
||||
err = cxgbi_ppm_ppods_reserve(ppm, ttinfo->nr_pages, 0, &ttinfo->idx,
|
||||
|
||||
@@ -82,7 +82,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
|
||||
{
|
||||
unsigned char cmd[6] = { TEST_UNIT_READY };
|
||||
struct scsi_sense_hdr sshdr;
|
||||
int ret = SCSI_DH_OK, res;
|
||||
int ret, res;
|
||||
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
|
||||
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||
const struct scsi_exec_args exec_args = {
|
||||
@@ -92,19 +92,18 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
|
||||
retry:
|
||||
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
|
||||
HP_SW_RETRIES, &exec_args);
|
||||
if (res) {
|
||||
if (scsi_sense_valid(&sshdr))
|
||||
ret = tur_done(sdev, h, &sshdr);
|
||||
else {
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending tur failed with %x\n",
|
||||
HP_SW_NAME, res);
|
||||
ret = SCSI_DH_IO;
|
||||
}
|
||||
} else {
|
||||
if (res > 0 && scsi_sense_valid(&sshdr)) {
|
||||
ret = tur_done(sdev, h, &sshdr);
|
||||
} else if (res == 0) {
|
||||
h->path_state = HP_SW_PATH_ACTIVE;
|
||||
ret = SCSI_DH_OK;
|
||||
} else {
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending tur failed with %x\n",
|
||||
HP_SW_NAME, res);
|
||||
ret = SCSI_DH_IO;
|
||||
}
|
||||
|
||||
if (ret == SCSI_DH_IMM_RETRY)
|
||||
goto retry;
|
||||
|
||||
@@ -122,7 +121,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
|
||||
unsigned char cmd[6] = { START_STOP, 0, 0, 0, 1, 0 };
|
||||
struct scsi_sense_hdr sshdr;
|
||||
struct scsi_device *sdev = h->sdev;
|
||||
int res, rc = SCSI_DH_OK;
|
||||
int res, rc;
|
||||
int retry_cnt = HP_SW_RETRIES;
|
||||
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
|
||||
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
|
||||
@@ -133,35 +132,37 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
|
||||
retry:
|
||||
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
|
||||
HP_SW_RETRIES, &exec_args);
|
||||
if (res) {
|
||||
if (!scsi_sense_valid(&sshdr)) {
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending start_stop_unit failed, "
|
||||
"no sense available\n", HP_SW_NAME);
|
||||
return SCSI_DH_IO;
|
||||
}
|
||||
switch (sshdr.sense_key) {
|
||||
case NOT_READY:
|
||||
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
|
||||
/*
|
||||
* LUN not ready - manual intervention required
|
||||
*
|
||||
* Switch-over in progress, retry.
|
||||
*/
|
||||
if (--retry_cnt)
|
||||
goto retry;
|
||||
rc = SCSI_DH_RETRY;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending start_stop_unit failed, "
|
||||
"sense %x/%x/%x\n", HP_SW_NAME,
|
||||
sshdr.sense_key, sshdr.asc, sshdr.ascq);
|
||||
rc = SCSI_DH_IO;
|
||||
}
|
||||
if (!res) {
|
||||
return SCSI_DH_OK;
|
||||
} else if (res < 0 || !scsi_sense_valid(&sshdr)) {
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending start_stop_unit failed, "
|
||||
"no sense available\n", HP_SW_NAME);
|
||||
return SCSI_DH_IO;
|
||||
}
|
||||
|
||||
switch (sshdr.sense_key) {
|
||||
case NOT_READY:
|
||||
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
|
||||
/*
|
||||
* LUN not ready - manual intervention required
|
||||
*
|
||||
* Switch-over in progress, retry.
|
||||
*/
|
||||
if (--retry_cnt)
|
||||
goto retry;
|
||||
rc = SCSI_DH_RETRY;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
sdev_printk(KERN_WARNING, sdev,
|
||||
"%s: sending start_stop_unit failed, "
|
||||
"sense %x/%x/%x\n", HP_SW_NAME,
|
||||
sshdr.sense_key, sshdr.asc, sshdr.ascq);
|
||||
rc = SCSI_DH_IO;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -530,7 +530,7 @@ static void send_mode_select(struct work_struct *work)
|
||||
container_of(work, struct rdac_controller, ms_work);
|
||||
struct scsi_device *sdev = ctlr->ms_sdev;
|
||||
struct rdac_dh_data *h = sdev->handler_data;
|
||||
int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT;
|
||||
int rc, err, retry_cnt = RDAC_RETRY_COUNT;
|
||||
struct rdac_queue_data *tmp, *qdata;
|
||||
LIST_HEAD(list);
|
||||
unsigned char cdb[MAX_COMMAND_SIZE];
|
||||
@@ -558,20 +558,23 @@ static void send_mode_select(struct work_struct *work)
|
||||
(char *) h->ctlr->array_name, h->ctlr->index,
|
||||
(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
|
||||
|
||||
if (scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
|
||||
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args)) {
|
||||
rc = scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
|
||||
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args);
|
||||
if (!rc) {
|
||||
h->state = RDAC_STATE_ACTIVE;
|
||||
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
|
||||
"MODE_SELECT completed",
|
||||
(char *) h->ctlr->array_name, h->ctlr->index);
|
||||
err = SCSI_DH_OK;
|
||||
} else if (rc < 0) {
|
||||
err = SCSI_DH_IO;
|
||||
} else {
|
||||
err = mode_select_handle_sense(sdev, &sshdr);
|
||||
if (err == SCSI_DH_RETRY && retry_cnt--)
|
||||
goto retry;
|
||||
if (err == SCSI_DH_IMM_RETRY)
|
||||
goto retry;
|
||||
}
|
||||
if (err == SCSI_DH_OK) {
|
||||
h->state = RDAC_STATE_ACTIVE;
|
||||
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
|
||||
"MODE_SELECT completed",
|
||||
(char *) h->ctlr->array_name, h->ctlr->index);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(qdata, tmp, &list, entry) {
|
||||
list_del(&qdata->entry);
|
||||
|
||||
@@ -1611,6 +1611,8 @@ static const struct target_core_fabric_ops efct_lio_ops = {
|
||||
.sess_get_initiator_sid = NULL,
|
||||
.tfc_tpg_base_attrs = efct_lio_tpg_attrs,
|
||||
.tfc_tpg_attrib_attrs = efct_lio_tpg_attrib_attrs,
|
||||
.default_submit_type = TARGET_DIRECT_SUBMIT,
|
||||
.direct_submit_supp = 1,
|
||||
};
|
||||
|
||||
static const struct target_core_fabric_ops efct_lio_npiv_ops = {
|
||||
@@ -1646,6 +1648,9 @@ static const struct target_core_fabric_ops efct_lio_npiv_ops = {
|
||||
.sess_get_initiator_sid = NULL,
|
||||
.tfc_tpg_base_attrs = efct_lio_npiv_tpg_attrs,
|
||||
.tfc_tpg_attrib_attrs = efct_lio_npiv_tpg_attrib_attrs,
|
||||
|
||||
.default_submit_type = TARGET_DIRECT_SUBMIT,
|
||||
.direct_submit_supp = 1,
|
||||
};
|
||||
|
||||
int efct_scsi_tgt_driver_init(void)
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#include "esas2r.h"
|
||||
|
||||
/*
|
||||
@@ -792,16 +794,10 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
|
||||
pcie_capability_read_dword(a->pcid, PCI_EXP_LNKCAP,
|
||||
&caps);
|
||||
|
||||
gai->pci.link_speed_curr =
|
||||
(u8)(stat & PCI_EXP_LNKSTA_CLS);
|
||||
gai->pci.link_speed_max =
|
||||
(u8)(caps & PCI_EXP_LNKCAP_SLS);
|
||||
gai->pci.link_width_curr =
|
||||
(u8)((stat & PCI_EXP_LNKSTA_NLW)
|
||||
>> PCI_EXP_LNKSTA_NLW_SHIFT);
|
||||
gai->pci.link_width_max =
|
||||
(u8)((caps & PCI_EXP_LNKCAP_MLW)
|
||||
>> 4);
|
||||
gai->pci.link_speed_curr = FIELD_GET(PCI_EXP_LNKSTA_CLS, stat);
|
||||
gai->pci.link_speed_max = FIELD_GET(PCI_EXP_LNKCAP_SLS, caps);
|
||||
gai->pci.link_width_curr = FIELD_GET(PCI_EXP_LNKSTA_NLW, stat);
|
||||
gai->pci.link_width_max = FIELD_GET(PCI_EXP_LNKCAP_MLW, caps);
|
||||
}
|
||||
|
||||
gai->pci.msi_vector_cnt = 1;
|
||||
|
||||
@@ -145,16 +145,17 @@ void fnic_handle_link(struct work_struct *work)
|
||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
|
||||
/* start FCoE VLAN discovery */
|
||||
fnic_fc_trace_set_data(
|
||||
fnic->lport->host->host_no,
|
||||
FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
|
||||
strlen("Link Status: DOWN_UP_VLAN"));
|
||||
fnic_fc_trace_set_data(fnic->lport->host->host_no,
|
||||
FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
|
||||
strlen("Link Status: DOWN_UP_VLAN"));
|
||||
fnic_fcoe_send_vlan_req(fnic);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
|
||||
fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
|
||||
"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
|
||||
"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
|
||||
fcoe_ctlr_link_up(&fnic->ctlr);
|
||||
} else {
|
||||
/* UP -> DOWN */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user