Commit 382f51fe authored by Linus Torvalds's avatar 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
  ...
parents 701791cc 54987386
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 -
(emaild-id:megaraidlinux@lsi.com)
......
......@@ -4196,6 +4196,13 @@ W: http://www.pmc-sierra.com/
S: Supported
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
M: Thomas Gleixner <tglx@linutronix.de>
S: Supported
......@@ -5772,6 +5779,14 @@ L: netdev@vger.kernel.org
S: Maintained
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
M: Liam Girdwood <lrg@slimlogic.co.uk>
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
......
......@@ -1208,6 +1208,7 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
* ata_scsi_change_queue_depth - SCSI callback for queue depth config
* @sdev: SCSI device to configure queue depth for
* @queue_depth: new queue depth
* @reason: calling context
*
* This is libata standard hostt->change_queue_depth callback.
* 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)
* RETURNS:
* 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_device *dev;
unsigned long flags;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (queue_depth < 1 || queue_depth == sdev->queue_depth)
return sdev->queue_depth;
......
......@@ -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));
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,
"Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
}
......
......@@ -625,6 +625,7 @@ static struct iscsi_transport iscsi_iser_transport = {
ISCSI_USERNAME | ISCSI_PASSWORD |
ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
ISCSI_PING_TMO | ISCSI_RECV_TMO |
ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
.host_param_mask = ISCSI_HOST_HWADDRESS |
......
......@@ -1116,8 +1116,9 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
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 priority_group *pg = pgpath->pg;
struct multipath *m = pg->m;
......@@ -1183,12 +1184,11 @@ static void pg_init_done(struct dm_path *path, int errors)
static void activate_path(struct work_struct *work)
{
int ret;
struct pgpath *pgpath =
container_of(work, struct pgpath, activate_path);
ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev));
pg_init_done(&pgpath->path, ret);
scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
pg_init_done, &pgpath->path);
}
/*
......
......@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.04.12"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.12"
#define MPT_LINUX_VERSION_COMMON "3.04.13"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.13"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......
......@@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX);
(iocp == NULL))
return -ENODEV;
}
if (!iocp->active) {
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)
* precedence!
*/
sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
/* Have already saved the status and sense data
if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
/*
* 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.
*/
;
} else {
if (ioc->bus_type == SPI) {
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 (scsi_status == 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)
sc->result = (DID_OK << 16) | scsi_status;
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,
* may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
......@@ -2275,11 +2351,12 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
* mptscsih_change_queue_depth - This function will set a devices queue depth
* @sdev: per scsi_device pointer
* @qdepth: requested queue depth
* @reason: calling context
*
* Adding support for new 'change_queue_depth' api.
*/
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);
VirtTarget *vtarget;
......@@ -2291,6 +2368,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
starget = scsi_target(sdev);
vtarget = starget->hostdata;
if (reason != SCSI_QDEPTH_DEFAULT)
return -EOPNOTSUPP;
if (ioc->bus_type == SPI) {
if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
max_depth = 1;
......@@ -2357,7 +2437,8 @@ mptscsih_slave_configure(struct scsi_device *sdev)
ioc->name, vtarget->negoFlags, vtarget->maxOffset,
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
"tagged %d, simple %d, ordered %d\n",
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
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_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 int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
extern struct device_attribute *mptscsih_host_attrs[];
......
This diff is collapsed.
......@@ -13,28 +13,34 @@
#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);
if (!adapter)
return 0;
mutex_lock(&zfcp_data.config_mutex);
struct zfcp_adapter *adapter;
unsigned long flags;
zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
zfcp_erp_wait(adapter);
spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags);
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)
{
struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
return 0;
......@@ -46,6 +52,8 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
zfcp_erp_wait(adapter);
flush_work(&adapter->scan_work);
zfcp_ccw_adapter_put(adapter);
return 0;
}
......@@ -67,28 +75,28 @@ int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
/**
* 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
* device found on the current system. This is only a stub to make cio
* work: To only allocate adapter resources for devices actually used,
* 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;
}
/**
* 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
* 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
* 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_port *port, *p;
......@@ -96,49 +104,37 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
LIST_HEAD(unit_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 = dev_get_drvdata(&ccw_device->dev);
adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
goto out;
mutex_unlock(&zfcp_data.config_mutex);
return;
cancel_work_sync(&adapter->scan_work);
mutex_lock(&zfcp_data.config_mutex);
/* 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) {
write_lock_irq(&adapter->port_list_lock);
list_for_each_entry_safe(port, p, &adapter->port_list, list) {
write_lock(&port->unit_list_lock);
list_for_each_entry_safe(unit, u, &port->unit_list, list)
list_move(&unit->list, &unit_remove_lh);
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
&unit->status);
}
write_unlock(&port->unit_list_lock);
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(&zfcp_data.config_lock);
write_unlock_irq(&adapter->port_list_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)
zfcp_unit_dequeue(unit);
zfcp_port_dequeue(port);
}
wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
zfcp_adapter_dequeue(adapter);
zfcp_device_unregister(&unit->sysfs_device,
&zfcp_sysfs_unit_attrs);
out:
mutex_unlock(&zfcp_data.config_mutex);
list_for_each_entry_safe(port, p, &port_remove_lh, list)
zfcp_device_unregister(&port->sysfs_device,
&zfcp_sysfs_port_attrs);
zfcp_adapter_unregister(adapter);
}
/**
* 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
* adapter into state online. The first call will allocate all
......@@ -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
* 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;
int ret = 0;
mutex_lock(&zfcp_data.config_mutex);
adapter = dev_get_drvdata(&ccw_device->dev);
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter) {
ret = zfcp_adapter_enqueue(ccw_device);
if (ret) {
dev_err(&ccw_device->dev,
adapter = zfcp_adapter_enqueue(cdev);
if (IS_ERR(adapter)) {
dev_err(&cdev->dev,
"Setting up data structures for the "
"FCP adapter failed\n");
goto out;
return PTR_ERR(adapter);
}
adapter = dev_get_drvdata(&ccw_device->dev);
kref_get(&adapter->ref);
}
/* initialize request counter */
......@@ -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,
"ccsonl2", NULL);
zfcp_erp_wait(adapter);
out:
mutex_unlock(&zfcp_data.config_mutex);
if (!ret)
flush_work(&adapter->scan_work);
return ret;
zfcp_ccw_adapter_put(adapter);
return 0;
}
/**
* 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
* 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_wait(adapter);
mutex_unlock(&zfcp_data.config_mutex);
zfcp_ccw_adapter_put(adapter);
return 0;
}
/**
* 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
*
* This function gets called by the common i/o layer if an adapter has gone
* 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) {
case CIO_GONE:
dev_warn(&adapter->ccw_device->dev,
"The FCP device has been detached\n");
dev_warn(&cdev->dev, "The FCP device has been detached\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
break;
case CIO_NO_PATH:
dev_warn(&adapter->ccw_device->dev,
dev_warn(&cdev->dev,
"The CHPID for the FCP device is offline\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
break;
case CIO_OPER:
dev_info(&adapter->ccw_device->dev,
"The FCP device is operational again\n");
dev_info(&cdev->dev, "The FCP device is operational again\n");
zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
ZFCP_STATUS_COMMON_RUNNING,
ZFCP_SET);
......@@ -236,11 +232,13 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
"ccnoti4", NULL);
break;
case CIO_BOXED:
dev_warn(&adapter->ccw_device->dev, "The FCP device "
"did not respond within the specified time\n");
dev_warn(&cdev->dev, "The FCP device did not respond within "
"the specified time\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
break;
}
zfcp_ccw_adapter_put(adapter);
return 1;
}
......@@ -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)
{
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)
goto out;
return;
zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter);
out:
mutex_unlock(&zfcp_data.config_mutex);
zfcp_ccw_adapter_put(adapter);
}
struct ccw_driver zfcp_ccw_driver = {
......@@ -274,18 +270,7 @@ struct ccw_driver zfcp_ccw_driver = {
.set_offline = zfcp_ccw_set_offline,
.notify = zfcp_ccw_notify,
.shutdown = zfcp_ccw_shutdown,
.freeze = zfcp_ccw_suspend,
.freeze = zfcp_ccw_set_offline,
.thaw = 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,
static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
{
char busid[9];
struct ccw_device *ccwdev;
struct zfcp_adapter *adapter = NULL;
struct ccw_device *cdev;
struct zfcp_adapter *adapter;
snprintf(busid, sizeof(busid), "0.0.%04x", devno);
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (!ccwdev)
goto out;
adapter = dev_get_drvdata(&ccwdev->dev);
if (!adapter)
goto out_put;
zfcp_adapter_get(adapter);
out_put:
put_device(&ccwdev->dev);
out:
cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
if (!cdev)
return NULL;
adapter = zfcp_ccw_adapter_by_cdev(cdev);
put_device(&cdev->dev);
return adapter;
}
......@@ -212,7 +207,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
retval = -ENXIO;
goto free_buffer;
}
zfcp_adapter_get(adapter);
retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
data_user->control_file);
......@@ -245,7 +239,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
free_sg:
zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
adapter_put:
zfcp_adapter_put(adapter);
zfcp_ccw_adapter_put(adapter);
free_buffer:
kfree(data);
no_mem_sense:
......
This diff is collapsed.
......@@ -22,6 +22,7 @@
#ifndef ZFCP_DBF_H
#define ZFCP_DBF_H
#include <scsi/fc/fc_fcp.h>
#include "zfcp_ext.h"
#include "zfcp_fsf.h"
#include "zfcp_def.h"
......@@ -122,7 +123,6 @@ struct zfcp_dbf_hba_record_response {
} unit;
struct {
u32 d_id;
u8 ls_code;
} els;
} u;
} __attribute__ ((packed));
......@@ -166,6 +166,7 @@ struct zfcp_dbf_san_record_ct_request {
u8 options;
u16 max_res_size;
u32 len;
u32 d_id;
} __attribute__ ((packed));
struct zfcp_dbf_san_record_ct_response {
......@@ -179,16 +180,13 @@ struct zfcp_dbf_san_record_ct_response {
} __attribute__ ((packed));
struct zfcp_dbf_san_record_els {
u8 ls_code;
u32 len;
u32 d_id;
} __attribute__ ((packed));
struct zfcp_dbf_san_record {
u8 tag[ZFCP_DBF_TAG_SIZE];
u64 fsf_reqid;
u32 fsf_seqno;
u32 s_id;
u32 d_id;
union {
struct zfcp_dbf_san_record_ct_request ct_req;
struct zfcp_dbf_san_record_ct_response ct_resp;
......@@ -343,7 +341,7 @@ static inline
void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
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);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -9,26 +9,31 @@
#ifndef ZFCP_EXT_H
#define ZFCP_EXT_H
#include <linux/types.h>
#include <scsi/fc/fc_els.h>
#include "zfcp_def.h"
#include "zfcp_fc.h"
/* zfcp_aux.c */
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 int zfcp_adapter_enqueue(struct ccw_device *);
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
u32);
extern void zfcp_port_dequeue(struct zfcp_port *);
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 void zfcp_sg_free_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 */
extern int zfcp_ccw_register(void);
extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
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 */
extern struct miscdevice zfcp_cfdc_misc;
......@@ -51,7 +56,7 @@ extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *,
struct fsf_status_read_buffer *);
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_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_els_request(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 *,
extern void zfcp_erp_timeout_handler(unsigned long);
/* zfcp_fc.c */
extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
extern void _zfcp_fc_scan_ports_later(struct work_struct *);
extern void zfcp_fc_scan_ports(struct work_struct *);
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fc_port_did_lookup(struct work_struct *);
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_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 void zfcp_fc_gs_destroy(struct zfcp_adapter *);
extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *);
extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
/* zfcp_fsf.c */
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_close_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_fc_wka_port *);
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_open_unit(struct zfcp_erp_action *);
......@@ -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 int zfcp_fsf_status_read(struct zfcp_qdio *);
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_els(struct zfcp_send_els *);
extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_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 *,
struct scsi_cmnd *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
......@@ -153,7 +158,6 @@ extern void zfcp_qdio_close(struct zfcp_qdio *);
extern struct zfcp_data zfcp_data;
extern int zfcp_adapter_scsi_register(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 void zfcp_scsi_rport_work(struct work_struct *);
extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
......
This diff is collapsed.
/*
* 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
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include <linux/pfn.h>
#include <linux/scatterlist.h>
#include <scsi/libfc.h>
#define FSF_QTCB_CURRENT_VERSION 0x00000001
......@@ -228,7 +229,8 @@ struct fsf_status_read_buffer {
u32 length;
u32 res1;
struct fsf_queue_designator queue_designator;
u32 d_id;
u8 res2;
u8 d_id[3];
u32 class;
u64 fcp_lun;
u8 res3[24];
......@@ -309,22 +311,7 @@ struct fsf_qtcb_header {
u8 res4[16];
} __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
struct fsf_plogi {
u32 code;
struct fsf_nport_serv_param serv_param;
} __attribute__ ((packed));
#define FSF_FCP_CMND_SIZE 288
#define FSF_FCP_RSP_SIZE 128
......@@ -342,8 +329,8 @@ struct fsf_qtcb_bottom_io {
struct fsf_qtcb_bottom_support {
u32 operation_subtype;
u8 res1[12];
u32 d_id;
u8 res1[13];
u8 d_id[3];
u32 option;
u64 fcp_lun;
u64 res2;
......@@ -372,18 +359,18 @@ struct fsf_qtcb_bottom_config {
u32 fc_topology;
u32 fc_link_speed;
u32 adapter_type;
u32 peer_d_id;
u8 res0;
u8 peer_d_id[3];
u8 res1[2];
u16 timer_interval;
u8 res2[8];
u32 s_id;
struct fsf_nport_serv_param nport_serv_param;
u8 reserved_nport_serv_param[16];
u8 res2[9];
u8 s_id[3];
u8 nport_serv_param[128];
u8 res3[8];
u32 adapter_ports;
u32 hardware_version;
u8 serial_number[32];
struct fsf_nport_serv_param plogi_payload;
u8 plogi_payload[112];
struct fsf_statistics_info stat_info;
u8 res4[112];
} __attribute__ ((packed));
......@@ -450,4 +437,22 @@ struct zfcp_blk_drv_data {
u64 fabric_lat;
} __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 */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment