提交 382f51fe 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (222 commits)
  [SCSI] zfcp: Remove flag ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP
  [SCSI] zfcp: Activate fc4s attributes for zfcp in FC transport class
  [SCSI] zfcp: Block scsi_eh thread for rport state BLOCKED
  [SCSI] zfcp: Update FSF error reporting
  [SCSI] zfcp: Improve ELS ADISC handling
  [SCSI] zfcp: Simplify handling of ct and els requests
  [SCSI] zfcp: Remove ZFCP_DID_MASK
  [SCSI] zfcp: Move WKA port to zfcp FC code
  [SCSI] zfcp: Use common code definitions for FC CT structs
  [SCSI] zfcp: Use common code definitions for FC ELS structs
  [SCSI] zfcp: Update FCP protocol related code
  [SCSI] zfcp: Dont fail SCSI commands when transitioning to blocked fc_rport
  [SCSI] zfcp: Assign scheduled work to driver queue
  [SCSI] zfcp: Remove STATUS_COMMON_REMOVE flag as it is not required anymore
  [SCSI] zfcp: Implement module unloading
  [SCSI] zfcp: Merge trace code for fsf requests in one function
  [SCSI] zfcp: Access ports and units with container_of in sysfs code
  [SCSI] zfcp: Remove suspend callback
  [SCSI] zfcp: Remove global config_mutex
  [SCSI] zfcp: Replace local reference counting with common kref
  ...
What: /sys/bus/pci/drivers/qla2xxx/.../devices/*
Date: September 2009
Contact: QLogic Linux Driver <linux-driver@qlogic.com>
Description: qla2xxx-udev.sh currently looks for uevent CHANGE events to
signal a firmware-dump has been generated by the driver and is
ready for retrieval.
Users: qla2xxx-udev.sh. Proposed changes should be mailed to
linux-driver@qlogic.com
1 Release Date : Tues. July 28, 2009 10:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
2 Current Version : 00.00.04.12
3 Older Version : 00.00.04.10
1. Change the AEN sys PD update from scsi_scan to
scsi_add_device and scsi_remove_device.
2. Takeoff the debug print-out in aen_polling routine.
1 Release Date : Thur. July 02, 2009 10:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
2 Current Version : 00.00.04.10
3 Older Version : 00.00.04.08
1. Add the 3 mins timeout during the controller initialize.
2. Add the fix for 64bit sense date errors.
1 Release Date : Tues. May 05, 2009 10:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
2 Current Version : 00.00.04.08
3 Older Version : 00.00.04.06
1. Add the fix of pending in FW after deleted the logic drives.
2. Add the fix of deallocating memory after get pdlist.
1 Release Date : Tues. March 26, 2009 10:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
2 Current Version : 00.00.04.06
3 Older Version : 00.00.04.04
1. Add the fix of the driver cmd empty fix of the driver cmd empty.
2. Add the fix of the driver MSM AEN CMD cause the system slow.
1 Release Date : Tues. March 03, 2009 10:12:45 PST 2009 -
(emaild-id:megaraidlinux@lsi.com)
Bo Yang
2 Current Version : 00.00.04.04
3 Older Version : 00.00.04.01
1. Add the Tape drive fix to the driver: If the command is for
the tape device, set the pthru timeout to the os layer timeout value.
2. Add Poll_wait mechanism to Gen-2 Linux driv.
In the aen handler, driver needs to wakeup poll handler similar to
the way it raises SIGIO.
3. Add new controller new SAS2 support to the driver.
4. Report the unconfigured PD (system PD) to OS.
5. Add the IEEE SGL support to the driver
6. Reasign the Application cmds to SAS2 controller
1 Release Date : Thur.July. 24 11:41:51 PST 2008 - 1 Release Date : Thur.July. 24 11:41:51 PST 2008 -
(emaild-id:megaraidlinux@lsi.com) (emaild-id:megaraidlinux@lsi.com)
......
...@@ -4196,6 +4196,13 @@ W: http://www.pmc-sierra.com/ ...@@ -4196,6 +4196,13 @@ W: http://www.pmc-sierra.com/
S: Supported S: Supported
F: drivers/scsi/pmcraid.* F: drivers/scsi/pmcraid.*
PMC SIERRA PM8001 DRIVER
M: jack_wang@usish.com
M: lindar_liu@usish.com
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/pm8001/
POSIX CLOCKS and TIMERS POSIX CLOCKS and TIMERS
M: Thomas Gleixner <tglx@linutronix.de> M: Thomas Gleixner <tglx@linutronix.de>
S: Supported S: Supported
...@@ -5772,6 +5779,14 @@ L: netdev@vger.kernel.org ...@@ -5772,6 +5779,14 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/vmxnet3/ F: drivers/net/vmxnet3/
VMware PVSCSI driver
M: Alok Kataria <akataria@vmware.com>
M: VMware PV-Drivers <pv-drivers@vmware.com>
L: linux-scsi@vger.kernel.org
S: Maintained
F: drivers/scsi/vmw_pvscsi.c
F: drivers/scsi/vmw_pvscsi.h
VOLTAGE AND CURRENT REGULATOR FRAMEWORK VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lrg@slimlogic.co.uk> M: Liam Girdwood <lrg@slimlogic.co.uk>
M: Mark Brown <broonie@opensource.wolfsonmicro.com> M: Mark Brown <broonie@opensource.wolfsonmicro.com>
......
...@@ -1208,6 +1208,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) ...@@ -1208,6 +1208,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
* ata_scsi_change_queue_depth - SCSI callback for queue depth config * ata_scsi_change_queue_depth - SCSI callback for queue depth config
* @sdev: SCSI device to configure queue depth for * @sdev: SCSI device to configure queue depth for
* @queue_depth: new queue depth * @queue_depth: new queue depth
* @reason: calling context
* *
* This is libata standard hostt->change_queue_depth callback. * This is libata standard hostt->change_queue_depth callback.
* SCSI will call into this callback when user tries to set queue * SCSI will call into this callback when user tries to set queue
...@@ -1219,12 +1220,16 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) ...@@ -1219,12 +1220,16 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
* RETURNS: * RETURNS:
* Newly configured queue depth. * Newly configured queue depth.
*/ */
int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{ {
struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev; struct ata_device *dev;
unsigned long flags; unsigned long flags;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth < 1 || queue_depth == sdev->queue_depth) if (queue_depth < 1 || queue_depth == sdev->queue_depth)
return sdev->queue_depth; return sdev->queue_depth;
......
...@@ -1975,7 +1975,7 @@ static int nv_swncq_slave_config(struct scsi_device *sdev) ...@@ -1975,7 +1975,7 @@ static int nv_swncq_slave_config(struct scsi_device *sdev)
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (strncmp(model_num, "Maxtor", 6) == 0) { if (strncmp(model_num, "Maxtor", 6) == 0) {
ata_scsi_change_queue_depth(sdev, 1); ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT);
ata_dev_printk(dev, KERN_NOTICE, ata_dev_printk(dev, KERN_NOTICE,
"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth); "Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
} }
......
...@@ -625,6 +625,7 @@ static struct iscsi_transport iscsi_iser_transport = { ...@@ -625,6 +625,7 @@ static struct iscsi_transport iscsi_iser_transport = {
ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME | ISCSI_PASSWORD |
ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO |
ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
.host_param_mask = ISCSI_HOST_HWADDRESS | .host_param_mask = ISCSI_HOST_HWADDRESS |
......
...@@ -1116,8 +1116,9 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath) ...@@ -1116,8 +1116,9 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
return limit_reached; return limit_reached;
} }
static void pg_init_done(struct dm_path *path, int errors) static void pg_init_done(void *data, int errors)
{ {
struct dm_path *path = data;
struct pgpath *pgpath = path_to_pgpath(path); struct pgpath *pgpath = path_to_pgpath(path);
struct priority_group *pg = pgpath->pg; struct priority_group *pg = pgpath->pg;
struct multipath *m = pg->m; struct multipath *m = pg->m;
...@@ -1183,12 +1184,11 @@ static void pg_init_done(struct dm_path *path, int errors) ...@@ -1183,12 +1184,11 @@ static void pg_init_done(struct dm_path *path, int errors)
static void activate_path(struct work_struct *work) static void activate_path(struct work_struct *work)
{ {
int ret;
struct pgpath *pgpath = struct pgpath *pgpath =
container_of(work, struct pgpath, activate_path); container_of(work, struct pgpath, activate_path);
ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev)); scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
pg_init_done(&pgpath->path, ret); pg_init_done, &pgpath->path);
} }
/* /*
......
...@@ -76,8 +76,8 @@ ...@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.04.12" #define MPT_LINUX_VERSION_COMMON "3.04.13"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.12" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.13"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
......
...@@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/ */
iocnumX = khdr.iocnum & 0xFF; iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (iocp == NULL))
printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX);
return -ENODEV; return -ENODEV;
}
if (!iocp->active) { if (!iocp->active) {
printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n", printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
......
...@@ -792,11 +792,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -792,11 +792,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* precedence! * precedence!
*/ */
sc->result = (DID_OK << 16) | scsi_status; sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
/* Have already saved the status and sense data
/*
* For an Errata on LSI53C1030
* When the length of request data
* and transfer data are different
* with result of command (READ or VERIFY),
* DID_SOFT_ERROR is set.
*/ */
; if (ioc->bus_type == SPI) {
} else { if (pScsiReq->CDB[0] == READ_6 ||
pScsiReq->CDB[0] == READ_10 ||
pScsiReq->CDB[0] == READ_12 ||
pScsiReq->CDB[0] == READ_16 ||
pScsiReq->CDB[0] == VERIFY ||
pScsiReq->CDB[0] == VERIFY_16) {
if (scsi_bufflen(sc) !=
xfer_cnt) {
sc->result =
DID_SOFT_ERROR << 16;
printk(KERN_WARNING "Errata"
"on LSI53C1030 occurred."
"sc->req_bufflen=0x%02x,"
"xfer_cnt=0x%02x\n",
scsi_bufflen(sc),
xfer_cnt);
}
}
}
if (xfer_cnt < sc->underflow) { if (xfer_cnt < sc->underflow) {
if (scsi_status == SAM_STAT_BUSY) if (scsi_status == SAM_STAT_BUSY)
sc->result = SAM_STAT_BUSY; sc->result = SAM_STAT_BUSY;
...@@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->result = (DID_OK << 16) | scsi_status; sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) { if (scsi_state == 0) {
; ;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { } else if (scsi_state &
MPI_SCSI_STATE_AUTOSENSE_VALID) {
/*
* For potential trouble on LSI53C1030.
* (date:2007.xx.)
* It is checked whether the length of
* request data is equal to
* the length of transfer and residual.
* MEDIUM_ERROR is set by incorrect data.
*/
if ((ioc->bus_type == SPI) &&
(sc->sense_buffer[2] & 0x20)) {
u32 difftransfer;
difftransfer =
sc->sense_buffer[3] << 24 |
sc->sense_buffer[4] << 16 |
sc->sense_buffer[5] << 8 |
sc->sense_buffer[6];
if (((sc->sense_buffer[3] & 0x80) ==
0x80) && (scsi_bufflen(sc)
!= xfer_cnt)) {
sc->sense_buffer[2] =
MEDIUM_ERROR;
sc->sense_buffer[12] = 0xff;
sc->sense_buffer[13] = 0xff;
printk(KERN_WARNING"Errata"
"on LSI53C1030 occurred."
"sc->req_bufflen=0x%02x,"
"xfer_cnt=0x%02x\n" ,
scsi_bufflen(sc),
xfer_cnt);
}
if (((sc->sense_buffer[3] & 0x80)
!= 0x80) &&
(scsi_bufflen(sc) !=
xfer_cnt + difftransfer)) {
sc->sense_buffer[2] =
MEDIUM_ERROR;
sc->sense_buffer[12] = 0xff;
sc->sense_buffer[13] = 0xff;
printk(KERN_WARNING
"Errata on LSI53C1030 occurred"
"sc->req_bufflen=0x%02x,"
" xfer_cnt=0x%02x,"
"difftransfer=0x%02x\n",
scsi_bufflen(sc),
xfer_cnt,
difftransfer);
}
}
/* /*
* If running against circa 200003dd 909 MPT f/w, * If running against circa 200003dd 909 MPT f/w,
* may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
...@@ -2275,11 +2351,12 @@ mptscsih_slave_destroy(struct scsi_device *sdev) ...@@ -2275,11 +2351,12 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
* mptscsih_change_queue_depth - This function will set a devices queue depth * mptscsih_change_queue_depth - This function will set a devices queue depth
* @sdev: per scsi_device pointer * @sdev: per scsi_device pointer
* @qdepth: requested queue depth * @qdepth: requested queue depth
* @reason: calling context
* *
* Adding support for new 'change_queue_depth' api. * Adding support for new 'change_queue_depth' api.
*/ */
int int
mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{ {
MPT_SCSI_HOST *hd = shost_priv(sdev->host); MPT_SCSI_HOST *hd = shost_priv(sdev->host);
VirtTarget *vtarget; VirtTarget *vtarget;
...@@ -2291,6 +2368,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) ...@@ -2291,6 +2368,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
starget = scsi_target(sdev); starget = scsi_target(sdev);
vtarget = starget->hostdata; vtarget = starget->hostdata;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (ioc->bus_type == SPI) { if (ioc->bus_type == SPI) {
if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
max_depth = 1; max_depth = 1;
...@@ -2357,7 +2437,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) ...@@ -2357,7 +2437,8 @@ mptscsih_slave_configure(struct scsi_device *sdev)
ioc->name, vtarget->negoFlags, vtarget->maxOffset, ioc->name, vtarget->negoFlags, vtarget->maxOffset,
vtarget->minSyncFactor)); vtarget->minSyncFactor));
mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
SCSI_QDEPTH_DEFAULT);
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"tagged %d, simple %d, ordered %d\n", "tagged %d, simple %d, ordered %d\n",
ioc->name,sdev->tagged_supported, sdev->simple_tags, ioc->name,sdev->tagged_supported, sdev->simple_tags,
......
...@@ -128,7 +128,8 @@ extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_F ...@@ -128,7 +128,8 @@ extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_F
extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason);
extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
extern struct device_attribute *mptscsih_host_attrs[]; extern struct device_attribute *mptscsih_host_attrs[];
......
此差异已折叠。
...@@ -13,28 +13,34 @@ ...@@ -13,28 +13,34 @@
#define ZFCP_MODEL_PRIV 0x4 #define ZFCP_MODEL_PRIV 0x4
static int zfcp_ccw_suspend(struct ccw_device *cdev) static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock);
struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev); struct zfcp_adapter *adapter;
unsigned long flags;
if (!adapter)
return 0;
mutex_lock(&zfcp_data.config_mutex);
zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL); spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
zfcp_erp_wait(adapter); adapter = dev_get_drvdata(&cdev->dev);
if (adapter)
kref_get(&adapter->ref);
spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
return adapter;
}
mutex_unlock(&zfcp_data.config_mutex); void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
{
unsigned long flags;
return 0; spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
kref_put(&adapter->ref, zfcp_adapter_release);
spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
} }
static int zfcp_ccw_activate(struct ccw_device *cdev) static int zfcp_ccw_activate(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev); struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter) if (!adapter)
return 0; return 0;
...@@ -46,6 +52,8 @@ static int zfcp_ccw_activate(struct ccw_device *cdev) ...@@ -46,6 +52,8 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
flush_work(&adapter->scan_work); flush_work(&adapter->scan_work);
zfcp_ccw_adapter_put(adapter);
return 0; return 0;
} }
...@@ -67,28 +75,28 @@ int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter) ...@@ -67,28 +75,28 @@ int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
/** /**
* zfcp_ccw_probe - probe function of zfcp driver * zfcp_ccw_probe - probe function of zfcp driver
* @ccw_device: pointer to belonging ccw device * @cdev: pointer to belonging ccw device
* *
* This function gets called by the common i/o layer for each FCP * This function gets called by the common i/o layer for each FCP
* device found on the current system. This is only a stub to make cio * device found on the current system. This is only a stub to make cio
* work: To only allocate adapter resources for devices actually used, * work: To only allocate adapter resources for devices actually used,
* the allocation is deferred to the first call to ccw_set_online. * the allocation is deferred to the first call to ccw_set_online.
*/ */
static int zfcp_ccw_probe(struct ccw_device *ccw_device) static int zfcp_ccw_probe(struct ccw_device *cdev)
{ {
return 0; return 0;
} }
/** /**
* zfcp_ccw_remove - remove function of zfcp driver * zfcp_ccw_remove - remove function of zfcp driver
* @ccw_device: pointer to belonging ccw device * @cdev: pointer to belonging ccw device
* *
* This function gets called by the common i/o layer and removes an adapter * This function gets called by the common i/o layer and removes an adapter
* from the system. Task of this function is to get rid of all units and * from the system. Task of this function is to get rid of all units and
* ports that belong to this adapter. And in addition all resources of this * ports that belong to this adapter. And in addition all resources of this
* adapter will be freed too. * adapter will be freed too.
*/ */
static void zfcp_ccw_remove(struct ccw_device *ccw_device) static void zfcp_ccw_remove(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter;
struct zfcp_port *port, *p; struct zfcp_port *port, *p;
...@@ -96,49 +104,37 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) ...@@ -96,49 +104,37 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
LIST_HEAD(unit_remove_lh); LIST_HEAD(unit_remove_lh);
LIST_HEAD(port_remove_lh); LIST_HEAD(port_remove_lh);
ccw_device_set_offline(ccw_device); ccw_device_set_offline(cdev);
mutex_lock(&zfcp_data.config_mutex); adapter = zfcp_ccw_adapter_by_cdev(cdev);
adapter = dev_get_drvdata(&ccw_device->dev);
if (!adapter) if (!adapter)
goto out; return;
mutex_unlock(&zfcp_data.config_mutex);
cancel_work_sync(&adapter->scan_work); write_lock_irq(&adapter->port_list_lock);
list_for_each_entry_safe(port, p, &adapter->port_list, list) {
mutex_lock(&zfcp_data.config_mutex); write_lock(&port->unit_list_lock);
list_for_each_entry_safe(unit, u, &port->unit_list, list)
/* this also removes the scsi devices, so call it first */
zfcp_adapter_scsi_unregister(adapter);
write_lock_irq(&zfcp_data.config_lock);
list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
list_move(&unit->list, &unit_remove_lh); list_move(&unit->list, &unit_remove_lh);
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, write_unlock(&port->unit_list_lock);
&unit->status);
}
list_move(&port->list, &port_remove_lh); list_move(&port->list, &port_remove_lh);
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
} }
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); write_unlock_irq(&adapter->port_list_lock);
write_unlock_irq(&zfcp_data.config_lock); zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
list_for_each_entry_safe(port, p, &port_remove_lh, list) { list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
list_for_each_entry_safe(unit, u, &unit_remove_lh, list) zfcp_device_unregister(&unit->sysfs_device,
zfcp_unit_dequeue(unit); &zfcp_sysfs_unit_attrs);
zfcp_port_dequeue(port);
}
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
zfcp_adapter_dequeue(adapter);
out: list_for_each_entry_safe(port, p, &port_remove_lh, list)
mutex_unlock(&zfcp_data.config_mutex); zfcp_device_unregister(&port->sysfs_device,
&zfcp_sysfs_port_attrs);
zfcp_adapter_unregister(adapter);
} }
/** /**
* zfcp_ccw_set_online - set_online function of zfcp driver * zfcp_ccw_set_online - set_online function of zfcp driver
* @ccw_device: pointer to belonging ccw device * @cdev: pointer to belonging ccw device
* *
* This function gets called by the common i/o layer and sets an * This function gets called by the common i/o layer and sets an
* adapter into state online. The first call will allocate all * adapter into state online. The first call will allocate all
...@@ -149,23 +145,20 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) ...@@ -149,23 +145,20 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
* the SCSI stack, that the QDIO queues will be set up and that the * the SCSI stack, that the QDIO queues will be set up and that the
* adapter will be opened. * adapter will be opened.
*/ */
static int zfcp_ccw_set_online(struct ccw_device *ccw_device) static int zfcp_ccw_set_online(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
int ret = 0;
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&ccw_device->dev);
if (!adapter) { if (!adapter) {
ret = zfcp_adapter_enqueue(ccw_device); adapter = zfcp_adapter_enqueue(cdev);
if (ret) {
dev_err(&ccw_device->dev, if (IS_ERR(adapter)) {
dev_err(&cdev->dev,
"Setting up data structures for the " "Setting up data structures for the "
"FCP adapter failed\n"); "FCP adapter failed\n");
goto out; return PTR_ERR(adapter);
} }
adapter = dev_get_drvdata(&ccw_device->dev); kref_get(&adapter->ref);
} }
/* initialize request counter */ /* initialize request counter */
...@@ -177,58 +170,61 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device) ...@@ -177,58 +170,61 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
"ccsonl2", NULL); "ccsonl2", NULL);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
out:
mutex_unlock(&zfcp_data.config_mutex); flush_work(&adapter->scan_work);
if (!ret)
flush_work(&adapter->scan_work); zfcp_ccw_adapter_put(adapter);
return ret; return 0;
} }
/** /**
* zfcp_ccw_set_offline - set_offline function of zfcp driver * zfcp_ccw_set_offline - set_offline function of zfcp driver
* @ccw_device: pointer to belonging ccw device * @cdev: pointer to belonging ccw device
* *
* This function gets called by the common i/o layer and sets an adapter * This function gets called by the common i/o layer and sets an adapter
* into state offline. * into state offline.
*/ */
static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) static int zfcp_ccw_set_offline(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
return 0;
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&ccw_device->dev);
zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
mutex_unlock(&zfcp_data.config_mutex);
zfcp_ccw_adapter_put(adapter);
return 0; return 0;
} }
/** /**
* zfcp_ccw_notify - ccw notify function * zfcp_ccw_notify - ccw notify function
* @ccw_device: pointer to belonging ccw device * @cdev: pointer to belonging ccw device
* @event: indicates if adapter was detached or attached * @event: indicates if adapter was detached or attached
* *
* This function gets called by the common i/o layer if an adapter has gone * This function gets called by the common i/o layer if an adapter has gone
* or reappeared. * or reappeared.
*/ */
static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
{ {
struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev); struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
return 1;
switch (event) { switch (event) {
case CIO_GONE: case CIO_GONE:
dev_warn(&adapter->ccw_device->dev, dev_warn(&cdev->dev, "The FCP device has been detached\n");
"The FCP device has been detached\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL); zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
break; break;
case CIO_NO_PATH: case CIO_NO_PATH:
dev_warn(&adapter->ccw_device->dev, dev_warn(&cdev->dev,
"The CHPID for the FCP device is offline\n"); "The CHPID for the FCP device is offline\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL); zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
break; break;
case CIO_OPER: case CIO_OPER:
dev_info(&adapter->ccw_device->dev, dev_info(&cdev->dev, "The FCP device is operational again\n");
"The FCP device is operational again\n");
zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL, zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
ZFCP_STATUS_COMMON_RUNNING, ZFCP_STATUS_COMMON_RUNNING,
ZFCP_SET); ZFCP_SET);
...@@ -236,11 +232,13 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) ...@@ -236,11 +232,13 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
"ccnoti4", NULL); "ccnoti4", NULL);
break; break;
case CIO_BOXED: case CIO_BOXED:
dev_warn(&adapter->ccw_device->dev, "The FCP device " dev_warn(&cdev->dev, "The FCP device did not respond within "
"did not respond within the specified time\n"); "the specified time\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
break; break;
} }
zfcp_ccw_adapter_put(adapter);
return 1; return 1;
} }
...@@ -250,18 +248,16 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) ...@@ -250,18 +248,16 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
*/ */
static void zfcp_ccw_shutdown(struct ccw_device *cdev) static void zfcp_ccw_shutdown(struct ccw_device *cdev)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&cdev->dev);
if (!adapter) if (!adapter)
goto out; return;
zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter); zfcp_erp_thread_kill(adapter);
out:
mutex_unlock(&zfcp_data.config_mutex); zfcp_ccw_adapter_put(adapter);
} }
struct ccw_driver zfcp_ccw_driver = { struct ccw_driver zfcp_ccw_driver = {
...@@ -274,18 +270,7 @@ struct ccw_driver zfcp_ccw_driver = { ...@@ -274,18 +270,7 @@ struct ccw_driver zfcp_ccw_driver = {
.set_offline = zfcp_ccw_set_offline, .set_offline = zfcp_ccw_set_offline,
.notify = zfcp_ccw_notify, .notify = zfcp_ccw_notify,
.shutdown = zfcp_ccw_shutdown, .shutdown = zfcp_ccw_shutdown,
.freeze = zfcp_ccw_suspend, .freeze = zfcp_ccw_set_offline,
.thaw = zfcp_ccw_activate, .thaw = zfcp_ccw_activate,
.restore = zfcp_ccw_activate, .restore = zfcp_ccw_activate,
}; };
/**
* zfcp_ccw_register - ccw register function
*
* Registers the driver at the common i/o layer. This function will be called
* at module load time/system start.
*/
int __init zfcp_ccw_register(void)
{
return ccw_driver_register(&zfcp_ccw_driver);
}
...@@ -86,22 +86,17 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer, ...@@ -86,22 +86,17 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer,
static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
{ {
char busid[9]; char busid[9];
struct ccw_device *ccwdev; struct ccw_device *cdev;
struct zfcp_adapter *adapter = NULL; struct zfcp_adapter *adapter;
snprintf(busid, sizeof(busid), "0.0.%04x", devno); snprintf(busid, sizeof(busid), "0.0.%04x", devno);
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (!ccwdev) if (!cdev)
goto out; return NULL;
adapter = dev_get_drvdata(&ccwdev->dev); adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
goto out_put; put_device(&cdev->dev);
zfcp_adapter_get(adapter);
out_put:
put_device(&ccwdev->dev);
out:
return adapter; return adapter;
} }
...@@ -212,7 +207,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, ...@@ -212,7 +207,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
retval = -ENXIO; retval = -ENXIO;
goto free_buffer; goto free_buffer;
} }
zfcp_adapter_get(adapter);
retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg, retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
data_user->control_file); data_user->control_file);
...@@ -245,7 +239,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, ...@@ -245,7 +239,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
free_sg: free_sg:
zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES); zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
adapter_put: adapter_put:
zfcp_adapter_put(adapter); zfcp_ccw_adapter_put(adapter);
free_buffer: free_buffer:
kfree(data); kfree(data);
no_mem_sense: no_mem_sense:
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/debug.h> #include <asm/debug.h>
#include "zfcp_dbf.h" #include "zfcp_dbf.h"
#include "zfcp_ext.h" #include "zfcp_ext.h"
#include "zfcp_fc.h"
static u32 dbfsize = 4; static u32 dbfsize = 4;
...@@ -177,8 +178,7 @@ void _zfcp_dbf_hba_fsf_response(const char *tag2, int level, ...@@ -177,8 +178,7 @@ void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
case FSF_QTCB_SEND_ELS: case FSF_QTCB_SEND_ELS:
send_els = (struct zfcp_send_els *)fsf_req->data; send_els = (struct zfcp_send_els *)fsf_req->data;
response->u.els.d_id = qtcb->bottom.support.d_id; response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id);
response->u.els.ls_code = send_els->ls_code >> 24;
break; break;
case FSF_QTCB_ABORT_FCP_CMND: case FSF_QTCB_ABORT_FCP_CMND:
...@@ -348,7 +348,6 @@ static void zfcp_dbf_hba_view_response(char **p, ...@@ -348,7 +348,6 @@ static void zfcp_dbf_hba_view_response(char **p,
case FSF_QTCB_SEND_ELS: case FSF_QTCB_SEND_ELS:
zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id); zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code);
break; break;
case FSF_QTCB_ABORT_FCP_CMND: case FSF_QTCB_ABORT_FCP_CMND:
...@@ -677,14 +676,14 @@ void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action) ...@@ -677,14 +676,14 @@ void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action)
/** /**
* zfcp_dbf_san_ct_request - trace event for issued CT request * zfcp_dbf_san_ct_request - trace event for issued CT request
* @fsf_req: request containing issued CT data * @fsf_req: request containing issued CT data
* @d_id: destination id where ct request is sent to
*/ */
void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req) void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id)
{ {
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
struct zfcp_wka_port *wka_port = ct->wka_port; struct zfcp_adapter *adapter = fsf_req->adapter;
struct zfcp_adapter *adapter = wka_port->adapter;
struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf *dbf = adapter->dbf;
struct ct_hdr *hdr = sg_virt(ct->req); struct fc_ct_hdr *hdr = sg_virt(ct->req);
struct zfcp_dbf_san_record *r = &dbf->san_buf; struct zfcp_dbf_san_record *r = &dbf->san_buf;
struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req; struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
int level = 3; int level = 3;
...@@ -695,19 +694,18 @@ void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req) ...@@ -695,19 +694,18 @@ void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req)
strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE); strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
r->fsf_reqid = fsf_req->req_id; r->fsf_reqid = fsf_req->req_id;
r->fsf_seqno = fsf_req->seq_no; r->fsf_seqno = fsf_req->seq_no;
r->s_id = fc_host_port_id(adapter->scsi_host); oct->d_id = d_id;
r->d_id = wka_port->d_id; oct->cmd_req_code = hdr->ct_cmd;
oct->cmd_req_code = hdr->cmd_rsp_code; oct->revision = hdr->ct_rev;
oct->revision = hdr->revision; oct->gs_type = hdr->ct_fs_type;
oct->gs_type = hdr->gs_type; oct->gs_subtype = hdr->ct_fs_subtype;
oct->gs_subtype = hdr->gs_subtype; oct->options = hdr->ct_options;
oct->options = hdr->options; oct->max_res_size = hdr->ct_mr_size;
oct->max_res_size = hdr->max_res_size; oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr),
oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
ZFCP_DBF_SAN_MAX_PAYLOAD); ZFCP_DBF_SAN_MAX_PAYLOAD);
debug_event(dbf->san, level, r, sizeof(*r)); debug_event(dbf->san, level, r, sizeof(*r));
zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level, zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
(void *)hdr + sizeof(struct ct_hdr), oct->len); (void *)hdr + sizeof(struct fc_ct_hdr), oct->len);
spin_unlock_irqrestore(&dbf->san_lock, flags); spin_unlock_irqrestore(&dbf->san_lock, flags);
} }
...@@ -717,10 +715,9 @@ void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req) ...@@ -717,10 +715,9 @@ void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req)
*/ */
void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req) void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
{ {
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data;
struct zfcp_wka_port *wka_port = ct->wka_port; struct zfcp_adapter *adapter = fsf_req->adapter;
struct zfcp_adapter *adapter = wka_port->adapter; struct fc_ct_hdr *hdr = sg_virt(ct->resp);
struct ct_hdr *hdr = sg_virt(ct->resp);
struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf *dbf = adapter->dbf;
struct zfcp_dbf_san_record *r = &dbf->san_buf; struct zfcp_dbf_san_record *r = &dbf->san_buf;
struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp; struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
...@@ -732,25 +729,23 @@ void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req) ...@@ -732,25 +729,23 @@ void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
r->fsf_reqid = fsf_req->req_id; r->fsf_reqid = fsf_req->req_id;
r->fsf_seqno = fsf_req->seq_no; r->fsf_seqno = fsf_req->seq_no;
r->s_id = wka_port->d_id; rct->cmd_rsp_code = hdr->ct_cmd;
r->d_id = fc_host_port_id(adapter->scsi_host); rct->revision = hdr->ct_rev;
rct->cmd_rsp_code = hdr->cmd_rsp_code; rct->reason_code = hdr->ct_reason;
rct->revision = hdr->revision; rct->expl = hdr->ct_explan;
rct->reason_code = hdr->reason_code; rct->vendor_unique = hdr->ct_vendor;
rct->expl = hdr->reason_code_expl; rct->max_res_size = hdr->ct_mr_size;
rct->vendor_unique = hdr->vendor_unique; rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr),
rct->max_res_size = hdr->max_res_size;
rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
ZFCP_DBF_SAN_MAX_PAYLOAD); ZFCP_DBF_SAN_MAX_PAYLOAD);
debug_event(dbf->san, level, r, sizeof(*r)); debug_event(dbf->san, level, r, sizeof(*r));
zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level, zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
(void *)hdr + sizeof(struct ct_hdr), rct->len); (void *)hdr + sizeof(struct fc_ct_hdr), rct->len);
spin_unlock_irqrestore(&dbf->san_lock, flags); spin_unlock_irqrestore(&dbf->san_lock, flags);
} }
static void zfcp_dbf_san_els(const char *tag, int level, static void zfcp_dbf_san_els(const char *tag, int level,
struct zfcp_fsf_req *fsf_req, u32 s_id, u32 d_id, struct zfcp_fsf_req *fsf_req, u32 d_id,
u8 ls_code, void *buffer, int buflen) void *buffer, int buflen)
{ {
struct zfcp_adapter *adapter = fsf_req->adapter; struct zfcp_adapter *adapter = fsf_req->adapter;
struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf *dbf = adapter->dbf;
...@@ -762,9 +757,7 @@ static void zfcp_dbf_san_els(const char *tag, int level, ...@@ -762,9 +757,7 @@ static void zfcp_dbf_san_els(const char *tag, int level,
strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
rec->fsf_reqid = fsf_req->req_id; rec->fsf_reqid = fsf_req->req_id;
rec->fsf_seqno = fsf_req->seq_no; rec->fsf_seqno = fsf_req->seq_no;
rec->s_id = s_id; rec->u.els.d_id = d_id;
rec->d_id = d_id;
rec->u.els.ls_code = ls_code;
debug_event(dbf->san, level, rec, sizeof(*rec)); debug_event(dbf->san, level, rec, sizeof(*rec));
zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level, zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD)); buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
...@@ -777,12 +770,11 @@ static void zfcp_dbf_san_els(const char *tag, int level, ...@@ -777,12 +770,11 @@ static void zfcp_dbf_san_els(const char *tag, int level,
*/ */
void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req) void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
{ {
struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
zfcp_dbf_san_els("oels", 2, fsf_req, zfcp_dbf_san_els("oels", 2, fsf_req, d_id,
fc_host_port_id(els->adapter->scsi_host), sg_virt(els->req), els->req->length);
els->d_id, *(u8 *) sg_virt(els->req),
sg_virt(els->req), els->req->length);
} }
/** /**
...@@ -791,12 +783,11 @@ void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req) ...@@ -791,12 +783,11 @@ void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
*/ */
void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req) void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
{ {
struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data;
u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id);
zfcp_dbf_san_els("rels", 2, fsf_req, els->d_id, zfcp_dbf_san_els("rels", 2, fsf_req, d_id,
fc_host_port_id(els->adapter->scsi_host), sg_virt(els->resp), els->resp->length);
*(u8 *)sg_virt(els->req), sg_virt(els->resp),
els->resp->length);
} }
/** /**
...@@ -805,16 +796,13 @@ void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req) ...@@ -805,16 +796,13 @@ void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
*/ */
void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req) void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
{ {
struct zfcp_adapter *adapter = fsf_req->adapter;
struct fsf_status_read_buffer *buf = struct fsf_status_read_buffer *buf =
(struct fsf_status_read_buffer *)fsf_req->data; (struct fsf_status_read_buffer *)fsf_req->data;
int length = (int)buf->length - int length = (int)buf->length -
(int)((void *)&buf->payload - (void *)buf); (int)((void *)&buf->payload - (void *)buf);
zfcp_dbf_san_els("iels", 1, fsf_req, buf->d_id, zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id),
fc_host_port_id(adapter->scsi_host), (void *)buf->payload.data, length);
buf->payload.data[0], (void *)buf->payload.data,
length);
} }
static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view, static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
...@@ -829,11 +817,10 @@ static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view, ...@@ -829,11 +817,10 @@ static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
zfcp_dbf_tag(&p, "tag", r->tag); zfcp_dbf_tag(&p, "tag", r->tag);
zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno); zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id);
zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);
if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req; struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id);
zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code); zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision); zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type); zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
...@@ -852,7 +839,7 @@ static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view, ...@@ -852,7 +839,7 @@ static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
struct zfcp_dbf_san_record_els *els = &r->u.els; struct zfcp_dbf_san_record_els *els = &r->u.els;
zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id);
} }
return p - out_buf; return p - out_buf;
} }
...@@ -870,8 +857,9 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, ...@@ -870,8 +857,9 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf; struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
unsigned long flags; unsigned long flags;
struct fcp_rsp_iu *fcp_rsp; struct fcp_resp_with_ext *fcp_rsp;
char *fcp_rsp_info = NULL, *fcp_sns_info = NULL; struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
char *fcp_sns_info = NULL;
int offset = 0, buflen = 0; int offset = 0, buflen = 0;
spin_lock_irqsave(&dbf->scsi_lock, flags); spin_lock_irqsave(&dbf->scsi_lock, flags);
...@@ -895,20 +883,22 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, ...@@ -895,20 +883,22 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
rec->scsi_allowed = scsi_cmnd->allowed; rec->scsi_allowed = scsi_cmnd->allowed;
} }
if (fsf_req != NULL) { if (fsf_req != NULL) {
fcp_rsp = (struct fcp_rsp_iu *) fcp_rsp = (struct fcp_resp_with_ext *)
&(fsf_req->qtcb->bottom.io.fcp_rsp); &(fsf_req->qtcb->bottom.io.fcp_rsp);
fcp_rsp_info = (unsigned char *) &fcp_rsp[1]; fcp_rsp_info = (struct fcp_resp_rsp_info *)
fcp_sns_info = &fcp_rsp[1];
zfcp_get_fcp_sns_info_ptr(fcp_rsp); fcp_sns_info = (char *) &fcp_rsp[1];
if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
rec->rsp_validity = fcp_rsp->validity.value; fcp_sns_info += fcp_rsp->ext.fr_sns_len;
rec->rsp_scsi_status = fcp_rsp->scsi_status;
rec->rsp_resid = fcp_rsp->fcp_resid; rec->rsp_validity = fcp_rsp->resp.fr_flags;
if (fcp_rsp->validity.bits.fcp_rsp_len_valid) rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
rec->rsp_code = *(fcp_rsp_info + 3); rec->rsp_resid = fcp_rsp->ext.fr_resid;
if (fcp_rsp->validity.bits.fcp_sns_len_valid) { if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
buflen = min((int)fcp_rsp->fcp_sns_len, rec->rsp_code = fcp_rsp_info->rsp_code;
ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
buflen = min(fcp_rsp->ext.fr_sns_len,
(u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
rec->sns_info_len = buflen; rec->sns_info_len = buflen;
memcpy(rec->sns_info, fcp_sns_info, memcpy(rec->sns_info, fcp_sns_info,
min(buflen, min(buflen,
...@@ -1067,6 +1057,8 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) ...@@ -1067,6 +1057,8 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
*/ */
void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf) void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
{ {
if (!dbf)
return;
debug_unregister(dbf->scsi); debug_unregister(dbf->scsi);
debug_unregister(dbf->san); debug_unregister(dbf->san);
debug_unregister(dbf->hba); debug_unregister(dbf->hba);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#ifndef ZFCP_DBF_H #ifndef ZFCP_DBF_H
#define ZFCP_DBF_H #define ZFCP_DBF_H
#include <scsi/fc/fc_fcp.h>
#include "zfcp_ext.h" #include "zfcp_ext.h"
#include "zfcp_fsf.h" #include "zfcp_fsf.h"
#include "zfcp_def.h" #include "zfcp_def.h"
...@@ -122,7 +123,6 @@ struct zfcp_dbf_hba_record_response { ...@@ -122,7 +123,6 @@ struct zfcp_dbf_hba_record_response {
} unit; } unit;
struct { struct {
u32 d_id; u32 d_id;
u8 ls_code;
} els; } els;
} u; } u;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -166,6 +166,7 @@ struct zfcp_dbf_san_record_ct_request { ...@@ -166,6 +166,7 @@ struct zfcp_dbf_san_record_ct_request {
u8 options; u8 options;
u16 max_res_size; u16 max_res_size;
u32 len; u32 len;
u32 d_id;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_dbf_san_record_ct_response { struct zfcp_dbf_san_record_ct_response {
...@@ -179,16 +180,13 @@ struct zfcp_dbf_san_record_ct_response { ...@@ -179,16 +180,13 @@ struct zfcp_dbf_san_record_ct_response {
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_dbf_san_record_els { struct zfcp_dbf_san_record_els {
u8 ls_code; u32 d_id;
u32 len;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_dbf_san_record { struct zfcp_dbf_san_record {
u8 tag[ZFCP_DBF_TAG_SIZE]; u8 tag[ZFCP_DBF_TAG_SIZE];
u64 fsf_reqid; u64 fsf_reqid;
u32 fsf_seqno; u32 fsf_seqno;
u32 s_id;
u32 d_id;
union { union {
struct zfcp_dbf_san_record_ct_request ct_req; struct zfcp_dbf_san_record_ct_request ct_req;
struct zfcp_dbf_san_record_ct_response ct_resp; struct zfcp_dbf_san_record_ct_response ct_resp;
...@@ -343,7 +341,7 @@ static inline ...@@ -343,7 +341,7 @@ static inline
void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd) struct scsi_cmnd *scsi_cmnd)
{ {
zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
unit->port->adapter->dbf, scsi_cmnd, NULL, 0); unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
} }
......
...@@ -71,131 +71,6 @@ ...@@ -71,131 +71,6 @@
/* timeout value for "default timer" for fsf requests */ /* timeout value for "default timer" for fsf requests */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ) #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
/* task attribute values in FCP-2 FCP_CMND IU */
#define SIMPLE_Q 0
#define HEAD_OF_Q 1
#define ORDERED_Q 2
#define ACA_Q 4
#define UNTAGGED 5
/* task management flags in FCP-2 FCP_CMND IU */
#define FCP_CLEAR_ACA 0x40
#define FCP_TARGET_RESET 0x20
#define FCP_LOGICAL_UNIT_RESET 0x10
#define FCP_CLEAR_TASK_SET 0x04
#define FCP_ABORT_TASK_SET 0x02
#define FCP_CDB_LENGTH 16
#define ZFCP_DID_MASK 0x00FFFFFF
/* FCP(-2) FCP_CMND IU */
struct fcp_cmnd_iu {
u64 fcp_lun; /* FCP logical unit number */
u8 crn; /* command reference number */
u8 reserved0:5; /* reserved */
u8 task_attribute:3; /* task attribute */
u8 task_management_flags; /* task management flags */
u8 add_fcp_cdb_length:6; /* additional FCP_CDB length */
u8 rddata:1; /* read data */
u8 wddata:1; /* write data */
u8 fcp_cdb[FCP_CDB_LENGTH];
} __attribute__((packed));
/* FCP(-2) FCP_RSP IU */
struct fcp_rsp_iu {
u8 reserved0[10];
union {
struct {
u8 reserved1:3;
u8 fcp_conf_req:1;
u8 fcp_resid_under:1;
u8 fcp_resid_over:1;
u8 fcp_sns_len_valid:1;
u8 fcp_rsp_len_valid:1;
} bits;
u8 value;
} validity;
u8 scsi_status;
u32 fcp_resid;
u32 fcp_sns_len;
u32 fcp_rsp_len;
} __attribute__((packed));
#define RSP_CODE_GOOD 0
#define RSP_CODE_LENGTH_MISMATCH 1
#define RSP_CODE_FIELD_INVALID 2
#define RSP_CODE_RO_MISMATCH 3
#define RSP_CODE_TASKMAN_UNSUPP 4
#define RSP_CODE_TASKMAN_FAILED 5
/* see fc-fs */
#define LS_RSCN 0x61
#define LS_LOGO 0x05
#define LS_PLOGI 0x03
struct fcp_rscn_head {
u8 command;
u8 page_length; /* always 0x04 */
u16 payload_len;
} __attribute__((packed));
struct fcp_rscn_element {
u8 reserved:2;
u8 event_qual:4;
u8 addr_format:2;
u32 nport_did:24;
} __attribute__((packed));
/* see fc-ph */
struct fcp_logo {
u32 command;
u32 nport_did;
u64 nport_wwpn;
} __attribute__((packed));
/*
* FC-FS stuff
*/
#define R_A_TOV 10 /* seconds */
#define ZFCP_LS_RLS 0x0f
#define ZFCP_LS_ADISC 0x52
#define ZFCP_LS_RPS 0x56
#define ZFCP_LS_RSCN 0x61
#define ZFCP_LS_RNID 0x78
struct zfcp_ls_adisc {
u8 code;
u8 field[3];
u32 hard_nport_id;
u64 wwpn;
u64 wwnn;
u32 nport_id;
} __attribute__ ((packed));
/*
* FC-GS-2 stuff
*/
#define ZFCP_CT_REVISION 0x01
#define ZFCP_CT_DIRECTORY_SERVICE 0xFC
#define ZFCP_CT_NAME_SERVER 0x02
#define ZFCP_CT_SYNCHRONOUS 0x00
#define ZFCP_CT_SCSI_FCP 0x08
#define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09
#define ZFCP_CT_GID_PN 0x0121
#define ZFCP_CT_GPN_FT 0x0172
#define ZFCP_CT_ACCEPT 0x8002
#define ZFCP_CT_REJECT 0x8001
/*
* FC-GS-4 stuff
*/
#define ZFCP_CT_TIMEOUT (3 * R_A_TOV)
/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
/* /*
...@@ -205,7 +80,6 @@ struct zfcp_ls_adisc { ...@@ -205,7 +80,6 @@ struct zfcp_ls_adisc {
#define ZFCP_COMMON_FLAGS 0xfff00000 #define ZFCP_COMMON_FLAGS 0xfff00000
/* common status bits */ /* common status bits */
#define ZFCP_STATUS_COMMON_REMOVE 0x80000000
#define ZFCP_STATUS_COMMON_RUNNING 0x40000000 #define ZFCP_STATUS_COMMON_RUNNING 0x40000000
#define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000 #define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000
#define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000 #define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000
...@@ -222,21 +96,10 @@ struct zfcp_ls_adisc { ...@@ -222,21 +96,10 @@ struct zfcp_ls_adisc {
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
/* FC-PH/FC-GS well-known address identifiers for generic services */
#define ZFCP_DID_WKA 0xFFFFF0
/* remote port status */ /* remote port status */
#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 #define ZFCP_STATUS_PORT_LINK_TEST 0x00000002
/* well known address (WKA) port status*/
enum zfcp_wka_status {
ZFCP_WKA_PORT_OFFLINE,
ZFCP_WKA_PORT_CLOSING,
ZFCP_WKA_PORT_OPENING,
ZFCP_WKA_PORT_ONLINE,
};
/* logical unit status */ /* logical unit status */
#define ZFCP_STATUS_UNIT_SHARED 0x00000004 #define ZFCP_STATUS_UNIT_SHARED 0x00000004
#define ZFCP_STATUS_UNIT_READONLY 0x00000008 #define ZFCP_STATUS_UNIT_READONLY 0x00000008
...@@ -247,10 +110,7 @@ enum zfcp_wka_status { ...@@ -247,10 +110,7 @@ enum zfcp_wka_status {
#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010
#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040 #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040
#define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080
#define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100
#define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200 #define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200
#define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP 0x00000400
#define ZFCP_STATUS_FSFREQ_RETRY 0x00000800
#define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000 #define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000
/************************* STRUCTURE DEFINITIONS *****************************/ /************************* STRUCTURE DEFINITIONS *****************************/
...@@ -265,125 +125,10 @@ struct zfcp_adapter_mempool { ...@@ -265,125 +125,10 @@ struct zfcp_adapter_mempool {
mempool_t *scsi_abort; mempool_t *scsi_abort;
mempool_t *status_read_req; mempool_t *status_read_req;
mempool_t *status_read_data; mempool_t *status_read_data;
mempool_t *gid_pn_data; mempool_t *gid_pn;
mempool_t *qtcb_pool; mempool_t *qtcb_pool;
}; };
/*
* header for CT_IU
*/
struct ct_hdr {
u8 revision; // 0x01
u8 in_id[3]; // 0x00
u8 gs_type; // 0xFC Directory Service
u8 gs_subtype; // 0x02 Name Server
u8 options; // 0x00 single bidirectional exchange
u8 reserved0;
u16 cmd_rsp_code; // 0x0121 GID_PN, or 0x0100 GA_NXT
u16 max_res_size; // <= (4096 - 16) / 4
u8 reserved1;
u8 reason_code;
u8 reason_code_expl;
u8 vendor_unique;
} __attribute__ ((packed));
/* nameserver request CT_IU -- for requests where
* a port name is required */
struct ct_iu_gid_pn_req {
struct ct_hdr header;
u64 wwpn;
} __attribute__ ((packed));
/* FS_ACC IU and data unit for GID_PN nameserver request */
struct ct_iu_gid_pn_resp {
struct ct_hdr header;
u32 d_id;
} __attribute__ ((packed));
struct ct_iu_gpn_ft_req {
struct ct_hdr header;
u8 flags;
u8 domain_id_scope;
u8 area_id_scope;
u8 fc4_type;
} __attribute__ ((packed));
/**
* struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
* @wka_port: port where the request is sent to
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
* @handler: handler function (called for response to the request)
* @handler_data: data passed to handler function
* @completion: completion for synchronization purposes
* @status: used to pass error status to calling function
*/
struct zfcp_send_ct {
struct zfcp_wka_port *wka_port;
struct scatterlist *req;
struct scatterlist *resp;
void (*handler)(unsigned long);
unsigned long handler_data;
struct completion *completion;
int status;
};
/* used for name server requests in error recovery */
struct zfcp_gid_pn_data {
struct zfcp_send_ct ct;
struct scatterlist req;
struct scatterlist resp;
struct ct_iu_gid_pn_req ct_iu_req;
struct ct_iu_gid_pn_resp ct_iu_resp;
struct zfcp_port *port;
};
/**
* struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
* @adapter: adapter where request is sent from
* @port: port where ELS is destinated (port reference count has to be increased)
* @d_id: destiniation id of port where request is sent to
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
* @handler: handler function (called for response to the request)
* @handler_data: data passed to handler function
* @completion: completion for synchronization purposes
* @ls_code: hex code of ELS command
* @status: used to pass error status to calling function
*/
struct zfcp_send_els {
struct zfcp_adapter *adapter;
struct zfcp_port *port;
u32 d_id;
struct scatterlist *req;
struct scatterlist *resp;
void (*handler)(unsigned long);
unsigned long handler_data;
struct completion *completion;
int ls_code;
int status;
};
struct zfcp_wka_port {
struct zfcp_adapter *adapter;
wait_queue_head_t completion_wq;
enum zfcp_wka_status status;
atomic_t refcount;
u32 d_id;
u32 handle;
struct mutex mutex;
struct delayed_work work;
};
struct zfcp_wka_ports {
struct zfcp_wka_port ms; /* management service */
struct zfcp_wka_port ts; /* time service */
struct zfcp_wka_port ds; /* directory service */
struct zfcp_wka_port as; /* alias service */
struct zfcp_wka_port ks; /* key distribution service */
};
struct zfcp_qdio_queue { struct zfcp_qdio_queue {
struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
u8 first; /* index of next free bfr in queue */ u8 first; /* index of next free bfr in queue */
...@@ -446,9 +191,7 @@ struct zfcp_qdio { ...@@ -446,9 +191,7 @@ struct zfcp_qdio {
}; };
struct zfcp_adapter { struct zfcp_adapter {
atomic_t refcount; /* reference count */ struct kref ref;
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
u64 peer_wwnn; /* P2P peer WWNN */ u64 peer_wwnn; /* P2P peer WWNN */
u64 peer_wwpn; /* P2P peer WWPN */ u64 peer_wwpn; /* P2P peer WWPN */
u32 peer_d_id; /* P2P peer D_ID */ u32 peer_d_id; /* P2P peer D_ID */
...@@ -461,7 +204,8 @@ struct zfcp_adapter { ...@@ -461,7 +204,8 @@ struct zfcp_adapter {
u32 hardware_version; /* of FCP channel */ u32 hardware_version; /* of FCP channel */
u16 timer_ticks; /* time int for a tick */ u16 timer_ticks; /* time int for a tick */
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
struct list_head port_list_head; /* remote port list */ struct list_head port_list; /* remote port list */
rwlock_t port_list_lock; /* port list lock */
unsigned long req_no; /* unique FSF req number */ unsigned long req_no; /* unique FSF req number */
struct list_head *req_list; /* list of pending reqs */ struct list_head *req_list; /* list of pending reqs */
spinlock_t req_list_lock; /* request list lock */ spinlock_t req_list_lock; /* request list lock */
...@@ -485,7 +229,7 @@ struct zfcp_adapter { ...@@ -485,7 +229,7 @@ struct zfcp_adapter {
u32 erp_low_mem_count; /* nr of erp actions waiting u32 erp_low_mem_count; /* nr of erp actions waiting
for memory */ for memory */
struct task_struct *erp_thread; struct task_struct *erp_thread;
struct zfcp_wka_ports *gs; /* generic services */ struct zfcp_fc_wka_ports *gs; /* generic services */
struct zfcp_dbf *dbf; /* debug traces */ struct zfcp_dbf *dbf; /* debug traces */
struct zfcp_adapter_mempool pool; /* Adapter memory pools */ struct zfcp_adapter_mempool pool; /* Adapter memory pools */
struct fc_host_statistics *fc_stats; struct fc_host_statistics *fc_stats;
...@@ -500,11 +244,9 @@ struct zfcp_port { ...@@ -500,11 +244,9 @@ struct zfcp_port {
struct device sysfs_device; /* sysfs device */ struct device sysfs_device; /* sysfs device */
struct fc_rport *rport; /* rport of fc transport class */ struct fc_rport *rport; /* rport of fc transport class */
struct list_head list; /* list of remote ports */ struct list_head list; /* list of remote ports */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct zfcp_adapter *adapter; /* adapter used to access port */ struct zfcp_adapter *adapter; /* adapter used to access port */
struct list_head unit_list_head; /* head of logical unit list */ struct list_head unit_list; /* head of logical unit list */
rwlock_t unit_list_lock; /* unit list lock */
atomic_t status; /* status of this remote port */ atomic_t status; /* status of this remote port */
u64 wwnn; /* WWNN if known */ u64 wwnn; /* WWNN if known */
u64 wwpn; /* WWPN */ u64 wwpn; /* WWPN */
...@@ -523,9 +265,6 @@ struct zfcp_port { ...@@ -523,9 +265,6 @@ struct zfcp_port {
struct zfcp_unit { struct zfcp_unit {
struct device sysfs_device; /* sysfs device */ struct device sysfs_device; /* sysfs device */
struct list_head list; /* list of logical units */ struct list_head list; /* list of logical units */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct zfcp_port *port; /* remote port of unit */ struct zfcp_port *port; /* remote port of unit */
atomic_t status; /* status of this logical unit */ atomic_t status; /* status of this logical unit */
u64 fcp_lun; /* own FCP_LUN */ u64 fcp_lun; /* own FCP_LUN */
...@@ -601,14 +340,11 @@ struct zfcp_fsf_req { ...@@ -601,14 +340,11 @@ struct zfcp_fsf_req {
struct zfcp_data { struct zfcp_data {
struct scsi_host_template scsi_host_template; struct scsi_host_template scsi_host_template;
struct scsi_transport_template *scsi_transport_template; struct scsi_transport_template *scsi_transport_template;
rwlock_t config_lock; /* serialises changes
to adapter/port/unit
lists */
struct mutex config_mutex;
struct kmem_cache *gpn_ft_cache; struct kmem_cache *gpn_ft_cache;
struct kmem_cache *qtcb_cache; struct kmem_cache *qtcb_cache;
struct kmem_cache *sr_buffer_cache; struct kmem_cache *sr_buffer_cache;
struct kmem_cache *gid_pn_cache; struct kmem_cache *gid_pn_cache;
struct kmem_cache *adisc_cache;
}; };
/********************** ZFCP SPECIFIC DEFINES ********************************/ /********************** ZFCP SPECIFIC DEFINES ********************************/
...@@ -657,47 +393,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req) ...@@ -657,47 +393,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
return NULL; return NULL;
} }
/*
* functions needed for reference/usage counting
*/
static inline void
zfcp_unit_get(struct zfcp_unit *unit)
{
atomic_inc(&unit->refcount);
}
static inline void
zfcp_unit_put(struct zfcp_unit *unit)
{
if (atomic_dec_return(&unit->refcount) == 0)
wake_up(&unit->remove_wq);
}
static inline void
zfcp_port_get(struct zfcp_port *port)
{
atomic_inc(&port->refcount);
}
static inline void
zfcp_port_put(struct zfcp_port *port)
{
if (atomic_dec_return(&port->refcount) == 0)
wake_up(&port->remove_wq);
}
static inline void
zfcp_adapter_get(struct zfcp_adapter *adapter)
{
atomic_inc(&adapter->refcount);
}
static inline void
zfcp_adapter_put(struct zfcp_adapter *adapter)
{
if (atomic_dec_return(&adapter->refcount) == 0)
wake_up(&adapter->remove_wq);
}
#endif /* ZFCP_DEF_H */ #endif /* ZFCP_DEF_H */
...@@ -99,9 +99,12 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) ...@@ -99,9 +99,12 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
zfcp_erp_action_dismiss(&port->erp_action); zfcp_erp_action_dismiss(&port->erp_action);
else else {
list_for_each_entry(unit, &port->unit_list_head, list) read_lock(&port->unit_list_lock);
zfcp_erp_action_dismiss_unit(unit); list_for_each_entry(unit, &port->unit_list, list)
zfcp_erp_action_dismiss_unit(unit);
read_unlock(&port->unit_list_lock);
}
} }
static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
...@@ -110,9 +113,12 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) ...@@ -110,9 +113,12 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
zfcp_erp_action_dismiss(&adapter->erp_action); zfcp_erp_action_dismiss(&adapter->erp_action);
else else {
list_for_each_entry(port, &adapter->port_list_head, list) read_lock(&adapter->port_list_lock);
list_for_each_entry(port, &adapter->port_list, list)
zfcp_erp_action_dismiss_port(port); zfcp_erp_action_dismiss_port(port);
read_unlock(&adapter->port_list_lock);
}
} }
static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
...@@ -168,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, ...@@ -168,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
switch (need) { switch (need) {
case ZFCP_ERP_ACTION_REOPEN_UNIT: case ZFCP_ERP_ACTION_REOPEN_UNIT:
zfcp_unit_get(unit); if (!get_device(&unit->sysfs_device))
return NULL;
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
erp_action = &unit->erp_action; erp_action = &unit->erp_action;
if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
...@@ -177,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, ...@@ -177,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
case ZFCP_ERP_ACTION_REOPEN_PORT: case ZFCP_ERP_ACTION_REOPEN_PORT:
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
zfcp_port_get(port); if (!get_device(&port->sysfs_device))
return NULL;
zfcp_erp_action_dismiss_port(port); zfcp_erp_action_dismiss_port(port);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
erp_action = &port->erp_action; erp_action = &port->erp_action;
...@@ -186,7 +194,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, ...@@ -186,7 +194,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
break; break;
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
zfcp_adapter_get(adapter); kref_get(&adapter->ref);
zfcp_erp_action_dismiss_adapter(adapter); zfcp_erp_action_dismiss_adapter(adapter);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
erp_action = &adapter->erp_action; erp_action = &adapter->erp_action;
...@@ -264,11 +272,16 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, ...@@ -264,11 +272,16 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
{ {
unsigned long flags; unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags); zfcp_erp_adapter_block(adapter, clear);
write_lock(&adapter->erp_lock); zfcp_scsi_schedule_rports_block(adapter);
_zfcp_erp_adapter_reopen(adapter, clear, id, ref);
write_unlock(&adapter->erp_lock); write_lock_irqsave(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags); if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
else
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
NULL, NULL, id, ref);
write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
/** /**
...@@ -345,11 +358,9 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id, ...@@ -345,11 +358,9 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
unsigned long flags; unsigned long flags;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
write_lock(&adapter->erp_lock);
_zfcp_erp_port_forced_reopen(port, clear, id, ref); _zfcp_erp_port_forced_reopen(port, clear, id, ref);
write_unlock(&adapter->erp_lock); write_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
} }
static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
...@@ -377,15 +388,13 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, ...@@ -377,15 +388,13 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
*/ */
int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
{ {
unsigned long flags;
int retval; int retval;
unsigned long flags;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
write_lock(&adapter->erp_lock);
retval = _zfcp_erp_port_reopen(port, clear, id, ref); retval = _zfcp_erp_port_reopen(port, clear, id, ref);
write_unlock(&adapter->erp_lock); write_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
return retval; return retval;
} }
...@@ -424,11 +433,9 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, ...@@ -424,11 +433,9 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
struct zfcp_port *port = unit->port; struct zfcp_port *port = unit->port;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
write_lock(&adapter->erp_lock);
_zfcp_erp_unit_reopen(unit, clear, id, ref); _zfcp_erp_unit_reopen(unit, clear, id, ref);
write_unlock(&adapter->erp_lock); write_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
} }
static int status_change_set(unsigned long mask, atomic_t *status) static int status_change_set(unsigned long mask, atomic_t *status)
...@@ -540,8 +547,10 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, ...@@ -540,8 +547,10 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
{ {
struct zfcp_port *port; struct zfcp_port *port;
list_for_each_entry(port, &adapter->port_list_head, list) read_lock(&adapter->port_list_lock);
list_for_each_entry(port, &adapter->port_list, list)
_zfcp_erp_port_reopen(port, clear, id, ref); _zfcp_erp_port_reopen(port, clear, id, ref);
read_unlock(&adapter->port_list_lock);
} }
static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
...@@ -549,8 +558,10 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, ...@@ -549,8 +558,10 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
{ {
struct zfcp_unit *unit; struct zfcp_unit *unit;
list_for_each_entry(unit, &port->unit_list_head, list) read_lock(&port->unit_list_lock);
list_for_each_entry(unit, &port->unit_list, list)
_zfcp_erp_unit_reopen(unit, clear, id, ref); _zfcp_erp_unit_reopen(unit, clear, id, ref);
read_unlock(&port->unit_list_lock);
} }
static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
...@@ -590,16 +601,14 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter) ...@@ -590,16 +601,14 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
{ {
unsigned long flags; unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags); read_lock_irqsave(&adapter->erp_lock, flags);
read_lock(&adapter->erp_lock);
if (list_empty(&adapter->erp_ready_head) && if (list_empty(&adapter->erp_ready_head) &&
list_empty(&adapter->erp_running_head)) { list_empty(&adapter->erp_running_head)) {
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
&adapter->status); &adapter->status);
wake_up(&adapter->erp_done_wqh); wake_up(&adapter->erp_done_wqh);
} }
read_unlock(&adapter->erp_lock); read_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
} }
static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
...@@ -1170,28 +1179,28 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) ...@@ -1170,28 +1179,28 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
switch (act->action) { switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT: case ZFCP_ERP_ACTION_REOPEN_UNIT:
if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
zfcp_unit_get(unit); get_device(&unit->sysfs_device);
if (scsi_queue_work(unit->port->adapter->scsi_host, if (scsi_queue_work(unit->port->adapter->scsi_host,
&unit->scsi_work) <= 0) &unit->scsi_work) <= 0)
zfcp_unit_put(unit); put_device(&unit->sysfs_device);
} }
zfcp_unit_put(unit); put_device(&unit->sysfs_device);
break; break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
case ZFCP_ERP_ACTION_REOPEN_PORT: case ZFCP_ERP_ACTION_REOPEN_PORT:
if (result == ZFCP_ERP_SUCCEEDED) if (result == ZFCP_ERP_SUCCEEDED)
zfcp_scsi_schedule_rport_register(port); zfcp_scsi_schedule_rport_register(port);
zfcp_port_put(port); put_device(&port->sysfs_device);
break; break;
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (result == ZFCP_ERP_SUCCEEDED) { if (result == ZFCP_ERP_SUCCEEDED) {
register_service_level(&adapter->service_level); register_service_level(&adapter->service_level);
schedule_work(&adapter->scan_work); queue_work(adapter->work_queue, &adapter->scan_work);
} else } else
unregister_service_level(&adapter->service_level); unregister_service_level(&adapter->service_level);
zfcp_adapter_put(adapter); kref_put(&adapter->ref, zfcp_adapter_release);
break; break;
} }
} }
...@@ -1214,12 +1223,12 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) ...@@ -1214,12 +1223,12 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
{ {
int retval; int retval;
struct zfcp_adapter *adapter = erp_action->adapter;
unsigned long flags; unsigned long flags;
struct zfcp_adapter *adapter = erp_action->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags); kref_get(&adapter->ref);
write_lock(&adapter->erp_lock);
write_lock_irqsave(&adapter->erp_lock, flags);
zfcp_erp_strategy_check_fsfreq(erp_action); zfcp_erp_strategy_check_fsfreq(erp_action);
if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
...@@ -1231,11 +1240,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) ...@@ -1231,11 +1240,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
zfcp_erp_action_to_running(erp_action); zfcp_erp_action_to_running(erp_action);
/* no lock to allow for blocking operations */ /* no lock to allow for blocking operations */
write_unlock(&adapter->erp_lock); write_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
retval = zfcp_erp_strategy_do_action(erp_action); retval = zfcp_erp_strategy_do_action(erp_action);
read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
write_lock(&adapter->erp_lock);
if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
retval = ZFCP_ERP_CONTINUES; retval = ZFCP_ERP_CONTINUES;
...@@ -1273,12 +1280,12 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) ...@@ -1273,12 +1280,12 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
zfcp_erp_strategy_followup_failed(erp_action); zfcp_erp_strategy_followup_failed(erp_action);
unlock: unlock:
write_unlock(&adapter->erp_lock); write_unlock_irqrestore(&adapter->erp_lock, flags);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
if (retval != ZFCP_ERP_CONTINUES) if (retval != ZFCP_ERP_CONTINUES)
zfcp_erp_action_cleanup(erp_action, retval); zfcp_erp_action_cleanup(erp_action, retval);
kref_put(&adapter->ref, zfcp_adapter_release);
return retval; return retval;
} }
...@@ -1415,6 +1422,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, ...@@ -1415,6 +1422,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
void *ref, u32 mask, int set_or_clear) void *ref, u32 mask, int set_or_clear)
{ {
struct zfcp_port *port; struct zfcp_port *port;
unsigned long flags;
u32 common_mask = mask & ZFCP_COMMON_FLAGS; u32 common_mask = mask & ZFCP_COMMON_FLAGS;
if (set_or_clear == ZFCP_SET) { if (set_or_clear == ZFCP_SET) {
...@@ -1429,10 +1437,13 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, ...@@ -1429,10 +1437,13 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
atomic_set(&adapter->erp_counter, 0); atomic_set(&adapter->erp_counter, 0);
} }
if (common_mask) if (common_mask) {
list_for_each_entry(port, &adapter->port_list_head, list) read_lock_irqsave(&adapter->port_list_lock, flags);
list_for_each_entry(port, &adapter->port_list, list)
zfcp_erp_modify_port_status(port, id, ref, common_mask, zfcp_erp_modify_port_status(port, id, ref, common_mask,
set_or_clear); set_or_clear);
read_unlock_irqrestore(&adapter->port_list_lock, flags);
}
} }
/** /**
...@@ -1449,6 +1460,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, ...@@ -1449,6 +1460,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
u32 mask, int set_or_clear) u32 mask, int set_or_clear)
{ {
struct zfcp_unit *unit; struct zfcp_unit *unit;
unsigned long flags;
u32 common_mask = mask & ZFCP_COMMON_FLAGS; u32 common_mask = mask & ZFCP_COMMON_FLAGS;
if (set_or_clear == ZFCP_SET) { if (set_or_clear == ZFCP_SET) {
...@@ -1463,10 +1475,13 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, ...@@ -1463,10 +1475,13 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
atomic_set(&port->erp_counter, 0); atomic_set(&port->erp_counter, 0);
} }
if (common_mask) if (common_mask) {
list_for_each_entry(unit, &port->unit_list_head, list) read_lock_irqsave(&port->unit_list_lock, flags);
list_for_each_entry(unit, &port->unit_list, list)
zfcp_erp_modify_unit_status(unit, id, ref, common_mask, zfcp_erp_modify_unit_status(unit, id, ref, common_mask,
set_or_clear); set_or_clear);
read_unlock_irqrestore(&port->unit_list_lock, flags);
}
} }
/** /**
...@@ -1502,12 +1517,8 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref, ...@@ -1502,12 +1517,8 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref,
*/ */
void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
{ {
unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags);
zfcp_erp_modify_port_status(port, id, ref, zfcp_erp_modify_port_status(port, id, ref,
ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
} }
...@@ -1535,13 +1546,9 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref) ...@@ -1535,13 +1546,9 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref)
*/ */
void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
{ {
unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags);
zfcp_erp_modify_port_status(port, id, ref, zfcp_erp_modify_port_status(port, id, ref,
ZFCP_STATUS_COMMON_ERP_FAILED | ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
} }
/** /**
...@@ -1574,12 +1581,15 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, ...@@ -1574,12 +1581,15 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
void *ref) void *ref)
{ {
struct zfcp_unit *unit; struct zfcp_unit *unit;
unsigned long flags;
int status = atomic_read(&port->status); int status = atomic_read(&port->status);
if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
ZFCP_STATUS_COMMON_ACCESS_BOXED))) { ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
list_for_each_entry(unit, &port->unit_list_head, list) read_lock_irqsave(&port->unit_list_lock, flags);
list_for_each_entry(unit, &port->unit_list, list)
zfcp_erp_unit_access_changed(unit, id, ref); zfcp_erp_unit_access_changed(unit, id, ref);
read_unlock_irqrestore(&port->unit_list_lock, flags);
return; return;
} }
...@@ -1595,14 +1605,14 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, ...@@ -1595,14 +1605,14 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
void *ref) void *ref)
{ {
struct zfcp_port *port;
unsigned long flags; unsigned long flags;
struct zfcp_port *port;
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
return; return;
read_lock_irqsave(&zfcp_data.config_lock, flags); read_lock_irqsave(&adapter->port_list_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) list_for_each_entry(port, &adapter->port_list, list)
zfcp_erp_port_access_changed(port, id, ref); zfcp_erp_port_access_changed(port, id, ref);
read_unlock_irqrestore(&zfcp_data.config_lock, flags); read_unlock_irqrestore(&adapter->port_list_lock, flags);
} }
...@@ -9,26 +9,31 @@ ...@@ -9,26 +9,31 @@
#ifndef ZFCP_EXT_H #ifndef ZFCP_EXT_H
#define ZFCP_EXT_H #define ZFCP_EXT_H
#include <linux/types.h>
#include <scsi/fc/fc_els.h>
#include "zfcp_def.h" #include "zfcp_def.h"
#include "zfcp_fc.h"
/* zfcp_aux.c */ /* zfcp_aux.c */
extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64); extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64); extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
extern int zfcp_adapter_enqueue(struct ccw_device *); extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
u32); u32);
extern void zfcp_port_dequeue(struct zfcp_port *);
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64); extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
extern void zfcp_unit_dequeue(struct zfcp_unit *);
extern int zfcp_reqlist_isempty(struct zfcp_adapter *); extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
extern void zfcp_sg_free_table(struct scatterlist *, int); extern void zfcp_sg_free_table(struct scatterlist *, int);
extern int zfcp_sg_setup_table(struct scatterlist *, int); extern int zfcp_sg_setup_table(struct scatterlist *, int);
extern void zfcp_device_unregister(struct device *,
const struct attribute_group *);
extern void zfcp_adapter_release(struct kref *);
extern void zfcp_adapter_unregister(struct zfcp_adapter *);
/* zfcp_ccw.c */ /* zfcp_ccw.c */
extern int zfcp_ccw_register(void);
extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
extern struct ccw_driver zfcp_ccw_driver; extern struct ccw_driver zfcp_ccw_driver;
extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *);
extern void zfcp_ccw_adapter_put(struct zfcp_adapter *);
/* zfcp_cfdc.c */ /* zfcp_cfdc.c */
extern struct miscdevice zfcp_cfdc_misc; extern struct miscdevice zfcp_cfdc_misc;
...@@ -51,7 +56,7 @@ extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *, ...@@ -51,7 +56,7 @@ extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *,
struct fsf_status_read_buffer *); struct fsf_status_read_buffer *);
extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int); extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *); extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *, u32);
extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *); extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *); extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *); extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
...@@ -92,24 +97,22 @@ extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *, ...@@ -92,24 +97,22 @@ extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
extern void zfcp_erp_timeout_handler(unsigned long); extern void zfcp_erp_timeout_handler(unsigned long);
/* zfcp_fc.c */ /* zfcp_fc.c */
extern int zfcp_fc_scan_ports(struct zfcp_adapter *); extern void zfcp_fc_scan_ports(struct work_struct *);
extern void _zfcp_fc_scan_ports_later(struct work_struct *);
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fc_port_did_lookup(struct work_struct *); extern void zfcp_fc_port_did_lookup(struct work_struct *);
extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *); extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);
extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fc_els_flogi *);
extern void zfcp_fc_test_link(struct zfcp_port *); extern void zfcp_fc_test_link(struct zfcp_port *);
extern void zfcp_fc_link_test_work(struct work_struct *); extern void zfcp_fc_link_test_work(struct work_struct *);
extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *); extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
extern int zfcp_fc_gs_setup(struct zfcp_adapter *); extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
extern void zfcp_fc_gs_destroy(struct zfcp_adapter *); extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *); extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
/* zfcp_fsf.c */ /* zfcp_fsf.c */
extern int zfcp_fsf_open_port(struct zfcp_erp_action *); extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *); extern int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *);
extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *); extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *);
extern int zfcp_fsf_close_port(struct zfcp_erp_action *); extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
...@@ -125,8 +128,10 @@ extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *, ...@@ -125,8 +128,10 @@ extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *,
extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
extern int zfcp_fsf_status_read(struct zfcp_qdio *); extern int zfcp_fsf_status_read(struct zfcp_qdio *);
extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *); extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
extern int zfcp_fsf_send_els(struct zfcp_send_els *); mempool_t *);
extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
struct zfcp_fsf_ct_els *);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
struct scsi_cmnd *); struct scsi_cmnd *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
...@@ -153,7 +158,6 @@ extern void zfcp_qdio_close(struct zfcp_qdio *); ...@@ -153,7 +158,6 @@ extern void zfcp_qdio_close(struct zfcp_qdio *);
extern struct zfcp_data zfcp_data; extern struct zfcp_data zfcp_data;
extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
extern struct fc_function_template zfcp_transport_functions; extern struct fc_function_template zfcp_transport_functions;
extern void zfcp_scsi_rport_work(struct work_struct *); extern void zfcp_scsi_rport_work(struct work_struct *);
extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
......
此差异已折叠。
/*
* zfcp device driver
*
* Fibre Channel related definitions and inline functions for the zfcp
* device driver
*
* Copyright IBM Corporation 2009
*/
#ifndef ZFCP_FC_H
#define ZFCP_FC_H
#include <scsi/fc/fc_els.h>
#include <scsi/fc/fc_fcp.h>
#include <scsi/fc/fc_ns.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_tcq.h>
#include "zfcp_fsf.h"
#define ZFCP_FC_CT_SIZE_PAGE (PAGE_SIZE - sizeof(struct fc_ct_hdr))
#define ZFCP_FC_GPN_FT_ENT_PAGE (ZFCP_FC_CT_SIZE_PAGE \
/ sizeof(struct fc_gpn_ft_resp))
#define ZFCP_FC_GPN_FT_NUM_BUFS 4 /* memory pages */
#define ZFCP_FC_GPN_FT_MAX_SIZE (ZFCP_FC_GPN_FT_NUM_BUFS * PAGE_SIZE \
- sizeof(struct fc_ct_hdr))
#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
(ZFCP_FC_GPN_FT_ENT_PAGE + 1))
/**
* struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
* @ct_hdr: FC GS common transport header
* @gid_pn: GID_PN request
*/
struct zfcp_fc_gid_pn_req {
struct fc_ct_hdr ct_hdr;
struct fc_ns_gid_pn gid_pn;
} __packed;
/**
* struct zfcp_fc_gid_pn_resp - container for ct header plus gid_pn response
* @ct_hdr: FC GS common transport header
* @gid_pn: GID_PN response
*/
struct zfcp_fc_gid_pn_resp {
struct fc_ct_hdr ct_hdr;
struct fc_gid_pn_resp gid_pn;
} __packed;
/**
* struct zfcp_fc_gid_pn - everything required in zfcp for gid_pn request
* @ct: data passed to zfcp_fsf for issuing fsf request
* @sg_req: scatterlist entry for request data
* @sg_resp: scatterlist entry for response data
* @gid_pn_req: GID_PN request data
* @gid_pn_resp: GID_PN response data
*/
struct zfcp_fc_gid_pn {
struct zfcp_fsf_ct_els ct;
struct scatterlist sg_req;
struct scatterlist sg_resp;
struct zfcp_fc_gid_pn_req gid_pn_req;
struct zfcp_fc_gid_pn_resp gid_pn_resp;
struct zfcp_port *port;
};
/**
* struct zfcp_fc_gpn_ft - container for ct header plus gpn_ft request
* @ct_hdr: FC GS common transport header
* @gpn_ft: GPN_FT request
*/
struct zfcp_fc_gpn_ft_req {
struct fc_ct_hdr ct_hdr;
struct fc_ns_gid_ft gpn_ft;
} __packed;
/**
* struct zfcp_fc_gpn_ft_resp - container for ct header plus gpn_ft response
* @ct_hdr: FC GS common transport header
* @gpn_ft: Array of gpn_ft response data to fill one memory page
*/
struct zfcp_fc_gpn_ft_resp {
struct fc_ct_hdr ct_hdr;
struct fc_gpn_ft_resp gpn_ft[ZFCP_FC_GPN_FT_ENT_PAGE];
} __packed;
/**
* struct zfcp_fc_gpn_ft - zfcp data for gpn_ft request
* @ct: data passed to zfcp_fsf for issuing fsf request
* @sg_req: scatter list entry for gpn_ft request
* @sg_resp: scatter list entries for gpn_ft responses (per memory page)
*/
struct zfcp_fc_gpn_ft {
struct zfcp_fsf_ct_els ct;
struct scatterlist sg_req;
struct scatterlist sg_resp[ZFCP_FC_GPN_FT_NUM_BUFS];
};
/**
* struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC
* @els: data required for issuing els fsf command
* @req: scatterlist entry for ELS ADISC request
* @resp: scatterlist entry for ELS ADISC response
* @adisc_req: ELS ADISC request data
* @adisc_resp: ELS ADISC response data
*/
struct zfcp_fc_els_adisc {
struct zfcp_fsf_ct_els els;
struct scatterlist req;
struct scatterlist resp;
struct fc_els_adisc adisc_req;
struct fc_els_adisc adisc_resp;
};
/**
* enum zfcp_fc_wka_status - FC WKA port status in zfcp
* @ZFCP_FC_WKA_PORT_OFFLINE: Port is closed and not in use
* @ZFCP_FC_WKA_PORT_CLOSING: The FSF "close port" request is pending
* @ZFCP_FC_WKA_PORT_OPENING: The FSF "open port" request is pending
* @ZFCP_FC_WKA_PORT_ONLINE: The port is open and the port handle is valid
*/
enum zfcp_fc_wka_status {
ZFCP_FC_WKA_PORT_OFFLINE,
ZFCP_FC_WKA_PORT_CLOSING,
ZFCP_FC_WKA_PORT_OPENING,
ZFCP_FC_WKA_PORT_ONLINE,
};
/**
* struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port
* @adapter: Pointer to adapter structure this WKA port belongs to
* @completion_wq: Wait for completion of open/close command
* @status: Current status of WKA port
* @refcount: Reference count to keep port open as long as it is in use
* @d_id: FC destination id or well-known-address
* @handle: FSF handle for the open WKA port
* @mutex: Mutex used during opening/closing state changes
* @work: For delaying the closing of the WKA port
*/
struct zfcp_fc_wka_port {
struct zfcp_adapter *adapter;
wait_queue_head_t completion_wq;
enum zfcp_fc_wka_status status;
atomic_t refcount;
u32 d_id;
u32 handle;
struct mutex mutex;
struct delayed_work work;
};
/**
* struct zfcp_fc_wka_ports - Data structures for FC generic services
* @ms: FC Management service
* @ts: FC time service
* @ds: FC directory service
* @as: FC alias service
*/
struct zfcp_fc_wka_ports {
struct zfcp_fc_wka_port ms;
struct zfcp_fc_wka_port ts;
struct zfcp_fc_wka_port ds;
struct zfcp_fc_wka_port as;
};
/**
* zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
* @fcp: fcp_cmnd to setup
* @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
*/
static inline
void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
{
char tag[2];
int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
if (scsi_populate_tag_msg(scsi, tag)) {
switch (tag[0]) {
case MSG_ORDERED_TAG:
fcp->fc_pri_ta |= FCP_PTA_ORDERED;
break;
case MSG_SIMPLE_TAG:
fcp->fc_pri_ta |= FCP_PTA_SIMPLE;
break;
};
} else
fcp->fc_pri_ta = FCP_PTA_SIMPLE;
if (scsi->sc_data_direction == DMA_FROM_DEVICE)
fcp->fc_flags |= FCP_CFL_RDDATA;
if (scsi->sc_data_direction == DMA_TO_DEVICE)
fcp->fc_flags |= FCP_CFL_WRDATA;
memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
fcp->fc_dl = scsi_bufflen(scsi);
}
/**
* zfcp_fc_fcp_tm - setup FCP command as task management command
* @fcp: fcp_cmnd to setup
* @dev: scsi_device where to send the task management command
* @tm: task management flags to setup tm command
*/
static inline
void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
{
int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
fcp->fc_tm_flags |= tm_flags;
}
/**
* zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
* @fcp_rsp: FCP RSP IU to evaluate
* @scsi: SCSI command where to update status and sense buffer
*/
static inline
void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
struct scsi_cmnd *scsi)
{
struct fcp_resp_rsp_info *rsp_info;
char *sense;
u32 sense_len, resid;
u8 rsp_flags;
set_msg_byte(scsi, COMMAND_COMPLETE);
scsi->result |= fcp_rsp->resp.fr_status;
rsp_flags = fcp_rsp->resp.fr_flags;
if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
if (rsp_info->rsp_code == FCP_TMF_CMPL)
set_host_byte(scsi, DID_OK);
else {
set_host_byte(scsi, DID_ERROR);
return;
}
}
if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
sense = (char *) &fcp_rsp[1];
if (rsp_flags & FCP_RSP_LEN_VAL)
sense += fcp_rsp->ext.fr_sns_len;
sense_len = min(fcp_rsp->ext.fr_sns_len,
(u32) SCSI_SENSE_BUFFERSIZE);
memcpy(scsi->sense_buffer, sense, sense_len);
}
if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
resid = fcp_rsp->ext.fr_resid;
scsi_set_resid(scsi, resid);
if (scsi_bufflen(scsi) - resid < scsi->underflow &&
!(rsp_flags & FCP_SNS_LEN_VAL) &&
fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
set_host_byte(scsi, DID_ERROR);
}
}
#endif
此差异已折叠。
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/pfn.h> #include <linux/pfn.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <scsi/libfc.h>
#define FSF_QTCB_CURRENT_VERSION 0x00000001 #define FSF_QTCB_CURRENT_VERSION 0x00000001
...@@ -228,7 +229,8 @@ struct fsf_status_read_buffer { ...@@ -228,7 +229,8 @@ struct fsf_status_read_buffer {
u32 length; u32 length;
u32 res1; u32 res1;
struct fsf_queue_designator queue_designator; struct fsf_queue_designator queue_designator;
u32 d_id; u8 res2;
u8 d_id[3];
u32 class; u32 class;
u64 fcp_lun; u64 fcp_lun;
u8 res3[24]; u8 res3[24];
...@@ -309,22 +311,7 @@ struct fsf_qtcb_header { ...@@ -309,22 +311,7 @@ struct fsf_qtcb_header {
u8 res4[16]; u8 res4[16];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct fsf_nport_serv_param {
u8 common_serv_param[16];
u64 wwpn;
u64 wwnn;
u8 class1_serv_param[16];
u8 class2_serv_param[16];
u8 class3_serv_param[16];
u8 class4_serv_param[16];
u8 vendor_version_level[16];
} __attribute__ ((packed));
#define FSF_PLOGI_MIN_LEN 112 #define FSF_PLOGI_MIN_LEN 112
struct fsf_plogi {
u32 code;
struct fsf_nport_serv_param serv_param;
} __attribute__ ((packed));
#define FSF_FCP_CMND_SIZE 288 #define FSF_FCP_CMND_SIZE 288
#define FSF_FCP_RSP_SIZE 128 #define FSF_FCP_RSP_SIZE 128
...@@ -342,8 +329,8 @@ struct fsf_qtcb_bottom_io { ...@@ -342,8 +329,8 @@ struct fsf_qtcb_bottom_io {
struct fsf_qtcb_bottom_support { struct fsf_qtcb_bottom_support {
u32 operation_subtype; u32 operation_subtype;
u8 res1[12]; u8 res1[13];
u32 d_id; u8 d_id[3];
u32 option; u32 option;
u64 fcp_lun; u64 fcp_lun;
u64 res2; u64 res2;
...@@ -372,18 +359,18 @@ struct fsf_qtcb_bottom_config { ...@@ -372,18 +359,18 @@ struct fsf_qtcb_bottom_config {
u32 fc_topology; u32 fc_topology;
u32 fc_link_speed; u32 fc_link_speed;
u32 adapter_type; u32 adapter_type;
u32 peer_d_id; u8 res0;
u8 peer_d_id[3];
u8 res1[2]; u8 res1[2];
u16 timer_interval; u16 timer_interval;
u8 res2[8]; u8 res2[9];
u32 s_id; u8 s_id[3];
struct fsf_nport_serv_param nport_serv_param; u8 nport_serv_param[128];
u8 reserved_nport_serv_param[16];
u8 res3[8]; u8 res3[8];
u32 adapter_ports; u32 adapter_ports;
u32 hardware_version; u32 hardware_version;
u8 serial_number[32]; u8 serial_number[32];
struct fsf_nport_serv_param plogi_payload; u8 plogi_payload[112];
struct fsf_statistics_info stat_info; struct fsf_statistics_info stat_info;
u8 res4[112]; u8 res4[112];
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -450,4 +437,22 @@ struct zfcp_blk_drv_data { ...@@ -450,4 +437,22 @@ struct zfcp_blk_drv_data {
u64 fabric_lat; u64 fabric_lat;
} __attribute__ ((packed)); } __attribute__ ((packed));
/**
* struct zfcp_fsf_ct_els - zfcp data for ct or els request
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
* @handler: handler function (called for response to the request)
* @handler_data: data passed to handler function
* @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
* @status: used to pass error status to calling function
*/
struct zfcp_fsf_ct_els {
struct scatterlist *req;
struct scatterlist *resp;
void (*handler)(void *);
void *handler_data;
struct zfcp_port *port;
int status;
};
#endif /* FSF_H */ #endif /* FSF_H */
此差异已折叠。
此差异已折叠。
...@@ -186,8 +186,12 @@ static ssize_t twa_show_stats(struct device *dev, ...@@ -186,8 +186,12 @@ static ssize_t twa_show_stats(struct device *dev,
} /* End twa_show_stats() */ } /* End twa_show_stats() */
/* This function will set a devices queue depth */ /* This function will set a devices queue depth */
static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth) static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{ {
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > TW_Q_LENGTH-2) if (queue_depth > TW_Q_LENGTH-2)
queue_depth = TW_Q_LENGTH-2; queue_depth = TW_Q_LENGTH-2;
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
......
此差异已折叠。
此差异已折叠。
...@@ -521,8 +521,12 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr, ...@@ -521,8 +521,12 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
} /* End tw_show_stats() */ } /* End tw_show_stats() */
/* This function will set a devices queue depth */ /* This function will set a devices queue depth */
static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth) static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
int reason)
{ {
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > TW_Q_LENGTH-2) if (queue_depth > TW_Q_LENGTH-2)
queue_depth = TW_Q_LENGTH-2; queue_depth = TW_Q_LENGTH-2;
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
......
...@@ -175,7 +175,7 @@ STATIC void NCR_700_chip_reset(struct Scsi_Host *host); ...@@ -175,7 +175,7 @@ STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth, int reason);
static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth); static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
STATIC struct device_attribute *NCR_700_dev_attrs[]; STATIC struct device_attribute *NCR_700_dev_attrs[];
...@@ -2082,8 +2082,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp) ...@@ -2082,8 +2082,11 @@ NCR_700_slave_destroy(struct scsi_device *SDp)
} }
static int static int
NCR_700_change_queue_depth(struct scsi_device *SDp, int depth) NCR_700_change_queue_depth(struct scsi_device *SDp, int depth, int reason)
{ {
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (depth > NCR_700_MAX_TAGS) if (depth > NCR_700_MAX_TAGS)
depth = NCR_700_MAX_TAGS; depth = NCR_700_MAX_TAGS;
......
...@@ -399,6 +399,17 @@ config SCSI_3W_9XXX ...@@ -399,6 +399,17 @@ config SCSI_3W_9XXX
Please read the comments at the top of Please read the comments at the top of
<file:drivers/scsi/3w-9xxx.c>. <file:drivers/scsi/3w-9xxx.c>.
config SCSI_3W_SAS
tristate "3ware 97xx SAS/SATA-RAID support"
depends on PCI && SCSI
help
This driver supports the LSI 3ware 9750 6Gb/s SAS/SATA-RAID cards.
<http://www.lsi.com>
Please read the comments at the top of
<file:drivers/scsi/3w-sas.c>.
config SCSI_7000FASST config SCSI_7000FASST
tristate "7000FASST SCSI support" tristate "7000FASST SCSI support"
depends on ISA && SCSI && ISA_DMA_API depends on ISA && SCSI && ISA_DMA_API
...@@ -621,6 +632,14 @@ config SCSI_FLASHPOINT ...@@ -621,6 +632,14 @@ config SCSI_FLASHPOINT
substantial, so users of MultiMaster Host Adapters may not substantial, so users of MultiMaster Host Adapters may not
wish to include it. wish to include it.
config VMWARE_PVSCSI
tristate "VMware PVSCSI driver support"
depends on PCI && SCSI && X86
help
This driver supports VMware's para virtualized SCSI HBA.
To compile this driver as a module, choose M here: the
module will be called vmw_pvscsi.
config LIBFC config LIBFC
tristate "LibFC module" tristate "LibFC module"
select SCSI_FC_ATTRS select SCSI_FC_ATTRS
...@@ -644,7 +663,7 @@ config FCOE ...@@ -644,7 +663,7 @@ config FCOE
config FCOE_FNIC config FCOE_FNIC
tristate "Cisco FNIC Driver" tristate "Cisco FNIC Driver"
depends on PCI && X86 depends on PCI && X86
select LIBFC select LIBFCOE
help help
This is support for the Cisco PCI-Express FCoE HBA. This is support for the Cisco PCI-Express FCoE HBA.
...@@ -1818,6 +1837,14 @@ config SCSI_PMCRAID ...@@ -1818,6 +1837,14 @@ config SCSI_PMCRAID
---help--- ---help---
This driver supports the PMC SIERRA MaxRAID adapters. This driver supports the PMC SIERRA MaxRAID adapters.
config SCSI_PM8001
tristate "PMC-Sierra SPC 8001 SAS/SATA Based Host Adapter driver"
depends on PCI && SCSI
select SCSI_SAS_LIBSAS
help
This driver supports PMC-Sierra PCIE SAS/SATA 8x6G SPC 8001 chip
based host adapters.
config SCSI_SRP config SCSI_SRP
tristate "SCSI RDMA Protocol helper library" tristate "SCSI RDMA Protocol helper library"
depends on SCSI && PCI depends on SCSI && PCI
......
...@@ -70,6 +70,7 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/ ...@@ -70,6 +70,7 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic7xxx/
obj-$(CONFIG_SCSI_AACRAID) += aacraid/ obj-$(CONFIG_SCSI_AACRAID) += aacraid/
obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/ obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/
obj-$(CONFIG_SCSI_PM8001) += pm8001/
obj-$(CONFIG_SCSI_IPS) += ips.o obj-$(CONFIG_SCSI_IPS) += ips.o
obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
...@@ -113,6 +114,7 @@ obj-$(CONFIG_SCSI_MESH) += mesh.o ...@@ -113,6 +114,7 @@ obj-$(CONFIG_SCSI_MESH) += mesh.o
obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o
obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o
obj-$(CONFIG_SCSI_3W_SAS) += 3w-sas.o
obj-$(CONFIG_SCSI_PPA) += ppa.o obj-$(CONFIG_SCSI_PPA) += ppa.o
obj-$(CONFIG_SCSI_IMM) += imm.o obj-$(CONFIG_SCSI_IMM) += imm.o
obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o
...@@ -133,6 +135,7 @@ obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/ ...@@ -133,6 +135,7 @@ obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/
obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/ obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/ obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
obj-$(CONFIG_VMWARE_PVSCSI) += vmw_pvscsi.o
obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_ARM) += arm/
......
...@@ -472,8 +472,12 @@ static int aac_slave_configure(struct scsi_device *sdev) ...@@ -472,8 +472,12 @@ static int aac_slave_configure(struct scsi_device *sdev)
* total capacity and the queue depth supported by the target device. * total capacity and the queue depth supported by the target device.
*/ */
static int aac_change_queue_depth(struct scsi_device *sdev, int depth) static int aac_change_queue_depth(struct scsi_device *sdev, int depth,
int reason)
{ {
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
(sdev_channel(sdev) == CONTAINER_CHANNEL)) { (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
struct scsi_device * dev; struct scsi_device * dev;
......
...@@ -98,8 +98,11 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); ...@@ -98,8 +98,11 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
static const char *arcmsr_info(struct Scsi_Host *); static const char *arcmsr_info(struct Scsi_Host *);
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
int queue_depth) int queue_depth, int reason)
{ {
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth > ARCMSR_MAX_CMD_PERLUN) if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
queue_depth = ARCMSR_MAX_CMD_PERLUN; queue_depth = ARCMSR_MAX_CMD_PERLUN;
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
......
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/blk-iopoll.h>
#define FW_VER_LEN 32 #define FW_VER_LEN 32
#define MCC_Q_LEN 128
#define MCC_CQ_LEN 256
struct be_dma_mem { struct be_dma_mem {
void *va; void *va;
...@@ -74,18 +76,14 @@ static inline void queue_tail_inc(struct be_queue_info *q) ...@@ -74,18 +76,14 @@ static inline void queue_tail_inc(struct be_queue_info *q)
struct be_eq_obj { struct be_eq_obj {
struct be_queue_info q; struct be_queue_info q;
char desc[32]; struct beiscsi_hba *phba;
struct be_queue_info *cq;
/* Adaptive interrupt coalescing (AIC) info */ struct blk_iopoll iopoll;
bool enable_aic;
u16 min_eqd; /* in usecs */
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
}; };
struct be_mcc_obj { struct be_mcc_obj {
struct be_queue_info *q; struct be_queue_info q;
struct be_queue_info *cq; struct be_queue_info cq;
}; };
struct be_ctrl_info { struct be_ctrl_info {
...@@ -176,8 +174,4 @@ static inline void swap_dws(void *wrb, int len) ...@@ -176,8 +174,4 @@ static inline void swap_dws(void *wrb, int len)
} while (len); } while (len);
#endif /* __BIG_ENDIAN */ #endif /* __BIG_ENDIAN */
} }
extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
u16 num_popped);
#endif /* BEISCSI_H */ #endif /* BEISCSI_H */
此差异已折叠。
...@@ -47,6 +47,8 @@ struct be_mcc_wrb { ...@@ -47,6 +47,8 @@ struct be_mcc_wrb {
#define CQE_FLAGS_VALID_MASK (1 << 31) #define CQE_FLAGS_VALID_MASK (1 << 31)
#define CQE_FLAGS_ASYNC_MASK (1 << 30) #define CQE_FLAGS_ASYNC_MASK (1 << 30)
#define CQE_FLAGS_COMPLETED_MASK (1 << 28)
#define CQE_FLAGS_CONSUMED_MASK (1 << 27)
/* Completion Status */ /* Completion Status */
#define MCC_STATUS_SUCCESS 0x0 #define MCC_STATUS_SUCCESS 0x0
...@@ -173,7 +175,7 @@ struct be_cmd_req_hdr { ...@@ -173,7 +175,7 @@ struct be_cmd_req_hdr {
u8 domain; /* dword 0 */ u8 domain; /* dword 0 */
u32 timeout; /* dword 1 */ u32 timeout; /* dword 1 */
u32 request_length; /* dword 2 */ u32 request_length; /* dword 2 */
u32 rsvd; /* dword 3 */ u32 rsvd0; /* dword 3 */
}; };
struct be_cmd_resp_hdr { struct be_cmd_resp_hdr {
...@@ -382,7 +384,6 @@ struct be_cmd_req_modify_eq_delay { ...@@ -382,7 +384,6 @@ struct be_cmd_req_modify_eq_delay {
#define ETH_ALEN 6 #define ETH_ALEN 6
struct be_cmd_req_get_mac_addr { struct be_cmd_req_get_mac_addr {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u32 nic_port_count; u32 nic_port_count;
...@@ -417,14 +418,21 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, ...@@ -417,14 +418,21 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
int type); int type);
int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
struct be_queue_info *mccq,
struct be_queue_info *cq);
int be_poll_mcc(struct be_ctrl_info *ctrl); int be_poll_mcc(struct be_ctrl_info *ctrl);
unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl); unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr); struct beiscsi_hba *phba);
int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr);
/*ISCSI Functuions */ /*ISCSI Functuions */
int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba);
int be_mcc_notify_wait(struct beiscsi_hba *phba);
int be_mbox_notify(struct be_ctrl_info *ctrl); int be_mbox_notify(struct be_ctrl_info *ctrl);
...@@ -531,6 +539,23 @@ struct amap_sol_cqe { ...@@ -531,6 +539,23 @@ struct amap_sol_cqe {
u8 valid; /* dword 3 */ u8 valid; /* dword 3 */
} __packed; } __packed;
#define SOL_ICD_INDEX_MASK 0x0003FFC0
struct amap_sol_cqe_ring {
u8 hw_sts[8]; /* dword 0 */
u8 i_sts[8]; /* dword 0 */
u8 i_resp[8]; /* dword 0 */
u8 i_flags[7]; /* dword 0 */
u8 s; /* dword 0 */
u8 i_exp_cmd_sn[32]; /* dword 1 */
u8 code[6]; /* dword 2 */
u8 icd_index[12]; /* dword 2 */
u8 rsvd[6]; /* dword 2 */
u8 i_cmd_wnd[8]; /* dword 2 */
u8 i_res_cnt[31]; /* dword 3 */
u8 valid; /* dword 3 */
} __packed;
/** /**
* Post WRB Queue Doorbell Register used by the host Storage * Post WRB Queue Doorbell Register used by the host Storage
...@@ -664,8 +689,8 @@ struct be_fw_cfg { ...@@ -664,8 +689,8 @@ struct be_fw_cfg {
#define OPCODE_COMMON_TCP_UPLOAD 56 #define OPCODE_COMMON_TCP_UPLOAD 56
#define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
#define CMD_ISCSI_CONNECTION_INVALIDATE 1 #define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001
#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2 #define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002
#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
#define INI_WR_CMD 1 /* Initiator write command */ #define INI_WR_CMD 1 /* Initiator write command */
......
...@@ -67,11 +67,11 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, ...@@ -67,11 +67,11 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
} }
cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
shost, cmds_max, shost, cmds_max,
sizeof(*beiscsi_sess), sizeof(*beiscsi_sess),
sizeof(*io_task), sizeof(*io_task),
initial_cmdsn, ISCSI_MAX_TARGET); initial_cmdsn, ISCSI_MAX_TARGET);
if (!cls_session) if (!cls_session)
return NULL; return NULL;
sess = cls_session->dd_data; sess = cls_session->dd_data;
...@@ -297,7 +297,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, ...@@ -297,7 +297,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
switch (param) { switch (param) {
case ISCSI_HOST_PARAM_HWADDRESS: case ISCSI_HOST_PARAM_HWADDRESS:
be_cmd_get_mac_addr(&phba->ctrl, phba->mac_address); be_cmd_get_mac_addr(phba, phba->mac_address);
len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
break; break;
default: default:
...@@ -377,16 +377,12 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) ...@@ -377,16 +377,12 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct beiscsi_endpoint *beiscsi_ep; struct beiscsi_endpoint *beiscsi_ep;
struct beiscsi_offload_params params; struct beiscsi_offload_params params;
struct iscsi_session *session = conn->session;
struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
struct beiscsi_hba *phba = iscsi_host_priv(shost);
memset(&params, 0, sizeof(struct beiscsi_offload_params)); memset(&params, 0, sizeof(struct beiscsi_offload_params));
beiscsi_ep = beiscsi_conn->ep; beiscsi_ep = beiscsi_conn->ep;
if (!beiscsi_ep) if (!beiscsi_ep)
SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n"); SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle);
beiscsi_conn->login_in_progress = 0; beiscsi_conn->login_in_progress = 0;
beiscsi_set_params_for_offld(beiscsi_conn, &params); beiscsi_set_params_for_offld(beiscsi_conn, &params);
beiscsi_offload_connection(beiscsi_conn, &params); beiscsi_offload_connection(beiscsi_conn, &params);
...@@ -498,6 +494,13 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, ...@@ -498,6 +494,13 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
SE_DEBUG(DBG_LVL_1, "shost is NULL \n"); SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
return ERR_PTR(ret); return ERR_PTR(ret);
} }
if (phba->state) {
ret = -EBUSY;
SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n");
return ERR_PTR(ret);
}
ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
if (!ep) { if (!ep) {
ret = -ENOMEM; ret = -ENOMEM;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册