From 8377dbc3cd376070145061212283c9e4a5afeb09 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 26 Apr 2013 16:13:47 +0200 Subject: [SCSI] zfcp: cfdc fops add owner Set the owner member of zfcp_cfdc_fops, to ensure that the caller of these functions holds a module reference. Signed-off-by: Sebastian Ott Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_cfdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 49b82e4..b46f54e 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +251,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, } static const struct file_operations zfcp_cfdc_fops = { + .owner = THIS_MODULE, .open = nonseekable_open, .unlocked_ioctl = zfcp_cfdc_dev_ioctl, #ifdef CONFIG_COMPAT -- cgit v1.1 From 83d4e1c33d9329e6d53cf4ac0a02c98ac83eba05 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 26 Apr 2013 16:13:48 +0200 Subject: [SCSI] zfcp: cleanup port sysfs attribute usage Let the driver core handle device attribute creation and removal. This will simplify the code and eliminates races between attribute availability and userspace notification via uevents. Reviewed-by: Steffen Maier Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 7 +------ drivers/s390/scsi/zfcp_ccw.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 2 +- drivers/s390/scsi/zfcp_fc.c | 2 +- drivers/s390/scsi/zfcp_sysfs.c | 12 ++++++------ 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index f6adde4..aa2aee6 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -530,6 +530,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, port->wwpn = wwpn; port->rport_task = RPORT_NONE; port->dev.parent = &adapter->ccw_device->dev; + port->dev.groups = zfcp_port_attr_groups; port->dev.release = zfcp_port_release; if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { @@ -543,10 +544,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, goto err_out; } - if (sysfs_create_group(&port->dev.kobj, - &zfcp_sysfs_port_attrs)) - goto err_out_put; - write_lock_irq(&adapter->port_list_lock); list_add_tail(&port->list, &adapter->port_list); write_unlock_irq(&adapter->port_list_lock); @@ -555,8 +552,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, return port; -err_out_put: - device_unregister(&port->dev); err_out: zfcp_ccw_adapter_put(adapter); return ERR_PTR(retval); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index f2dd3a0..202f395 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -132,7 +132,7 @@ static void zfcp_ccw_remove(struct ccw_device *cdev) zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); list_for_each_entry_safe(port, p, &port_remove_lh, list) - zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); + device_unregister(&port->dev); zfcp_adapter_unregister(adapter); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 1d3dd3f..695b133 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -160,7 +160,7 @@ extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); /* zfcp_sysfs.c */ extern struct attribute_group zfcp_sysfs_unit_attrs; extern struct attribute_group zfcp_sysfs_adapter_attrs; -extern struct attribute_group zfcp_sysfs_port_attrs; +extern const struct attribute_group *zfcp_port_attr_groups[]; extern struct mutex zfcp_sysfs_port_units_mutex; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index ff598cd..ca28e1c 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -668,7 +668,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req, list_for_each_entry_safe(port, tmp, &remove_lh, list) { zfcp_erp_port_shutdown(port, 0, "fcegpf2"); - zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); + device_unregister(&port->dev); } return ret; diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 1e0eb08..d926126 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -268,7 +268,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, put_device(&port->dev); zfcp_erp_port_shutdown(port, 0, "syprs_1"); - zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); + device_unregister(&port->dev); out: zfcp_ccw_adapter_put(adapter); return retval ? retval : (ssize_t) count; @@ -340,13 +340,13 @@ static struct attribute *zfcp_port_attrs[] = { &dev_attr_port_access_denied.attr, NULL }; - -/** - * zfcp_sysfs_port_attrs - sysfs attributes for all other ports - */ -struct attribute_group zfcp_sysfs_port_attrs = { +static struct attribute_group zfcp_port_attr_group = { .attrs = zfcp_port_attrs, }; +const struct attribute_group *zfcp_port_attr_groups[] = { + &zfcp_port_attr_group, + NULL, +}; static struct attribute *zfcp_unit_attrs[] = { &dev_attr_unit_failed.attr, -- cgit v1.1 From 86bdf218a717b77cb775b82ce48c7847cb72a86d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 26 Apr 2013 16:13:49 +0200 Subject: [SCSI] zfcp: cleanup unit sysfs attribute usage Let the driver core handle device attribute creation and removal. This will simplify the code and eliminates races between attribute availability and userspace notification via uevents. Reviewed-by: Steffen Maier Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_ccw.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 2 +- drivers/s390/scsi/zfcp_sysfs.c | 7 +++++-- drivers/s390/scsi/zfcp_unit.c | 9 ++------- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 202f395..8e71d35 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -129,7 +129,7 @@ static void zfcp_ccw_remove(struct ccw_device *cdev) zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */ list_for_each_entry_safe(unit, u, &unit_remove_lh, list) - zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); + device_unregister(&unit->dev); list_for_each_entry_safe(port, p, &port_remove_lh, list) device_unregister(&port->dev); diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 695b133..b993d11 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -158,7 +158,7 @@ extern void zfcp_scsi_set_prot(struct zfcp_adapter *); extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); /* zfcp_sysfs.c */ -extern struct attribute_group zfcp_sysfs_unit_attrs; +extern const struct attribute_group *zfcp_unit_attr_groups[]; extern struct attribute_group zfcp_sysfs_adapter_attrs; extern const struct attribute_group *zfcp_port_attr_groups[]; extern struct mutex zfcp_sysfs_port_units_mutex; diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index d926126..05423ac 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -357,10 +357,13 @@ static struct attribute *zfcp_unit_attrs[] = { &dev_attr_unit_access_readonly.attr, NULL }; - -struct attribute_group zfcp_sysfs_unit_attrs = { +static struct attribute_group zfcp_unit_attr_group = { .attrs = zfcp_unit_attrs, }; +const struct attribute_group *zfcp_unit_attr_groups[] = { + &zfcp_unit_attr_group, + NULL, +}; #define ZFCP_DEFINE_LATENCY_ATTR(_name) \ static ssize_t \ diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c index 1cd2b99..39f5446 100644 --- a/drivers/s390/scsi/zfcp_unit.c +++ b/drivers/s390/scsi/zfcp_unit.c @@ -145,6 +145,7 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) unit->fcp_lun = fcp_lun; unit->dev.parent = &port->dev; unit->dev.release = zfcp_unit_release; + unit->dev.groups = zfcp_unit_attr_groups; INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work); if (dev_set_name(&unit->dev, "0x%016llx", @@ -160,12 +161,6 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) goto out; } - if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) { - device_unregister(&unit->dev); - retval = -EINVAL; - goto out; - } - atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */ write_lock_irq(&port->unit_list_lock); @@ -254,7 +249,7 @@ int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun) put_device(&unit->dev); - zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); + device_unregister(&unit->dev); return 0; } -- cgit v1.1 From bd3238667ba76026bb543a953d63c11c4d52f28d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 26 Apr 2013 16:13:50 +0200 Subject: [SCSI] zfcp: remove unused device_unregister wrapper Remove the now unused function zfcp_device_unregister since all users have been converted to use device_unregister directly. Reviewed-by: Steffen Maier Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 14 -------------- drivers/s390/scsi/zfcp_ext.h | 2 -- 2 files changed, 16 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index aa2aee6..3a8c1b7 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -464,20 +464,6 @@ void zfcp_adapter_release(struct kref *ref) put_device(&cdev->dev); } -/** - * zfcp_device_unregister - remove port, unit from system - * @dev: reference to device which is to be removed - * @grp: related reference to attribute group - * - * Helper function to unregister port, unit from system - */ -void zfcp_device_unregister(struct device *dev, - const struct attribute_group *grp) -{ - sysfs_remove_group(&dev->kobj, grp); - device_unregister(dev); -} - static void zfcp_port_release(struct device *dev) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index b993d11..248578d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -21,8 +21,6 @@ extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, u32); 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 *); -- cgit v1.1 From f76ccaac4f82c463a037aa4a1e4ccb85c7011814 Mon Sep 17 00:00:00 2001 From: Daniel Hansel Date: Fri, 26 Apr 2013 17:32:14 +0200 Subject: [SCSI] zfcp: fix adapter (re)open recovery while link to SAN is down FCP device remains in status ERP_FAILED when device is switched online or adapter recovery is triggered while link to SAN is down. When Exchange Configuration Data command returns the FSF status FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE it aborts the exchange process. The only retries are done during the common error recovery procedure (i.e. max. 3 retries with 8sec sleep between) and remains in status ERP_FAILED with QDIO down. This commit reverts the commit 0df138476c8306478d6e726f044868b4bccf411c (zfcp: Fix adapter activation on link down). When FSF status FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE is received the adapter recovery will be finished without any retries. QDIO will be up now and status changes such as LINK UP will be received now. Signed-off-by: Daniel Hansel Signed-off-by: Steffen Maier Cc: #2.6.37+ Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c7e148f..06760e4 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -563,6 +563,10 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; adapter->hydra_version = 0; + /* avoids adapter shutdown to be able to recognize + * events such as LINK UP */ + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); break; -- cgit v1.1 From 5fea4291deacd80188b996d2f555fc6a1940e5d4 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 26 Apr 2013 17:33:45 +0200 Subject: [SCSI] zfcp: block queue limits with data router Commit 86a9668a8d29ea711613e1cb37efa68e7c4db564 "[SCSI] zfcp: support for hardware data router" reduced the initial block queue limits in the scsi_host_template to the absolute minimum and adjusted them later on. However, the adjustment was too late for the BSG devices of Scsi_Host and fc_host. Therefore, ioctl(..., SG_IO, ...) with request or response size > 4kB to a BSG device of an fc_host or a Scsi_Host fails with EINVAL. As a result, users of such ioctl such as HBA_SendCTPassThru() in libzfcphbaapi return with error HBA_STATUS_ERROR. Initialize the block queue limits in zfcp_scsi_host_template to the greatest common denominator (GCD). While we cannot exploit the slightly enlarged maximum request size with data router, this should be neglectible. Doing so also avoids running into trouble after live guest relocation (LGR) / migration from a data router FCP device to an FCP device that does not support data router. In that case, zfcp would figure out the new limits on adapter recovery, but the fc_host and Scsi_Host (plus in fact all sdevs) still exist with the old and now too large queue limits. It should also OK, not to use half the size as in the DIX case, because fc_host and Scsi_Host do not transport FCP requests including SCSI commands using protection data. Signed-off-by: Steffen Maier Reviewed-by: Martin Peschke Cc: #3.2+ Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_scsi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 7b31e3f..7b35364 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -3,7 +3,7 @@ * * Interface to Linux SCSI midlayer. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -311,8 +311,12 @@ static struct scsi_host_template zfcp_scsi_host_template = { .proc_name = "zfcp", .can_queue = 4096, .this_id = -1, - .sg_tablesize = 1, /* adjusted later */ - .max_sectors = 8, /* adjusted later */ + .sg_tablesize = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1) + * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2), + /* GCD, adjusted later */ + .max_sectors = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1) + * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8, + /* GCD, adjusted later */ .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, .cmd_per_lun = 1, .use_clustering = 1, -- cgit v1.1 From bf3ea3aec568a9f10a9fea3f3f0a290a94d5cc12 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 26 Apr 2013 16:13:53 +0200 Subject: [SCSI] zfcp: module parameter dbflevel for early debugging So far, we could only increase the s390dbf log level after an FCP device has been initially set online for it to create the dbf entries required to adjust the level. Introduce zfcp.dbflevel as counterpart to the already existing zfcp.dbfsize to enable debugging of e.g. setting an FCP device online. Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_dbf.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index e1a8cc2..132a905 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -3,7 +3,7 @@ * * Debug traces for zfcp. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -23,6 +23,13 @@ module_param(dbfsize, uint, 0400); MODULE_PARM_DESC(dbfsize, "number of pages for each debug feature area (default 4)"); +static u32 dbflevel = 3; + +module_param(dbflevel, uint, 0400); +MODULE_PARM_DESC(dbflevel, + "log level for each debug feature area " + "(default 3, range 0..6)"); + static inline unsigned int zfcp_dbf_plen(unsigned int offset) { return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC; @@ -447,7 +454,7 @@ static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size) return NULL; debug_register_view(d, &debug_hex_ascii_view); - debug_set_level(d, 3); + debug_set_level(d, dbflevel); return d; } -- cgit v1.1 From 663e0890e31cb85f0cca5ac1faaee0d2d52880b5 Mon Sep 17 00:00:00 2001 From: Martin Peschke Date: Fri, 26 Apr 2013 16:13:54 +0200 Subject: [SCSI] zfcp: remove access control tables interface This patch removes an interface that was used to manage access control tables within the HBA. The patch consequently removes the handling for conditions related to those access control tables, too. That initiator-based access control feature was only needed until the introduction of NPIV and was withdrawn with z10 years ago. It's time to cleanup the corresponding device driver code. Signed-off-by: Martin Peschke Signed-off-by: Steffen Maier Signed-off-by: James Bottomley --- drivers/s390/scsi/Makefile | 2 +- drivers/s390/scsi/zfcp_aux.c | 10 - drivers/s390/scsi/zfcp_ccw.c | 9 - drivers/s390/scsi/zfcp_cfdc.c | 448 ----------------------------------------- drivers/s390/scsi/zfcp_def.h | 4 - drivers/s390/scsi/zfcp_erp.c | 3 +- drivers/s390/scsi/zfcp_ext.h | 14 -- drivers/s390/scsi/zfcp_fsf.c | 127 ++---------- drivers/s390/scsi/zfcp_fsf.h | 26 --- drivers/s390/scsi/zfcp_sysfs.c | 8 - 10 files changed, 15 insertions(+), 636 deletions(-) delete mode 100644 drivers/s390/scsi/zfcp_cfdc.c diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index c454ffe..9259039 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -2,7 +2,7 @@ # Makefile for the S/390 specific device drivers # -zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \ +zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_dbf.o zfcp_erp.o \ zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \ zfcp_unit.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 3a8c1b7..19fe0df 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -140,13 +140,6 @@ static int __init zfcp_module_init(void) scsi_transport_reserve_device(zfcp_scsi_transport_template, sizeof(struct zfcp_scsi_dev)); - - retval = misc_register(&zfcp_cfdc_misc); - if (retval) { - pr_err("Registering the misc device zfcp_cfdc failed\n"); - goto out_misc; - } - retval = ccw_driver_register(&zfcp_ccw_driver); if (retval) { pr_err("The zfcp device driver could not register with " @@ -159,8 +152,6 @@ static int __init zfcp_module_init(void) return 0; out_ccw_register: - misc_deregister(&zfcp_cfdc_misc); -out_misc: fc_release_transport(zfcp_scsi_transport_template); out_transport: kmem_cache_destroy(zfcp_fc_req_cache); @@ -175,7 +166,6 @@ module_init(zfcp_module_init); static void __exit zfcp_module_exit(void) { ccw_driver_unregister(&zfcp_ccw_driver); - misc_deregister(&zfcp_cfdc_misc); fc_release_transport(zfcp_scsi_transport_template); kmem_cache_destroy(zfcp_fc_req_cache); kmem_cache_destroy(zfcp_fsf_qtcb_cache); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 8e71d35..f9879d4 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -72,15 +72,6 @@ static struct ccw_device_id zfcp_ccw_device_id[] = { MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); /** - * zfcp_ccw_priv_sch - check if subchannel is privileged - * @adapter: Adapter/Subchannel to check - */ -int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter) -{ - return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV; -} - -/** * zfcp_ccw_probe - probe function of zfcp driver * @cdev: pointer to belonging ccw device * diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c deleted file mode 100644 index b46f54e..0000000 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * zfcp device driver - * - * Userspace interface for accessing the - * Access Control Lists / Control File Data Channel; - * handling of response code and states for ports and LUNs. - * - * Copyright IBM Corp. 2008, 2010 - */ - -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include "zfcp_def.h" -#include "zfcp_ext.h" -#include "zfcp_fsf.h" - -#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL 0x00010001 -#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE 0x00010101 -#define ZFCP_CFDC_CMND_FULL_ACCESS 0x00000201 -#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS 0x00000401 -#define ZFCP_CFDC_CMND_UPLOAD 0x00010002 - -#define ZFCP_CFDC_DOWNLOAD 0x00000001 -#define ZFCP_CFDC_UPLOAD 0x00000002 -#define ZFCP_CFDC_WITH_CONTROL_FILE 0x00010000 - -#define ZFCP_CFDC_IOC_MAGIC 0xDD -#define ZFCP_CFDC_IOC \ - _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data) - -/** - * struct zfcp_cfdc_data - data for ioctl cfdc interface - * @signature: request signature - * @devno: FCP adapter device number - * @command: command code - * @fsf_status: returns status of FSF command to userspace - * @fsf_status_qual: returned to userspace - * @payloads: access conflicts list - * @control_file: access control table - */ -struct zfcp_cfdc_data { - u32 signature; - u32 devno; - u32 command; - u32 fsf_status; - u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; - u8 payloads[256]; - u8 control_file[0]; -}; - -static int zfcp_cfdc_copy_from_user(struct scatterlist *sg, - void __user *user_buffer) -{ - unsigned int length; - unsigned int size = ZFCP_CFDC_MAX_SIZE; - - while (size) { - length = min((unsigned int)size, sg->length); - if (copy_from_user(sg_virt(sg++), user_buffer, length)) - return -EFAULT; - user_buffer += length; - size -= length; - } - return 0; -} - -static int zfcp_cfdc_copy_to_user(void __user *user_buffer, - struct scatterlist *sg) -{ - unsigned int length; - unsigned int size = ZFCP_CFDC_MAX_SIZE; - - while (size) { - length = min((unsigned int) size, sg->length); - if (copy_to_user(user_buffer, sg_virt(sg++), length)) - return -EFAULT; - user_buffer += length; - size -= length; - } - return 0; -} - -static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) -{ - char busid[9]; - struct ccw_device *cdev; - struct zfcp_adapter *adapter; - - snprintf(busid, sizeof(busid), "0.0.%04x", devno); - 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; -} - -static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) -{ - switch (command) { - case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_NORMAL_MODE; - break; - case ZFCP_CFDC_CMND_DOWNLOAD_FORCE: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_FORCE; - break; - case ZFCP_CFDC_CMND_FULL_ACCESS: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_FULL_ACCESS; - break; - case ZFCP_CFDC_CMND_RESTRICTED_ACCESS: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_RESTRICTED_ACCESS; - break; - case ZFCP_CFDC_CMND_UPLOAD: - fsf_cfdc->command = FSF_QTCB_UPLOAD_CONTROL_FILE; - fsf_cfdc->option = 0; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg, - u8 __user *control_file) -{ - int retval; - retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES); - if (retval) - return retval; - - sg[ZFCP_CFDC_PAGES - 1].length = ZFCP_CFDC_MAX_SIZE % PAGE_SIZE; - - if (command & ZFCP_CFDC_WITH_CONTROL_FILE && - command & ZFCP_CFDC_DOWNLOAD) { - retval = zfcp_cfdc_copy_from_user(sg, control_file); - if (retval) { - zfcp_sg_free_table(sg, ZFCP_CFDC_PAGES); - return -EFAULT; - } - } - - return 0; -} - -static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data, - struct zfcp_fsf_req *req) -{ - data->fsf_status = req->qtcb->header.fsf_status; - memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual, - sizeof(union fsf_status_qual)); - memcpy(&data->payloads, &req->qtcb->bottom.support.els, - sizeof(req->qtcb->bottom.support.els)); -} - -static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, - unsigned long arg) -{ - struct zfcp_cfdc_data *data; - struct zfcp_cfdc_data __user *data_user; - struct zfcp_adapter *adapter; - struct zfcp_fsf_req *req; - struct zfcp_fsf_cfdc *fsf_cfdc; - int retval; - - if (command != ZFCP_CFDC_IOC) - return -ENOTTY; - - if (is_compat_task()) - data_user = compat_ptr(arg); - else - data_user = (void __user *)arg; - - if (!data_user) - return -EINVAL; - - fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL); - if (!fsf_cfdc) - return -ENOMEM; - - data = memdup_user(data_user, sizeof(*data_user)); - if (IS_ERR(data)) { - retval = PTR_ERR(data); - goto no_mem_sense; - } - - if (data->signature != 0xCFDCACDF) { - retval = -EINVAL; - goto free_buffer; - } - - retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command); - - adapter = zfcp_cfdc_get_adapter(data->devno); - if (!adapter) { - retval = -ENXIO; - goto free_buffer; - } - - retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg, - data_user->control_file); - if (retval) - goto adapter_put; - req = zfcp_fsf_control_file(adapter, fsf_cfdc); - if (IS_ERR(req)) { - retval = PTR_ERR(req); - goto free_sg; - } - - if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { - retval = -ENXIO; - goto free_fsf; - } - - zfcp_cfdc_req_to_sense(data, req); - retval = copy_to_user(data_user, data, sizeof(*data_user)); - if (retval) { - retval = -EFAULT; - goto free_fsf; - } - - if (data->command & ZFCP_CFDC_UPLOAD) - retval = zfcp_cfdc_copy_to_user(&data_user->control_file, - fsf_cfdc->sg); - - free_fsf: - zfcp_fsf_req_free(req); - free_sg: - zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES); - adapter_put: - zfcp_ccw_adapter_put(adapter); - free_buffer: - kfree(data); - no_mem_sense: - kfree(fsf_cfdc); - return retval; -} - -static const struct file_operations zfcp_cfdc_fops = { - .owner = THIS_MODULE, - .open = nonseekable_open, - .unlocked_ioctl = zfcp_cfdc_dev_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = zfcp_cfdc_dev_ioctl, -#endif - .llseek = no_llseek, -}; - -struct miscdevice zfcp_cfdc_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "zfcp_cfdc", - .fops = &zfcp_cfdc_fops, -}; - -/** - * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT - * @adapter: Adapter where the Access Control Table (ACT) changed - * - * After a change in the adapter ACT, check if access to any - * previously denied resources is now possible. - */ -void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) -{ - unsigned long flags; - struct zfcp_port *port; - struct scsi_device *sdev; - struct zfcp_scsi_dev *zfcp_sdev; - int status; - - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - return; - - read_lock_irqsave(&adapter->port_list_lock, flags); - list_for_each_entry(port, &adapter->port_list, list) { - status = atomic_read(&port->status); - if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || - (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) - zfcp_erp_port_reopen(port, - ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_1"); - } - read_unlock_irqrestore(&adapter->port_list_lock, flags); - - shost_for_each_device(sdev, adapter->scsi_host) { - zfcp_sdev = sdev_to_zfcp(sdev); - status = atomic_read(&zfcp_sdev->status); - if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || - (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) - zfcp_erp_lun_reopen(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_2"); - } -} - -static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) -{ - u16 subtable = table >> 16; - u16 rule = table & 0xffff; - const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; - - if (subtable && subtable < ARRAY_SIZE(act_type)) - dev_warn(&adapter->ccw_device->dev, - "Access denied according to ACT rule type %s, " - "rule %d\n", act_type[subtable], rule); -} - -/** - * zfcp_cfdc_port_denied - Process "access denied" for port - * @port: The port where the access has been denied - * @qual: The FSF status qualifier for the access denied FSF status - */ -void zfcp_cfdc_port_denied(struct zfcp_port *port, - union fsf_status_qual *qual) -{ - dev_warn(&port->adapter->ccw_device->dev, - "Access denied to port 0x%016Lx\n", - (unsigned long long)port->wwpn); - - zfcp_act_eval_err(port->adapter, qual->halfword[0]); - zfcp_act_eval_err(port->adapter, qual->halfword[1]); - zfcp_erp_set_port_status(port, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); -} - -/** - * zfcp_cfdc_lun_denied - Process "access denied" for LUN - * @sdev: The SCSI device / LUN where the access has been denied - * @qual: The FSF status qualifier for the access denied FSF status - */ -void zfcp_cfdc_lun_denied(struct scsi_device *sdev, - union fsf_status_qual *qual) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - - dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, - "Access denied to LUN 0x%016Lx on port 0x%016Lx\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]); - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]); - zfcp_erp_set_lun_status(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); - - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); -} - -/** - * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status - * @sdev: The LUN / SCSI device where sharing violation occurred - * @qual: The FSF status qualifier from the LUN sharing violation - */ -void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev, - union fsf_status_qual *qual) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - - if (qual->word[0]) - dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, - "LUN 0x%Lx on port 0x%Lx is already in " - "use by CSS%d, MIF Image ID %x\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn, - qual->fsf_queue_designator.cssid, - qual->fsf_queue_designator.hla); - else - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]); - - zfcp_erp_set_lun_status(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); -} - -/** - * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun" - * @sdev: The SCSI device / LUN where to evaluate the status - * @bottom: The qtcb bottom with the status from the "open lun" - * - * Returns: 0 if LUN is usable, -EACCES if the access control table - * reports an unsupported configuration. - */ -int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, - struct fsf_qtcb_bottom_support *bottom) -{ - int shared, rw; - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; - - if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) || - !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) || - zfcp_ccw_priv_sch(adapter)) - return 0; - - shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE); - rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); - - if (shared) - atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - - if (!rw) { - atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); - dev_info(&adapter->ccw_device->dev, "SCSI device at LUN " - "0x%016Lx on port 0x%016Lx opened read-only\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - } - - if (!shared && !rw) { - dev_err(&adapter->ccw_device->dev, "Exclusive read-only access " - "not supported (LUN 0x%016Lx, port 0x%016Lx)\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6"); - return -EACCES; - } - - if (shared && rw) { - dev_err(&adapter->ccw_device->dev, - "Shared read-write access not supported " - "(LUN 0x%016Lx, port 0x%016Lx)\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8"); - return -EACCES; - } - - return 0; -} diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 1305955..d91173f 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -86,10 +86,6 @@ struct zfcp_reqlist; #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 #define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 -/* logical unit status */ -#define ZFCP_STATUS_LUN_SHARED 0x00000004 -#define ZFCP_STATUS_LUN_READONLY 0x00000008 - /* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4133ab6..1d4c8fe 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -950,8 +950,7 @@ static void zfcp_erp_lun_strategy_clearstati(struct scsi_device *sdev) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_LUN_SHARED | ZFCP_STATUS_LUN_READONLY, + atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &zfcp_sdev->status); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 248578d..83e3f14 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -25,22 +25,10 @@ extern void zfcp_adapter_release(struct kref *); extern void zfcp_adapter_unregister(struct zfcp_adapter *); /* zfcp_ccw.c */ -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; -extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *); -extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *); -extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *, - union fsf_status_qual *); -extern int zfcp_cfdc_open_lun_eval(struct scsi_device *, - struct fsf_qtcb_bottom_support *); -extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *); - - /* zfcp_dbf.c */ extern int zfcp_dbf_adapter_register(struct zfcp_adapter *); extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *); @@ -115,8 +103,6 @@ extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *, extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *, struct fsf_qtcb_bottom_port *); -extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *, - struct zfcp_fsf_cfdc *); 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); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 06760e4..0bb40c9 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -254,14 +254,9 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) break; case FSF_STATUS_READ_NOTIFICATION_LOST: - if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) - zfcp_cfdc_adapter_access_changed(adapter); if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) zfcp_fc_conditional_port_scan(adapter); break; - case FSF_STATUS_READ_CFDC_UPDATED: - zfcp_cfdc_adapter_access_changed(adapter); - break; case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: adapter->adapter_features = sr_buf->payload.word[0]; break; @@ -935,8 +930,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) break; } break; - case FSF_ACCESS_DENIED: - break; case FSF_PORT_BOXED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1090,7 +1083,6 @@ out: static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) { struct zfcp_fsf_ct_els *send_els = req->data; - struct zfcp_port *port = send_els->port; struct fsf_qtcb_header *header = &req->qtcb->header; send_els->status = -EINVAL; @@ -1120,12 +1112,6 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) case FSF_REQUEST_SIZE_TOO_LARGE: case FSF_RESPONSE_SIZE_TOO_LARGE: break; - case FSF_ACCESS_DENIED: - if (port) { - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - } - break; case FSF_SBAL_MISMATCH: /* should never occur, avoided in zfcp_fsf_send_els */ /* fall through */ @@ -1213,8 +1199,6 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->bottom.config.feature_selection = - FSF_FEATURE_CFDC | - FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; req->erp_action = erp_action; @@ -1254,8 +1238,6 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, req->handler = zfcp_fsf_exchange_config_data_handler; req->qtcb->bottom.config.feature_selection = - FSF_FEATURE_CFDC | - FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; @@ -1382,10 +1364,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_PORT_ALREADY_OPEN: break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: dev_warn(&req->adapter->ccw_device->dev, "Not enough FCP adapter resources to open " @@ -1568,8 +1546,6 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) /* fall through */ case FSF_ADAPTER_STATUS_AVAILABLE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; - /* fall through */ - case FSF_ACCESS_DENIED: wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; break; case FSF_GOOD: @@ -1689,9 +1665,6 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1"); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - break; case FSF_PORT_BOXED: /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ @@ -1777,7 +1750,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) struct scsi_device *sdev = req->data; struct zfcp_scsi_dev *zfcp_sdev; struct fsf_qtcb_header *header = &req->qtcb->header; - struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; + union fsf_status_qual *qual = &header->fsf_status_qual; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; @@ -1785,9 +1758,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) zfcp_sdev = sdev_to_zfcp(sdev); atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_COMMON_ACCESS_BOXED | - ZFCP_STATUS_LUN_SHARED | - ZFCP_STATUS_LUN_READONLY, + ZFCP_STATUS_COMMON_ACCESS_BOXED, &zfcp_sdev->status); switch (header->fsf_status) { @@ -1797,10 +1768,6 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) /* fall through */ case FSF_LUN_ALREADY_OPEN: break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_PORT_BOXED: zfcp_erp_set_port_status(zfcp_sdev->port, ZFCP_STATUS_COMMON_ACCESS_BOXED); @@ -1809,7 +1776,17 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_SHARING_VIOLATION: - zfcp_cfdc_lun_shrng_vltn(sdev, &header->fsf_status_qual); + if (qual->word[0]) + dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, + "LUN 0x%Lx on port 0x%Lx is already in " + "use by CSS%d, MIF Image ID %x\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn, + qual->fsf_queue_designator.cssid, + qual->fsf_queue_designator.hla); + zfcp_erp_set_lun_status(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: @@ -1837,7 +1814,6 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) case FSF_GOOD: zfcp_sdev->lun_handle = header->lun_handle; atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status); - zfcp_cfdc_open_lun_eval(sdev, bottom); break; } } @@ -2065,10 +2041,6 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) case FSF_SERVICE_CLASS_NOT_SUPPORTED: zfcp_fsf_class_not_supp(req); break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_DIRECTION_INDICATOR_NOT_VALID: dev_err(&req->adapter->ccw_device->dev, "Incorrect direction %d, LUN 0x%016Lx on port " @@ -2369,79 +2341,6 @@ out: return req; } -static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) -{ -} - -/** - * zfcp_fsf_control_file - control file upload/download - * @adapter: pointer to struct zfcp_adapter - * @fsf_cfdc: pointer to struct zfcp_fsf_cfdc - * Returns: on success pointer to struct zfcp_fsf_req, NULL otherwise - */ -struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, - struct zfcp_fsf_cfdc *fsf_cfdc) -{ - struct zfcp_qdio *qdio = adapter->qdio; - struct zfcp_fsf_req *req = NULL; - struct fsf_qtcb_bottom_support *bottom; - int retval = -EIO; - u8 direction; - - if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) - return ERR_PTR(-EOPNOTSUPP); - - switch (fsf_cfdc->command) { - case FSF_QTCB_DOWNLOAD_CONTROL_FILE: - direction = SBAL_SFLAGS0_TYPE_WRITE; - break; - case FSF_QTCB_UPLOAD_CONTROL_FILE: - direction = SBAL_SFLAGS0_TYPE_READ; - break; - default: - return ERR_PTR(-EINVAL); - } - - spin_lock_irq(&qdio->req_q_lock); - if (zfcp_qdio_sbal_get(qdio)) - goto out; - - req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, direction, NULL); - if (IS_ERR(req)) { - retval = -EPERM; - goto out; - } - - req->handler = zfcp_fsf_control_file_handler; - - bottom = &req->qtcb->bottom.support; - bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; - bottom->option = fsf_cfdc->option; - - retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg); - - if (retval || - (zfcp_qdio_real_bytes(fsf_cfdc->sg) != ZFCP_CFDC_MAX_SIZE)) { - zfcp_fsf_req_free(req); - retval = -EIO; - goto out; - } - zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); - if (zfcp_adapter_multi_buffer_active(adapter)) - zfcp_qdio_set_scount(qdio, &req->qdio_req); - - zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); - retval = zfcp_fsf_req_send(req); -out: - spin_unlock_irq(&qdio->req_q_lock); - - if (!retval) { - wait_for_completion(&req->completion); - return req; - } - return ERR_PTR(retval); -} - /** * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO * @adapter: pointer to struct zfcp_adapter diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 5e795b8..57ae3ae 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -36,13 +36,6 @@ #define FSF_CONFIG_COMMAND 0x00000003 #define FSF_PORT_COMMAND 0x00000004 -/* FSF control file upload/download operations' subtype and options */ -#define FSF_CFDC_OPERATION_SUBTYPE 0x00020001 -#define FSF_CFDC_OPTION_NORMAL_MODE 0x00000000 -#define FSF_CFDC_OPTION_FORCE 0x00000001 -#define FSF_CFDC_OPTION_FULL_ACCESS 0x00000002 -#define FSF_CFDC_OPTION_RESTRICTED_ACCESS 0x00000004 - /* FSF protocol states */ #define FSF_PROT_GOOD 0x00000001 #define FSF_PROT_QTCB_VERSION_ERROR 0x00000010 @@ -64,7 +57,6 @@ #define FSF_HANDLE_MISMATCH 0x00000005 #define FSF_SERVICE_CLASS_NOT_SUPPORTED 0x00000006 #define FSF_FCPLUN_NOT_VALID 0x00000009 -#define FSF_ACCESS_DENIED 0x00000010 #define FSF_LUN_SHARING_VIOLATION 0x00000012 #define FSF_FCP_COMMAND_DOES_NOT_EXIST 0x00000022 #define FSF_DIRECTION_INDICATOR_NOT_VALID 0x00000030 @@ -130,7 +122,6 @@ #define FSF_STATUS_READ_LINK_DOWN 0x00000005 #define FSF_STATUS_READ_LINK_UP 0x00000006 #define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009 -#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C /* status subtypes for link down */ @@ -140,7 +131,6 @@ /* status subtypes for unsolicited status notification lost */ #define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001 -#define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020 /* topologie that is detected by the adapter */ #define FSF_TOPO_P2P 0x00000001 @@ -166,8 +156,6 @@ #define FSF_QTCB_LOG_SIZE 1024 /* channel features */ -#define FSF_FEATURE_CFDC 0x00000002 -#define FSF_FEATURE_LUN_SHARING 0x00000004 #define FSF_FEATURE_NOTIFICATION_LOST 0x00000008 #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 @@ -182,20 +170,6 @@ /* option */ #define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 -/* open LUN access flags*/ -#define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000 -#define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000 - -/* FSF interface for CFDC */ -#define ZFCP_CFDC_MAX_SIZE 127 * 1024 -#define ZFCP_CFDC_PAGES PFN_UP(ZFCP_CFDC_MAX_SIZE) - -struct zfcp_fsf_cfdc { - struct scatterlist sg[ZFCP_CFDC_PAGES]; - u32 command; - u32 option; -}; - struct fsf_queue_designator { u8 cssid; u8 chpid; diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 05423ac..3f01bbf 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -75,12 +75,6 @@ ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n", ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n", (zfcp_unit_sdev_status(unit) & ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); -ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n", - (zfcp_unit_sdev_status(unit) & - ZFCP_STATUS_LUN_SHARED) != 0); -ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n", - (zfcp_unit_sdev_status(unit) & - ZFCP_STATUS_LUN_READONLY) != 0); static ssize_t zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, @@ -353,8 +347,6 @@ static struct attribute *zfcp_unit_attrs[] = { &dev_attr_unit_in_recovery.attr, &dev_attr_unit_status.attr, &dev_attr_unit_access_denied.attr, - &dev_attr_unit_access_shared.attr, - &dev_attr_unit_access_readonly.attr, NULL }; static struct attribute_group zfcp_unit_attr_group = { -- cgit v1.1 From 9edf7d75ee5f21663a0183d21f702682d0ef132f Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 26 Apr 2013 17:34:54 +0200 Subject: [SCSI] zfcp: status read buffers on first adapter open with link down Commit 64deb6efdc5504ce97b5c1c6f281fffbc150bd93 "[SCSI] zfcp: Use status_read_buf_num provided by FCP channel" started using a value returned by the channel but only evaluated the value if the fabric link is up. Commit 8d88cf3f3b9af4713642caeb221b6d6a42019001 "[SCSI] zfcp: Update status read mempool" introduced mempool resizings based on the above value. On setting an FCP device online for the very first time since boot, a new zeroed adapter object is allocated. If the link is down, the number of status read requests remains zero. Since just the config data exchange is incomplete, we proceed with adapter open recovery. However, we unconditionally call mempool_resize with adapter->stat_read_buf_num == 0 in this case. This causes a kernel message "kernel BUG at mm/mempool.c:131!" in process "zfcperp" with last function mempool_resize in Krnl PSW and zfcp_erp_thread in the Call Trace. Don't evaluate channel values which are invalid on link down. The number of status read requests is always valid, evaluated, and set to a positive minimum greater than zero. The adapter open recovery can proceed and the channel has status read buffers to inform us on a future link up event. While we are not aware of any other code path that could result in mempool resize attempts of size zero, we still also initialize the number of status read buffers to be posted to a static minimum number on adapter object allocation. Signed-off-by: Steffen Maier Cc: #2.6.35+ Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 5 ++++- drivers/s390/scsi/zfcp_fsf.c | 23 ++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 19fe0df..1b9e4ae 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -3,7 +3,7 @@ * * Module interface and handling of zfcp data structures. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ /* @@ -23,6 +23,7 @@ * Christof Schmitt * Martin Petermann * Sven Schuetz + * Steffen Maier */ #define KMSG_COMPONENT "zfcp" @@ -405,6 +406,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; + adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; + if (!zfcp_scsi_adapter_register(adapter)) return adapter; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 0bb40c9..510e9b0 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3,7 +3,7 @@ * * Implementation of FSF commands. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -478,12 +478,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) fc_host_port_name(shost) = nsp->fl_wwpn; fc_host_node_name(shost) = nsp->fl_wwnn; - fc_host_port_id(shost) = ntoh24(bottom->s_id); - fc_host_speed(shost) = - zfcp_fsf_convert_portspeed(bottom->fc_link_speed); fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; - adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)FSF_STATUS_READS_RECOM); @@ -491,6 +487,19 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) if (fc_host_permanent_port_name(shost) == -1) fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + zfcp_scsi_set_prot(adapter); + + /* no error return above here, otherwise must fix call chains */ + /* do not evaluate invalid fields */ + if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE) + return 0; + + fc_host_port_id(shost) = ntoh24(bottom->s_id); + fc_host_speed(shost) = + zfcp_fsf_convert_portspeed(bottom->fc_link_speed); + + adapter->hydra_version = bottom->adapter_type; + switch (bottom->fc_topology) { case FSF_TOPO_P2P: adapter->peer_d_id = ntoh24(bottom->peer_d_id); @@ -512,8 +521,6 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) return -EIO; } - zfcp_scsi_set_prot(adapter); - return 0; } @@ -564,6 +571,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); + if (zfcp_fsf_exchange_config_evaluate(req)) + return; break; default: zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3"); -- cgit v1.1 From e73823f7a2c921dcf068d34ea03bd682498d9e42 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 7 May 2013 15:38:18 -0700 Subject: [SCSI] libsas: implement > 16 byte CDB support Remove the arbitrary expectation in libsas that all SCSI commands are 16 bytes or less. Instead do all copies via cmd->cmd_len (and use a pointer to this in the libsas task instead of a copy). Note that this still doesn't enable > 16 byte CDB support in the underlying drivers because their internal format has to be fixed and the wire format of > 16 byte CDBs according to the SAS spec is different. the libsas drivers (isci, aic94xx, mvsas and pm8xxx are all updated for this change. Cc: Lukasz Dorau Cc: Maciej Patelczyk Cc: Dave Jiang Cc: Jack Wang Cc: Lindar Liu Cc: Xiangliang Yu Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_task.c | 3 ++- drivers/scsi/isci/request.c | 4 ++-- drivers/scsi/libsas/sas_scsi_host.c | 2 +- drivers/scsi/mvsas/mv_sas.c | 3 ++- drivers/scsi/pm8001/pm8001_hwi.c | 3 ++- drivers/scsi/pm8001/pm80xx_hwi.c | 21 +++++++++++---------- include/scsi/libsas.h | 2 +- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 393e7ce..59b86e2 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -505,7 +505,8 @@ static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task, scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK; scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3); scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7); - memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16); + memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF); scb->ssp_task.conn_handle = cpu_to_le16( diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index e3e3bcb..7b08215 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -184,8 +184,8 @@ static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq) cmd_iu->task_attr = task->ssp_task.task_attr; cmd_iu->_r_c = 0; - sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb, - sizeof(task->ssp_task.cdb) / sizeof(u32)); + sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len / sizeof(u32)); } static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq) diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 6e795a1..da3aee1 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -167,7 +167,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, int_to_scsilun(cmd->device->lun, &lun); memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8); task->ssp_task.task_attr = TASK_ATTR_SIMPLE; - memcpy(task->ssp_task.cdb, cmd->cmnd, 16); + task->ssp_task.cmd = cmd; task->scatter = scsi_sglist(cmd); task->num_scatter = scsi_sg_count(cmd); diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index c9e2449..f14665a 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -686,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, if (ssp_hdr->frame_type != SSP_TASK) { buf_cmd[9] = fburst | task->ssp_task.task_attr | (task->ssp_task.task_prio << 3); - memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); + memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); } else{ buf_cmd[10] = tmf->tmf; switch (tmf->tmf) { diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 69dd49c..a58546f 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -4291,7 +4291,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); - memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); + memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); circularQ = &pm8001_ha->inbnd_q_tbl[0]; /* fill in PRD (scatter/gather) table, if any */ diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 302514d..f6c65ee 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -3559,9 +3559,9 @@ err_out: static int check_enc_sas_cmd(struct sas_task *task) { - if ((task->ssp_task.cdb[0] == READ_10) - || (task->ssp_task.cdb[0] == WRITE_10) - || (task->ssp_task.cdb[0] == WRITE_VERIFY)) + u8 cmd = task->ssp_task.cmd->cmnd[0]; + + if (cmd == READ_10 || cmd == WRITE_10 || cmd == WRITE_VERIFY) return 1; else return 0; @@ -3624,7 +3624,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); - memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); + memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); circularQ = &pm8001_ha->inbnd_q_tbl[0]; /* Check if encryption is set */ @@ -3632,7 +3633,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { PM8001_IO_DBG(pm8001_ha, pm8001_printk( "Encryption enabled.Sending Encrypt SAS command 0x%x\n", - task->ssp_task.cdb[0])); + task->ssp_task.cmd->cmnd[0])); opc = OPC_INB_SSP_INI_DIF_ENC_IO; /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ ssp_cmd.dad_dir_m_tlr = cpu_to_le32 @@ -3666,14 +3667,14 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, /* XTS mode. All other fields are 0 */ ssp_cmd.key_cmode = 0x6 << 4; /* set tweak values. Should be the start lba */ - ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cdb[2] << 24) | - (task->ssp_task.cdb[3] << 16) | - (task->ssp_task.cdb[4] << 8) | - (task->ssp_task.cdb[5])); + ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) | + (task->ssp_task.cmd->cmnd[3] << 16) | + (task->ssp_task.cmd->cmnd[4] << 8) | + (task->ssp_task.cmd->cmnd[5])); } else { PM8001_IO_DBG(pm8001_ha, pm8001_printk( "Sending Normal SAS command 0x%x inb q %x\n", - task->ssp_task.cdb[0], inb)); + task->ssp_task.cmd->cmnd[0], inb)); /* fill in PRD (scatter/gather) table, if any */ if (task->num_scatter > 1) { pm8001_chip_make_sg(task->scatter, ccb->n_elem, diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index e2c1e66..f843dd8 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -608,7 +608,7 @@ struct sas_ssp_task { u8 enable_first_burst:1; enum task_attribute task_attr; u8 task_prio; - u8 cdb[16]; + struct scsi_cmnd *cmd; }; struct sas_task { -- cgit v1.1 From 808cbb68de49b8d9d72f9bdf28251c8a87c96f39 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 May 2013 15:48:13 +0300 Subject: [SCSI] pm80xx: remove unneeded NULL check Coccinelle complains about the inconsistent NULL checking on "t". It turns out the check isn't needed because we verified that "t" is non-NULL at the start of the function. Signed-off-by: Dan Carpenter Acked-by: Anand Kumar Santhanam Signed-off-by: James Bottomley --- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a58546f..5456f5c 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3740,7 +3740,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb(); - if ((pm8001_dev->id & NCQ_ABORT_ALL_FLAG) && t) { + if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) { pm8001_tag_free(pm8001_ha, tag); sas_free_task(t); /* clear the flag */ -- cgit v1.1 From 123f87758658285f5f844d7e8a8b974ce88d1ffc Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 14 May 2013 21:34:13 +0530 Subject: [SCSI] ufs: Remove redundant platform_set_drvdata() Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd-pltfrm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 03319ac..3db2ee1 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -184,7 +184,6 @@ static int ufshcd_pltfrm_remove(struct platform_device *pdev) mem_size = resource_size(mem_res); release_mem_region(mem_res->start, mem_size); } - platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.1 From a4bfbcba691b2870d81218814267c6add885ac47 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 14 May 2013 21:34:14 +0530 Subject: [SCSI] ufs: SCSI_UFSHCD should depend on SCSI_DMA If NO_DMA=y: drivers/built-in.o: In function `ufshcd_transfer_req_compl': drivers/scsi/ufs/ufshcd.c:1182: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_map_sg': drivers/scsi/ufs/ufshcd.c:377: undefined reference to `scsi_dma_map' drivers/built-in.o: In function `ufshcd_do_reset': drivers/scsi/ufs/ufshcd.c:912: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_memory_alloc': drivers/scsi/ufs/ufshcd.c:565: undefined reference to `dma_alloc_coherent' drivers/built-in.o: In function `ufshcd_free_hba_memory': drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:199: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent' drivers/built-in.o:drivers/scsi/ufs/ufshcd.c:199: more undefined references to `dma_free_coherent' follow drivers/built-in.o: In function `ufshcd_abort': drivers/scsi/ufs/ufshcd.c:1498: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_device_reset': drivers/scsi/ufs/ufshcd.c:1436: undefined reference to `scsi_dma_unmap' Signed-off-by: Geert Uytterhoeven Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 35faf24..f07f9017 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -34,7 +34,7 @@ config SCSI_UFSHCD tristate "Universal Flash Storage Controller Driver Core" - depends on SCSI + depends on SCSI && SCSI_DMA ---help--- This selects the support for UFS devices in Linux, say Y and make sure that you know the name of your UFS host adapter (the card -- cgit v1.1 From 1642e66201d7b35c383d8e832603c24a78670e62 Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Tue, 14 May 2013 21:34:15 +0530 Subject: [SCSI] Documentation/devicetree: Add DT bindings for UFS host controller Compatible list is used in commit 03b1781 but is not documented. Add necessary device tree bindings to describe on-chip UFS host controllers. Signed-off-by: Sujit Reddy Thumma Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt new file mode 100644 index 0000000..20468b2 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -0,0 +1,16 @@ +* Universal Flash Storage (UFS) Host Controller + +UFSHC nodes are defined to describe on-chip UFS host controllers. +Each UFS controller instance should have its own node. + +Required properties: +- compatible : compatible list, contains "jedec,ufs-1.1" +- interrupts : +- reg : + +Example: + ufshc@0xfc598000 { + compatible = "jedec,ufs-1.1"; + reg = <0xfc598000 0x800>; + interrupts = <0 28 0>; + }; -- cgit v1.1 From 70288b4c8fd35340b79b25b2ac9c86a79d105e60 Mon Sep 17 00:00:00 2001 From: "wenxiong@linux.vnet.ibm.com" Date: Thu, 14 Mar 2013 13:52:25 -0500 Subject: [SCSI] ipr: Avoid target_destroy accessing memory after it was freed Defined target_ids,array_ids and vsets_ids as unsigned long to avoid target_destroy accessing memory after it was freed. Signed-off-by: Wen Xiong Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 16 ---------------- drivers/scsi/ipr.h | 6 +++--- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 82a3c1e..6c4cedb 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -8980,19 +8980,6 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) if (!ioa_cfg->res_entries) goto out; - if (ioa_cfg->sis64) { - ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) * - BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); - ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) * - BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); - ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) * - BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); - - if (!ioa_cfg->target_ids || !ioa_cfg->array_ids - || !ioa_cfg->vset_ids) - goto out_free_res_entries; - } - for (i = 0; i < ioa_cfg->max_devs_supported; i++) { list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; @@ -9089,9 +9076,6 @@ out_free_vpd_cbs: ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma); out_free_res_entries: kfree(ioa_cfg->res_entries); - kfree(ioa_cfg->target_ids); - kfree(ioa_cfg->array_ids); - kfree(ioa_cfg->vset_ids); goto out; } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index a1fb840..07a85ce 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1440,9 +1440,9 @@ struct ipr_ioa_cfg { /* * Bitmaps for SIS64 generated target values */ - unsigned long *target_ids; - unsigned long *array_ids; - unsigned long *vset_ids; + unsigned long target_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; + unsigned long array_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; + unsigned long vset_ids[BITS_TO_LONGS(IPR_MAX_SIS64_DEVS)]; u16 type; /* CCIN of the card */ -- cgit v1.1 From 0761df9c4b2d966da3af2ac4ee7372afa681ce63 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 10 May 2013 11:06:16 +0200 Subject: [SCSI] sd: avoid deadlocks when running under multipath When multipathed systems run into an all-paths-down scenario all devices might be dropped, too. This causes 'del_gendisk' to be called, which will unregister the kobj_map->probe() function for all disk device numbers. When the device comes back the default ->probe() function is run which will call __request_module(), which will deadlock. As 'del_gendisk' typically does _not_ trigger a module unload the default ->probe() function is pointless anyway. This patch implements a dummy ->probe() function, which will just return NULL if the disk is not registered. This will avoid the deadlock. Plus it'll speed up device scanning. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c1c5552..a37eda9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -504,6 +504,16 @@ static struct scsi_driver sd_template = { }; /* + * Dummy kobj_map->probe function. + * The default ->probe function will call modprobe, which is + * pointless as this module is already loaded. + */ +static struct kobject *sd_default_probe(dev_t devt, int *partno, void *data) +{ + return NULL; +} + +/* * Device no to disk mapping: * * major disc2 disc p1 @@ -2970,8 +2980,10 @@ static int sd_probe(struct device *dev) static int sd_remove(struct device *dev) { struct scsi_disk *sdkp; + dev_t devt; sdkp = dev_get_drvdata(dev); + devt = disk_devt(sdkp->disk); scsi_autopm_get_device(sdkp->device); async_synchronize_full_domain(&scsi_sd_probe_domain); @@ -2981,6 +2993,9 @@ static int sd_remove(struct device *dev) del_gendisk(sdkp->disk); sd_shutdown(dev); + blk_register_region(devt, SD_MINORS, NULL, + sd_default_probe, NULL, NULL); + mutex_lock(&sd_ref_mutex); dev_set_drvdata(dev, NULL); put_device(&sdkp->dev); @@ -3124,9 +3139,13 @@ static int __init init_sd(void) SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); - for (i = 0; i < SD_MAJORS; i++) - if (register_blkdev(sd_major(i), "sd") == 0) - majors++; + for (i = 0; i < SD_MAJORS; i++) { + if (register_blkdev(sd_major(i), "sd") != 0) + continue; + majors++; + blk_register_region(sd_major(i), SD_MINORS, NULL, + sd_default_probe, NULL, NULL); + } if (!majors) return -ENODEV; @@ -3185,8 +3204,10 @@ static void __exit exit_sd(void) class_unregister(&sd_disk_class); - for (i = 0; i < SD_MAJORS; i++) + for (i = 0; i < SD_MAJORS; i++) { + blk_unregister_region(sd_major(i), SD_MINORS); unregister_blkdev(sd_major(i), "sd"); + } } module_init(init_sd); -- cgit v1.1 From 0816c9251a7180383bb7811e1a1545f7b78e5374 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 10 May 2013 10:36:04 -0400 Subject: [SCSI] Allow error handling timeout to be specified Introduce eh_timeout which can be used for error handling purposes. This was previously hardcoded to 10 seconds in the SCSI error handling code. However, for some fast-fail scenarios it is necessary to be able to tune this as it can take several iterations (bus device, target, bus, controller) before we give up. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 7 +++---- drivers/scsi/scsi_scan.c | 2 ++ drivers/scsi/scsi_sysfs.c | 30 ++++++++++++++++++++++++++++++ include/scsi/scsi.h | 5 +++++ include/scsi/scsi_device.h | 1 + 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index f43de1e..5624744 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -45,8 +45,6 @@ static void scsi_eh_done(struct scsi_cmnd *scmd); -#define SENSE_TIMEOUT (10*HZ) - /* * These should *probably* be handled by the host itself. * Since it is allowed to sleep, it probably should. @@ -881,7 +879,7 @@ retry: */ static int scsi_request_sense(struct scsi_cmnd *scmd) { - return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0); + return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0); } /** @@ -982,7 +980,8 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) int retry_cnt = 1, rtn; retry_tur: - rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0); + rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, + scmd->device->eh_timeout, 0); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", __func__, scmd, rtn)); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3e58b22..852915a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -924,6 +924,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_NO_DIF) sdev->no_dif = 1; + sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; + transport_configure_device(&sdev->sdev_gendev); if (sdev->host->hostt->slave_configure) { diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 931a7d9..7e50061 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -560,6 +560,35 @@ sdev_store_timeout (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout); static ssize_t +sdev_show_eh_timeout(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scsi_device *sdev; + sdev = to_scsi_device(dev); + return snprintf(buf, 20, "%u\n", sdev->eh_timeout / HZ); +} + +static ssize_t +sdev_store_eh_timeout(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev; + unsigned int eh_timeout; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + sdev = to_scsi_device(dev); + err = kstrtouint(buf, 10, &eh_timeout); + if (err) + return err; + sdev->eh_timeout = eh_timeout * HZ; + + return count; +} +static DEVICE_ATTR(eh_timeout, S_IRUGO | S_IWUSR, sdev_show_eh_timeout, sdev_store_eh_timeout); + +static ssize_t store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -723,6 +752,7 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_delete.attr, &dev_attr_state.attr, &dev_attr_timeout.attr, + &dev_attr_eh_timeout.attr, &dev_attr_iocounterbits.attr, &dev_attr_iorequest_cnt.attr, &dev_attr_iodone_cnt.attr, diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 66216c1..4b87d99 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -10,9 +10,14 @@ #include #include +#include struct scsi_cmnd; +enum scsi_timeouts { + SCSI_DEFAULT_EH_TIMEOUT = 10 * HZ, +}; + /* * The maximum number of SG segments that we will put inside a * scatterlist (unless chaining is used). Should ideally fit inside a diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index cc64587..a44954c 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -113,6 +113,7 @@ struct scsi_device { * scsi_devinfo.[hc]. For now used only to * pass settings from slave_alloc to scsi * core. */ + unsigned int eh_timeout; /* Error handling timeout */ unsigned writeable:1; unsigned removable:1; unsigned changed:1; /* Data invalid due to media change */ -- cgit v1.1 From 111ecbe426241bdc89c33e9acd08eb15744ce031 Mon Sep 17 00:00:00 2001 From: Vijay Mohan Guvva Date: Mon, 13 May 2013 03:49:44 -0600 Subject: [SCSI] bfa: fix faulty handling of events in lps sm When a switch disable/enable or a reboot is done, the HBA port gets an offline and a subsequent online notification. When the port comes up a link up notification is sent to bfa from the firmware. The bfa then send an FLOGI to the firmware which is sent out on the wire. The switch port meanwhile goes offline (presumably for diagnostics) which causes the switch not to respond to the FLOGI. The link down notification is sent to the HBA driver. However owing to a bug in the lps state machine handling the lps state machine does not move to sm_init state (it remains in sm_login state and send a login complete message to fcs). This results in a zero PID assignment as the login is not really complete. This fix is to correctly handle the events in lps state machine. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_svc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 299c1c8..7ed2c57 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -1276,7 +1276,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) switch (event) { case BFA_LPS_SM_FWRSP: - case BFA_LPS_SM_OFFLINE: if (lps->status == BFA_STATUS_OK) { bfa_sm_set_state(lps, bfa_lps_sm_online); if (lps->fdisc) @@ -1305,6 +1304,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) bfa_lps_login_comp(lps); break; + case BFA_LPS_SM_OFFLINE: case BFA_LPS_SM_DELETE: bfa_sm_set_state(lps, bfa_lps_sm_init); break; -- cgit v1.1 From 07cdc0464fb9438fd205069dc09d47b8783ad271 Mon Sep 17 00:00:00 2001 From: Vijay Mohan Guvva Date: Mon, 13 May 2013 03:56:48 -0600 Subject: [SCSI] bfa: fix for FC Direct Attach LUN discovery failure Resending the patch as it didn't make the linux-scsi list. This patch fixes fcs rport state machine to address ocassional Brocade FC Direct Attach LUN discovery failure due to not sending PLOGI accept to the target. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcs_rport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 58ac643..610ca95 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -189,8 +189,8 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) break; case RPSM_EVENT_PLOGI_RCVD: - bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); - bfa_fcs_rport_fcs_online_action(rport); + bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); + bfa_fcs_rport_send_plogiacc(rport, NULL); break; case RPSM_EVENT_PLOGI_COMP: -- cgit v1.1 From 49c1241384b599421a5e8c9f73f72e2052dd416d Mon Sep 17 00:00:00 2001 From: Naresh Kumar Inna Date: Fri, 17 May 2013 15:50:03 +0530 Subject: [SCSI] csiostor: Retain default adapter configuration in absence of config file. - Retain firmware defined configuration settings in the absence of user-provided configuration by eliminating the global RSS and the PF/VF capabilities mailbox commands. - Remove S_IRUGO from sysfs parameters that don't have 'show' functionality. Signed-off-by: Naresh Kumar Inna Signed-off-by: James Bottomley --- drivers/scsi/csiostor/csio_hw.c | 91 --------------------------------------- drivers/scsi/csiostor/csio_hw.h | 11 ----- drivers/scsi/csiostor/csio_mb.c | 77 --------------------------------- drivers/scsi/csiostor/csio_mb.h | 11 ----- drivers/scsi/csiostor/csio_scsi.c | 4 +- 5 files changed, 2 insertions(+), 192 deletions(-) diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 1936055..0eb35b9 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -1597,87 +1597,6 @@ out: return rv; } -static int -csio_config_global_rss(struct csio_hw *hw) -{ - struct csio_mb *mbp; - enum fw_retval retval; - - mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); - if (!mbp) { - CSIO_INC_STATS(hw, n_err_nomem); - return -ENOMEM; - } - - csio_rss_glb_config(hw, mbp, CSIO_MB_DEFAULT_TMO, - FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, - FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | - FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ | - FW_RSS_GLB_CONFIG_CMD_TNLALLLKP, - NULL); - - if (csio_mb_issue(hw, mbp)) { - csio_err(hw, "Issue of FW_RSS_GLB_CONFIG_CMD failed!\n"); - mempool_free(mbp, hw->mb_mempool); - return -EINVAL; - } - - retval = csio_mb_fw_retval(mbp); - if (retval != FW_SUCCESS) { - csio_err(hw, "FW_RSS_GLB_CONFIG_CMD returned 0x%x!\n", retval); - mempool_free(mbp, hw->mb_mempool); - return -EINVAL; - } - - mempool_free(mbp, hw->mb_mempool); - - return 0; -} - -/* - * csio_config_pfvf - Configure Physical/Virtual functions settings. - * @hw: HW module - * - */ -static int -csio_config_pfvf(struct csio_hw *hw) -{ - struct csio_mb *mbp; - enum fw_retval retval; - - mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); - if (!mbp) { - CSIO_INC_STATS(hw, n_err_nomem); - return -ENOMEM; - } - - /* - * For now, allow all PFs to access to all ports using a pmask - * value of 0xF (M_FW_PFVF_CMD_PMASK). Once we have VFs, we will - * need to provide access based on some rule. - */ - csio_mb_pfvf(hw, mbp, CSIO_MB_DEFAULT_TMO, hw->pfn, 0, CSIO_NEQ, - CSIO_NETH_CTRL, CSIO_NIQ_FLINT, 0, 0, CSIO_NVI, CSIO_CMASK, - CSIO_PMASK, CSIO_NEXACTF, CSIO_R_CAPS, CSIO_WX_CAPS, NULL); - - if (csio_mb_issue(hw, mbp)) { - csio_err(hw, "Issue of FW_PFVF_CMD failed!\n"); - mempool_free(mbp, hw->mb_mempool); - return -EINVAL; - } - - retval = csio_mb_fw_retval(mbp); - if (retval != FW_SUCCESS) { - csio_err(hw, "FW_PFVF_CMD returned 0x%x!\n", retval); - mempool_free(mbp, hw->mb_mempool); - return -EINVAL; - } - - mempool_free(mbp, hw->mb_mempool); - - return 0; -} - /* * csio_enable_ports - Bring up all available ports. * @hw: HW module. @@ -2056,16 +1975,6 @@ csio_hw_no_fwconfig(struct csio_hw *hw, int reset) if (rv != 0) goto out; - /* Config Global RSS command */ - rv = csio_config_global_rss(hw); - if (rv != 0) - goto out; - - /* Configure PF/VF capabilities of device */ - rv = csio_config_pfvf(hw); - if (rv != 0) - goto out; - /* device parameters */ rv = csio_get_device_params(hw); if (rv != 0) diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h index 489fc09..49b1daa 100644 --- a/drivers/scsi/csiostor/csio_hw.h +++ b/drivers/scsi/csiostor/csio_hw.h @@ -153,17 +153,6 @@ enum { CSIO_SGE_INT_CNT_VAL_1 = 4, CSIO_SGE_INT_CNT_VAL_2 = 8, CSIO_SGE_INT_CNT_VAL_3 = 16, - - /* Storage specific - used by FW_PFVF_CMD */ - CSIO_WX_CAPS = FW_CMD_CAP_PF, /* w/x all */ - CSIO_R_CAPS = FW_CMD_CAP_PF, /* r all */ - CSIO_NVI = 4, - CSIO_NIQ_FLINT = 34, - CSIO_NETH_CTRL = 32, - CSIO_NEQ = 66, - CSIO_NEXACTF = 32, - CSIO_CMASK = FW_PFVF_CMD_CMASK_MASK, - CSIO_PMASK = FW_PFVF_CMD_PMASK_MASK, }; /* Slowpath events */ diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index f5d9ee1..15b6351 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -326,83 +326,6 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET); } -void -csio_rss_glb_config(struct csio_hw *hw, struct csio_mb *mbp, - uint32_t tmo, uint8_t mode, unsigned int flags, - void (*cbfn)(struct csio_hw *, struct csio_mb *)) -{ - struct fw_rss_glb_config_cmd *cmdp = - (struct fw_rss_glb_config_cmd *)(mbp->mb); - - CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - - cmdp->op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); - - if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) { - cmdp->u.manual.mode_pkd = - htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); - } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) { - cmdp->u.basicvirtual.mode_pkd = - htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); - cmdp->u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags); - } -} - - -/* - * csio_mb_pfvf - FW Write PF/VF capabilities command helper. - * @hw: The HW structure - * @mbp: Mailbox structure - * @pf: - * @vf: - * @txq: - * @txq_eht_ctrl: - * @rxqi: - * @rxq: - * @tc: - * @vi: - * @pmask: - * @rcaps: - * @wxcaps: - * @cbfn: Callback, if any. - * - */ -void -csio_mb_pfvf(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, - unsigned int pf, unsigned int vf, unsigned int txq, - unsigned int txq_eth_ctrl, unsigned int rxqi, - unsigned int rxq, unsigned int tc, unsigned int vi, - unsigned int cmask, unsigned int pmask, unsigned int nexactf, - unsigned int rcaps, unsigned int wxcaps, - void (*cbfn) (struct csio_hw *, struct csio_mb *)) -{ - struct fw_pfvf_cmd *cmdp = (struct fw_pfvf_cmd *)(mbp->mb); - - CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | - FW_PFVF_CMD_PFN(pf) | - FW_PFVF_CMD_VFN(vf)); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); - cmdp->niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) | - FW_PFVF_CMD_NIQ(rxq)); - - cmdp->type_to_neq = htonl(FW_PFVF_CMD_TYPE | - FW_PFVF_CMD_CMASK(cmask) | - FW_PFVF_CMD_PMASK(pmask) | - FW_PFVF_CMD_NEQ(txq)); - cmdp->tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | - FW_PFVF_CMD_NVI(vi) | - FW_PFVF_CMD_NEXACTF(nexactf)); - cmdp->r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) | - FW_PFVF_CMD_WX_CAPS(wxcaps) | - FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl)); -} - #define CSIO_ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG) diff --git a/drivers/scsi/csiostor/csio_mb.h b/drivers/scsi/csiostor/csio_mb.h index 1788ea5..a84179e 100644 --- a/drivers/scsi/csiostor/csio_mb.h +++ b/drivers/scsi/csiostor/csio_mb.h @@ -183,17 +183,6 @@ void csio_mb_caps_config(struct csio_hw *, struct csio_mb *, uint32_t, bool, bool, bool, bool, void (*)(struct csio_hw *, struct csio_mb *)); -void csio_rss_glb_config(struct csio_hw *, struct csio_mb *, - uint32_t, uint8_t, unsigned int, - void (*)(struct csio_hw *, struct csio_mb *)); - -void csio_mb_pfvf(struct csio_hw *, struct csio_mb *, uint32_t, - unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int, - unsigned int, void (*) (struct csio_hw *, struct csio_mb *)); - void csio_mb_port(struct csio_hw *, struct csio_mb *, uint32_t, uint8_t, bool, uint32_t, uint16_t, void (*) (struct csio_hw *, struct csio_mb *)); diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index ddd38e5..7494e4b 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1479,8 +1479,8 @@ csio_store_dbg_level(struct device *dev, } static DEVICE_ATTR(hw_state, S_IRUGO, csio_show_hw_state, NULL); -static DEVICE_ATTR(device_reset, S_IRUGO | S_IWUSR, NULL, csio_device_reset); -static DEVICE_ATTR(disable_port, S_IRUGO | S_IWUSR, NULL, csio_disable_port); +static DEVICE_ATTR(device_reset, S_IWUSR, NULL, csio_device_reset); +static DEVICE_ATTR(disable_port, S_IWUSR, NULL, csio_disable_port); static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level, csio_store_dbg_level); -- cgit v1.1 From b0df96a0068daee4f9c2189c29b9053eb6e46b17 Mon Sep 17 00:00:00 2001 From: "Reddy, Sreekanth" Date: Tue, 26 Feb 2013 16:59:59 +0530 Subject: [SCSI] mpt2sas: Fix for issue Missing delay not getting set during system bootup Missing delay is not getting set properly. The reason is that it is not defined in the same file from where it is being invoked. The fix is to move the missing delay module parameter from mpt2sas_base.c to mpt2sas_scsh.c. Signed-off-by: Sreekanth Reddy Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_base.c | 13 +++---------- drivers/scsi/mpt2sas/mpt2sas_base.h | 3 +++ drivers/scsi/mpt2sas/mpt2sas_scsih.c | 8 +++++++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index bcb23d2..c76b18b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -80,10 +80,6 @@ static int msix_disable = -1; module_param(msix_disable, int, 0); MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); -static int missing_delay[2] = {-1, -1}; -module_param_array(missing_delay, int, NULL, 0); -MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); - static int mpt2sas_fwfault_debug; MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " "and halt firmware - (default=0)"); @@ -2199,7 +2195,7 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) } /** - * _base_update_missing_delay - change the missing delay timers + * mpt2sas_base_update_missing_delay - change the missing delay timers * @ioc: per adapter object * @device_missing_delay: amount of time till device is reported missing * @io_missing_delay: interval IO is returned when there is a missing device @@ -2210,8 +2206,8 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) * delay, as well as the io missing delay. This should be called at driver * load time. */ -static void -_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc, +void +mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc, u16 device_missing_delay, u8 io_missing_delay) { u16 dmd, dmd_new, dmd_orignal; @@ -4407,9 +4403,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) if (r) goto out_free_resources; - if (missing_delay[0] != -1 && missing_delay[1] != -1) - _base_update_missing_delay(ioc, missing_delay[0], - missing_delay[1]); ioc->non_operational_loop = 0; return 0; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 4caaac1..1130197 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -1055,6 +1055,9 @@ void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_ty void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc); +void mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc, + u16 device_missing_delay, u8 io_missing_delay); + int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc); /* scsih shared API */ diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index c6bdc92..116e201 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -101,6 +101,10 @@ static ushort max_sectors = 0xFFFF; module_param(max_sectors, ushort, 0); MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767 default=32767"); +static int missing_delay[2] = {-1, -1}; +module_param_array(missing_delay, int, NULL, 0); +MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); + /* scsi-mid layer global parmeter is max_report_luns, which is 511 */ #define MPT2SAS_MAX_LUN (16895) static int max_lun = MPT2SAS_MAX_LUN; @@ -7303,7 +7307,9 @@ _firmware_event_work(struct work_struct *work) case MPT2SAS_PORT_ENABLE_COMPLETE: ioc->start_scan = 0; - + if (missing_delay[0] != -1 && missing_delay[1] != -1) + mpt2sas_base_update_missing_delay(ioc, missing_delay[0], + missing_delay[1]); dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete " "from worker thread\n", ioc->name)); -- cgit v1.1 From 10ec24e4ce0356f61a12d79f84996cea3686b926 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 1 Feb 2013 21:54:13 +0530 Subject: [SCSI] mpt2sas: MPI2 Rev W (2.00.15) specification Change set in MPI 2.0 Rev W(2.00.15) specification and 2.00.27 header files 1. Added a bit to the IOCExceptions field of the IOCFacts Reply to indicate that the IOC detected a partial memory failure. 2. Added ElapsedSeconds field to RAID Volume Indicator Structure. Added Elapsed Seconds Valid flag to Flags field of this structure. 3. Added ElapsedSeconds field to Integrated RAID Operations Status Event Data. 4. In the IOCSettings field of BIOS Page 1, modified the Adapter Support bits description to specify X86 BIOS. 5. Toolbox Diagnostic CLI Tool Request may now use chain elements in the SGL. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpi/mpi2.h | 6 ++++-- drivers/scsi/mpt2sas/mpi/mpi2_init.h | 4 +++- drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 8 ++++++-- drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 9 +++++++-- drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 10 ++++++---- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h index e960f96..31b5b15 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2.h @@ -8,7 +8,7 @@ * scatter/gather formats. * Creation Date: June 21, 2006 * - * mpi2.h Version: 02.00.25 + * mpi2.h Version: 02.00.27 * * Version History * --------------- @@ -75,6 +75,8 @@ * 02-06-12 02.00.24 Bumped MPI2_HEADER_VERSION_UNIT. * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT. * Added Hard Reset delay timings. + * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. + * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- */ @@ -100,7 +102,7 @@ #define MPI2_VERSION_02_00 (0x0200) /* versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x19) +#define MPI2_HEADER_VERSION_UNIT (0x1B) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h index 38c5da3..963761f 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h @@ -6,7 +6,7 @@ * Title: MPI SCSI initiator mode messages and structures * Creation Date: June 23, 2006 * - * mpi2_init.h Version: 02.00.13 + * mpi2_init.h Version: 02.00.14 * * Version History * --------------- @@ -36,6 +36,7 @@ * 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define. * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command * Priority to match SAM-4. + * 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION. * -------------------------------------------------------------------------- */ @@ -189,6 +190,7 @@ typedef struct _MPI2_SCSI_IO_REQUEST #define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26) #define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000) +#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24) #define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000) #define MPI2_SCSIIO_CONTROL_WRITE (0x01000000) #define MPI2_SCSIIO_CONTROL_READ (0x02000000) diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h index b0d4760..e93f8f5 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h @@ -6,7 +6,7 @@ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: October 11, 2006 * - * mpi2_ioc.h Version: 02.00.21 + * mpi2_ioc.h Version: 02.00.22 * * Version History * --------------- @@ -118,6 +118,9 @@ * MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure. * Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete. * 03-29-12 02.00.21 Added a product specific range to event values. + * 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE. + * Added ElapsedSeconds field to + * MPI2_EVENT_DATA_IR_OPERATION_STATUS. * -------------------------------------------------------------------------- */ @@ -284,6 +287,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0) /* IOCExceptions */ +#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200) #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100) #define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0) @@ -624,7 +628,7 @@ typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS U8 RAIDOperation; /* 0x04 */ U8 PercentComplete; /* 0x05 */ U16 Reserved2; /* 0x06 */ - U32 Resereved3; /* 0x08 */ + U32 ElapsedSeconds; /* 0x08 */ } MPI2_EVENT_DATA_IR_OPERATION_STATUS, MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS, Mpi2EventDataIrOperationStatus_t, diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h index 2b38af2..255b0ca 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h @@ -6,7 +6,7 @@ * Title: MPI Integrated RAID messages and structures * Creation Date: April 26, 2007 * - * mpi2_raid.h Version: 02.00.08 + * mpi2_raid.h Version: 02.00.09 * * Version History * --------------- @@ -27,6 +27,8 @@ * related structures and defines. * Added product-specific range to RAID Action values. * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. + * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. + * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. * -------------------------------------------------------------------------- */ @@ -276,10 +278,13 @@ typedef struct _MPI2_RAID_VOL_INDICATOR U64 TotalBlocks; /* 0x00 */ U64 BlocksRemaining; /* 0x08 */ U32 Flags; /* 0x10 */ + U32 ElapsedSeconds; /* 0x14 */ } MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR, Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t; /* defines for RAID Volume Indicator Flags field */ +#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000) + #define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) #define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) @@ -320,7 +325,7 @@ MPI2_POINTER pMpi2RaidCompatibilityResultStruct_t; /* RAID Action Reply ActionData union */ typedef union _MPI2_RAID_ACTION_REPLY_DATA { - U32 Word[5]; + U32 Word[6]; MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; U16 VolDevHandle; U8 VolumeState; diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h index 3cbe677..67c387f 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2010 LSI Corporation. + * Copyright (c) 2000-2012 LSI Corporation. * * * Name: mpi2_tool.h * Title: MPI diagnostic tool structures and definitions * Creation Date: March 26, 2007 * - * mpi2_tool.h Version: 02.00.07 + * mpi2_tool.h Version: 02.00.10 * * Version History * --------------- @@ -27,6 +27,8 @@ * Post Request. * 05-25-11 02.00.07 Added Flags field and related defines to * MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST. + * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that + * it uses MPI Chain SGE as well as MPI Simple SGE. * -------------------------------------------------------------------------- */ @@ -270,7 +272,7 @@ typedef struct _MPI2_TOOLBOX_BEACON_REQUEST #define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C) -/* Toolbox Diagnostic CLI Tool request message */ +/* MPI v2.0 Toolbox Diagnostic CLI Tool request message */ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { U8 Tool; /* 0x00 */ U8 Reserved1; /* 0x01 */ @@ -288,7 +290,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { U32 DataLength; /* 0x10 */ U8 DiagnosticCliCommand [MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH]; /* 0x14 */ - MPI2_SGE_SIMPLE_UNION SGL; /* 0x70 */ + MPI2_MPI_SGE_IO_UNION SGL; /* 0x70 */ } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, Mpi2ToolboxDiagnosticCliRequest_t, -- cgit v1.1 From ca6832e91b5d851fca4ea8579915cd2b6c958117 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 1 Feb 2013 21:55:43 +0530 Subject: [SCSI] mpt2sas: Update the timing requirements for issuing a Hard Reset Updated the mpt2sas driver code that issues hard reset to comply with the timing requirements mentioned in MPI specifications rev V. [jejb: checpatch fixes] Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_base.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index c76b18b..8bb1fe9 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3936,11 +3936,15 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, &ioc->chip->HostDiagnostic); - /* don't access any registers for 50 milliseconds */ - msleep(50); + /* This delay allows the chip PCIe hardware time to finish reset tasks*/ + if (sleep_flag == CAN_SLEEP) + msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); + else + mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); - /* 300 second max wait */ - for (count = 0; count < 3000000 ; count++) { + /* Approximately 300 second max wait */ + for (count = 0; count < (300000000 / + MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { host_diagnostic = readl(&ioc->chip->HostDiagnostic); @@ -3949,11 +3953,13 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) break; - /* wait 100 msec */ + /* Wait to pass the second read delay window */ if (sleep_flag == CAN_SLEEP) - msleep(1); + msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC + /1000); else - mdelay(1); + mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC + /1000); } if (host_diagnostic & MPI2_DIAG_HCB_MODE) { -- cgit v1.1 From 6241f22ca12a26ee149cbe31b27bac97dbdc8bc4 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 2 Feb 2013 00:56:18 +0530 Subject: [SCSI] mpt2sas: Fix for device scan following host reset could get stuck in a infinite loop Modified device scan routine so each configuration page read breaks from the while loop when the ioc_status is not equal to MPI2_IOCSTATUS_SUCCESS. [jejb: checkpatch fixes] Signed-off-by: Sreekanth Reddy Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 122 +++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 116e201..01dfbab 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -7097,12 +7097,15 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) struct _sas_device *sas_device; struct _sas_node *expander_device; static struct _raid_device *raid_device; + u8 retry_count; unsigned long flags; printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name); _scsih_sas_host_refresh(ioc); + printk(MPT2SAS_INFO_FMT "\tscan devices: expanders start\n", + ioc->name); /* expanders */ handle = 0xFFFF; while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, @@ -7111,6 +7114,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: " + "ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } handle = le16_to_cpu(expander_pg0.DevHandle); spin_lock_irqsave(&ioc->sas_node_lock, flags); expander_device = mpt2sas_scsih_expander_find_by_sas_address( @@ -7119,13 +7129,26 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) if (expander_device) _scsih_refresh_expander_links(ioc, expander_device, handle); - else + else { + printk(MPT2SAS_INFO_FMT "\tBEFORE adding expander: " + "handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(expander_pg0.SASAddress)); _scsih_expander_add(ioc, handle); + printk(MPT2SAS_INFO_FMT "\tAFTER adding expander: " + "handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(expander_pg0.SASAddress)); + } } + printk(MPT2SAS_INFO_FMT "\tscan devices: expanders complete\n", + ioc->name); + if (!ioc->ir_firmware) goto skip_to_sas; + printk(MPT2SAS_INFO_FMT "\tscan devices phys disk start\n", ioc->name); /* phys disk */ phys_disk_num = 0xFF; while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, @@ -7135,6 +7158,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:" + "ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } phys_disk_num = pd_pg0.PhysDiskNum; handle = le16_to_cpu(pd_pg0.DevHandle); spin_lock_irqsave(&ioc->sas_device_lock, flags); @@ -7146,17 +7176,46 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle) != 0) continue; + ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & + MPI2_IOCSTATUS_MASK; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan " + "ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { + printk(MPT2SAS_INFO_FMT "\tBEFORE adding phys disk: " + " handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(sas_device_pg0.SASAddress)); mpt2sas_transport_update_links(ioc, sas_address, handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); set_bit(handle, ioc->pd_handles); - _scsih_add_device(ioc, handle, 0, 1); + retry_count = 0; + /* This will retry adding the end device. + * _scsih_add_device() will decide on retries and + * return "1" when it should be retried + */ + while (_scsih_add_device(ioc, handle, retry_count++, + 1)) { + ssleep(1); + } + printk(MPT2SAS_INFO_FMT "\tAFTER adding phys disk: " + " handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(sas_device_pg0.SASAddress)); } } + printk(MPT2SAS_INFO_FMT "\tscan devices: phys disk complete\n", + ioc->name); + + printk(MPT2SAS_INFO_FMT "\tscan devices: volumes start\n", ioc->name); /* volumes */ handle = 0xFFFF; while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, @@ -7165,6 +7224,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: " + "ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } handle = le16_to_cpu(volume_pg1.DevHandle); spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_wwid(ioc, @@ -7176,18 +7242,38 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, sizeof(Mpi2RaidVolPage0_t))) continue; + ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & + MPI2_IOCSTATUS_MASK; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: " + "ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) { memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t)); element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED; element.VolDevHandle = volume_pg1.DevHandle; + printk(MPT2SAS_INFO_FMT "\tBEFORE adding volume: " + " handle (0x%04x)\n", ioc->name, + volume_pg1.DevHandle); _scsih_sas_volume_add(ioc, &element); + printk(MPT2SAS_INFO_FMT "\tAFTER adding volume: " + " handle (0x%04x)\n", ioc->name, + volume_pg1.DevHandle); } } + printk(MPT2SAS_INFO_FMT "\tscan devices: volumes complete\n", + ioc->name); + skip_to_sas: + printk(MPT2SAS_INFO_FMT "\tscan devices: end devices start\n", + ioc->name); /* sas devices */ handle = 0xFFFF; while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, @@ -7197,6 +7283,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) break; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:" + " ioc_status(0x%04x), loginfo(0x%08x)\n", + ioc->name, ioc_status, + le32_to_cpu(mpi_reply.IOCLogInfo)); + break; + } handle = le16_to_cpu(sas_device_pg0.DevHandle); if (!(_scsih_is_end_device( le32_to_cpu(sas_device_pg0.DeviceInfo)))) @@ -7209,12 +7302,31 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) continue; parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { + printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: " + "handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(sas_device_pg0.SASAddress)); mpt2sas_transport_update_links(ioc, sas_address, handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); - _scsih_add_device(ioc, handle, 0, 0); + retry_count = 0; + /* This will retry adding the end device. + * _scsih_add_device() will decide on retries and + * return "1" when it should be retried + */ + while (_scsih_add_device(ioc, handle, retry_count++, + 0)) { + ssleep(1); + } + printk(MPT2SAS_INFO_FMT "\tAFTER adding end device: " + "handle (0x%04x), sas_addr(0x%016llx)\n", + ioc->name, handle, (unsigned long long) + le64_to_cpu(sas_device_pg0.SASAddress)); } } + printk(MPT2SAS_INFO_FMT "\tscan devices: end devices complete\n", + ioc->name); + printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name); } @@ -8076,8 +8188,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (max_sectors != 0xFFFF) { if (max_sectors < 64) { shost->max_sectors = 64; - printk(MPT2SAS_WARN_FMT "Invalid value %d passed "\ - "for max_sectors, range is 64 to 32767. Assigning "\ + printk(MPT2SAS_WARN_FMT "Invalid value %d passed " + "for max_sectors, range is 64 to 32767. Assigning " "value of 64.\n", ioc->name, max_sectors); } else if (max_sectors > 32767) { shost->max_sectors = 32767; -- cgit v1.1 From 48ba2efc382f94fae16ca8ca011e5961a81ad1ea Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 2 Feb 2013 00:58:20 +0530 Subject: [SCSI] mpt2sas: fix firmware failure with wrong task attribute When SCSI command is received with task attribute not set, set it to SIMPLE. Previously it is set to untagged. This causes the firmware to fail the commands. Signed-off-by: Sreekanth Reddy Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 01dfbab..c78216c 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -3998,11 +3998,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) else mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; } else -/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */ -/* mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED; - */ - mpi_control |= (0x500); - + mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; } else mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; /* Make sure Device is not raid volume. -- cgit v1.1 From 148124d9310f3870fb016bd2637057841d5b7705 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 1 Feb 2013 22:02:04 +0530 Subject: [SCSI] mpt2sas: Calulate the Reply post queue depth calculation as per the MPI spec [jejb: checkpatch fixes] Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_base.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 8bb1fe9..ccd6d5a 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -2503,23 +2503,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) /* reply free queue sizing - taking into account for 64 FW events */ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; + /* calculate reply descriptor post queue depth */ + ioc->reply_post_queue_depth = ioc->hba_queue_depth + + ioc->reply_free_queue_depth + 1; /* align the reply post queue on the next 16 count boundary */ - if (!ioc->reply_free_queue_depth % 16) - ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16; - else - ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + - 32 - (ioc->reply_free_queue_depth % 16); + if (ioc->reply_post_queue_depth % 16) + ioc->reply_post_queue_depth += 16 - + (ioc->reply_post_queue_depth % 16); + + if (ioc->reply_post_queue_depth > facts->MaxReplyDescriptorPostQueueDepth) { - ioc->reply_post_queue_depth = min_t(u16, - (facts->MaxReplyDescriptorPostQueueDepth - - (facts->MaxReplyDescriptorPostQueueDepth % 16)), - (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16))); - ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16; - ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64; + ioc->reply_post_queue_depth = + facts->MaxReplyDescriptorPostQueueDepth - + (facts->MaxReplyDescriptorPostQueueDepth % 16); + ioc->hba_queue_depth = + ((ioc->reply_post_queue_depth - 64) / 2) - 1; + ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; } - dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: " "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message, -- cgit v1.1 From 627d1a19574732f2b2e8430afca54a58de1212bc Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 1 Feb 2013 22:03:17 +0530 Subject: [SCSI] mpt2sas: Bump driver vesion to v15.100.00.00 Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 1130197..6fbd084 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -69,8 +69,8 @@ #define MPT2SAS_DRIVER_NAME "mpt2sas" #define MPT2SAS_AUTHOR "LSI Corporation " #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" -#define MPT2SAS_DRIVER_VERSION "14.100.00.00" -#define MPT2SAS_MAJOR_VERSION 14 +#define MPT2SAS_DRIVER_VERSION "15.100.00.00" +#define MPT2SAS_MAJOR_VERSION 15 #define MPT2SAS_MINOR_VERSION 100 #define MPT2SAS_BUILD_VERSION 00 #define MPT2SAS_RELEASE_VERSION 00 -- cgit v1.1 From c3a634bf78242177fba9c85deb709e7b63ed0ef1 Mon Sep 17 00:00:00 2001 From: "Reddy, Sreekanth" Date: Tue, 26 Feb 2013 17:36:12 +0530 Subject: [SCSI] mpt2sas: fix for unused variable 'event_data' warning If CONFIG_SCSI_MPT2SAS_LOGGING is undefined, then these warnings are emitted drivers/scsi/mpt2sas/mpt2sas_scsih.c: In function '_scsih_sas_broadcast_primitive_event' drivers/scsi/mpt2sas/mpt2sas_scsih.c:5810:40: warning: unused variable 'event_data' Use pr_info() function instead of dewtprintk(). Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index c78216c..5100476 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -5815,9 +5815,10 @@ _scsih_sas_broadcast_primitive_event(struct MPT2SAS_ADAPTER *ioc, u8 task_abort_retries; mutex_lock(&ioc->tm_cmds.mutex); - dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: phy number(%d), " - "width(%d)\n", ioc->name, __func__, event_data->PhyNum, - event_data->PortWidth)); + pr_info(MPT2SAS_FMT + "%s: enter: phy number(%d), width(%d)\n", + ioc->name, __func__, event_data->PhyNum, + event_data->PortWidth); _scsih_block_io_all_device(ioc); -- cgit v1.1 From 56f2a8016e0ab54de8daaac3df4712cad0fcef2e Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 24 Apr 2013 21:19:47 -0400 Subject: [SCSI] Workaround for disks that report bad optimal transfer length Not all disks fill out the VPD pages correctly. Add a blacklist flag that allows us ignore the SBC-3 VPD pages for a given device. The BLIST_SKIP_VPD_PAGES flag triggers our existing skip_vpd_pages scsi_device parameter to bypass VPD scanning. Also blacklist the offending Seagate drive model. Reported-by: Mike Snitzer Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/scsi_devinfo.c | 1 + drivers/scsi/scsi_scan.c | 3 +++ include/scsi/scsi_devinfo.h | 1 + 3 files changed, 5 insertions(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 43fca91..f969aca 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -228,6 +228,7 @@ static struct { {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ {"SEAGATE", "ST3390N", "9546", BLIST_NOTQ}, + {"SEAGATE", "ST900MM0006", NULL, BLIST_SKIP_VPD_PAGES}, {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 852915a..307a811 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -926,6 +926,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; + if (*bflags & BLIST_SKIP_VPD_PAGES) + sdev->skip_vpd_pages = 1; + transport_configure_device(&sdev->sdev_gendev); if (sdev->host->hostt->slave_configure) { diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index cc1f3e7..447d2d7 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -31,4 +31,5 @@ #define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */ #define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ #define BLIST_NO_DIF 0x2000000 /* Disable T10 PI (DIF) */ +#define BLIST_SKIP_VPD_PAGES 0x4000000 /* Ignore SBC-3 VPD pages */ #endif -- cgit v1.1 From 28ce280fe46f0ba90c7df26d9fa5ba21a2e8a6bc Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 29 Apr 2013 12:13:01 -0400 Subject: [SCSI] 3w-xxxx: Create sense buffer for unsupported commands Make the driver return appropriate sense data when an unsupported operation is queued. This will cause the SCSI layer to stop issuing the offending command. Reported-by: Florian Westphal Signed-off-by: Martin K. Petersen Acked-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/3w-xxxx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 56662ae..b9276d1 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -216,6 +216,7 @@ #include #include #include +#include #include "3w-xxxx.h" /* Globals */ @@ -2009,7 +2010,8 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command); tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); - SCpnt->result = (DID_BAD_TARGET << 16); + SCpnt->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0); done(SCpnt); retval = 0; } -- cgit v1.1 From b09e66da3f5d9c47336dfe63f1e76696931fbdb0 Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:29:28 +0530 Subject: [SCSI] megaraid_sas: Return DID_ERROR for SCSI IO, when controller is in critical h/w error Do not return SCSI_MLQUEUE_HOST_BUSY, but send DID_ERROR to SCSI mid-layer, if adapter is in critical error state. "SCSI_MLQUEUE_HOST_BUSY" will keep same SCSI command in loop and it is not a right return value, if controller is hardware critical error. Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3a9ddae..cd2ee47 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1471,6 +1471,14 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd return SCSI_MLQUEUE_HOST_BUSY; spin_lock_irqsave(&instance->hba_lock, flags); + + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { + spin_unlock_irqrestore(&instance->hba_lock, flags); + scmd->result = DID_ERROR << 16; + done(scmd); + return 0; + } + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { spin_unlock_irqrestore(&instance->hba_lock, flags); return SCSI_MLQUEUE_HOST_BUSY; -- cgit v1.1 From b5bccadd804151d13530351f9a521e893cac5350 Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:29:54 +0530 Subject: [SCSI] megaraid_sas: Fix the interrupt mask for Gen2 controller Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index cd2ee47..3d1aee7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -711,7 +711,7 @@ megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs) */ status = readl(®s->outbound_intr_status); - if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) { + if (status & MFI_INTR_FLAG_REPLY_MESSAGE) { mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; } if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) { -- cgit v1.1 From 70b47b881e1e50360cba17417f779953956b960d Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:30:22 +0530 Subject: [SCSI] megaraid_sas: Update balance count in driver to be in sync of firmware Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a11df82..b06a240 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -503,8 +503,9 @@ u8 megasas_get_best_arm(struct LD_LOAD_BALANCE_INFO *lbInfo, u8 arm, u64 block, diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]); bestArm = (diff0 <= diff1 ? 0 : 1); - if ((bestArm == arm && pend0 > pend1 + 16) || - (bestArm != arm && pend1 > pend0 + 16)) + /*Make balance count from 16 to 4 to keep driver in sync with Firmware*/ + if ((bestArm == arm && pend0 > pend1 + 4) || + (bestArm != arm && pend1 > pend0 + 4)) bestArm ^= 1; /* Update the last accessed block on the correct pd */ -- cgit v1.1 From 105900d56e6f8a4dd47bb88fa387ab22ea787884 Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:30:54 +0530 Subject: [SCSI] megaraid_sas: Free event detail memory without device ID check Free event detail memory from more common place, instead of doing it for limited device types. Signed-off-by: Sumit Saxena Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3d1aee7..eadc8c8 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4599,10 +4599,6 @@ static void megasas_detach_one(struct pci_dev *pdev) break; default: megasas_release_mfi(instance); - pci_free_consistent(pdev, - sizeof(struct megasas_evt_detail), - instance->evt_detail, - instance->evt_detail_h); pci_free_consistent(pdev, sizeof(u32), instance->producer, instance->producer_h); @@ -4612,6 +4608,9 @@ static void megasas_detach_one(struct pci_dev *pdev) break; } + if (instance->evt_detail) + pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), + instance->evt_detail, instance->evt_detail_h); scsi_host_put(host); pci_set_drvdata(pdev, NULL); -- cgit v1.1 From 32d8745c88a08edaef1c35fcbf2ce3b6804b92d8 Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:31:18 +0530 Subject: [SCSI] megaraid_sas: Set IO request timeout value provided by OS timeout for Tape devices Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a7d5668..750cbdf 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1527,6 +1527,18 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); cmd->request_desc->SCSIIO.DevHandle = local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; + /* + * If the command is for the tape device, set the + * FP timeout to the os layer timeout value. + */ + if (scmd->device->type == TYPE_TAPE) { + if ((scmd->request->timeout / HZ) > 0xFFFF) + io_request->RaidContext.timeoutValue = + 0xFFFF; + else + io_request->RaidContext.timeoutValue = + scmd->request->timeout / HZ; + } } else { io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; io_request->DevHandle = device_id; -- cgit v1.1 From 21d3c7105b7d87ad85b5d16d5c573941fc51585f Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:31:43 +0530 Subject: [SCSI] megaraid_sas: Add support for MegaRAID Fury (device ID-0x005f) 12Gb/s controllers Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 48 +++++++++++++++++++++-------- drivers/scsi/megaraid/megaraid_sas_fp.c | 13 +++++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 27 ++++++++++------ 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 684cc34..d5efad7 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -49,6 +49,7 @@ #define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071 #define PCI_DEVICE_ID_LSI_FUSION 0x005b #define PCI_DEVICE_ID_LSI_INVADER 0x005d +#define PCI_DEVICE_ID_LSI_FURY 0x005f /* * ===================================== diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index eadc8c8..63108d7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -122,6 +122,8 @@ static struct pci_device_id megasas_pci_table[] = { /* Fusion */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)}, /* Invader */ + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)}, + /* Fury */ {} }; @@ -223,6 +225,7 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) cmd->frame_count = 0; if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) && (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) && + (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) && (reset_devices)) cmd->frame->hdr.cmd = MFI_CMD_INVALID; list_add_tail(&cmd->list, &instance->cmd_pool); @@ -1599,7 +1602,8 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { writel(MFI_STOP_ADP, &instance->reg_set->doorbell); } else { writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); @@ -1974,7 +1978,8 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) * First wait for all commands to complete */ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) ret = megasas_reset_fusion(scmd->device->host); else ret = megasas_generic_reset(scmd); @@ -2680,9 +2685,11 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || (instance->pdev->device == - PCI_DEVICE_ID_LSI_FUSION) || + PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == - PCI_DEVICE_ID_LSI_INVADER)) { + PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_FURY)) { writel( MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, &instance->reg_set->doorbell); @@ -2704,7 +2711,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == - PCI_DEVICE_ID_LSI_INVADER)) { + PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_FURY)) { writel(MFI_INIT_HOTPLUG, &instance->reg_set->doorbell); } else @@ -2727,13 +2736,17 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device - == PCI_DEVICE_ID_LSI_INVADER)) { + == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device + == PCI_DEVICE_ID_LSI_FURY)) { writel(MFI_RESET_FLAGS, &instance->reg_set->doorbell); if ((instance->pdev->device == - PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == - PCI_DEVICE_ID_LSI_INVADER)) { + PCI_DEVICE_ID_LSI_FUSION) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_FURY)) { for (i = 0; i < (10 * 1000); i += 20) { if (readl( &instance-> @@ -2958,6 +2971,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) cmd->frame->io.pad_0 = 0; if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) && (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) && + (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) && (reset_devices)) cmd->frame->hdr.cmd = MFI_CMD_INVALID; } @@ -3495,6 +3509,7 @@ static int megasas_init_fw(struct megasas_instance *instance) switch (instance->pdev->device) { case PCI_DEVICE_ID_LSI_FUSION: case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_FURY: instance->instancet = &megasas_instance_template_fusion; break; case PCI_DEVICE_ID_LSI_SAS1078R: @@ -3528,7 +3543,8 @@ static int megasas_init_fw(struct megasas_instance *instance) if (msix_enable && !msix_disable) { /* Check max MSI-X vectors */ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { instance->msix_vectors = (readl(&instance->reg_set-> outbound_scratch_pad_2 ) & 0x1F) + 1; @@ -3933,7 +3949,8 @@ static int megasas_io_attach(struct megasas_instance *instance) /* Fusion only supports host reset */ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) { + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { host->hostt->eh_device_reset_handler = NULL; host->hostt->eh_bus_reset_handler = NULL; } @@ -4044,6 +4061,7 @@ static int megasas_probe_one(struct pci_dev *pdev, switch (instance->pdev->device) { case PCI_DEVICE_ID_LSI_FUSION: case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_FURY: { struct fusion_context *fusion; @@ -4136,7 +4154,8 @@ static int megasas_probe_one(struct pci_dev *pdev, instance->disableOnlineCtrlReset = 1; if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); else INIT_WORK(&instance->work_init, process_fw_state_change_wq); @@ -4227,7 +4246,8 @@ static int megasas_probe_one(struct pci_dev *pdev, free_irq(instance->pdev->irq, &instance->irq_context[0]); fail_irq: if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) + (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) megasas_release_fusion(instance); else megasas_release_mfi(instance); @@ -4438,6 +4458,7 @@ megasas_resume(struct pci_dev *pdev) switch (instance->pdev->device) { case PCI_DEVICE_ID_LSI_FUSION: case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_FURY: { megasas_reset_reply_desc(instance); if (megasas_ioc_init_fusion(instance)) { @@ -4587,6 +4608,7 @@ static void megasas_detach_one(struct pci_dev *pdev) switch (instance->pdev->device) { case PCI_DEVICE_ID_LSI_FUSION: case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_FURY: megasas_release_fusion(instance); for (i = 0; i < 2 ; i++) if (fusion->ld_map[i]) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index b06a240..356b684 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -238,6 +238,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, u64 row; u8 retval = TRUE; int error_code = 0; + u8 do_invader = 0; + + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER || + instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) + do_invader = 1; row = mega_div64_32(stripRow, raid->rowDataSize); @@ -282,9 +287,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, else { *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */ if ((raid->level >= 5) && - ((instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER && - raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) + (!do_invader || (do_invader && + (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { /* Get alternate Pd. */ @@ -405,7 +409,8 @@ MR_BuildRaidContext(struct megasas_instance *instance, } pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec; - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) pRAID_Context->regLockFlags = (isRead) ? raid->regTypeReqOnRead : raid->regTypeReqOnWrite; else diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 750cbdf..454743d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1071,7 +1071,8 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, fusion = instance->ctrl_context; - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr; sgl_ptr_end += fusion->max_sge_in_main_msg - 1; sgl_ptr_end->Flags = 0; @@ -1088,7 +1089,8 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, sgl_ptr->Length = sg_dma_len(os_sgl); sgl_ptr->Address = sg_dma_address(os_sgl); sgl_ptr->Flags = 0; - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { if (i == sge_count - 1) sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST; } @@ -1100,8 +1102,10 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, (sge_count > fusion->max_sge_in_main_msg)) { struct MPI25_IEEE_SGE_CHAIN64 *sg_chain; - if (instance->pdev->device == - PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == + PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_FURY)) { if ((cmd->io_request->IoFlags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) != MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) @@ -1117,8 +1121,10 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, sg_chain = sgl_ptr; /* Prepare chain element */ sg_chain->NextChainOffset = 0; - if (instance->pdev->device == - PCI_DEVICE_ID_LSI_INVADER) + if ((instance->pdev->device == + PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_FURY)) sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT; else sg_chain->Flags = @@ -1434,7 +1440,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, cmd->request_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { if (io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED) cmd->request_desc->SCSIIO.RequestFlags = @@ -1465,7 +1472,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, cmd->request_desc->SCSIIO.RequestFlags = (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { if (io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED) cmd->request_desc->SCSIIO.RequestFlags = @@ -1941,7 +1949,8 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, fusion = instance->ctrl_context; io_req = cmd->io_request; - if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) { + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL; sgl_ptr_end += fusion->max_sge_in_main_msg - 1; -- cgit v1.1 From 39b72c3c74c775d2d1b926d9f702762c0f721eba Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:32:43 +0530 Subject: [SCSI] megaraid_sas: Add support to display Customer branding details in syslog Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 26 ++++++++++++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 62 +++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d5efad7..9504b51 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -52,6 +52,32 @@ #define PCI_DEVICE_ID_LSI_FURY 0x005f /* + * Intel HBA SSDIDs + */ +#define MEGARAID_INTEL_RS3DC080_SSDID 0x9360 +#define MEGARAID_INTEL_RS3DC040_SSDID 0x9362 +#define MEGARAID_INTEL_RS3SC008_SSDID 0x9380 +#define MEGARAID_INTEL_RS3MC044_SSDID 0x9381 +#define MEGARAID_INTEL_RS3WC080_SSDID 0x9341 +#define MEGARAID_INTEL_RS3WC040_SSDID 0x9343 + +/* + * Intel HBA branding + */ +#define MEGARAID_INTEL_RS3DC080_BRANDING \ + "Intel(R) RAID Controller RS3DC080" +#define MEGARAID_INTEL_RS3DC040_BRANDING \ + "Intel(R) RAID Controller RS3DC040" +#define MEGARAID_INTEL_RS3SC008_BRANDING \ + "Intel(R) RAID Controller RS3SC008" +#define MEGARAID_INTEL_RS3MC044_BRANDING \ + "Intel(R) RAID Controller RS3MC044" +#define MEGARAID_INTEL_RS3WC080_BRANDING \ + "Intel(R) RAID Controller RS3WC080" +#define MEGARAID_INTEL_RS3WC040_BRANDING \ + "Intel(R) RAID Controller RS3WC040" + +/* * ===================================== * MegaRAID SAS MFI firmware definitions * ===================================== diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 454743d..73aa68e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -864,6 +864,66 @@ megasas_sync_map_info(struct megasas_instance *instance) return ret; } +/* + * meagasas_display_intel_branding - Display branding string + * @instance: per adapter object + * + * Return nothing. + */ +static void +megasas_display_intel_branding(struct megasas_instance *instance) +{ + if (instance->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL) + return; + + switch (instance->pdev->device) { + case PCI_DEVICE_ID_LSI_INVADER: + switch (instance->pdev->subsystem_device) { + case MEGARAID_INTEL_RS3DC080_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3DC080_BRANDING); + break; + case MEGARAID_INTEL_RS3DC040_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3DC040_BRANDING); + break; + case MEGARAID_INTEL_RS3SC008_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3SC008_BRANDING); + break; + case MEGARAID_INTEL_RS3MC044_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3MC044_BRANDING); + break; + default: + break; + } + break; + case PCI_DEVICE_ID_LSI_FURY: + switch (instance->pdev->subsystem_device) { + case MEGARAID_INTEL_RS3WC080_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3WC080_BRANDING); + break; + case MEGARAID_INTEL_RS3WC040_SSDID: + dev_info(&instance->pdev->dev, "scsi host %d: %s\n", + instance->host->host_no, + MEGARAID_INTEL_RS3WC040_BRANDING); + break; + default: + break; + } + break; + default: + break; + } +} + /** * megasas_init_adapter_fusion - Initializes the FW * @instance: Adapter soft state @@ -944,6 +1004,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) if (megasas_ioc_init_fusion(instance)) goto fail_ioc_init; + megasas_display_intel_branding(instance); + instance->flag_ieee = 1; fusion->map_sz = sizeof(struct MR_FW_RAID_MAP) + -- cgit v1.1 From 5d0d908d4481187070cc94664417ab347f15d1fe Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:33:29 +0530 Subject: [SCSI] megaraid_sas: Set IoFlags to enable Fast Path for JBODs for 12 Gb/s controllers Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 73aa68e..c60f478 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1592,6 +1592,10 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, io_request->RaidContext.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT; + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) + io_request->IoFlags |= + MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH; cmd->request_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); -- cgit v1.1 From d46a3ad679c7232b72b21c6d0ca047dc4a68063f Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:34:14 +0530 Subject: [SCSI] megaraid_sas: Add support for Extended MSI-x vectors for 12Gb/s controller This Driver will use more than 8 MSI-x support provided by Invader/Fury max upto 128 MSI-x. [jejb: fix checkpatch warning] Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 25 +++++-- drivers/scsi/megaraid/megaraid_sas_base.c | 111 ++++++++++++++++++++-------- drivers/scsi/megaraid/megaraid_sas_fusion.c | 38 ++++++++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 5 +- 4 files changed, 136 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 9504b51..2371e5c 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -786,7 +786,7 @@ struct megasas_ctrl_info { #define MEGASAS_INT_CMDS 32 #define MEGASAS_SKINNY_INT_CMDS 5 -#define MEGASAS_MAX_MSIX_QUEUES 16 +#define MEGASAS_MAX_MSIX_QUEUES 128 /* * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit * SGLs based on the size of dma_addr_t @@ -811,6 +811,11 @@ struct megasas_ctrl_info { #define MFI_1068_PCSR_OFFSET 0x84 #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0xDDDD0000 + +#define MR_MAX_REPLY_QUEUES_OFFSET 0X0000001F +#define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 +#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14 +#define MR_MAX_MSIX_REG_ARRAY 16 /* * register set for both 1068 and 1078 controllers * structure extended for 1078 registers @@ -920,6 +925,15 @@ union megasas_sgl_frame { } __attribute__ ((packed)); +typedef union _MFI_CAPABILITIES { + struct { + u32 support_fp_remote_lun:1; + u32 support_additional_msix:1; + u32 reserved:30; + } mfi_capabilities; + u32 reg; +} MFI_CAPABILITIES; + struct megasas_init_frame { u8 cmd; /*00h */ @@ -927,7 +941,7 @@ struct megasas_init_frame { u8 cmd_status; /*02h */ u8 reserved_1; /*03h */ - u32 reserved_2; /*04h */ + MFI_CAPABILITIES driver_operations; /*04h*/ u32 context; /*08h */ u32 pad_0; /*0Ch */ @@ -1324,7 +1338,7 @@ struct megasas_instance { unsigned long base_addr; struct megasas_register_set __iomem *reg_set; - + u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; u8 ld_ids[MEGASAS_MAX_LD_IDS]; s8 init_id; @@ -1393,6 +1407,7 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; int throttlequeuedepth; + u8 mask_interrupts; }; enum { @@ -1408,8 +1423,8 @@ struct megasas_instance_template { void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \ u32, struct megasas_register_set __iomem *); - void (*enable_intr)(struct megasas_register_set __iomem *) ; - void (*disable_intr)(struct megasas_register_set __iomem *); + void (*enable_intr)(struct megasas_instance *); + void (*disable_intr)(struct megasas_instance *); int (*clear_intr)(struct megasas_register_set __iomem *); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 63108d7..11f1c94 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -244,8 +244,10 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) * @regs: MFI register set */ static inline void -megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) +megasas_enable_intr_xscale(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; writel(0, &(regs)->outbound_intr_mask); /* Dummy readl to force pci flush */ @@ -257,9 +259,11 @@ megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) * @regs: MFI register set */ static inline void -megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) +megasas_disable_intr_xscale(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; u32 mask = 0x1f; + regs = instance->reg_set; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); @@ -413,8 +417,10 @@ static struct megasas_instance_template megasas_instance_template_xscale = { * @regs: MFI register set */ static inline void -megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) +megasas_enable_intr_ppc(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); writel(~0x80000000, &(regs)->outbound_intr_mask); @@ -428,9 +434,11 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) * @regs: MFI register set */ static inline void -megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) +megasas_disable_intr_ppc(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; u32 mask = 0xFFFFFFFF; + regs = instance->reg_set; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); @@ -531,8 +539,10 @@ static struct megasas_instance_template megasas_instance_template_ppc = { * @regs: MFI register set */ static inline void -megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs) +megasas_enable_intr_skinny(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; writel(0xFFFFFFFF, &(regs)->outbound_intr_mask); writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); @@ -546,9 +556,11 @@ megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs) * @regs: MFI register set */ static inline void -megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs) +megasas_disable_intr_skinny(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; u32 mask = 0xFFFFFFFF; + regs = instance->reg_set; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); @@ -666,8 +678,10 @@ static struct megasas_instance_template megasas_instance_template_skinny = { * @regs: MFI register set */ static inline void -megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) +megasas_enable_intr_gen2(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); /* write ~0x00000005 (4 & 1) to the intr mask*/ @@ -682,9 +696,11 @@ megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) * @regs: MFI register set */ static inline void -megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs) +megasas_disable_intr_gen2(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; u32 mask = 0xFFFFFFFF; + regs = instance->reg_set; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); @@ -1707,7 +1723,7 @@ void megasas_do_ocr(struct megasas_instance *instance) (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) { *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN; } - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; instance->issuepend_done = 0; @@ -2490,7 +2506,7 @@ process_fw_state_change_wq(struct work_struct *work) printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault" "state, restarting it...\n"); - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); atomic_set(&instance->fw_outstanding, 0); atomic_set(&instance->fw_reset_no_pci_access, 1); @@ -2531,7 +2547,7 @@ process_fw_state_change_wq(struct work_struct *work) spin_lock_irqsave(&instance->hba_lock, flags); instance->adprecovery = MEGASAS_HBA_OPERATIONAL; spin_unlock_irqrestore(&instance->hba_lock, flags); - instance->instancet->enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance); megasas_issue_pending_cmds_again(instance); instance->issuepend_done = 1; @@ -2594,7 +2610,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, } - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; instance->issuepend_done = 0; @@ -2728,7 +2744,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) /* * Bring it to READY state; assuming max wait 10 secs */ - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == @@ -3374,7 +3390,7 @@ megasas_issue_init_mfi(struct megasas_instance *instance) /* * disable the intr before firing the init frame to FW */ - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); /* * Issue the init frame in polled mode @@ -3481,11 +3497,11 @@ static int megasas_init_fw(struct megasas_instance *instance) { u32 max_sectors_1; u32 max_sectors_2; - u32 tmp_sectors, msix_enable; + u32 tmp_sectors, msix_enable, scratch_pad_2; struct megasas_register_set __iomem *reg_set; struct megasas_ctrl_info *ctrl_info; unsigned long bar_list; - int i; + int i, loop, fw_msix_count = 0; /* Find first memory bar */ bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); @@ -3537,21 +3553,49 @@ static int megasas_init_fw(struct megasas_instance *instance) if (megasas_transition_to_ready(instance, 0)) goto fail_ready_state; + /* + * MSI-X host index 0 is common for all adapter. + * It is used for all MPT based Adapters. + */ + instance->reply_post_host_index_addr[0] = + (u32 *)((u8 *)instance->reg_set + + MPI2_REPLY_POST_HOST_INDEX_OFFSET); + /* Check if MSI-X is supported while in ready state */ msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & 0x4000000) >> 0x1a; if (msix_enable && !msix_disable) { + scratch_pad_2 = readl + (&instance->reg_set->outbound_scratch_pad_2); /* Check max MSI-X vectors */ - if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { - instance->msix_vectors = (readl(&instance->reg_set-> - outbound_scratch_pad_2 - ) & 0x1F) + 1; + if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) { + instance->msix_vectors = (scratch_pad_2 + & MR_MAX_REPLY_QUEUES_OFFSET) + 1; + fw_msix_count = instance->msix_vectors; if (msix_vectors) instance->msix_vectors = min(msix_vectors, instance->msix_vectors); + } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) + || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { + /* Invader/Fury supports more than 8 MSI-X */ + instance->msix_vectors = ((scratch_pad_2 + & MR_MAX_REPLY_QUEUES_EXT_OFFSET) + >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1; + fw_msix_count = instance->msix_vectors; + /* Save 1-15 reply post index address to local memory + * Index 0 is already saved from reg offset + * MPI2_REPLY_POST_HOST_INDEX_OFFSET + */ + for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) { + instance->reply_post_host_index_addr[loop] = + (u32 *)((u8 *)instance->reg_set + + MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET + + (loop * 0x10)); + } + if (msix_vectors) + instance->msix_vectors = min(msix_vectors, + instance->msix_vectors); } else instance->msix_vectors = 1; /* Don't bother allocating more MSI-X vectors than cpus */ @@ -3571,6 +3615,12 @@ static int megasas_init_fw(struct megasas_instance *instance) } } else instance->msix_vectors = 0; + + dev_info(&instance->pdev->dev, "[scsi%d]: FW supports" + "<%d> MSIX vector,Online CPUs: <%d>," + "Current MSIX <%d>\n", instance->host->host_no, + fw_msix_count, (unsigned int)num_online_cpus(), + instance->msix_vectors); } /* Get operational params, sge flags, send init cmd to controller */ @@ -4166,6 +4216,7 @@ static int megasas_probe_one(struct pci_dev *pdev, if (megasas_init_fw(instance)) goto fail_init_mfi; +retry_irq_register: /* * Register IRQ */ @@ -4183,7 +4234,9 @@ static int megasas_probe_one(struct pci_dev *pdev, free_irq( instance->msixentry[j].vector, &instance->irq_context[j]); - goto fail_irq; + /* Retry irq register for IO_APIC */ + instance->msix_vectors = 0; + goto retry_irq_register; } } } else { @@ -4197,7 +4250,7 @@ static int megasas_probe_one(struct pci_dev *pdev, } } - instance->instancet->enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance); /* * Store instance in PCI softstate @@ -4237,7 +4290,7 @@ static int megasas_probe_one(struct pci_dev *pdev, megasas_mgmt_info.max_index--; pci_set_drvdata(pdev, NULL); - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); if (instance->msix_vectors) for (i = 0 ; i < instance->msix_vectors; i++) free_irq(instance->msixentry[i].vector, @@ -4387,7 +4440,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) tasklet_kill(&instance->isr_tasklet); pci_set_drvdata(instance->pdev, instance); - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); if (instance->msix_vectors) for (i = 0 ; i < instance->msix_vectors; i++) @@ -4512,7 +4565,7 @@ megasas_resume(struct pci_dev *pdev) } } - instance->instancet->enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance); instance->unload = 0; /* @@ -4594,7 +4647,7 @@ static void megasas_detach_one(struct pci_dev *pdev) pci_set_drvdata(instance->pdev, NULL); - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); if (instance->msix_vectors) for (i = 0 ; i < instance->msix_vectors; i++) @@ -4654,7 +4707,7 @@ static void megasas_shutdown(struct pci_dev *pdev) instance->unload = 1; megasas_flush_cache(instance); megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); if (instance->msix_vectors) for (i = 0 ; i < instance->msix_vectors; i++) free_irq(instance->msixentry[i].vector, diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index c60f478..748b8ac 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -101,8 +101,10 @@ extern int resetwaittime; * @regs: MFI register set */ void -megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs) +megasas_enable_intr_fusion(struct megasas_instance *instance) { + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; /* For Thunderbolt/Invader also clear intr on enable */ writel(~0, ®s->outbound_intr_status); readl(®s->outbound_intr_status); @@ -111,6 +113,7 @@ megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs) /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask); + instance->mask_interrupts = 0; } /** @@ -118,10 +121,13 @@ megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs) * @regs: MFI register set */ void -megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs) +megasas_disable_intr_fusion(struct megasas_instance *instance) { u32 mask = 0xFFFFFFFF; u32 status; + struct megasas_register_set __iomem *regs; + regs = instance->reg_set; + instance->mask_interrupts = 1; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ @@ -643,6 +649,12 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) init_frame->cmd = MFI_CMD_INIT; init_frame->cmd_status = 0xFF; + /* driver support Extended MSIX */ + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) + init_frame->driver_operations. + mfi_capabilities.support_additional_msix = 1; + init_frame->queue_info_new_phys_addr_lo = ioc_init_handle; init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST); @@ -657,7 +669,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) /* * disable the intr before firing the init frame */ - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); for (i = 0; i < (10 * 1000); i += 20) { if (readl(&instance->reg_set->doorbell) & 1) @@ -1911,8 +1923,15 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) return IRQ_NONE; wmb(); - writel((MSIxIndex << 24) | fusion->last_reply_idx[MSIxIndex], - &instance->reg_set->reply_post_host_index); + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) + writel(((MSIxIndex & 0x7) << 24) | + fusion->last_reply_idx[MSIxIndex], + instance->reply_post_host_index_addr[MSIxIndex/8]); + else + writel((MSIxIndex << 24) | + fusion->last_reply_idx[MSIxIndex], + instance->reply_post_host_index_addr[0]); megasas_check_and_restore_queue_depth(instance); return IRQ_HANDLED; } @@ -1954,6 +1973,9 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp) struct megasas_instance *instance = irq_context->instance; u32 mfiStatus, fw_state; + if (instance->mask_interrupts) + return IRQ_NONE; + if (!instance->msix_vectors) { mfiStatus = instance->instancet->clear_intr(instance->reg_set); if (!mfiStatus) @@ -2219,7 +2241,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) mutex_lock(&instance->reset_mutex); set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; - instance->instancet->disable_intr(instance->reg_set); + instance->instancet->disable_intr(instance); msleep(1000); /* First try waiting for commands to complete */ @@ -2343,7 +2365,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); - instance->instancet->enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance); instance->adprecovery = MEGASAS_HBA_OPERATIONAL; /* Re-fire management commands */ @@ -2405,7 +2427,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) retval = FAILED; } else { clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); - instance->instancet->enable_intr(instance->reg_set); + instance->instancet->enable_intr(instance); instance->adprecovery = MEGASAS_HBA_OPERATIONAL; } out: diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index f68a3cd..004c18e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -43,7 +43,7 @@ #define HOST_DIAG_WRITE_ENABLE 0x80 #define HOST_DIAG_RESET_ADAPTER 0x4 #define MEGASAS_FUSION_MAX_RESET_TRIES 3 -#define MAX_MSIX_QUEUES_FUSION 16 +#define MAX_MSIX_QUEUES_FUSION 128 /* Invader defines */ #define MPI2_TYPE_CUDA 0x2 @@ -62,6 +62,9 @@ #define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 #define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 +#define MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) +#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) + /* * Raid context flags */ -- cgit v1.1 From bc93d425fcb6443ffd6e20efa08f4960a30ab26f Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:35:04 +0530 Subject: [SCSI] megaraid_sas: Add support for Uneven Span PRL11 MegaRAID older Firmware does not support uneven span configuration for PRL11. E.g User wants to create 34 Driver PRL11 config, it was not possible using old firmware, since it was not supported configuration in old firmware Old Firmware expect even number of Drives in each span and same number of physical drives at each span. Considering above design, 17 Drives at Span-0 and 17 drives at span-1 was not possible. Now, using this new feature Firmware and Driver both required changes. New Firmware can allow user to create 16 Drives at span-0 and 18 Drives at span-1. This will allow user to create 34 Drives Uneven span PRL11. RAID map is interface between Driver and FW to fetch all required fields(attributes) for each Virtual Drives. Since legacy RAID map consider Even Span design, there was no place to keep Uneven span information in existing Raid map. Because of this limitation, for Uneven span VD, driver can not use RAID map. This patch address the changes required in Driver to support Uneven span PRL11 support. 1. Driver will find if Firmware has UnevenSpanSupport or not by reading Controller Info. 2. If Firmware has UnvenSpan PRL11 support, then Driver will inform about its capability of handling UnevenSpan PRL11 to the firmware. 3. Driver will update its copy of span info on each time Raid map update is called. 4. Follow different IO path if it is Uneven Span. (For Uneven Span, Driver uses Span Set info to find relavent fields for that particular Virtual Disk) More verbose prints will be available by setting "SPAN_DEBUG" to 1 at compilation time. Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 127 ++++- drivers/scsi/megaraid/megaraid_sas_base.c | 26 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 766 ++++++++++++++++++++++++++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 30 +- 5 files changed, 904 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 2371e5c..55a08d8 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -190,6 +190,12 @@ #define MR_DCMD_PD_LIST_QUERY 0x02010100 /* + * Global functions + */ +extern u8 MR_ValidateMapInfo(struct megasas_instance *instance); + + +/* * MFI command completion codes */ enum MFI_STAT { @@ -729,8 +735,126 @@ struct megasas_ctrl_info { */ char package_version[0x60]; - u8 pad[0x800 - 0x6a0]; + /* + * If adapterOperations.supportMoreThan8Phys is set, + * and deviceInterface.portCount is greater than 8, + * SAS Addrs for first 8 ports shall be populated in + * deviceInterface.portAddr, and the rest shall be + * populated in deviceInterfacePortAddr2. + */ + u64 deviceInterfacePortAddr2[8]; /*6a0h */ + u8 reserved3[128]; /*6e0h */ + + struct { /*760h */ + u16 minPdRaidLevel_0:4; + u16 maxPdRaidLevel_0:12; + + u16 minPdRaidLevel_1:4; + u16 maxPdRaidLevel_1:12; + + u16 minPdRaidLevel_5:4; + u16 maxPdRaidLevel_5:12; + + u16 minPdRaidLevel_1E:4; + u16 maxPdRaidLevel_1E:12; + + u16 minPdRaidLevel_6:4; + u16 maxPdRaidLevel_6:12; + + u16 minPdRaidLevel_10:4; + u16 maxPdRaidLevel_10:12; + + u16 minPdRaidLevel_50:4; + u16 maxPdRaidLevel_50:12; + + u16 minPdRaidLevel_60:4; + u16 maxPdRaidLevel_60:12; + + u16 minPdRaidLevel_1E_RLQ0:4; + u16 maxPdRaidLevel_1E_RLQ0:12; + + u16 minPdRaidLevel_1E0_RLQ0:4; + u16 maxPdRaidLevel_1E0_RLQ0:12; + + u16 reserved[6]; + } pdsForRaidLevels; + + u16 maxPds; /*780h */ + u16 maxDedHSPs; /*782h */ + u16 maxGlobalHSPs; /*784h */ + u16 ddfSize; /*786h */ + u8 maxLdsPerArray; /*788h */ + u8 partitionsInDDF; /*789h */ + u8 lockKeyBinding; /*78ah */ + u8 maxPITsPerLd; /*78bh */ + u8 maxViewsPerLd; /*78ch */ + u8 maxTargetId; /*78dh */ + u16 maxBvlVdSize; /*78eh */ + + u16 maxConfigurableSSCSize; /*790h */ + u16 currentSSCsize; /*792h */ + + char expanderFwVersion[12]; /*794h */ + + u16 PFKTrialTimeRemaining; /*7A0h */ + + u16 cacheMemorySize; /*7A2h */ + + struct { /*7A4h */ + u32 supportPIcontroller:1; + u32 supportLdPIType1:1; + u32 supportLdPIType2:1; + u32 supportLdPIType3:1; + u32 supportLdBBMInfo:1; + u32 supportShieldState:1; + u32 blockSSDWriteCacheChange:1; + u32 supportSuspendResumeBGops:1; + u32 supportEmergencySpares:1; + u32 supportSetLinkSpeed:1; + u32 supportBootTimePFKChange:1; + u32 supportJBOD:1; + u32 disableOnlinePFKChange:1; + u32 supportPerfTuning:1; + u32 supportSSDPatrolRead:1; + u32 realTimeScheduler:1; + + u32 supportResetNow:1; + u32 supportEmulatedDrives:1; + u32 headlessMode:1; + u32 dedicatedHotSparesLimited:1; + + + u32 supportUnevenSpans:1; + u32 reserved:11; + } adapterOperations2; + + u8 driverVersion[32]; /*7A8h */ + u8 maxDAPdCountSpinup60; /*7C8h */ + u8 temperatureROC; /*7C9h */ + u8 temperatureCtrl; /*7CAh */ + u8 reserved4; /*7CBh */ + u16 maxConfigurablePds; /*7CCh */ + + + u8 reserved5[2]; /*0x7CDh */ + + /* + * HA cluster information + */ + struct { + u32 peerIsPresent:1; + u32 peerIsIncompatible:1; + u32 hwIncompatible:1; + u32 fwVersionMismatch:1; + u32 ctrlPropIncompatible:1; + u32 premiumFeatureMismatch:1; + u32 reserved:26; + } cluster; + + char clusterId[16]; /*7D4h */ + + u8 pad[0x800-0x7E4]; /*7E4 */ } __packed; /* @@ -1389,6 +1513,7 @@ struct megasas_instance { u8 flag_ieee; u8 issuepend_done; u8 disableOnlineCtrlReset; + u8 UnevenSpanSupport; u8 adprecovery; unsigned long last_time; u32 mfiStatus; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 11f1c94..6d7b656 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -171,8 +171,6 @@ megasas_sync_map_info(struct megasas_instance *instance); int wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd); void megasas_reset_reply_desc(struct megasas_instance *instance); -u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, - struct LD_LOAD_BALANCE_INFO *lbInfo); int megasas_reset_fusion(struct Scsi_Host *shost); void megasas_fusion_ocr_wq(struct work_struct *work); @@ -2295,6 +2293,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, /* Check for LD map update */ if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) && (cmd->frame->dcmd.mbox.b[1] == 1)) { + fusion->fast_path_io = 0; spin_lock_irqsave(instance->host->host_lock, flags); if (cmd->frame->hdr.cmd_status != 0) { if (cmd->frame->hdr.cmd_status != @@ -2312,9 +2311,13 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, } else instance->map_id++; megasas_return_cmd(instance, cmd); - if (MR_ValidateMapInfo( - fusion->ld_map[(instance->map_id & 1)], - fusion->load_balance_info)) + + /* + * Set fast path IO to ZERO. + * Validate Map will set proper value. + * Meanwhile all IOs will go as LD IO. + */ + if (MR_ValidateMapInfo(instance)) fusion->fast_path_io = 1; else fusion->fast_path_io = 0; @@ -3661,6 +3664,18 @@ static int megasas_init_fw(struct megasas_instance *instance) tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); instance->disableOnlineCtrlReset = ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; + instance->UnevenSpanSupport = + ctrl_info->adapterOperations2.supportUnevenSpans; + if (instance->UnevenSpanSupport) { + struct fusion_context *fusion = instance->ctrl_context; + dev_info(&instance->pdev->dev, "FW supports: " + "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport); + if (MR_ValidateMapInfo(instance)) + fusion->fast_path_io = 1; + else + fusion->fast_path_io = 0; + + } } instance->max_sectors_per_req = instance->max_num_sge * @@ -4202,6 +4217,7 @@ static int megasas_probe_one(struct pci_dev *pdev, instance->unload = 1; instance->last_time = 0; instance->disableOnlineCtrlReset = 1; + instance->UnevenSpanSupport = 0; if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 356b684..8056eac 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -60,10 +60,22 @@ #define FALSE 0 #define TRUE 1 +#define SPAN_DEBUG 0 +#define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowSize) +#define SPAN_ROW_DATA_SIZE(map_, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize) +#define SPAN_INVALID 0xff + /* Prototypes */ -void -mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map, - struct LD_LOAD_BALANCE_INFO *lbInfo); +void mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map, + struct LD_LOAD_BALANCE_INFO *lbInfo); + +static void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, + PLD_SPAN_INFO ldSpanInfo); +static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info, + struct RAID_CONTEXT *pRAID_Context, struct MR_FW_RAID_MAP_ALL *map); +static u64 get_row_from_strip(struct megasas_instance *instance, u32 ld, + u64 strip, struct MR_FW_RAID_MAP_ALL *map); u32 mega_mod64(u64 dividend, u32 divisor) { @@ -148,9 +160,12 @@ static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span, /* * This function will validate Map info data provided by FW */ -u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, - struct LD_LOAD_BALANCE_INFO *lbInfo) +u8 MR_ValidateMapInfo(struct megasas_instance *instance) { + struct fusion_context *fusion = instance->ctrl_context; + struct MR_FW_RAID_MAP_ALL *map = fusion->ld_map[(instance->map_id & 1)]; + struct LD_LOAD_BALANCE_INFO *lbInfo = fusion->load_balance_info; + PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap; if (pFwRaidMap->totalSize != @@ -167,13 +182,16 @@ u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, return 0; } + if (instance->UnevenSpanSupport) + mr_update_span_set(map, ldSpanInfo); + mr_update_load_balance_params(map, lbInfo); return 1; } u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, - struct MR_FW_RAID_MAP_ALL *map, int *div_error) + struct MR_FW_RAID_MAP_ALL *map) { struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map); struct MR_QUAD_ELEMENT *quad; @@ -185,10 +203,8 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) { quad = &pSpanBlock->block_span_info.quad[j]; - if (quad->diff == 0) { - *div_error = 1; - return span; - } + if (quad->diff == 0) + return SPAN_INVALID; if (quad->logStart <= row && row <= quad->logEnd && (mega_mod64(row-quad->logStart, quad->diff)) == 0) { if (span_blk != NULL) { @@ -207,7 +223,456 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, } } } - return span; + return SPAN_INVALID; +} + +/* +****************************************************************************** +* +* Function to print info about span set created in driver from FW raid map +* +* Inputs : +* map - LD map +* ldSpanInfo - ldSpanInfo per HBA instance +*/ +#if SPAN_DEBUG +static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) +{ + + u8 span; + u32 element; + struct MR_LD_RAID *raid; + LD_SPAN_SET *span_set; + struct MR_QUAD_ELEMENT *quad; + int ldCount; + u16 ld; + + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { + ld = MR_TargetIdToLdGet(ldCount, map); + if (ld >= MAX_LOGICAL_DRIVES) + continue; + raid = MR_LdRaidGet(ld, map); + dev_dbg(&instance->pdev->dev, "LD %x: span_depth=%x\n", + ld, raid->spanDepth); + for (span = 0; span < raid->spanDepth; span++) + dev_dbg(&instance->pdev->dev, "Span=%x," + " number of quads=%x\n", span, + map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements); + for (element = 0; element < MAX_QUAD_DEPTH; element++) { + span_set = &(ldSpanInfo[ld].span_set[element]); + if (span_set->span_row_data_width == 0) + break; + + dev_dbg(&instance->pdev->dev, "Span Set %x:" + "width=%x, diff=%x\n", element, + (unsigned int)span_set->span_row_data_width, + (unsigned int)span_set->diff); + dev_dbg(&instance->pdev->dev, "logical LBA" + "start=0x%08lx, end=0x%08lx\n", + (long unsigned int)span_set->log_start_lba, + (long unsigned int)span_set->log_end_lba); + dev_dbg(&instance->pdev->dev, "span row start=0x%08lx," + " end=0x%08lx\n", + (long unsigned int)span_set->span_row_start, + (long unsigned int)span_set->span_row_end); + dev_dbg(&instance->pdev->dev, "data row start=0x%08lx," + " end=0x%08lx\n", + (long unsigned int)span_set->data_row_start, + (long unsigned int)span_set->data_row_end); + dev_dbg(&instance->pdev->dev, "data strip start=0x%08lx," + " end=0x%08lx\n", + (long unsigned int)span_set->data_strip_start, + (long unsigned int)span_set->data_strip_end); + + for (span = 0; span < raid->spanDepth; span++) { + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= + element + 1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info. + quad[element]; + dev_dbg(&instance->pdev->dev, "Span=%x," + "Quad=%x, diff=%x\n", span, + element, quad->diff); + dev_dbg(&instance->pdev->dev, + "offset_in_span=0x%08lx\n", + (long unsigned int)quad->offsetInSpan); + dev_dbg(&instance->pdev->dev, + "logical start=0x%08lx, end=0x%08lx\n", + (long unsigned int)quad->logStart, + (long unsigned int)quad->logEnd); + } + } + } + } + return 0; +} +#endif + +/* +****************************************************************************** +* +* This routine calculates the Span block for given row using spanset. +* +* Inputs : +* instance - HBA instance +* ld - Logical drive number +* row - Row number +* map - LD map +* +* Outputs : +* +* span - Span number +* block - Absolute Block number in the physical disk +* div_error - Devide error code. +*/ + +u32 mr_spanset_get_span_block(struct megasas_instance *instance, + u32 ld, u64 row, u64 *span_blk, struct MR_FW_RAID_MAP_ALL *map) +{ + struct fusion_context *fusion = instance->ctrl_context; + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + struct MR_QUAD_ELEMENT *quad; + u32 span, info; + PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + + if (row > span_set->data_row_end) + continue; + + for (span = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info+1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span]. + block_span_info.quad[info]; + if (quad->diff == 0) + return SPAN_INVALID; + if (quad->logStart <= row && + row <= quad->logEnd && + (mega_mod64(row - quad->logStart, + quad->diff)) == 0) { + if (span_blk != NULL) { + u64 blk; + blk = mega_div64_32 + ((row - quad->logStart), + quad->diff); + blk = (blk + quad->offsetInSpan) + << raid->stripeShift; + *span_blk = blk; + } + return span; + } + } + } + return SPAN_INVALID; +} + +/* +****************************************************************************** +* +* This routine calculates the row for given strip using spanset. +* +* Inputs : +* instance - HBA instance +* ld - Logical drive number +* Strip - Strip +* map - LD map +* +* Outputs : +* +* row - row associated with strip +*/ + +static u64 get_row_from_strip(struct megasas_instance *instance, + u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map) +{ + struct fusion_context *fusion = instance->ctrl_context; + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; + u32 info, strip_offset, span, span_offset; + u64 span_set_Strip, span_set_Row, retval; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (strip > span_set->data_strip_end) + continue; + + span_set_Strip = strip - span_set->data_strip_start; + strip_offset = mega_mod64(span_set_Strip, + span_set->span_row_data_width); + span_set_Row = mega_div64_32(span_set_Strip, + span_set->span_row_data_width) * span_set->diff; + for (span = 0, span_offset = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info+1) { + if (strip_offset >= + span_set->strip_offset[span]) + span_offset++; + else + break; + } +#if SPAN_DEBUG + dev_info(&instance->pdev->dev, "Strip 0x%llx," + "span_set_Strip 0x%llx, span_set_Row 0x%llx" + "data width 0x%llx span offset 0x%x\n", strip, + (unsigned long long)span_set_Strip, + (unsigned long long)span_set_Row, + (unsigned long long)span_set->span_row_data_width, + span_offset); + dev_info(&instance->pdev->dev, "For strip 0x%llx" + "row is 0x%llx\n", strip, + (unsigned long long) span_set->data_row_start + + (unsigned long long) span_set_Row + (span_offset - 1)); +#endif + retval = (span_set->data_row_start + span_set_Row + + (span_offset - 1)); + return retval; + } + return -1LLU; +} + + +/* +****************************************************************************** +* +* This routine calculates the Start Strip for given row using spanset. +* +* Inputs : +* instance - HBA instance +* ld - Logical drive number +* row - Row number +* map - LD map +* +* Outputs : +* +* Strip - Start strip associated with row +*/ + +static u64 get_strip_from_row(struct megasas_instance *instance, + u32 ld, u64 row, struct MR_FW_RAID_MAP_ALL *map) +{ + struct fusion_context *fusion = instance->ctrl_context; + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + struct MR_QUAD_ELEMENT *quad; + PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; + u32 span, info; + u64 strip; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (row > span_set->data_row_end) + continue; + + for (span = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info+1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info.quad[info]; + if (quad->logStart <= row && + row <= quad->logEnd && + mega_mod64((row - quad->logStart), + quad->diff) == 0) { + strip = mega_div64_32 + (((row - span_set->data_row_start) + - quad->logStart), + quad->diff); + strip *= span_set->span_row_data_width; + strip += span_set->data_strip_start; + strip += span_set->strip_offset[span]; + return strip; + } + } + } + dev_err(&instance->pdev->dev, "get_strip_from_row" + "returns invalid strip for ld=%x, row=%lx\n", + ld, (long unsigned int)row); + return -1; +} + +/* +****************************************************************************** +* +* This routine calculates the Physical Arm for given strip using spanset. +* +* Inputs : +* instance - HBA instance +* ld - Logical drive number +* strip - Strip +* map - LD map +* +* Outputs : +* +* Phys Arm - Phys Arm associated with strip +*/ + +static u32 get_arm_from_strip(struct megasas_instance *instance, + u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map) +{ + struct fusion_context *fusion = instance->ctrl_context; + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; + u32 info, strip_offset, span, span_offset, retval; + + for (info = 0 ; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (strip > span_set->data_strip_end) + continue; + + strip_offset = (uint)mega_mod64 + ((strip - span_set->data_strip_start), + span_set->span_row_data_width); + + for (span = 0, span_offset = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info+1) { + if (strip_offset >= + span_set->strip_offset[span]) + span_offset = + span_set->strip_offset[span]; + else + break; + } +#if SPAN_DEBUG + dev_info(&instance->pdev->dev, "get_arm_from_strip:" + "for ld=0x%x strip=0x%lx arm is 0x%x\n", ld, + (long unsigned int)strip, (strip_offset - span_offset)); +#endif + retval = (strip_offset - span_offset); + return retval; + } + + dev_err(&instance->pdev->dev, "get_arm_from_strip" + "returns invalid arm for ld=%x strip=%lx\n", + ld, (long unsigned int)strip); + + return -1; +} + +/* This Function will return Phys arm */ +u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe, + struct MR_FW_RAID_MAP_ALL *map) +{ + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + /* Need to check correct default value */ + u32 arm = 0; + + switch (raid->level) { + case 0: + case 5: + case 6: + arm = mega_mod64(stripe, SPAN_ROW_SIZE(map, ld, span)); + break; + case 1: + /* start with logical arm */ + arm = get_arm_from_strip(instance, ld, stripe, map); + if (arm != -1UL) + arm *= 2; + break; + } + + return arm; +} + + +/* +****************************************************************************** +* +* This routine calculates the arm, span and block for the specified stripe and +* reference in stripe using spanset +* +* Inputs : +* +* ld - Logical drive number +* stripRow - Stripe number +* stripRef - Reference in stripe +* +* Outputs : +* +* span - Span number +* block - Absolute Block number in the physical disk +*/ +static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info, + struct RAID_CONTEXT *pRAID_Context, + struct MR_FW_RAID_MAP_ALL *map) +{ + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + u32 pd, arRef; + u8 physArm, span; + u64 row; + u8 retval = TRUE; + u8 do_invader = 0; + u64 *pdBlock = &io_info->pdBlock; + u16 *pDevHandle = &io_info->devHandle; + u32 logArm, rowMod, armQ, arm; + + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER || + instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) + do_invader = 1; + + /*Get row and span from io_info for Uneven Span IO.*/ + row = io_info->start_row; + span = io_info->start_span; + + + if (raid->level == 6) { + logArm = get_arm_from_strip(instance, ld, stripRow, map); + if (logArm == -1UL) + return FALSE; + rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span)); + armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod; + arm = armQ + 1 + logArm; + if (arm >= SPAN_ROW_SIZE(map, ld, span)) + arm -= SPAN_ROW_SIZE(map, ld, span); + physArm = (u8)arm; + } else + /* Calculate the arm */ + physArm = get_arm(instance, ld, span, stripRow, map); + if (physArm == 0xFF) + return FALSE; + + arRef = MR_LdSpanArrayGet(ld, span, map); + pd = MR_ArPdGet(arRef, physArm, map); + + if (pd != MR_PD_INVALID) + *pDevHandle = MR_PdDevHandleGet(pd, map); + else { + *pDevHandle = MR_PD_INVALID; + if ((raid->level >= 5) && + (!do_invader || (do_invader && + (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) + pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; + else if (raid->level == 1) { + pd = MR_ArPdGet(arRef, physArm + 1, map); + if (pd != MR_PD_INVALID) + *pDevHandle = MR_PdDevHandleGet(pd, map); + } + } + + *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; + pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | + physArm; + return retval; } /* @@ -228,17 +693,18 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, * block - Absolute Block number in the physical disk */ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, - u16 stripRef, u64 *pdBlock, u16 *pDevHandle, - struct RAID_CONTEXT *pRAID_Context, - struct MR_FW_RAID_MAP_ALL *map) + u16 stripRef, struct IO_REQUEST_INFO *io_info, + struct RAID_CONTEXT *pRAID_Context, + struct MR_FW_RAID_MAP_ALL *map) { struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); u32 pd, arRef; u8 physArm, span; u64 row; u8 retval = TRUE; - int error_code = 0; u8 do_invader = 0; + u64 *pdBlock = &io_info->pdBlock; + u16 *pDevHandle = &io_info->devHandle; if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER || instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) @@ -272,8 +738,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, span = 0; *pdBlock = row << raid->stripeShift; } else { - span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code); - if (error_code == 1) + span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map); + if (span == SPAN_INVALID) return FALSE; } @@ -331,17 +797,42 @@ MR_BuildRaidContext(struct megasas_instance *instance, u32 numBlocks, ldTgtId; u8 isRead; u8 retval = 0; + u8 startlba_span = SPAN_INVALID; + u64 *pdBlock = &io_info->pdBlock; ldStartBlock = io_info->ldStartBlock; numBlocks = io_info->numBlocks; ldTgtId = io_info->ldTgtId; isRead = io_info->isRead; + io_info->IoforUnevenSpan = 0; + io_info->start_span = SPAN_INVALID; ld = MR_TargetIdToLdGet(ldTgtId, map); raid = MR_LdRaidGet(ld, map); + /* + * if rowDataSize @RAID map and spanRowDataSize @SPAN INFO are zero + * return FALSE + */ + if (raid->rowDataSize == 0) { + if (MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize == 0) + return FALSE; + else if (instance->UnevenSpanSupport) { + io_info->IoforUnevenSpan = 1; + } else { + dev_info(&instance->pdev->dev, + "raid->rowDataSize is 0, but has SPAN[0]" + "rowDataSize = 0x%0x," + "but there is _NO_ UnevenSpanSupport\n", + MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize); + return FALSE; + } + } + stripSize = 1 << raid->stripeShift; stripe_mask = stripSize-1; + + /* * calculate starting row and stripe, and number of strips and rows */ @@ -351,11 +842,50 @@ MR_BuildRaidContext(struct megasas_instance *instance, ref_in_end_stripe = (u16)(endLba & stripe_mask); endStrip = endLba >> raid->stripeShift; num_strips = (u8)(endStrip - start_strip + 1); /* End strip */ - if (raid->rowDataSize == 0) - return FALSE; - start_row = mega_div64_32(start_strip, raid->rowDataSize); - endRow = mega_div64_32(endStrip, raid->rowDataSize); - numRows = (u8)(endRow - start_row + 1); + + if (io_info->IoforUnevenSpan) { + start_row = get_row_from_strip(instance, ld, start_strip, map); + endRow = get_row_from_strip(instance, ld, endStrip, map); + if (start_row == -1ULL || endRow == -1ULL) { + dev_info(&instance->pdev->dev, "return from %s %d." + "Send IO w/o region lock.\n", + __func__, __LINE__); + return FALSE; + } + + if (raid->spanDepth == 1) { + startlba_span = 0; + *pdBlock = start_row << raid->stripeShift; + } else + startlba_span = (u8)mr_spanset_get_span_block(instance, + ld, start_row, pdBlock, map); + if (startlba_span == SPAN_INVALID) { + dev_info(&instance->pdev->dev, "return from %s %d" + "for row 0x%llx,start strip %llx" + "endSrip %llx\n", __func__, __LINE__, + (unsigned long long)start_row, + (unsigned long long)start_strip, + (unsigned long long)endStrip); + return FALSE; + } + io_info->start_span = startlba_span; + io_info->start_row = start_row; +#if SPAN_DEBUG + dev_dbg(&instance->pdev->dev, "Check Span number from %s %d" + "for row 0x%llx, start strip 0x%llx end strip 0x%llx" + " span 0x%x\n", __func__, __LINE__, + (unsigned long long)start_row, + (unsigned long long)start_strip, + (unsigned long long)endStrip, startlba_span); + dev_dbg(&instance->pdev->dev, "start_row 0x%llx endRow 0x%llx" + "Start span 0x%x\n", (unsigned long long)start_row, + (unsigned long long)endRow, startlba_span); +#endif + } else { + start_row = mega_div64_32(start_strip, raid->rowDataSize); + endRow = mega_div64_32(endStrip, raid->rowDataSize); + } + numRows = (u8)(endRow - start_row + 1); /* * calculate region info. @@ -388,24 +918,51 @@ MR_BuildRaidContext(struct megasas_instance *instance, regSize = numBlocks; } /* multi-strip IOs always need to full stripe locked */ - } else { + } else if (io_info->IoforUnevenSpan == 0) { + /* + * For Even span region lock optimization. + * If the start strip is the last in the start row + */ if (start_strip == (start_row + 1) * raid->rowDataSize - 1) { - /* If the start strip is the last in the start row */ regStart += ref_in_start_stripe; - regSize = stripSize - ref_in_start_stripe; /* initialize count to sectors from startref to end of strip */ + regSize = stripSize - ref_in_start_stripe; } + /* add complete rows in the middle of the transfer */ if (numRows > 2) - /* Add complete rows in the middle of the transfer */ regSize += (numRows-2) << raid->stripeShift; - /* if IO ends within first strip of last row */ + /* if IO ends within first strip of last row*/ if (endStrip == endRow*raid->rowDataSize) regSize += ref_in_end_stripe+1; else regSize += stripSize; + } else { + /* + * For Uneven span region lock optimization. + * If the start strip is the last in the start row + */ + if (start_strip == (get_strip_from_row(instance, ld, start_row, map) + + SPAN_ROW_DATA_SIZE(map, ld, startlba_span) - 1)) { + regStart += ref_in_start_stripe; + /* initialize count to sectors from + * startRef to end of strip + */ + regSize = stripSize - ref_in_start_stripe; + } + /* Add complete rows in the middle of the transfer*/ + + if (numRows > 2) + /* Add complete rows in the middle of the transfer*/ + regSize += (numRows-2) << raid->stripeShift; + + /* if IO ends within first strip of last row */ + if (endStrip == get_strip_from_row(instance, ld, endRow, map)) + regSize += ref_in_end_stripe + 1; + else + regSize += stripSize; } pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec; @@ -424,30 +981,161 @@ MR_BuildRaidContext(struct megasas_instance *instance, /*Get Phy Params only if FP capable, or else leave it to MR firmware to do the calculation.*/ if (io_info->fpOkForIo) { - retval = MR_GetPhyParams(instance, ld, start_strip, - ref_in_start_stripe, - &io_info->pdBlock, - &io_info->devHandle, pRAID_Context, - map); - /* If IO on an invalid Pd, then FP i snot possible */ + retval = io_info->IoforUnevenSpan ? + mr_spanset_get_phy_params(instance, ld, + start_strip, ref_in_start_stripe, + io_info, pRAID_Context, map) : + MR_GetPhyParams(instance, ld, start_strip, + ref_in_start_stripe, io_info, + pRAID_Context, map); + /* If IO on an invalid Pd, then FP is not possible.*/ if (io_info->devHandle == MR_PD_INVALID) io_info->fpOkForIo = FALSE; return retval; } else if (isRead) { uint stripIdx; for (stripIdx = 0; stripIdx < num_strips; stripIdx++) { - if (!MR_GetPhyParams(instance, ld, - start_strip + stripIdx, - ref_in_start_stripe, - &io_info->pdBlock, - &io_info->devHandle, - pRAID_Context, map)) + retval = io_info->IoforUnevenSpan ? + mr_spanset_get_phy_params(instance, ld, + start_strip + stripIdx, + ref_in_start_stripe, io_info, + pRAID_Context, map) : + MR_GetPhyParams(instance, ld, + start_strip + stripIdx, ref_in_start_stripe, + io_info, pRAID_Context, map); + if (!retval) return TRUE; } } + +#if SPAN_DEBUG + /* Just for testing what arm we get for strip.*/ + if (io_info->IoforUnevenSpan) + get_arm_from_strip(instance, ld, start_strip, map); +#endif return TRUE; } +/* +****************************************************************************** +* +* This routine pepare spanset info from Valid Raid map and store it into +* local copy of ldSpanInfo per instance data structure. +* +* Inputs : +* map - LD map +* ldSpanInfo - ldSpanInfo per HBA instance +* +*/ +void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, + PLD_SPAN_INFO ldSpanInfo) +{ + u8 span, count; + u32 element, span_row_width; + u64 span_row; + struct MR_LD_RAID *raid; + LD_SPAN_SET *span_set, *span_set_prev; + struct MR_QUAD_ELEMENT *quad; + int ldCount; + u16 ld; + + + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { + ld = MR_TargetIdToLdGet(ldCount, map); + if (ld >= MAX_LOGICAL_DRIVES) + continue; + raid = MR_LdRaidGet(ld, map); + for (element = 0; element < MAX_QUAD_DEPTH; element++) { + for (span = 0; span < raid->spanDepth; span++) { + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements < + element + 1) + continue; + span_set = &(ldSpanInfo[ld].span_set[element]); + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info. + quad[element]; + + span_set->diff = quad->diff; + + for (count = 0, span_row_width = 0; + count < raid->spanDepth; count++) { + if (map->raidMap.ldSpanMap[ld]. + spanBlock[count]. + block_span_info. + noElements >= element + 1) { + span_set->strip_offset[count] = + span_row_width; + span_row_width += + MR_LdSpanPtrGet + (ld, count, map)->spanRowDataSize; + printk(KERN_INFO "megasas:" + "span %x rowDataSize %x\n", + count, MR_LdSpanPtrGet + (ld, count, map)->spanRowDataSize); + } + } + + span_set->span_row_data_width = span_row_width; + span_row = mega_div64_32(((quad->logEnd - + quad->logStart) + quad->diff), + quad->diff); + + if (element == 0) { + span_set->log_start_lba = 0; + span_set->log_end_lba = + ((span_row << raid->stripeShift) + * span_row_width) - 1; + + span_set->span_row_start = 0; + span_set->span_row_end = span_row - 1; + + span_set->data_strip_start = 0; + span_set->data_strip_end = + (span_row * span_row_width) - 1; + + span_set->data_row_start = 0; + span_set->data_row_end = + (span_row * quad->diff) - 1; + } else { + span_set_prev = &(ldSpanInfo[ld]. + span_set[element - 1]); + span_set->log_start_lba = + span_set_prev->log_end_lba + 1; + span_set->log_end_lba = + span_set->log_start_lba + + ((span_row << raid->stripeShift) + * span_row_width) - 1; + + span_set->span_row_start = + span_set_prev->span_row_end + 1; + span_set->span_row_end = + span_set->span_row_start + span_row - 1; + + span_set->data_strip_start = + span_set_prev->data_strip_end + 1; + span_set->data_strip_end = + span_set->data_strip_start + + (span_row * span_row_width) - 1; + + span_set->data_row_start = + span_set_prev->data_row_end + 1; + span_set->data_row_end = + span_set->data_row_start + + (span_row * quad->diff) - 1; + } + break; + } + if (span == raid->spanDepth) + break; + } + } +#if SPAN_DEBUG + getSpanInfo(map, ldSpanInfo); +#endif + +} + void mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 748b8ac..417d5f1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -86,8 +86,6 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map); void megasas_check_and_restore_queue_depth(struct megasas_instance *instance); -u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, - struct LD_LOAD_BALANCE_INFO *lbInfo); u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); int megasas_transition_to_ready(struct megasas_instance *instance, int ocr); @@ -782,8 +780,7 @@ megasas_get_map_info(struct megasas_instance *instance) fusion->fast_path_io = 0; if (!megasas_get_ld_map_info(instance)) { - if (MR_ValidateMapInfo(fusion->ld_map[(instance->map_id & 1)], - fusion->load_balance_info)) { + if (MR_ValidateMapInfo(instance)) { fusion->fast_path_io = 1; return 0; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 004c18e..12ff01c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -463,6 +463,7 @@ struct MPI2_IOC_INIT_REQUEST { /* mrpriv defines */ #define MR_PD_INVALID 0xFFFF #define MAX_SPAN_DEPTH 8 +#define MAX_QUAD_DEPTH MAX_SPAN_DEPTH #define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH) #define MAX_ROW_SIZE 32 #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE) @@ -504,7 +505,9 @@ struct MR_LD_SPAN { u64 startBlk; u64 numBlks; u16 arrayRef; - u8 reserved[6]; + u8 spanRowSize; + u8 spanRowDataSize; + u8 reserved[4]; }; struct MR_SPAN_BLOCK_INFO { @@ -590,6 +593,10 @@ struct IO_REQUEST_INFO { u16 devHandle; u64 pdBlock; u8 fpOkForIo; + u8 IoforUnevenSpan; + u8 start_span; + u8 reserved; + u64 start_row; }; struct MR_LD_TARGET_SYNC { @@ -651,6 +658,26 @@ struct LD_LOAD_BALANCE_INFO { u64 last_accessed_block[2]; }; +/* SPAN_SET is info caclulated from span info from Raid map per LD */ +typedef struct _LD_SPAN_SET { + u64 log_start_lba; + u64 log_end_lba; + u64 span_row_start; + u64 span_row_end; + u64 data_strip_start; + u64 data_strip_end; + u64 data_row_start; + u64 data_row_end; + u8 strip_offset[MAX_SPAN_DEPTH]; + u32 span_row_data_width; + u32 diff; + u32 reserved[2]; +} LD_SPAN_SET, *PLD_SPAN_SET; + +typedef struct LOG_BLOCK_SPAN_INFO { + LD_SPAN_SET span_set[MAX_SPAN_DEPTH]; +} LD_SPAN_INFO, *PLD_SPAN_INFO; + struct MR_FW_RAID_MAP_ALL { struct MR_FW_RAID_MAP raidMap; struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1]; @@ -695,6 +722,7 @@ struct fusion_context { u32 map_sz; u8 fast_path_io; struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES]; + LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES]; }; union desc_value { -- cgit v1.1 From 404a8a1a891e9eadf8b1ef5ad945f569758c0884 Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:35:33 +0530 Subject: [SCSI] megaraid_sas: Add support to differentiate between iMR vs MR Firmware Add support to differentiate between iMR(no external memory) and MR(with external memory) controllers. Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 55a08d8..209fe36 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1533,6 +1533,7 @@ struct megasas_instance { struct mutex reset_mutex; int throttlequeuedepth; u8 mask_interrupts; + u8 is_imr; }; enum { diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6d7b656..a97b321 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1641,10 +1641,7 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance) spin_lock_irqsave(instance->host->host_lock, flags); instance->flag &= ~MEGASAS_FW_BUSY; - if ((instance->pdev->device == - PCI_DEVICE_ID_LSI_SAS0073SKINNY) || - (instance->pdev->device == - PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { + if (instance->is_imr) { instance->host->can_queue = instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; } else @@ -3662,6 +3659,18 @@ static int megasas_init_fw(struct megasas_instance *instance) max_sectors_2 = ctrl_info->max_request_size; tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); + + /*Check whether controller is iMR or MR */ + if (ctrl_info->memory_size) { + instance->is_imr = 0; + dev_info(&instance->pdev->dev, "Controller type: MR," + "Memory size is: %dMB\n", + ctrl_info->memory_size); + } else { + instance->is_imr = 1; + dev_info(&instance->pdev->dev, + "Controller type: iMR\n"); + } instance->disableOnlineCtrlReset = ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; instance->UnevenSpanSupport = @@ -3686,8 +3695,7 @@ static int megasas_init_fw(struct megasas_instance *instance) kfree(ctrl_info); /* Check for valid throttlequeuedepth module parameter */ - if (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY || - instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) { + if (instance->is_imr) { if (throttlequeuedepth > (instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS)) instance->throttlequeuedepth = @@ -3971,8 +3979,7 @@ static int megasas_io_attach(struct megasas_instance *instance) */ host->irq = instance->pdev->irq; host->unique_id = instance->unique_id; - if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { + if (instance->is_imr) { host->can_queue = instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS; } else @@ -4167,6 +4174,7 @@ static int megasas_probe_one(struct pci_dev *pdev, instance->ev = NULL; instance->issuepend_done = 1; instance->adprecovery = MEGASAS_HBA_OPERATIONAL; + instance->is_imr = 0; megasas_poll_wait_aen = 0; instance->evt_detail = pci_alloc_consistent(pdev, -- cgit v1.1 From 7525be545c839a65bb05ac71e795d17eafcaf20a Mon Sep 17 00:00:00 2001 From: "Sumit.Saxena@lsi.com" Date: Wed, 22 May 2013 12:36:17 +0530 Subject: [SCSI] megaraid_sas: Changelog and driver version update Signed-off-by: Sumit Saxena Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- Documentation/scsi/ChangeLog.megaraid_sas | 22 ++++++++++++++++++++++ drivers/scsi/megaraid/megaraid_sas.h | 6 +++--- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index 09673c7..cc92ca8 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,3 +1,25 @@ +Release Date : Wed. May 15, 2013 17:00:00 PST 2013 - + (emaild-id:megaraidlinux@lsi.com) + Adam Radford + Kashyap Desai + Sumit Saxena +Current Version : 06.600.18.00-rc1 +Old Version : 06.506.00.00-rc1 + 1. Return DID_ERROR for scsi io, when controller is in critical h/w error. + 2. Fix the interrupt mask for Gen2 controller. + 3. Update balance count in driver to be in sync of firmware. + 4. Free event detail memory without device ID check. + 5. Set IO request timeout value provided by OS timeout for Tape devices. + 6. Add support for MegaRAID Fury (device ID-0x005f) 12Gb/s controllers. + 7. Add support to display Customer branding details in syslog. + 8. Set IoFlags to enable Fast Path for JBODs for Invader/Fury(12 Gb/s) + controllers. + 9. Add support for Extended MSI-x vectors for Invader and Fury(12Gb/s + HBA). + 10.Add support for Uneven Span PRL11. + 11.Add support to differentiate between iMR and MR Firmware. + 12.Version and Changelog update. +------------------------------------------------------------------------------- Release Date : Sat. Feb 9, 2013 17:00:00 PST 2013 - (emaild-id:megaraidlinux@lsi.com) Adam Radford diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 209fe36..04a42a5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -33,9 +33,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "06.506.00.00-rc1" -#define MEGASAS_RELDATE "Feb. 9, 2013" -#define MEGASAS_EXT_VERSION "Sat. Feb. 9 17:00:00 PDT 2013" +#define MEGASAS_VERSION "06.600.18.00-rc1" +#define MEGASAS_RELDATE "May. 15, 2013" +#define MEGASAS_EXT_VERSION "Wed. May. 15 17:00:00 PDT 2013" /* * Device IDs diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index a97b321..4c4abe1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * FILE: megaraid_sas_base.c - * Version : v06.506.00.00-rc1 + * Version : 06.600.18.00-rc1 * * Authors: LSI Corporation * Sreenivas Bagalkote -- cgit v1.1 From c6e23d83c35380909edf2eb364943719bc10e9be Mon Sep 17 00:00:00 2001 From: Jakob Normark Date: Wed, 15 May 2013 21:41:51 +0200 Subject: [SCSI] bfa: Fixes for 0-terminated strncpy and possible null pointer dereference This patch fixes two cppcheck errors in drivers/scsi/bfa/bfad_im.c [jejb: correct strlcpy fix] Signed-off-by: Jakob Normark Acked-by: Vijay Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfad_im.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 5864f98..9796284 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -944,13 +944,15 @@ static int bfad_im_slave_alloc(struct scsi_device *sdev) { struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); - struct bfad_itnim_data_s *itnim_data = - (struct bfad_itnim_data_s *) rport->dd_data; - struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa; + struct bfad_itnim_data_s *itnim_data; + struct bfa_s *bfa; if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; + itnim_data = (struct bfad_itnim_data_s *) rport->dd_data; + bfa = itnim_data->itnim->bfa_itnim->bfa; + if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED) { /* * We should not mask LUN 0 - since this will translate @@ -1035,7 +1037,7 @@ bfad_fc_host_init(struct bfad_im_port_s *im_port) /* For fibre channel services type 0x20 */ fc_host_supported_fc4s(host)[7] = 1; - strncpy(symname, bfad->bfa_fcs.fabric.bport.port_cfg.sym_name.symname, + strlcpy(symname, bfad->bfa_fcs.fabric.bport.port_cfg.sym_name.symname, BFA_SYMNAME_MAXLEN); sprintf(fc_host_symbolic_name(host), "%s", symname); -- cgit v1.1 From 2ee3e26c673e75c05ef8b914f54fadee3d7b9c88 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 May 2013 19:07:19 +0100 Subject: [SCSI] sd: Fix parsing of 'temporary ' cache mode prefix Commit 39c60a0948cc '[SCSI] sd: fix array cache flushing bug causing performance problems' added temp as a pointer to "temporary " and used sizeof(temp) - 1 as its length. But sizeof(temp) is the size of the pointer, not the size of the string constant. Change temp to a static array so that sizeof() does what was intended. Signed-off-by: Ben Hutchings Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a37eda9..91e8a95 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -142,7 +142,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, char *buffer_data; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; - const char *temp = "temporary "; + static const char temp[] = "temporary "; int len; if (sdp->type != TYPE_DISK) -- cgit v1.1 From 3bd3e8bf6250f32c153d95f85ec9249ed305589d Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Wed, 29 May 2013 17:13:28 -0700 Subject: [SCSI] cxgb4i: add support for T5 adapter Signed-off-by: Karen Xie Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 159 +++++++++++++++++++++++++++++-------- 1 file changed, 128 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 3fecf35..e659feb 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -20,6 +20,7 @@ #include #include +#include "t4_regs.h" #include "t4_msg.h" #include "cxgb4.h" #include "cxgb4_uld.h" @@ -32,13 +33,12 @@ static unsigned int dbg_level; #include "../libcxgbi.h" #define DRV_MODULE_NAME "cxgb4i" -#define DRV_MODULE_DESC "Chelsio T4 iSCSI Driver" -#define DRV_MODULE_VERSION "0.9.1" -#define DRV_MODULE_RELDATE "Aug. 2010" +#define DRV_MODULE_DESC "Chelsio T4/T5 iSCSI Driver" +#define DRV_MODULE_VERSION "0.9.4" static char version[] = DRV_MODULE_DESC " " DRV_MODULE_NAME - " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + " v" DRV_MODULE_VERSION "\n"; MODULE_AUTHOR("Chelsio Communications, Inc."); MODULE_DESCRIPTION(DRV_MODULE_DESC); @@ -175,10 +175,56 @@ static inline int is_ofld_imm(const struct sk_buff *skb) sizeof(struct fw_ofld_tx_data_wr)); } + +#define VLAN_NONE 0xfff +#define FILTER_SEL_VLAN_NONE 0xffff +#define FILTER_SEL_WIDTH_P_FC (3+1) /* port uses 3 bits, FCoE one bit */ +#define FILTER_SEL_WIDTH_VIN_P_FC \ + (6 + 7 + FILTER_SEL_WIDTH_P_FC) /* 6 bits are unused, VF uses 7 bits*/ +#define FILTER_SEL_WIDTH_TAG_P_FC \ + (3 + FILTER_SEL_WIDTH_VIN_P_FC) /* PF uses 3 bits */ +#define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC) + +static unsigned int select_ntuple(struct cxgbi_device *cdev, + struct l2t_entry *l2t) +{ + struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); + unsigned int ntuple = 0; + u32 viid; + + switch (lldi->filt_mode) { + + /* default filter mode */ + case HW_TPL_FR_MT_PR_IV_P_FC: + if (l2t->vlan == VLAN_NONE) + ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC; + else { + ntuple |= l2t->vlan << FILTER_SEL_WIDTH_P_FC; + ntuple |= 1 << FILTER_SEL_WIDTH_VLD_TAG_P_FC; + } + ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << + FILTER_SEL_WIDTH_VLD_TAG_P_FC; + break; + case HW_TPL_FR_MT_PR_OV_P_FC: { + viid = cxgb4_port_viid(l2t->neigh->dev); + + ntuple |= FW_VIID_VIN_GET(viid) << FILTER_SEL_WIDTH_P_FC; + ntuple |= FW_VIID_PFN_GET(viid) << FILTER_SEL_WIDTH_VIN_P_FC; + ntuple |= FW_VIID_VIVLD_GET(viid) << FILTER_SEL_WIDTH_TAG_P_FC; + ntuple |= l2t->lport << S_PORT | IPPROTO_TCP << + FILTER_SEL_WIDTH_VLD_TAG_P_FC; + break; + } + default: + break; + } + return ntuple; +} + static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, struct l2t_entry *e) { - struct cpl_act_open_req *req; + struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); int wscale = cxgbi_sock_compute_wscale(csk->mss_idx); unsigned long long opt0; unsigned int opt2; @@ -195,29 +241,58 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, RCV_BUFSIZ(cxgb4i_rcv_win >> 10); opt2 = RX_CHANNEL(0) | RSS_QUEUE_VALID | - (1 << 20) | (1 << 22) | + (1 << 20) | RSS_QUEUE(csk->rss_qid); - set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id); - req = (struct cpl_act_open_req *)skb->head; + if (is_t4(lldi->adapter_type)) { + struct cpl_act_open_req *req = + (struct cpl_act_open_req *)skb->head; - INIT_TP_WR(req, 0); - OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, + req = (struct cpl_act_open_req *)skb->head; + + INIT_TP_WR(req, 0); + OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, qid_atid)); - req->local_port = csk->saddr.sin_port; - req->peer_port = csk->daddr.sin_port; - req->local_ip = csk->saddr.sin_addr.s_addr; - req->peer_ip = csk->daddr.sin_addr.s_addr; - req->opt0 = cpu_to_be64(opt0); - req->params = 0; - req->opt2 = cpu_to_be32(opt2); + req->local_port = csk->saddr.sin_port; + req->peer_port = csk->daddr.sin_port; + req->local_ip = csk->saddr.sin_addr.s_addr; + req->peer_ip = csk->daddr.sin_addr.s_addr; + req->opt0 = cpu_to_be64(opt0); + req->params = cpu_to_be32(select_ntuple(csk->cdev, csk->l2t)); + opt2 |= 1 << 22; + req->opt2 = cpu_to_be32(opt2); - log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, - "csk 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n", - csk, &req->local_ip, ntohs(req->local_port), - &req->peer_ip, ntohs(req->peer_port), - csk->atid, csk->rss_qid); + log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, + "csk t4 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n", + csk, &req->local_ip, ntohs(req->local_port), + &req->peer_ip, ntohs(req->peer_port), + csk->atid, csk->rss_qid); + } else { + struct cpl_t5_act_open_req *req = + (struct cpl_t5_act_open_req *)skb->head; + + req = (struct cpl_t5_act_open_req *)skb->head; + + INIT_TP_WR(req, 0); + OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, + qid_atid)); + req->local_port = csk->saddr.sin_port; + req->peer_port = csk->daddr.sin_port; + req->local_ip = csk->saddr.sin_addr.s_addr; + req->peer_ip = csk->daddr.sin_addr.s_addr; + req->opt0 = cpu_to_be64(opt0); + req->params = cpu_to_be32(select_ntuple(csk->cdev, csk->l2t)); + opt2 |= 1 << 31; + req->opt2 = cpu_to_be32(opt2); + log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, + "csk t5 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n", + csk, &req->local_ip, ntohs(req->local_port), + &req->peer_ip, ntohs(req->peer_port), + csk->atid, csk->rss_qid); + } + + set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id); cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t); } @@ -632,6 +707,7 @@ static void csk_act_open_retry_timer(unsigned long data) { struct sk_buff *skb; struct cxgbi_sock *csk = (struct cxgbi_sock *)data; + struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev); log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n", @@ -639,7 +715,10 @@ static void csk_act_open_retry_timer(unsigned long data) cxgbi_sock_get(csk); spin_lock_bh(&csk->lock); - skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC); + skb = alloc_wr(is_t4(lldi->adapter_type) ? + sizeof(struct cpl_act_open_req) : + sizeof(struct cpl_t5_act_open_req), + 0, GFP_ATOMIC); if (!skb) cxgbi_sock_fail_act_open(csk, -ENOMEM); else { @@ -871,7 +950,7 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb) if (!csk->skb_ulp_lhdr) { unsigned char *bhs; - unsigned int hlen, dlen; + unsigned int hlen, dlen, plen; log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX, "csk 0x%p,%u,0x%lx, tid %u, skb 0x%p header.\n", @@ -890,11 +969,15 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb) hlen = ntohs(cpl->len); dlen = ntohl(*(unsigned int *)(bhs + 4)) & 0xFFFFFF; - if ((hlen + dlen) != ISCSI_PDU_LEN(pdu_len_ddp) - 40) { + plen = ISCSI_PDU_LEN(pdu_len_ddp); + if (is_t4(lldi->adapter_type)) + plen -= 40; + + if ((hlen + dlen) != plen) { pr_info("tid 0x%x, CPL_ISCSI_HDR, pdu len " "mismatch %u != %u + %u, seq 0x%x.\n", - csk->tid, ISCSI_PDU_LEN(pdu_len_ddp) - 40, - hlen, dlen, cxgbi_skcb_tcp_seq(skb)); + csk->tid, plen, hlen, dlen, + cxgbi_skcb_tcp_seq(skb)); goto abort_conn; } @@ -1154,7 +1237,10 @@ static int init_act_open(struct cxgbi_sock *csk) } cxgbi_sock_get(csk); - skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL); + skb = alloc_wr(is_t4(lldi->adapter_type) ? + sizeof(struct cpl_act_open_req) : + sizeof(struct cpl_t5_act_open_req), + 0, GFP_ATOMIC); if (!skb) goto rel_resource; skb->sk = (struct sock *)csk; @@ -1193,6 +1279,8 @@ rel_resource: return -EINVAL; } +#define CPL_ISCSI_DATA 0xB2 +#define CPL_RX_ISCSI_DDP 0x49 cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = { [CPL_ACT_ESTABLISH] = do_act_establish, [CPL_ACT_OPEN_RPL] = do_act_open_rpl, @@ -1202,8 +1290,10 @@ cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = { [CPL_CLOSE_CON_RPL] = do_close_con_rpl, [CPL_FW4_ACK] = do_fw4_ack, [CPL_ISCSI_HDR] = do_rx_iscsi_hdr, + [CPL_ISCSI_DATA] = do_rx_iscsi_hdr, [CPL_SET_TCB_RPL] = do_set_tcb_rpl, [CPL_RX_DATA_DDP] = do_rx_data_ddp, + [CPL_RX_ISCSI_DDP] = do_rx_data_ddp, }; int cxgb4i_ofld_init(struct cxgbi_device *cdev) @@ -1234,14 +1324,20 @@ int cxgb4i_ofld_init(struct cxgbi_device *cdev) * functions to program the pagepod in h/w */ #define ULPMEM_IDATA_MAX_NPPODS 4 /* 256/PPOD_SIZE */ -static inline void ulp_mem_io_set_hdr(struct ulp_mem_io *req, +static inline void ulp_mem_io_set_hdr(struct cxgb4_lld_info *lldi, + struct ulp_mem_io *req, unsigned int wr_len, unsigned int dlen, unsigned int pm_addr) { struct ulptx_idata *idata = (struct ulptx_idata *)(req + 1); INIT_ULPTX_WR(req, wr_len, 0, 0); - req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1 << 23)); + if (is_t4(lldi->adapter_type)) + req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | + (ULP_MEMIO_ORDER(1))); + else + req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | + (V_T5_ULP_MEMIO_IMM(1))); req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5)); req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5)); req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16)); @@ -1257,6 +1353,7 @@ static int ddp_ppod_write_idata(struct cxgbi_device *cdev, unsigned int port_id, unsigned int gl_pidx) { struct cxgbi_ddp_info *ddp = cdev->ddp; + struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); struct sk_buff *skb; struct ulp_mem_io *req; struct ulptx_idata *idata; @@ -1276,7 +1373,7 @@ static int ddp_ppod_write_idata(struct cxgbi_device *cdev, unsigned int port_id, req = (struct ulp_mem_io *)skb->head; set_queue(skb, CPL_PRIORITY_CONTROL, NULL); - ulp_mem_io_set_hdr(req, wr_len, dlen, pm_addr); + ulp_mem_io_set_hdr(lldi, req, wr_len, dlen, pm_addr); idata = (struct ulptx_idata *)(req + 1); ppod = (struct cxgbi_pagepod *)(idata + 1); -- cgit v1.1 From feccada972756b959e21d450e75f91907e53e9e1 Mon Sep 17 00:00:00 2001 From: "wenxiong@linux.vnet.ibm.com" Date: Fri, 24 May 2013 09:59:13 -0500 Subject: [SCSI] ipr: possible irq lock inversion dependency detected When enable lockdep, seeing "possible irq lock inversion dependency detected" error. This patch fixes the issue. Signed-off-by: Wen Xiong Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 6c4cedb..a87767f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9392,7 +9392,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev, void __iomem *ipr_regs; int rc = PCIBIOS_SUCCESSFUL; volatile u32 mask, uproc, interrupts; - unsigned long lock_flags; + unsigned long lock_flags, driver_lock_flags; ENTER; @@ -9615,9 +9615,9 @@ static int ipr_probe_ioa(struct pci_dev *pdev, } else ioa_cfg->reset = ipr_reset_start_bist; - spin_lock(&ipr_driver_lock); + spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags); list_add_tail(&ioa_cfg->queue, &ipr_ioa_head); - spin_unlock(&ipr_driver_lock); + spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags); LEAVE; out: @@ -9700,6 +9700,7 @@ static void __ipr_remove(struct pci_dev *pdev) unsigned long host_lock_flags = 0; struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); int i; + unsigned long driver_lock_flags; ENTER; spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); @@ -9723,9 +9724,9 @@ static void __ipr_remove(struct pci_dev *pdev) INIT_LIST_HEAD(&ioa_cfg->used_res_q); spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); - spin_lock(&ipr_driver_lock); + spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags); list_del(&ioa_cfg->queue); - spin_unlock(&ipr_driver_lock); + spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags); if (ioa_cfg->sdt_state == ABORT_DUMP) ioa_cfg->sdt_state = WAIT_FOR_DUMP; @@ -9991,12 +9992,12 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) { struct ipr_cmnd *ipr_cmd; struct ipr_ioa_cfg *ioa_cfg; - unsigned long flags = 0; + unsigned long flags = 0, driver_lock_flags; if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) return NOTIFY_DONE; - spin_lock(&ipr_driver_lock); + spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags); list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { spin_lock_irqsave(ioa_cfg->host->host_lock, flags); @@ -10014,7 +10015,7 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); } - spin_unlock(&ipr_driver_lock); + spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags); return NOTIFY_OK; } -- cgit v1.1 From b246de174300db84cf9ef8fae6d4ae3f73900a9e Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:03:07 -0400 Subject: [SCSI] lpfc 8.3.40: Fix lpfc_used_cpu to be more dynamic Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 30 +++++++++++++++++++++++------- drivers/scsi/lpfc/lpfc_sli4.h | 1 - 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cb465b2..7e5a2b1 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -60,7 +60,8 @@ unsigned long _dump_buf_dif_order; spinlock_t _dump_buf_lock; /* Used when mapping IRQ vectors in a driver centric manner */ -uint16_t lpfc_used_cpu[LPFC_MAX_CPU]; +uint16_t *lpfc_used_cpu; +uint32_t lpfc_present_cpu; static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static int lpfc_post_rcv_buf(struct lpfc_hba *); @@ -5213,6 +5214,21 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) rc = -ENOMEM; goto out_free_msix; } + if (lpfc_used_cpu == NULL) { + lpfc_used_cpu = kzalloc((sizeof(uint16_t) * lpfc_present_cpu), + GFP_KERNEL); + if (!lpfc_used_cpu) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3335 Failed allocate memory for msi-x " + "interrupt vector mapping\n"); + kfree(phba->sli4_hba.cpu_map); + rc = -ENOMEM; + goto out_free_msix; + } + for (i = 0; i < lpfc_present_cpu; i++) + lpfc_used_cpu[i] = LPFC_VECTOR_MAP_EMPTY; + } + /* Initialize io channels for round robin */ cpup = phba->sli4_hba.cpu_map; rc = 0; @@ -6824,8 +6840,6 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) int cfg_fcp_io_channel; uint32_t cpu; uint32_t i = 0; - uint32_t j = 0; - /* * Sanity check for configured queue parameters against the run-time @@ -6839,10 +6853,9 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) for_each_present_cpu(cpu) { if (cpu_online(cpu)) i++; - j++; } phba->sli4_hba.num_online_cpu = i; - phba->sli4_hba.num_present_cpu = j; + phba->sli4_hba.num_present_cpu = lpfc_present_cpu; if (i < cfg_fcp_io_channel) { lpfc_printf_log(phba, @@ -10967,8 +10980,10 @@ lpfc_init(void) } /* Initialize in case vector mapping is needed */ - for (cpu = 0; cpu < LPFC_MAX_CPU; cpu++) - lpfc_used_cpu[cpu] = LPFC_VECTOR_MAP_EMPTY; + lpfc_used_cpu = NULL; + lpfc_present_cpu = 0; + for_each_present_cpu(cpu) + lpfc_present_cpu++; error = pci_register_driver(&lpfc_driver); if (error) { @@ -11008,6 +11023,7 @@ lpfc_exit(void) (1L << _dump_buf_dif_order), _dump_buf_dif); free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order); } + kfree(lpfc_used_cpu); } module_init(lpfc_init); diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 67af460..d9de52f 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -444,7 +444,6 @@ struct lpfc_vector_map_info { struct cpumask maskbits; }; #define LPFC_VECTOR_MAP_EMPTY 0xffff -#define LPFC_MAX_CPU 256 /* SLI4 HBA data structure entries */ struct lpfc_sli4_hba { -- cgit v1.1 From 3bf41ba9376cda911e908dca36fe016293ad8fef Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:03:18 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed crash during FCoE failover testing. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8523b278e..5d63dad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -4074,7 +4074,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, cmd->device ? cmd->device->id : 0xffff, cmd->device ? cmd->device->lun : 0xffff, lpfc_cmd->status, lpfc_cmd->result, - vport->fc_myDID, pnode->nlp_DID, + vport->fc_myDID, + (pnode) ? pnode->nlp_DID : 0, phba->sli_rev == LPFC_SLI_REV4 ? lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff, pIocbOut->iocb.ulpContext, -- cgit v1.1 From 9c6aa9d75fe848ce6c4ef000565d394b08f7260f Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:03:39 -0400 Subject: [SCSI] lpfc 8.3.40: Fix BlockGuard error checking Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 109 ++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 5d63dad..2e31106 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -68,14 +68,12 @@ struct scsi_dif_tuple { __be32 ref_tag; /* Target LBA or indirect LBA */ }; -#if !defined(SCSI_PROT_GUARD_CHECK) || !defined(SCSI_PROT_REF_CHECK) -#define scsi_prot_flagged(sc, flg) sc -#endif - static void lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); static void lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); +static int +lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc); static void lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) @@ -134,6 +132,30 @@ lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) } } +static inline unsigned +lpfc_cmd_blksize(struct scsi_cmnd *sc) +{ + return sc->device->sector_size; +} + +#define LPFC_CHECK_PROTECT_GUARD 1 +#define LPFC_CHECK_PROTECT_REF 2 +static inline unsigned +lpfc_cmd_protect(struct scsi_cmnd *sc, int flag) +{ + return 1; +} + +static inline unsigned +lpfc_cmd_guard_csum(struct scsi_cmnd *sc) +{ + if (lpfc_prot_group_type(NULL, sc) == LPFC_PG_TYPE_NO_DIF) + return 0; + if (scsi_host_get_guard(sc->device->host) == SHOST_DIX_GUARD_IP) + return 1; + return 0; +} + /** * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge. * @phba: Pointer to HBA object. @@ -1409,12 +1431,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) return 0; } -static inline unsigned -lpfc_cmd_blksize(struct scsi_cmnd *sc) -{ - return sc->device->sector_size; -} - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS /* Return if if error injection is detected by Initiator */ @@ -1847,10 +1863,9 @@ static int lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint8_t *txop, uint8_t *rxop) { - uint8_t guard_type = scsi_host_get_guard(sc->device->host); uint8_t ret = 0; - if (guard_type == SHOST_DIX_GUARD_IP) { + if (lpfc_cmd_guard_csum(sc)) { switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: @@ -1928,10 +1943,9 @@ static int lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint8_t *txop, uint8_t *rxop) { - uint8_t guard_type = scsi_host_get_guard(sc->device->host); uint8_t ret = 0; - if (guard_type == SHOST_DIX_GUARD_IP) { + if (lpfc_cmd_guard_csum(sc)) { switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: @@ -2078,12 +2092,12 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, * protection data is automatically generated, not checked. */ if (datadir == DMA_FROM_DEVICE) { - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) bf_set(pde6_ce, pde6, checking); else bf_set(pde6_ce, pde6, 0); - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF)) bf_set(pde6_re, pde6, checking); else bf_set(pde6_re, pde6, 0); @@ -2240,12 +2254,12 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, bf_set(pde6_optx, pde6, txop); bf_set(pde6_oprx, pde6, rxop); - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) bf_set(pde6_ce, pde6, checking); else bf_set(pde6_ce, pde6, 0); - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF)) bf_set(pde6_re, pde6, checking); else bf_set(pde6_re, pde6, 0); @@ -2454,12 +2468,12 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, * protection data is automatically generated, not checked. */ if (sc->sc_data_direction == DMA_FROM_DEVICE) { - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); else bf_set(lpfc_sli4_sge_dif_ce, diseed, 0); - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF)) bf_set(lpfc_sli4_sge_dif_re, diseed, checking); else bf_set(lpfc_sli4_sge_dif_re, diseed, 0); @@ -2610,7 +2624,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, diseed->ref_tag = cpu_to_le32(reftag); diseed->ref_tag_tran = diseed->ref_tag; - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) { + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) { bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); } else { @@ -2629,7 +2643,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, } - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) + if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF)) bf_set(lpfc_sli4_sge_dif_re, diseed, checking); else bf_set(lpfc_sli4_sge_dif_re, diseed, 0); @@ -2792,11 +2806,12 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) ret = LPFC_PG_TYPE_DIF_BUF; break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "9021 Unsupported protection op:%d\n", op); + if (phba) + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "9021 Unsupported protection op:%d\n", + op); break; } - return ret; } @@ -2821,22 +2836,22 @@ lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba, /* Check if there is protection data on the wire */ if (sc->sc_data_direction == DMA_FROM_DEVICE) { - /* Read */ + /* Read check for protection data */ if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT) return fcpdl; } else { - /* Write */ + /* Write check for protection data */ if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP) return fcpdl; } /* * If we are in DIF Type 1 mode every data block has a 8 byte - * DIF (trailer) attached to it. Must ajust FCP data length. + * DIF (trailer) attached to it. Must ajust FCP data length + * to account for the protection data. */ - if (scsi_prot_flagged(sc, SCSI_PROT_TRANSFER_PI)) - fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8; + fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8; return fcpdl; } @@ -3090,25 +3105,10 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) goto skipit; } - /* App Tag checking */ - app_tag = src->app_tag; - if (chk_app && (app_tag != start_app_tag)) { - err_type = BGS_APPTAG_ERR_MASK; - goto out; - } - - /* Reference Tag checking */ - ref_tag = be32_to_cpu(src->ref_tag); - if (chk_ref && (ref_tag != start_ref_tag)) { - err_type = BGS_REFTAG_ERR_MASK; - goto out; - } - start_ref_tag++; - - /* Guard Tag checking */ + /* First Guard Tag checking */ if (chk_guard) { guard_tag = src->guard_tag; - if (guard_type == SHOST_DIX_GUARD_IP) + if (lpfc_cmd_guard_csum(cmd)) sum = lpfc_bg_csum(data_src, blksize); else @@ -3119,6 +3119,21 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) goto out; } } + + /* Reference Tag checking */ + ref_tag = be32_to_cpu(src->ref_tag); + if (chk_ref && (ref_tag != start_ref_tag)) { + err_type = BGS_REFTAG_ERR_MASK; + goto out; + } + start_ref_tag++; + + /* App Tag checking */ + app_tag = src->app_tag; + if (chk_app && (app_tag != start_app_tag)) { + err_type = BGS_APPTAG_ERR_MASK; + goto out; + } skipit: len -= sizeof(struct scsi_dif_tuple); if (len < 0) -- cgit v1.1 From 61f35bff15dd94ad4108c7deb8bf3fcf53d32958 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:03:48 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed system panic during handling unsolicited receive buffer error condition Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 572579f..bd185e1 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -3279,7 +3279,7 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (free_saveq) { list_for_each_entry_safe(rspiocbp, next_iocb, &saveq->list, list) { - list_del(&rspiocbp->list); + list_del_init(&rspiocbp->list); __lpfc_sli_release_iocbq(phba, rspiocbp); } __lpfc_sli_release_iocbq(phba, saveq); -- cgit v1.1 From 91f32d01d9fff7f5f15f3ad136e55dc42d02f9ff Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:01 -0400 Subject: [SCSI] lpfc 8.3.40: Fix inconsistent list removal causes crash. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bd185e1..2e86ac0 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1011,17 +1011,6 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) else sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_lxritag); - /* - ** This should have been removed from the txcmplq before calling - ** iocbq_release. The normal completion - ** path should have already done the list_del_init. - */ - if (unlikely(!list_empty(&iocbq->list))) { - if (iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) - iocbq->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; - list_del_init(&iocbq->list); - } - if (sglq) { if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && @@ -1070,13 +1059,6 @@ __lpfc_sli_release_iocbq_s3(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { size_t start_clean = offsetof(struct lpfc_iocbq, iocb); - /* - ** This should have been removed from the txcmplq before calling - ** iocbq_release. The normal completion - ** path should have already done the list_del_init. - */ - if (unlikely(!list_empty(&iocbq->list))) - list_del_init(&iocbq->list); /* * Clean all volatile data fields, preserve iotag and node struct. -- cgit v1.1 From e85d8f9f62ef5f20a980f3627b07290243daa310 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:10 -0400 Subject: [SCSI] lpfc 8.3.40: Fix starting reference tag when calculating BG error Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 2e31106..8532239 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3088,9 +3088,9 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) chk_guard = 1; guard_type = scsi_host_get_guard(cmd->device->host); + src = (struct scsi_dif_tuple *)sg_virt(sgpe); start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */ start_app_tag = src->app_tag; - src = (struct scsi_dif_tuple *)sg_virt(sgpe); len = sgpe->length; while (src && protsegcnt) { while (len) { -- cgit v1.1 From 398d81c9ff6b8754b4dbfc21d564d90b3b6d470b Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:19 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed list corruption when lpfc_drain_tx runs. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 2e86ac0..a36a8c7 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -16286,7 +16286,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) union lpfc_wqe wqe; int txq_cnt = 0; - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irqsave(&pring->ring_lock, iflags); list_for_each_entry(piocbq, &pring->txq, list) { txq_cnt++; } @@ -16294,14 +16294,14 @@ lpfc_drain_txq(struct lpfc_hba *phba) if (txq_cnt > pring->txq_max) pring->txq_max = txq_cnt; - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&pring->ring_lock, iflags); while (!list_empty(&pring->txq)) { - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irqsave(&pring->ring_lock, iflags); piocbq = lpfc_sli_ringtx_get(phba, pring); if (!piocbq) { - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&pring->ring_lock, iflags); lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "2823 txq empty and txq_cnt is %d\n ", txq_cnt); @@ -16310,7 +16310,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) sglq = __lpfc_sli_get_sglq(phba, piocbq); if (!sglq) { __lpfc_sli_ringtx_put(phba, pring, piocbq); - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&pring->ring_lock, iflags); break; } txq_cnt--; @@ -16338,7 +16338,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) piocbq->iotag, piocbq->sli4_xritag); list_add_tail(&piocbq->list, &completions); } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&pring->ring_lock, iflags); } /* Cancel all the IOCBs that cannot be issued */ -- cgit v1.1 From 8e668af5c200fe96d96d10ec3f0cda3a64bef5a6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:28 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed some logging message fields Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a36a8c7..59addac 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -8713,7 +8713,7 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba, lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, "3116 Port generated FCP XRI ABORT event on " "vpi %d rpi %d xri x%x status 0x%x parameter x%x\n", - ndlp->vport->vpi, ndlp->nlp_rpi, + ndlp->vport->vpi, phba->sli4_hba.rpi_ids[ndlp->nlp_rpi], bf_get(lpfc_wcqe_xa_xri, axri), bf_get(lpfc_wcqe_xa_status, axri), axri->parameter); @@ -9769,7 +9769,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3096 ABORT_XRI_CN completing on xri x%x " + "3096 ABORT_XRI_CN completing on rpi x%x " "original iotag x%x, abort cmd iotag x%x " "status 0x%x, reason 0x%x\n", cmdiocb->iocb.un.acxri.abortContextTag, -- cgit v1.1 From b069d7eb02e72f774050f57794fa79faec39d581 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:36 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed a missing return code in a logging message Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 59addac..876e61b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4566,7 +4566,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) } else { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "2708 This device does not support " - "Advanced Error Reporting (AER)\n"); + "Advanced Error Reporting (AER): %d\n", + rc); phba->cfg_aer_support = 0; } } -- cgit v1.1 From 06f3555125f7fb70242164b6841328af8b7354a8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:50 -0400 Subject: [SCSI] lpfc 8.3.40: Fix to allow OCM to report FEC status Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 094be2c..565dd72 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -3392,6 +3392,7 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, case MBX_DOWN_LOAD: case MBX_UPDATE_CFG: case MBX_KILL_BOARD: + case MBX_READ_TOPOLOGY: case MBX_LOAD_AREA: case MBX_LOAD_EXP_ROM: case MBX_BEACON: @@ -3422,7 +3423,6 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, } break; case MBX_READ_SPARM64: - case MBX_READ_TOPOLOGY: case MBX_REG_LOGIN: case MBX_REG_LOGIN64: case MBX_CONFIG_PORT: -- cgit v1.1 From c4a7c922f55116c3e958ff5d5a53f5bf672ccef1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:04:59 -0400 Subject: [SCSI] lpfc 8.3.40: Clarified the behavior of the lpfc_max_luns module parameter Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 3c5625b..5cb08ae 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -4070,11 +4070,28 @@ LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " "during discovery"); /* -# lpfc_max_luns: maximum allowed LUN. +# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that +# will be scanned by the SCSI midlayer when sequential scanning is +# used; and is also the highest LUN ID allowed when the SCSI midlayer +# parses REPORT_LUN responses. The lpfc driver has no LUN count or +# LUN ID limit, but the SCSI midlayer requires this field for the uses +# above. The lpfc driver limits the default value to 255 for two reasons. +# As it bounds the sequential scan loop, scanning for thousands of luns +# on a target can take minutes of wall clock time. Additionally, +# there are FC targets, such as JBODs, that only recognize 8-bits of +# LUN ID. When they receive a value greater than 8 bits, they chop off +# the high order bits. In other words, they see LUN IDs 0, 256, 512, +# and so on all as LUN ID 0. This causes the linux kernel, which sees +# valid responses at each of the LUN IDs, to believe there are multiple +# devices present, when in fact, there is only 1. +# A customer that is aware of their target behaviors, and the results as +# indicated above, is welcome to increase the lpfc_max_luns value. +# As mentioned, this value is not used by the lpfc driver, only the +# SCSI midlayer. # Value range is [0,65535]. Default value is 255. # NOTE: The SCSI layer might probe all allowed LUN on some old targets. */ -LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN"); +LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID"); /* # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. -- cgit v1.1 From df0d085fdd2e7c39d1249c2d4ad6b3e176efb60c Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:08 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed FCoE connection list vlan identifier and add FCF list debug Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_hbadisc.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 0f6e254..0309cc1 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -6158,12 +6158,44 @@ lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba, memcpy(&conn_entry->conn_rec, &conn_rec[i], sizeof(struct lpfc_fcf_conn_rec)); conn_entry->conn_rec.vlan_tag = - le16_to_cpu(conn_entry->conn_rec.vlan_tag) & 0xFFF; + conn_entry->conn_rec.vlan_tag; conn_entry->conn_rec.flags = - le16_to_cpu(conn_entry->conn_rec.flags); + conn_entry->conn_rec.flags; list_add_tail(&conn_entry->list, &phba->fcf_conn_rec_list); } + + if (!list_empty(&phba->fcf_conn_rec_list)) { + i = 0; + list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, + list) { + conn_rec = &conn_entry->conn_rec; + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3345 FCF connection list rec[%02d]: " + "flags:x%04x, vtag:x%04x, " + "fabric_name:x%02x:%02x:%02x:%02x:" + "%02x:%02x:%02x:%02x, " + "switch_name:x%02x:%02x:%02x:%02x:" + "%02x:%02x:%02x:%02x\n", i++, + conn_rec->flags, conn_rec->vlan_tag, + conn_rec->fabric_name[0], + conn_rec->fabric_name[1], + conn_rec->fabric_name[2], + conn_rec->fabric_name[3], + conn_rec->fabric_name[4], + conn_rec->fabric_name[5], + conn_rec->fabric_name[6], + conn_rec->fabric_name[7], + conn_rec->switch_name[0], + conn_rec->switch_name[1], + conn_rec->switch_name[2], + conn_rec->switch_name[3], + conn_rec->switch_name[4], + conn_rec->switch_name[5], + conn_rec->switch_name[6], + conn_rec->switch_name[7]); + } + } } /** -- cgit v1.1 From 3be30e0e4486b3568044efe27caf405296d7845a Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:17 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed system panic due to unsafe walking and deleting linked list Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_scsi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8532239..5fd3528 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1166,13 +1166,14 @@ lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) static struct lpfc_scsi_buf* lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { - struct lpfc_scsi_buf *lpfc_cmd ; + struct lpfc_scsi_buf *lpfc_cmd, *lpfc_cmd_next; unsigned long gflag = 0; unsigned long pflag = 0; int found = 0; spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag); - list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, list) { + list_for_each_entry_safe(lpfc_cmd, lpfc_cmd_next, + &phba->lpfc_scsi_buf_list_get, list) { if (lpfc_test_rrq_active(phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag)) continue; @@ -1186,8 +1187,8 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) &phba->lpfc_scsi_buf_list_get); INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put); spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag); - list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, - list) { + list_for_each_entry_safe(lpfc_cmd, lpfc_cmd_next, + &phba->lpfc_scsi_buf_list_get, list) { if (lpfc_test_rrq_active( phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag)) continue; -- cgit v1.1 From b230b8a298d1f042fb501a4bbdbc954c927e9ff1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:27 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed issue mailbox wait routine failed to issue dump memory mbox command Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 876e61b..bb78e4d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10092,12 +10092,13 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, uint32_t timeout) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); + MAILBOX_t *mb = NULL; int retval; unsigned long flag; - /* The caller must leave context1 empty. */ + /* The caller might set context1 for extended buffer */ if (pmboxq->context1) - return MBX_NOT_FINISHED; + mb = (MAILBOX_t *)pmboxq->context1; pmboxq->mbox_flag &= ~LPFC_MBX_WAKE; /* setup wake call as IOCB callback */ @@ -10113,7 +10114,8 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, msecs_to_jiffies(timeout * 1000)); spin_lock_irqsave(&phba->hbalock, flag); - pmboxq->context1 = NULL; + /* restore the possible extended buffer for free resource */ + pmboxq->context1 = (uint8_t *)mb; /* * if LPFC_MBX_WAKE flag is set the mailbox is completed * else do not free the resources. @@ -10126,6 +10128,9 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; } spin_unlock_irqrestore(&phba->hbalock, flag); + } else { + /* restore the possible extended buffer for free resource */ + pmboxq->context1 = (uint8_t *)mb; } return retval; -- cgit v1.1 From c2b9712edd32967d84befe8628270a85f1b7e5a6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:36 -0400 Subject: [SCSI] lpfc 8.3.40: Fixed a race condition between SLI host and port failed FCF rediscovery Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 97 ++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 62 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7e5a2b1..cba2d95 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4050,52 +4050,6 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba) } /** - * lpfc_sli4_perform_inuse_fcf_recovery - Perform inuse fcf recovery - * @vport: pointer to lpfc hba data structure. - * - * This routine is to perform FCF recovery when the in-use FCF either dead or - * got modified. - **/ -static void -lpfc_sli4_perform_inuse_fcf_recovery(struct lpfc_hba *phba, - struct lpfc_acqe_fip *acqe_fip) -{ - int rc; - - spin_lock_irq(&phba->hbalock); - /* Mark the fast failover process in progress */ - phba->fcf.fcf_flag |= FCF_DEAD_DISC; - spin_unlock_irq(&phba->hbalock); - - lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, - "2771 Start FCF fast failover process due to in-use " - "FCF DEAD/MODIFIED event: evt_tag:x%x, index:x%x\n", - acqe_fip->event_tag, acqe_fip->index); - rc = lpfc_sli4_redisc_fcf_table(phba); - if (rc) { - lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, - "2772 Issue FCF rediscover mabilbox command " - "failed, fail through to FCF dead event\n"); - spin_lock_irq(&phba->hbalock); - phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; - spin_unlock_irq(&phba->hbalock); - /* - * Last resort will fail over by treating this as a link - * down to FCF registration. - */ - lpfc_sli4_fcf_dead_failthrough(phba); - } else { - /* Reset FCF roundrobin bmask for new discovery */ - lpfc_sli4_clear_fcf_rr_bmask(phba); - /* - * Handling fast FCF failover to a DEAD FCF event is - * considered equalivant to receiving CVL to all vports. - */ - lpfc_sli4_perform_all_vport_cvl(phba); - } -} - -/** * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event * @phba: pointer to lpfc hba data structure. * @acqe_link: pointer to the async fcoe completion queue entry. @@ -4160,22 +4114,9 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, break; } - /* If FCF has been in discovered state, perform rediscovery - * only if the FCF with the same index of the in-use FCF got - * modified during normal operation. Otherwise, do nothing. - */ - if (phba->pport->port_state > LPFC_FLOGI) { + /* If the FCF has been in discovered state, do nothing. */ + if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { spin_unlock_irq(&phba->hbalock); - if (phba->fcf.current_rec.fcf_indx == - acqe_fip->index) { - lpfc_printf_log(phba, KERN_ERR, LOG_FIP, - "3300 In-use FCF (%d) " - "modified, perform FCF " - "rediscovery\n", - acqe_fip->index); - lpfc_sli4_perform_inuse_fcf_recovery(phba, - acqe_fip); - } break; } spin_unlock_irq(&phba->hbalock); @@ -4228,7 +4169,39 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, * is no longer valid as we are not in the middle of FCF * failover process already. */ - lpfc_sli4_perform_inuse_fcf_recovery(phba, acqe_fip); + spin_lock_irq(&phba->hbalock); + /* Mark the fast failover process in progress */ + phba->fcf.fcf_flag |= FCF_DEAD_DISC; + spin_unlock_irq(&phba->hbalock); + + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2771 Start FCF fast failover process due to " + "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " + "\n", acqe_fip->event_tag, acqe_fip->index); + rc = lpfc_sli4_redisc_fcf_table(phba); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | + LOG_DISCOVERY, + "2772 Issue FCF rediscover mabilbox " + "command failed, fail through to FCF " + "dead event\n"); + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; + spin_unlock_irq(&phba->hbalock); + /* + * Last resort will fail over by treating this + * as a link down to FCF registration. + */ + lpfc_sli4_fcf_dead_failthrough(phba); + } else { + /* Reset FCF roundrobin bmask for new discovery */ + lpfc_sli4_clear_fcf_rr_bmask(phba); + /* + * Handling fast FCF failover to a DEAD FCF event is + * considered equalivant to receiving CVL to all vports. + */ + lpfc_sli4_perform_all_vport_cvl(phba); + } break; case LPFC_FIP_EVENT_TYPE_CVL: phba->fcoe_cvl_eventtag = acqe_fip->event_tag; -- cgit v1.1 From 92c13f291e42e35d9f15decca9cc8ddee2ae350b Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:45 -0400 Subject: [SCSI] lpfc 8.3.40: Update Copyrights to 2013 for 8.3.38, 8.3.39, and 8.3.40 modifications Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc.h | 2 +- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 2 +- drivers/scsi/lpfc/lpfc_els.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_hw.h | 2 +- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_mbox.c | 2 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.h | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 2 +- drivers/scsi/lpfc/lpfc_sli4.h | 2 +- drivers/scsi/lpfc/lpfc_version.h | 4 ++-- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index bcc56ca..93f222d 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 565dd72..6630520 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2009-2012 Emulex. All rights reserved. * + * Copyright (C) 2009-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index d41456e..cda076a 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2011 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index ae1a07c..6839117 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2010 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3cae0a9..6b8ee74 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 0309cc1..60d6ca2 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 83700c1..6f927d3 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2011 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 713a461..4ec3d7c 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2009-2012 Emulex. All rights reserved. * + * Copyright (C) 2009-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cba2d95..e0b20fa 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 41363db..b1c510f 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2009 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 31e9b92..6aaf39a 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 5fd3528..243de1d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 21a2ffe..b1d9f7fc 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bb78e4d..43440ca 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index d9de52f..d710b87 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2009-2011 Emulex. All rights reserved. * + * Copyright (C) 2009-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index a38dc3b..60a2981 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -30,4 +30,4 @@ #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION -#define LPFC_COPYRIGHT "Copyright(c) 2004-2009 Emulex. All rights reserved." +#define LPFC_COPYRIGHT "Copyright(c) 2004-2013 Emulex. All rights reserved." -- cgit v1.1 From 9246cc2bd46cc674e027ea9f11a0e3c443079e90 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 31 May 2013 17:05:53 -0400 Subject: [SCSI] lpfc 8.3.40: Update lpfc version to driver version 8.3.40 Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 60a2981..c6c32ee 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.39" +#define LPFC_DRIVER_VERSION "8.3.40" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- cgit v1.1 From 32d3d793fb2d40d2a255af64ffa17cfb2132c323 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 21 May 2013 23:24:22 +0400 Subject: [SCSI] ipr: qc_fill_rtf() method should not store alternate status register The 'ctl' field of the 'struct ata_taskfile' is not really dual purpose, i.e. it is not intended for storing the alternate status register (which is mapped at the same address in the legacy IDE controllers) in the qc_fill_rtf() method. No other 'libata' driver except 'drivers/scsi/ipr.c' stores the alternate status register's value in the 'ctl' field of 'qc->result_tf', hence this driver should not do this as well... Signed-off-by: Sergei Shtylyov Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a87767f..0d43176 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6662,7 +6662,6 @@ static bool ipr_qc_fill_rtf(struct ata_queued_cmd *qc) tf->hob_lbal = g->hob_lbal; tf->hob_lbam = g->hob_lbam; tf->hob_lbah = g->hob_lbah; - tf->ctl = g->alt_status; return true; } -- cgit v1.1 From bbe37a67d9da18e40dfd9232586612424b1466f7 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:19 -0700 Subject: [SCSI] bfa: Support for FC BB credit recovery This patch includes changes to 1) Enable/disable fc credit recovery on Brocade FC adapter port operating at max supported speed. 2) Get credit recovery status and stats related to credit loss and recovered credits Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs.h | 10 +++++ drivers/scsi/bfa/bfa_defs_svc.h | 49 +++++++++++++++++---- drivers/scsi/bfa/bfa_fcs.c | 62 +++----------------------- drivers/scsi/bfa/bfa_fcs.h | 5 --- drivers/scsi/bfa/bfa_fcs_rport.c | 2 +- drivers/scsi/bfa/bfa_svc.c | 95 +++++++++++++++++++++++++++++++++++----- drivers/scsi/bfa/bfa_svc.h | 12 ++--- drivers/scsi/bfa/bfad_bsg.c | 47 ++++++++++++++------ drivers/scsi/bfa/bfad_bsg.h | 19 +++++++- drivers/scsi/bfa/bfi_ms.h | 5 +-- 10 files changed, 202 insertions(+), 104 deletions(-) diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index 0efdf31..bdd1bae 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -185,6 +185,8 @@ enum bfa_status { BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */ BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */ BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ + BFA_STATUS_BBCR_FC_ONLY = 201, /*!< BBCredit Recovery is supported for * + * FC mode only */ BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */ BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */ @@ -198,6 +200,14 @@ enum bfa_status { BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ + BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is + * supported at max port speed alone */ + BFA_STATUS_ERROR_BBCR_ENABLED = 259, /*!< BB credit recovery + * is enabled */ + BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value. + * Valid range is [1-15] */ + BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational. + * Disable BBCR and try this operation again. */ BFA_STATUS_MAX_VAL /* Unknown error code */ }; #define bfa_status_t enum bfa_status diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index ec03c8c..c06359b 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -257,8 +257,6 @@ struct bfa_fw_port_lksm_stats_s { u32 nos_tx; /* No. of times NOS tx started */ u32 hwsm_lrr_rx; /* No. of times LRR rx-ed by HWSM */ u32 hwsm_lr_rx; /* No. of times LR rx-ed by HWSM */ - u32 bbsc_lr; /* LKSM LR tx for credit recovery */ - u32 rsvd; }; struct bfa_fw_port_snsm_stats_s { @@ -409,7 +407,7 @@ struct bfa_fw_trunk_stats_s { u32 rsvd; /* padding for 64 bit alignment */ }; -struct bfa_fw_advsm_stats_s { +struct bfa_fw_aport_stats_s { u32 flogi_sent; /* Flogi sent */ u32 flogi_acc_recvd; /* Flogi Acc received */ u32 flogi_rjt_recvd; /* Flogi rejects received */ @@ -419,6 +417,12 @@ struct bfa_fw_advsm_stats_s { u32 elp_accepted; /* ELP Accepted */ u32 elp_rejected; /* ELP rejected */ u32 elp_dropped; /* ELP dropped */ + + u32 bbcr_lr_count; /*!< BBCR Link Resets */ + u32 frame_lost_intrs; /*!< BBCR Frame loss intrs */ + u32 rrdy_lost_intrs; /*!< BBCR Rrdy loss intrs */ + + u32 rsvd; }; /* @@ -489,7 +493,7 @@ struct bfa_fw_stats_s { struct bfa_fw_fcxchg_stats_s fcxchg_stats; struct bfa_fw_lps_stats_s lps_stats; struct bfa_fw_trunk_stats_s trunk_stats; - struct bfa_fw_advsm_stats_s advsm_stats; + struct bfa_fw_aport_stats_s aport_stats; struct bfa_fw_mac_mod_stats_s macmod_stats; struct bfa_fw_ct_mod_stats_s ctmod_stats; struct bfa_fw_eth_sndrcv_stats_s ethsndrcv_stats; @@ -545,6 +549,27 @@ struct bfa_qos_attr_s { struct bfa_qos_bw_s qos_bw_op; /* QOS bw operational */ }; +enum bfa_bbcr_state { + BFA_BBCR_DISABLED, /*!< BBCR is disable */ + BFA_BBCR_ONLINE, /*!< BBCR is online */ + BFA_BBCR_OFFLINE, /*!< BBCR is offline */ +}; + +enum bfa_bbcr_err_reason { + BFA_BBCR_ERR_REASON_NONE, /*!< Unknown */ + BFA_BBCR_ERR_REASON_SPEED_UNSUP, /*!< Port speed < max sup_speed */ + BFA_BBCR_ERR_REASON_PEER_UNSUP, /*!< BBCR is disable on peer port */ + BFA_BBCR_ERR_REASON_NON_BRCD_SW, /*!< Connected to non BRCD switch */ + BFA_BBCR_ERR_REASON_FLOGI_RJT, /*!< Login rejected by the switch */ +}; + +struct bfa_bbcr_attr_s { + u8 state; + u8 peer_bb_scn; + u8 reason; + u8 rsvd; +}; + /* * These fields should be displayed only from the CLI. * There will be a separate BFAL API (get_qos_vc_attr ?) @@ -892,6 +917,9 @@ struct bfa_defs_fcpim_throttle_s { u16 rsvd; }; +#define BFA_BB_SCN_DEF 3 +#define BFA_BB_SCN_MAX 0x0F + /* * Physical port configuration */ @@ -907,8 +935,8 @@ struct bfa_port_cfg_s { u8 tx_bbcredit; /* transmit buffer credits */ u8 ratelimit; /* ratelimit enabled or not */ u8 trl_def_speed; /* ratelimit default speed */ - u8 bb_scn; /* BB_SCN value from FLOGI Exchg */ - u8 bb_scn_state; /* Config state of BB_SCN */ + u8 bb_cr_enabled; /*!< Config state of BB_SCN */ + u8 bb_scn; /*!< BB_SCN value for FLOGI Exchg */ u8 faa_state; /* FAA enabled/disabled */ u8 rsvd1; u16 path_tov; /* device path timeout */ @@ -1052,6 +1080,7 @@ struct bfa_port_link_s { struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ union { struct bfa_fcport_loop_info_s loop_info; + struct bfa_bbcr_attr_s bbcr_attr; union { struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ @@ -1215,9 +1244,11 @@ struct bfa_port_fc_stats_s { u64 bad_os_count; /* Invalid ordered sets */ u64 err_enc_out; /* Encoding err nonframe_8b10b */ u64 err_enc; /* Encoding err frame_8b10b */ - u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */ - u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */ - u64 bbsc_link_resets; /* Credit Recovery-Link Resets */ + u64 bbcr_frames_lost; /*!< BBCR Frames Lost */ + u64 bbcr_rrdys_lost; /*!< BBCR RRDYs Lost */ + u64 bbcr_link_resets; /*!< BBCR Link Resets */ + u64 bbcr_frame_lost_intrs; /*!< BBCR Frame loss intrs */ + u64 bbcr_rrdy_lost_intrs; /*!< BBCR Rrdy loss intrs */ u64 loop_timeouts; /* Loop timeouts */ }; diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index d428808..a3ab5cc 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -240,9 +240,6 @@ static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg, u32 rsp_len, u32 resid_len, struct fchs_s *rspfchs); -static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric); -static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled( - struct bfa_fcs_fabric_s *fabric); static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, enum bfa_fcs_fabric_event event); @@ -404,8 +401,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_CONT_OP: bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, - fabric->bb_credit, - bfa_fcs_fabric_oper_bbscn(fabric)); + fabric->bb_credit); fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; if (fabric->auth_reqd && fabric->is_auth) { @@ -433,8 +429,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_NO_FABRIC: fabric->fab_type = BFA_FCS_FABRIC_N2N; bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, - fabric->bb_credit, - bfa_fcs_fabric_oper_bbscn(fabric)); + fabric->bb_credit); bfa_fcs_fabric_notify_online(fabric); bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); break; @@ -602,8 +597,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_NO_FABRIC: bfa_trc(fabric->fcs, fabric->bb_credit); bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, - fabric->bb_credit, - bfa_fcs_fabric_oper_bbscn(fabric)); + fabric->bb_credit); break; case BFA_FCS_FABRIC_SM_RETRY_OP: @@ -965,10 +959,6 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status) case BFA_STATUS_FABRIC_RJT: fabric->stats.flogi_rejects++; - if (fabric->lps->lsrjt_rsn == FC_LS_RJT_RSN_LOGICAL_ERROR && - fabric->lps->lsrjt_expl == FC_LS_RJT_EXP_NO_ADDL_INFO) - fabric->fcs->bbscn_flogi_rjt = BFA_TRUE; - bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); return; @@ -1014,14 +1004,11 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) { struct bfa_s *bfa = fabric->fcs->bfa; struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; - u8 alpa = 0, bb_scn = 0; + u8 alpa = 0; - if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && - (!fabric->fcs->bbscn_flogi_rjt)) - bb_scn = BFA_FCS_PORT_DEF_BB_SCN; bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa), - pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd, bb_scn); + pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); fabric->stats.flogi_sent++; } @@ -1102,40 +1089,6 @@ bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric) } /* - * Computes operating BB_SCN value - */ -static u8 -bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) -{ - u8 pr_bbscn = fabric->lps->pr_bbscn; - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa); - - if (!(fcport->cfg.bb_scn_state && pr_bbscn)) - return 0; - - /* return max of local/remote bb_scn values */ - return ((pr_bbscn > BFA_FCS_PORT_DEF_BB_SCN) ? - pr_bbscn : BFA_FCS_PORT_DEF_BB_SCN); -} - -/* - * Check if BB_SCN can be enabled. - */ -static bfa_boolean_t -bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric) -{ - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa); - - if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) && - fcport->cfg.bb_scn_state && - !bfa_fcport_is_qos_enabled(fabric->fcs->bfa) && - !bfa_fcport_is_trunk_enabled(fabric->fcs->bfa)) - return BFA_TRUE; - else - return BFA_FALSE; -} - -/* * Delete all vports and wait for vport delete completions. */ static void @@ -1273,7 +1226,6 @@ void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric) { bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); - fabric->fcs->bbscn_flogi_rjt = BFA_FALSE; bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN); } @@ -1480,7 +1432,6 @@ bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric, } fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred); - fabric->lps->pr_bbscn = (be16_to_cpu(flogi->csp.rxsz) >> 12); bport->port_topo.pn2n.rem_port_wwn = flogi->port_name; bport->port_topo.pn2n.reply_oxid = fchs->ox_id; @@ -1513,8 +1464,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) n2n_port->reply_oxid, pcfg->pwwn, pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa), - bfa_fcport_get_rx_bbcredit(bfa), - bfa_fcs_fabric_oper_bbscn(fabric)); + bfa_fcport_get_rx_bbcredit(bfa), 0); bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag, BFA_FALSE, FC_CLASS_3, diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index a449706..1369682 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -258,9 +258,6 @@ struct bfa_fcs_fabric_s; #define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 48 #define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ 16 -/* bb_scn value in 2^bb_scn */ -#define BFA_FCS_PORT_DEF_BB_SCN 3 - /* * Get FC port ID for a logical port. */ @@ -683,8 +680,6 @@ struct bfa_fcs_s { struct bfa_trc_mod_s *trcmod; /* tracing module */ bfa_boolean_t vf_enabled; /* VF mode is enabled */ bfa_boolean_t fdmi_enabled; /* FDMI is enabled */ - bfa_boolean_t bbscn_enabled; /* Driver Config Parameter */ - bfa_boolean_t bbscn_flogi_rjt;/* FLOGI reject due to BB_SCN */ bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ u16 port_vfid; /* port default VF ID */ struct bfa_fcs_driver_info_s driver_info; diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 610ca95..62713a7 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -2577,7 +2577,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred); bfa_fcport_set_tx_bbcredit(port->fcs->bfa, - port->fabric->bb_credit, 0); + port->fabric->bb_credit); } } diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 7ed2c57..6ed6042 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -1614,7 +1614,6 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) lps->lp_mac = rsp->lp_mac; lps->brcd_switch = rsp->brcd_switch; lps->fcf_mac = rsp->fcf_mac; - lps->pr_bbscn = rsp->bb_scn; break; @@ -1744,7 +1743,6 @@ bfa_lps_send_login(struct bfa_lps_s *lps) m->nwwn = lps->nwwn; m->fdisc = lps->fdisc; m->auth_en = lps->auth_en; - m->bb_scn = lps->bb_scn; bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); list_del(&lps->qe); @@ -1940,7 +1938,7 @@ bfa_lps_delete(struct bfa_lps_s *lps) */ void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, - wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn) + wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en) { lps->uarg = uarg; lps->alpa = alpa; @@ -1949,7 +1947,6 @@ bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, lps->nwwn = nwwn; lps->fdisc = BFA_FALSE; lps->auth_en = auth_en; - lps->bb_scn = bb_scn; bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); } @@ -3158,6 +3155,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) fcport->qos_attr = pevent->link_state.qos_attr; fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; + if (fcport->cfg.bb_cr_enabled) + fcport->bbcr_attr = pevent->link_state.attr.bbcr_attr; /* * update trunk state if applicable */ @@ -3177,7 +3176,6 @@ bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) { fcport->speed = BFA_PORT_SPEED_UNKNOWN; fcport->topology = BFA_PORT_TOPOLOGY_NONE; - fcport->bbsc_op_state = BFA_FALSE; } /* @@ -3629,6 +3627,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) fcport->qos_attr.qos_bw_op = i2hmsg.penable_rsp->port_cfg.qos_bw; + if (fcport->cfg.bb_cr_enabled) + fcport->bbcr_attr.state = BFA_BBCR_OFFLINE; + else + fcport->bbcr_attr.state = BFA_BBCR_DISABLED; + bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); } break; @@ -3639,6 +3642,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) break; case BFI_FCPORT_I2H_EVENT: + if (fcport->cfg.bb_cr_enabled) + fcport->bbcr_attr.state = BFA_BBCR_OFFLINE; + else + fcport->bbcr_attr.state = BFA_BBCR_DISABLED; + if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); else { @@ -3964,14 +3972,11 @@ bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) } void -bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn) +bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); fcport->cfg.tx_bbcredit = (u8)tx_bbcredit; - fcport->cfg.bb_scn = bb_scn; - if (bb_scn) - fcport->bbsc_op_state = BFA_TRUE; } /* @@ -4021,7 +4026,6 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); - attr->bbsc_op_status = fcport->bbsc_op_state; /* PBC Disabled State */ if (bfa_fcport_is_pbcdisabled(bfa)) @@ -4217,6 +4221,77 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) return fcport->cfg.trunked; } +bfa_status_t +bfa_fcport_cfg_bbcr(struct bfa_s *bfa, bfa_boolean_t on_off, u8 bb_scn) +{ + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + + bfa_trc(bfa, on_off); + + if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC) + return BFA_STATUS_BBCR_FC_ONLY; + + if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type) && + (bfa->ioc.attr->card_type != BFA_MFG_TYPE_CHINOOK)) + return BFA_STATUS_CMD_NOTSUPP_MEZZ; + + if (on_off) { + if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) + return BFA_STATUS_TOPOLOGY_LOOP; + + if (fcport->cfg.qos_enabled) + return BFA_STATUS_ERROR_QOS_ENABLED; + + if (fcport->cfg.trunked) + return BFA_STATUS_TRUNK_ENABLED; + + if ((fcport->cfg.speed != BFA_PORT_SPEED_AUTO) && + (fcport->cfg.speed < bfa_ioc_speed_sup(&bfa->ioc))) + return BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT; + + if (bfa_ioc_speed_sup(&bfa->ioc) < BFA_PORT_SPEED_8GBPS) + return BFA_STATUS_FEATURE_NOT_SUPPORTED; + + if (fcport->cfg.bb_cr_enabled) { + if (bb_scn != fcport->cfg.bb_scn) + return BFA_STATUS_BBCR_CFG_NO_CHANGE; + else + return BFA_STATUS_NO_CHANGE; + } + + if ((bb_scn == 0) || (bb_scn > BFA_BB_SCN_MAX)) + bb_scn = BFA_BB_SCN_DEF; + + fcport->cfg.bb_cr_enabled = on_off; + fcport->cfg.bb_scn = bb_scn; + } else { + if (!fcport->cfg.bb_cr_enabled) + return BFA_STATUS_NO_CHANGE; + + fcport->cfg.bb_cr_enabled = on_off; + fcport->cfg.bb_scn = 0; + } + + return BFA_STATUS_OK; +} + +bfa_status_t +bfa_fcport_get_bbcr_attr(struct bfa_s *bfa, + struct bfa_bbcr_attr_s *bbcr_attr) +{ + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + + if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC) + return BFA_STATUS_BBCR_FC_ONLY; + + if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) + return BFA_STATUS_TOPOLOGY_LOOP; + + *bbcr_attr = fcport->bbcr_attr; + + return BFA_STATUS_OK; +} + void bfa_fcport_dportenable(struct bfa_s *bfa) { diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 8d7fbec..768ed6a 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -405,8 +405,6 @@ struct bfa_lps_s { bfa_status_t status; /* login status */ u16 pdusz; /* max receive PDU size */ u16 pr_bbcred; /* BB_CREDIT from peer */ - u8 pr_bbscn; /* BB_SCN from peer */ - u8 bb_scn; /* local BB_SCN */ u8 lsrjt_rsn; /* LSRJT reason */ u8 lsrjt_expl; /* LSRJT explanation */ u8 lun_mask; /* LUN mask flag */ @@ -510,11 +508,11 @@ struct bfa_fcport_s { bfa_boolean_t diag_busy; /* diag busy status */ bfa_boolean_t beacon; /* port beacon status */ bfa_boolean_t link_e2e_beacon; /* link beacon status */ - bfa_boolean_t bbsc_op_state; /* Cred recov Oper State */ struct bfa_fcport_trunk_s trunk; u16 fcoe_vlan; struct bfa_mem_dma_s fcport_dma; bfa_boolean_t stats_dma_ready; + struct bfa_bbcr_attr_s bbcr_attr; }; #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) @@ -556,7 +554,7 @@ bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw); enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); -void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); +void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); void bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon); @@ -571,6 +569,10 @@ void bfa_fcport_dportenable(struct bfa_s *bfa); void bfa_fcport_dportdisable(struct bfa_s *bfa); bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); +bfa_status_t bfa_fcport_cfg_bbcr(struct bfa_s *bfa, + bfa_boolean_t on_off, u8 bb_scn); +bfa_status_t bfa_fcport_get_bbcr_attr(struct bfa_s *bfa, + struct bfa_bbcr_attr_s *bbcr_attr); /* * bfa rport API functions @@ -667,7 +669,7 @@ struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); void bfa_lps_delete(struct bfa_lps_s *lps); void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, wwn_t pwwn, wwn_t nwwn, - bfa_boolean_t auth_en, u8 bb_scn); + bfa_boolean_t auth_en); void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, wwn_t nwwn); void bfa_lps_fdisclogo(struct bfa_lps_s *lps); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 555e7db..bda1500 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -402,25 +402,43 @@ bfad_iocmd_port_cfg_maxfrsize(struct bfad_s *bfad, void *cmd) } int -bfad_iocmd_port_cfg_bbsc(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) +bfad_iocmd_port_cfg_bbcr(struct bfad_s *bfad, unsigned int cmd, void *pcmd) { - struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); - unsigned long flags; + struct bfa_bsg_bbcr_enable_s *iocmd = + (struct bfa_bsg_bbcr_enable_s *)pcmd; + unsigned long flags; + int rc; spin_lock_irqsave(&bfad->bfad_lock, flags); - if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { - if (v_cmd == IOCMD_PORT_BBSC_ENABLE) - fcport->cfg.bb_scn_state = BFA_TRUE; - else if (v_cmd == IOCMD_PORT_BBSC_DISABLE) - fcport->cfg.bb_scn_state = BFA_FALSE; + if (cmd == IOCMD_PORT_BBCR_ENABLE) + rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_TRUE, iocmd->bb_scn); + else if (cmd == IOCMD_PORT_BBCR_DISABLE) + rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_FALSE, 0); + else { + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + return -EINVAL; } spin_unlock_irqrestore(&bfad->bfad_lock, flags); - iocmd->status = BFA_STATUS_OK; + iocmd->status = rc; return 0; } +int +bfad_iocmd_port_get_bbcr_attr(struct bfad_s *bfad, void *pcmd) +{ + struct bfa_bsg_bbcr_attr_s *iocmd = (struct bfa_bsg_bbcr_attr_s *) pcmd; + unsigned long flags; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = + bfa_fcport_get_bbcr_attr(&bfad->bfa, &iocmd->attr); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + return 0; +} + + static int bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) { @@ -2750,9 +2768,12 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, case IOCMD_PORT_CFG_MAXFRSZ: rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd); break; - case IOCMD_PORT_BBSC_ENABLE: - case IOCMD_PORT_BBSC_DISABLE: - rc = bfad_iocmd_port_cfg_bbsc(bfad, iocmd, cmd); + case IOCMD_PORT_BBCR_ENABLE: + case IOCMD_PORT_BBCR_DISABLE: + rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, iocmd); + break; + case IOCMD_PORT_BBCR_GET_ATTR: + rc = bfad_iocmd_port_get_bbcr_attr(bfad, iocmd); break; case IOCMD_LPORT_GET_ATTR: rc = bfad_iocmd_lport_get_attr(bfad, iocmd); diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 15e1fc8..612463b 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -46,8 +46,9 @@ enum { IOCMD_PORT_CFG_ALPA, IOCMD_PORT_CFG_MAXFRSZ, IOCMD_PORT_CLR_ALPA, - IOCMD_PORT_BBSC_ENABLE, - IOCMD_PORT_BBSC_DISABLE, + IOCMD_PORT_BBCR_ENABLE, + IOCMD_PORT_BBCR_DISABLE, + IOCMD_PORT_BBCR_GET_ATTR, IOCMD_LPORT_GET_ATTR, IOCMD_LPORT_GET_RPORTS, IOCMD_LPORT_GET_STATS, @@ -495,6 +496,20 @@ struct bfa_bsg_port_cfg_mode_s { struct bfa_port_cfg_mode_s cfg; }; +struct bfa_bsg_bbcr_enable_s { + bfa_status_t status; + u16 bfad_num; + u8 bb_scn; + u8 rsvd; +}; + +struct bfa_bsg_bbcr_attr_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + struct bfa_bbcr_attr_s attr; +}; + struct bfa_bsg_faa_attr_s { bfa_status_t status; u16 bfad_num; diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index 5ae2c16..1a3fe5a 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -276,8 +276,7 @@ struct bfi_fcport_enable_req_s { struct bfi_fcport_set_svc_params_req_s { struct bfi_mhdr_s mh; /* msg header */ __be16 tx_bbcredit; /* Tx credits */ - u8 bb_scn; /* BB_SC FC credit recovery */ - u8 rsvd; + u8 rsvd[2]; }; /* @@ -446,8 +445,8 @@ struct bfi_lps_login_rsp_s { mac_t fcf_mac; u8 ext_status; u8 brcd_switch; /* attached peer is brcd switch */ - u8 bb_scn; /* atatched port's bb_scn */ u8 bfa_tag; + u8 rsvd; }; struct bfi_lps_logout_req_s { -- cgit v1.1 From 4e1e0d8d71810fb5e4c294299ab35c30a746353d Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:20 -0700 Subject: [SCSI] bfa: Forward Error Correction status query This patch includes changes to get FC HBA feature Forward Error Correction (FEC) (enabled at 16Gig speed) status from firmware and to return to brocade HBA management utility. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs_svc.h | 15 +++++++++++++-- drivers/scsi/bfa/bfa_svc.c | 8 ++++++++ drivers/scsi/bfa/bfa_svc.h | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index c06359b..0880d86 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -882,6 +882,15 @@ enum bfa_lunmask_state_s { BFA_LUNMASK_UNINITIALIZED = 0xff, }; +/** + * FEC states + */ +enum bfa_fec_state_s { + BFA_FEC_ONLINE = 1, /*!< FEC is online */ + BFA_FEC_OFFLINE = 2, /*!< FEC is offline */ + BFA_FEC_OFFLINE_NOT_16G = 3, /*!< FEC is offline (speed not 16Gig) */ +}; + #pragma pack(1) /* * LUN mask configuration @@ -978,6 +987,7 @@ struct bfa_port_attr_s { bfa_boolean_t link_e2e_beacon; /* link beacon is on */ bfa_boolean_t bbsc_op_status; /* fc credit recovery oper * state */ + enum bfa_fec_state_s fec_state; /*!< current FEC state */ /* * Dynamic field - info from FCS @@ -989,7 +999,7 @@ struct bfa_port_attr_s { /* FCoE specific */ u16 fcoe_vlan; - u8 rsvd1[6]; + u8 rsvd1[2]; }; /* @@ -1076,7 +1086,8 @@ struct bfa_port_link_s { u8 speed; /* Link speed (1/2/4/8 G) */ u32 linkstate_opt; /* Linkstate optional data (debug) */ u8 trunked; /* Trunked or not (1 or 0) */ - u8 resvd[7]; + u8 fec_state; /*!< State of FEC */ + u8 resvd[6]; struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ union { struct bfa_fcport_loop_info_s loop_info; diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 6ed6042..1baa9b3 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -3079,6 +3079,8 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, port_cfg->qos_bw.med = BFA_QOS_BW_MED; port_cfg->qos_bw.low = BFA_QOS_BW_LOW; + fcport->fec_state = BFA_FEC_OFFLINE; + INIT_LIST_HEAD(&fcport->stats_pending_q); INIT_LIST_HEAD(&fcport->statsclr_pending_q); @@ -3157,6 +3159,9 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) if (fcport->cfg.bb_cr_enabled) fcport->bbcr_attr = pevent->link_state.attr.bbcr_attr; + + fcport->fec_state = pevent->link_state.fec_state; + /* * update trunk state if applicable */ @@ -3176,6 +3181,7 @@ bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) { fcport->speed = BFA_PORT_SPEED_UNKNOWN; fcport->topology = BFA_PORT_TOPOLOGY_NONE; + fcport->fec_state = BFA_FEC_OFFLINE; } /* @@ -4027,6 +4033,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); + attr->fec_state = fcport->fec_state; + /* PBC Disabled State */ if (bfa_fcport_is_pbcdisabled(bfa)) attr->port_state = BFA_PORT_ST_PREBOOT_DISABLED; diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 768ed6a..5af64de1 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -513,6 +513,7 @@ struct bfa_fcport_s { struct bfa_mem_dma_s fcport_dma; bfa_boolean_t stats_dma_ready; struct bfa_bbcr_attr_s bbcr_attr; + enum bfa_fec_state_s fec_state; }; #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) -- cgit v1.1 From 1a898a794d5913c899a329c5dec39d28e6065672 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:21 -0700 Subject: [SCSI] bfa: Add dynamic diagnostic port support D-Port is a new port type created with the intention of running link level diagnostic tests like loopback, traffic test. In static D-port mode, user configures the port to D-port mode and starts the test, but in dynamic D-port, once the Brocade switch port is configured to D-port, it will reject the regular FLOGI from HBA with reason that it is in D-port mode. So based on the reason code HBA port will turn itself into D-port and start diagnostic test. Signed-off-by: Sudarsana Reddy Kalluru Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs.h | 79 +++++- drivers/scsi/bfa/bfa_defs_svc.h | 1 + drivers/scsi/bfa/bfa_svc.c | 595 +++++++++++++++++++++++++++++++++++++--- drivers/scsi/bfa/bfa_svc.h | 21 +- drivers/scsi/bfa/bfad_bsg.c | 81 ++++-- drivers/scsi/bfa/bfad_bsg.h | 25 +- drivers/scsi/bfa/bfi.h | 68 ++++- 7 files changed, 781 insertions(+), 89 deletions(-) diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index bdd1bae..d65a9b4 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -199,15 +199,34 @@ enum bfa_status { BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ + BFA_STATUS_DPORT_NO_SFP = 243, /* SFP is not present.\n D-port will be + * enabled but it will be operational + * only after inserting a valid SFP. */ BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ + BFA_STATUS_DPORT_ENOSYS = 254, /* Switch has no D_Port functionality */ + BFA_STATUS_DPORT_CANT_PERF = 255, /* Switch port is not D_Port capable + * or D_Port is disabled */ + BFA_STATUS_DPORT_LOGICALERR = 256, /* Switch D_Port fail */ + BFA_STATUS_DPORT_SWBUSY = 257, /* Switch port busy */ BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is * supported at max port speed alone */ BFA_STATUS_ERROR_BBCR_ENABLED = 259, /*!< BB credit recovery * is enabled */ BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value. * Valid range is [1-15] */ + BFA_STATUS_DDPORT_ERR = 261, /* Dynamic D_Port mode is active.\n To + * exit dynamic mode, disable D_Port on + * the remote port */ + BFA_STATUS_DPORT_SFPWRAP_ERR = 262, /* Clear e/o_wrap fail, check or + * replace SFP */ BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational. * Disable BBCR and try this operation again. */ + BFA_STATUS_DPORT_SW_NOTREADY = 268, /* Remote port is not ready to + * start dport test. Check remote + * port status. */ + BFA_STATUS_DPORT_INV_SFP = 271, /* Invalid SFP for D-PORT mode. */ + BFA_STATUS_DPORT_CMD_NOTSUPP = 273, /* Dport is not supported by + * remote port */ BFA_STATUS_MAX_VAL /* Unknown error code */ }; #define bfa_status_t enum bfa_status @@ -527,17 +546,6 @@ struct bfa_ioc_aen_data_s { }; /* - * D-port states - * -*/ -enum bfa_dport_state { - BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */ - BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */ - BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */ - BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */ -}; - -/* * ---------------------- mfg definitions ------------ */ @@ -1136,6 +1144,7 @@ struct bfa_flash_attr_s { #define LB_PATTERN_DEFAULT 0xB5B5B5B5 #define QTEST_CNT_DEFAULT 10 #define QTEST_PAT_DEFAULT LB_PATTERN_DEFAULT +#define DPORT_ENABLE_LOOPCNT_DEFAULT (1024 * 1024) struct bfa_diag_memtest_s { u8 algo; @@ -1164,6 +1173,54 @@ struct bfa_diag_loopback_result_s { u8 rsvd[3]; }; +enum bfa_diag_dport_test_status { + DPORT_TEST_ST_IDLE = 0, /* the test has not started yet. */ + DPORT_TEST_ST_FINAL = 1, /* the test done successfully */ + DPORT_TEST_ST_SKIP = 2, /* the test skipped */ + DPORT_TEST_ST_FAIL = 3, /* the test failed */ + DPORT_TEST_ST_INPRG = 4, /* the testing is in progress */ + DPORT_TEST_ST_RESPONDER = 5, /* test triggered from remote port */ + DPORT_TEST_ST_STOPPED = 6, /* the test stopped by user. */ + DPORT_TEST_ST_MAX +}; + +enum bfa_diag_dport_test_type { + DPORT_TEST_ELOOP = 0, + DPORT_TEST_OLOOP = 1, + DPORT_TEST_ROLOOP = 2, + DPORT_TEST_LINK = 3, + DPORT_TEST_MAX +}; + +enum bfa_diag_dport_test_opmode { + BFA_DPORT_OPMODE_AUTO = 0, + BFA_DPORT_OPMODE_MANU = 1, +}; + +struct bfa_diag_dport_subtest_result_s { + u8 status; /* bfa_diag_dport_test_status */ + u8 rsvd[7]; /* 64bit align */ + u64 start_time; /* timestamp */ +}; + +struct bfa_diag_dport_result_s { + wwn_t rp_pwwn; /* switch port wwn */ + wwn_t rp_nwwn; /* switch node wwn */ + u64 start_time; /* user/sw start time */ + u64 end_time; /* timestamp */ + u8 status; /* bfa_diag_dport_test_status */ + u8 mode; /* bfa_diag_dport_test_opmode */ + u8 rsvd; /* 64bit align */ + u8 speed; /* link speed for buf_reqd */ + u16 buffer_required; + u16 frmsz; /* frame size for buf_reqd */ + u32 lpcnt; /* Frame count */ + u32 pat; /* Pattern */ + u32 roundtrip_latency; /* in nano sec */ + u32 est_cable_distance; /* in meter */ + struct bfa_diag_dport_subtest_result_s subtest[DPORT_TEST_MAX]; +}; + struct bfa_diag_ledtest_s { u32 cmd; /* bfa_led_op_t */ u32 color; /* bfa_led_color_t */ diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 0880d86..2f20ba5 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -761,6 +761,7 @@ enum bfa_port_states { BFA_PORT_ST_TOGGLING_QWAIT = 14, BFA_PORT_ST_FAA_MISCONFIG = 15, BFA_PORT_ST_DPORT = 16, + BFA_PORT_ST_DDPORT = 17, BFA_PORT_ST_MAX_STATE, }; diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 1baa9b3..6c41e57 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -70,6 +70,8 @@ enum bfa_fcport_sm_event { BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */ + BFA_FCPORT_SM_DDPORTENABLE = 13, /* enable ddport */ + BFA_FCPORT_SM_DDPORTDISABLE = 14, /* disable ddport */ }; /* @@ -202,6 +204,8 @@ static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event); static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event); @@ -234,6 +238,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = { {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, + {BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT}, {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, }; @@ -2646,6 +2651,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, bfa_sm_set_state(fcport, bfa_fcport_sm_dport); break; + case BFA_FCPORT_SM_DDPORTENABLE: + bfa_sm_set_state(fcport, bfa_fcport_sm_ddport); + break; + default: bfa_sm_fault(fcport->bfa, event); } @@ -2759,6 +2768,40 @@ bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) } static void +bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) +{ + bfa_trc(fcport->bfa, event); + + switch (event) { + case BFA_FCPORT_SM_DISABLE: + case BFA_FCPORT_SM_DDPORTDISABLE: + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); + break; + + case BFA_FCPORT_SM_DPORTENABLE: + case BFA_FCPORT_SM_DPORTDISABLE: + case BFA_FCPORT_SM_ENABLE: + case BFA_FCPORT_SM_START: + /** + * Ignore event for a port that is ddport + */ + break; + + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); + break; + + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); + break; + + default: + bfa_sm_fault(fcport->bfa, event); + } +} + +static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) { @@ -3860,6 +3903,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) return BFA_STATUS_LOOP_UNSUPP_MEZZ; if (bfa_fcport_is_dport(bfa) != BFA_FALSE) return BFA_STATUS_DPORT_ERR; + if (bfa_fcport_is_ddport(bfa) != BFA_FALSE) + return BFA_STATUS_DPORT_ERR; break; case BFA_PORT_TOPOLOGY_AUTO: @@ -4127,6 +4172,15 @@ bfa_fcport_is_dport(struct bfa_s *bfa) BFA_PORT_ST_DPORT); } +bfa_boolean_t +bfa_fcport_is_ddport(struct bfa_s *bfa) +{ + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + + return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == + BFA_PORT_ST_DDPORT); +} + bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) { @@ -4320,6 +4374,24 @@ bfa_fcport_dportdisable(struct bfa_s *bfa) bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); } +void +bfa_fcport_ddportenable(struct bfa_s *bfa) +{ + /* + * Assume caller check for port is in disable state + */ + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE); +} + +void +bfa_fcport_ddportdisable(struct bfa_s *bfa) +{ + /* + * Assume caller check for port is in disable state + */ + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE); +} + /* * Rport State machine functions */ @@ -5705,6 +5777,14 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) * Dport forward declaration */ +enum bfa_dport_test_state_e { + BFA_DPORT_ST_DISABLED = 0, /*!< dport is disabled */ + BFA_DPORT_ST_INP = 1, /*!< test in progress */ + BFA_DPORT_ST_COMP = 2, /*!< test complete successfully */ + BFA_DPORT_ST_NO_SFP = 3, /*!< sfp is not present */ + BFA_DPORT_ST_NOTSTART = 4, /*!< test not start dport is enabled */ +}; + /* * BFA DPORT state machine events */ @@ -5714,6 +5794,9 @@ enum bfa_dport_sm_event { BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ + BFA_DPORT_SM_START = 6, /* re-start dport test */ + BFA_DPORT_SM_REQFAIL = 7, /* request failure */ + BFA_DPORT_SM_SCN = 8, /* state change notify frm fw */ }; static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, @@ -5728,9 +5811,19 @@ static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, enum bfa_dport_sm_event event); static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event); +static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event); +static void bfa_dport_sm_starting(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event); +static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event); +static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event); static void bfa_dport_qresume(void *cbarg); static void bfa_dport_req_comp(struct bfa_dport_s *dport, - bfi_diag_dport_rsp_t *msg); + struct bfi_diag_dport_rsp_s *msg); +static void bfa_dport_scn(struct bfa_dport_s *dport, + struct bfi_diag_dport_scn_s *msg); /* * BFA fcdiag module @@ -5772,6 +5865,8 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); dport->cbfn = NULL; dport->cbarg = NULL; + dport->test_state = BFA_DPORT_ST_DISABLED; + memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s)); } static void @@ -5974,7 +6069,12 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); break; case BFI_DIAG_I2H_DPORT: - bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); + bfa_dport_req_comp(&fcdiag->dport, + (struct bfi_diag_dport_rsp_s *)msg); + break; + case BFI_DIAG_I2H_DPORT_SCN: + bfa_dport_scn(&fcdiag->dport, + (struct bfi_diag_dport_scn_s *)msg); break; default: bfa_trc(fcdiag, msg->mhdr.msg_id); @@ -6069,7 +6169,11 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, return BFA_STATUS_UNSUPP_SPEED; } } - + /* check to see if fcport is dport */ + if (bfa_fcport_is_dport(bfa)) { + bfa_trc(fcdiag, fcdiag->lb.lock); + return BFA_STATUS_DPORT_ENABLED; + } /* check to see if there is another destructive diag cmd running */ if (fcdiag->lb.lock) { bfa_trc(fcdiag, fcdiag->lb.lock); @@ -6173,6 +6277,15 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa) /* * D-port */ +#define bfa_dport_result_start(__dport, __mode) do { \ + (__dport)->result.start_time = bfa_get_log_time(); \ + (__dport)->result.status = DPORT_TEST_ST_INPRG; \ + (__dport)->result.mode = (__mode); \ + (__dport)->result.rp_pwwn = (__dport)->rp_pwwn; \ + (__dport)->result.rp_nwwn = (__dport)->rp_nwwn; \ + (__dport)->result.lpcnt = (__dport)->lpcnt; \ +} while (0) + static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req); static void @@ -6207,6 +6320,18 @@ bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) /* ignore */ break; + case BFA_DPORT_SM_SCN: + if (dport->i2hmsg.scn.state == BFI_DPORT_SCN_DDPORT_ENABLE) { + bfa_fcport_ddportenable(dport->bfa); + dport->dynamic = BFA_TRUE; + dport->test_state = BFA_DPORT_ST_NOTSTART; + bfa_sm_set_state(dport, bfa_dport_sm_enabled); + } else { + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); + WARN_ON(1); + } + break; + default: bfa_sm_fault(dport->bfa, event); } @@ -6242,9 +6367,23 @@ bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) switch (event) { case BFA_DPORT_SM_FWRSP: + memset(&dport->result, 0, + sizeof(struct bfa_diag_dport_result_s)); + if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { + dport->test_state = BFA_DPORT_ST_NO_SFP; + } else { + dport->test_state = BFA_DPORT_ST_INP; + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO); + } bfa_sm_set_state(dport, bfa_dport_sm_enabled); break; + case BFA_DPORT_SM_REQFAIL: + dport->test_state = BFA_DPORT_ST_DISABLED; + bfa_fcport_dportdisable(dport->bfa); + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + break; + case BFA_DPORT_SM_HWFAIL: bfa_sm_set_state(dport, bfa_dport_sm_disabled); bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); @@ -6261,8 +6400,11 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) bfa_trc(dport->bfa, event); switch (event) { - case BFA_DPORT_SM_ENABLE: - /* Already enabled */ + case BFA_DPORT_SM_START: + if (bfa_dport_send_req(dport, BFI_DPORT_START)) + bfa_sm_set_state(dport, bfa_dport_sm_starting); + else + bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait); break; case BFA_DPORT_SM_DISABLE: @@ -6277,6 +6419,48 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) bfa_sm_set_state(dport, bfa_dport_sm_disabled); break; + case BFA_DPORT_SM_SCN: + switch (dport->i2hmsg.scn.state) { + case BFI_DPORT_SCN_TESTCOMP: + dport->test_state = BFA_DPORT_ST_COMP; + break; + + case BFI_DPORT_SCN_TESTSTART: + dport->test_state = BFA_DPORT_ST_INP; + break; + + case BFI_DPORT_SCN_TESTSKIP: + case BFI_DPORT_SCN_SUBTESTSTART: + /* no state change */ + break; + + case BFI_DPORT_SCN_SFP_REMOVED: + dport->test_state = BFA_DPORT_ST_NO_SFP; + break; + + case BFI_DPORT_SCN_DDPORT_DISABLE: + bfa_fcport_ddportdisable(dport->bfa); + + if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE)) + bfa_sm_set_state(dport, + bfa_dport_sm_dynamic_disabling); + else + bfa_sm_set_state(dport, + bfa_dport_sm_dynamic_disabling_qwait); + break; + + case BFI_DPORT_SCN_FCPORT_DISABLE: + bfa_fcport_ddportdisable(dport->bfa); + + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + dport->dynamic = BFA_FALSE; + break; + + default: + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); + bfa_sm_fault(dport->bfa, event); + } + break; default: bfa_sm_fault(dport->bfa, event); } @@ -6300,6 +6484,10 @@ bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); break; + case BFA_DPORT_SM_SCN: + /* ignore */ + break; + default: bfa_sm_fault(dport->bfa, event); } @@ -6312,7 +6500,98 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) switch (event) { case BFA_DPORT_SM_FWRSP: + dport->test_state = BFA_DPORT_ST_DISABLED; + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + break; + + case BFA_DPORT_SM_HWFAIL: bfa_sm_set_state(dport, bfa_dport_sm_disabled); + bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); + break; + + case BFA_DPORT_SM_SCN: + /* no state change */ + break; + + default: + bfa_sm_fault(dport->bfa, event); + } +} + +static void +bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event) +{ + bfa_trc(dport->bfa, event); + + switch (event) { + case BFA_DPORT_SM_QRESUME: + bfa_sm_set_state(dport, bfa_dport_sm_starting); + bfa_dport_send_req(dport, BFI_DPORT_START); + break; + + case BFA_DPORT_SM_HWFAIL: + bfa_reqq_wcancel(&dport->reqq_wait); + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); + break; + + default: + bfa_sm_fault(dport->bfa, event); + } +} + +static void +bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) +{ + bfa_trc(dport->bfa, event); + + switch (event) { + case BFA_DPORT_SM_FWRSP: + memset(&dport->result, 0, + sizeof(struct bfa_diag_dport_result_s)); + if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { + dport->test_state = BFA_DPORT_ST_NO_SFP; + } else { + dport->test_state = BFA_DPORT_ST_INP; + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU); + } + /* fall thru */ + + case BFA_DPORT_SM_REQFAIL: + bfa_sm_set_state(dport, bfa_dport_sm_enabled); + break; + + case BFA_DPORT_SM_HWFAIL: + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); + break; + + default: + bfa_sm_fault(dport->bfa, event); + } +} + +static void +bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event) +{ + bfa_trc(dport->bfa, event); + + switch (event) { + case BFA_DPORT_SM_SCN: + switch (dport->i2hmsg.scn.state) { + case BFI_DPORT_SCN_DDPORT_DISABLED: + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + dport->dynamic = BFA_FALSE; + bfa_fcport_enable(dport->bfa); + break; + + default: + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); + bfa_sm_fault(dport->bfa, event); + + } break; case BFA_DPORT_SM_HWFAIL: @@ -6325,6 +6604,32 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) } } +static void +bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, + enum bfa_dport_sm_event event) +{ + bfa_trc(dport->bfa, event); + + switch (event) { + case BFA_DPORT_SM_QRESUME: + bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling); + bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE); + break; + + case BFA_DPORT_SM_HWFAIL: + bfa_sm_set_state(dport, bfa_dport_sm_disabled); + bfa_reqq_wcancel(&dport->reqq_wait); + bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); + break; + + case BFA_DPORT_SM_SCN: + /* ignore */ + break; + + default: + bfa_sm_fault(dport->bfa, event); + } +} static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) @@ -6332,12 +6637,6 @@ bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) struct bfi_diag_dport_req_s *m; /* - * Increment message tag before queue check, so that responses to old - * requests are discarded. - */ - dport->msgtag++; - - /* * check for room in queue to send request now */ m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); @@ -6349,7 +6648,10 @@ bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, bfa_fn_lpu(dport->bfa)); m->req = req; - m->msgtag = dport->msgtag; + if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) { + m->lpcnt = cpu_to_be32(dport->lpcnt); + m->payload = cpu_to_be32(dport->payload); + } /* * queue I/O message to firmware @@ -6368,19 +6670,131 @@ bfa_dport_qresume(void *cbarg) } static void -bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) +bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg) { - bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); + msg->status = cpu_to_be32(msg->status); + dport->i2hmsg.rsp.status = msg->status; + dport->rp_pwwn = msg->pwwn; + dport->rp_nwwn = msg->nwwn; + + if ((msg->status == BFA_STATUS_OK) || + (msg->status == BFA_STATUS_DPORT_NO_SFP)) { + bfa_trc(dport->bfa, msg->status); + bfa_trc(dport->bfa, dport->rp_pwwn); + bfa_trc(dport->bfa, dport->rp_nwwn); + bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); + + } else { + bfa_trc(dport->bfa, msg->status); + bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL); + } bfa_cb_fcdiag_dport(dport, msg->status); } +static bfa_boolean_t +bfa_dport_is_sending_req(struct bfa_dport_s *dport) +{ + if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || + bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || + bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || + bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) || + bfa_sm_cmp_state(dport, bfa_dport_sm_starting) || + bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) { + return BFA_TRUE; + } else { + return BFA_FALSE; + } +} + +static void +bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg) +{ + int i; + uint8_t subtesttype; + + bfa_trc(dport->bfa, msg->state); + dport->i2hmsg.scn.state = msg->state; + + switch (dport->i2hmsg.scn.state) { + case BFI_DPORT_SCN_TESTCOMP: + dport->result.end_time = bfa_get_log_time(); + bfa_trc(dport->bfa, dport->result.end_time); + + dport->result.status = msg->info.testcomp.status; + bfa_trc(dport->bfa, dport->result.status); + + dport->result.roundtrip_latency = + cpu_to_be32(msg->info.testcomp.latency); + dport->result.est_cable_distance = + cpu_to_be32(msg->info.testcomp.distance); + dport->result.buffer_required = + be16_to_cpu(msg->info.testcomp.numbuffer); + + dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz); + dport->result.speed = msg->info.testcomp.speed; + + bfa_trc(dport->bfa, dport->result.roundtrip_latency); + bfa_trc(dport->bfa, dport->result.est_cable_distance); + bfa_trc(dport->bfa, dport->result.buffer_required); + bfa_trc(dport->bfa, dport->result.frmsz); + bfa_trc(dport->bfa, dport->result.speed); + + for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) { + dport->result.subtest[i].status = + msg->info.testcomp.subtest_status[i]; + bfa_trc(dport->bfa, dport->result.subtest[i].status); + } + break; + + case BFI_DPORT_SCN_TESTSKIP: + case BFI_DPORT_SCN_DDPORT_ENABLE: + memset(&dport->result, 0, + sizeof(struct bfa_diag_dport_result_s)); + break; + + case BFI_DPORT_SCN_TESTSTART: + memset(&dport->result, 0, + sizeof(struct bfa_diag_dport_result_s)); + dport->rp_pwwn = msg->info.teststart.pwwn; + dport->rp_nwwn = msg->info.teststart.nwwn; + dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm); + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO); + break; + + case BFI_DPORT_SCN_SUBTESTSTART: + subtesttype = msg->info.teststart.type; + dport->result.subtest[subtesttype].start_time = + bfa_get_log_time(); + dport->result.subtest[subtesttype].status = + DPORT_TEST_ST_INPRG; + + bfa_trc(dport->bfa, subtesttype); + bfa_trc(dport->bfa, + dport->result.subtest[subtesttype].start_time); + break; + + case BFI_DPORT_SCN_SFP_REMOVED: + case BFI_DPORT_SCN_DDPORT_DISABLED: + case BFI_DPORT_SCN_DDPORT_DISABLE: + case BFI_DPORT_SCN_FCPORT_DISABLE: + dport->result.status = DPORT_TEST_ST_IDLE; + break; + + default: + bfa_sm_fault(dport->bfa, msg->state); + } + + bfa_sm_send_event(dport, BFA_DPORT_SM_SCN); +} + /* * Dport enable * * @param[in] *bfa - bfa data struct */ bfa_status_t -bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) +bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, + bfa_cb_diag_t cbfn, void *cbarg) { struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); struct bfa_dport_s *dport = &fcdiag->dport; @@ -6394,6 +6808,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) } /* + * Dport is supported in CT2 or above + */ + if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) { + bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id); + return BFA_STATUS_FEATURE_NOT_SUPPORTED; + } + + /* * Check to see if IOC is down */ if (!bfa_iocfc_is_operational(bfa)) @@ -6431,6 +6853,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) } /* + * Check if diag loopback is running + */ + if (bfa_fcdiag_lb_is_running(bfa)) { + bfa_trc(dport->bfa, 0); + return BFA_STATUS_DIAG_BUSY; + } + + /* * Check to see if port is disable or in dport state */ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && @@ -6440,14 +6870,16 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) } /* + * Check if dport is in dynamic mode + */ + if (dport->dynamic) + return BFA_STATUS_DDPORT_ERR; + + /* * Check if dport is busy */ - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) { + if (bfa_dport_is_sending_req(dport)) return BFA_STATUS_DEVBUSY; - } /* * Check if dport is already enabled @@ -6457,6 +6889,10 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) return BFA_STATUS_DPORT_ENABLED; } + bfa_trc(dport->bfa, lpcnt); + bfa_trc(dport->bfa, pat); + dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; + dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; dport->cbfn = cbfn; dport->cbarg = cbarg; @@ -6485,6 +6921,13 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) } /* + * Check if dport is in dynamic mode + */ + if (dport->dynamic) { + return BFA_STATUS_DDPORT_ERR; + } + + /* * Check to see if port is disable or in dport state */ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && @@ -6496,10 +6939,7 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) /* * Check if dport is busy */ - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) + if (bfa_dport_is_sending_req(dport)) return BFA_STATUS_DEVBUSY; /* @@ -6518,30 +6958,105 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) } /* - * Get D-port state + * Dport start -- restart dport test * - * @param[in] *bfa - bfa data struct + * @param[in] *bfa - bfa data struct */ +bfa_status_t +bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, + bfa_cb_diag_t cbfn, void *cbarg) +{ + struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); + struct bfa_dport_s *dport = &fcdiag->dport; + /* + * Check to see if IOC is down + */ + if (!bfa_iocfc_is_operational(bfa)) + return BFA_STATUS_IOC_NON_OP; + + /* + * Check if dport is in dynamic mode + */ + if (dport->dynamic) + return BFA_STATUS_DDPORT_ERR; + + /* + * Check if dport is busy + */ + if (bfa_dport_is_sending_req(dport)) + return BFA_STATUS_DEVBUSY; + + /* + * Check if dport is in enabled state. + * Test can only be restart when previous test has completed + */ + if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { + bfa_trc(dport->bfa, 0); + return BFA_STATUS_DPORT_DISABLED; + + } else { + if (dport->test_state == BFA_DPORT_ST_NO_SFP) + return BFA_STATUS_DPORT_INV_SFP; + + if (dport->test_state == BFA_DPORT_ST_INP) + return BFA_STATUS_DEVBUSY; + + WARN_ON(dport->test_state != BFA_DPORT_ST_COMP); + } + + bfa_trc(dport->bfa, lpcnt); + bfa_trc(dport->bfa, pat); + + dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; + dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; + + dport->cbfn = cbfn; + dport->cbarg = cbarg; + + bfa_sm_send_event(dport, BFA_DPORT_SM_START); + return BFA_STATUS_OK; +} + +/* + * Dport show -- return dport test result + * + * @param[in] *bfa - bfa data struct + */ bfa_status_t -bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) +bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result) { struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); struct bfa_dport_s *dport = &fcdiag->dport; - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) - *state = BFA_DPORT_ST_ENABLED; - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) - *state = BFA_DPORT_ST_ENABLING; - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) - *state = BFA_DPORT_ST_DISABLED; - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) - *state = BFA_DPORT_ST_DISABLING; - else { - bfa_trc(dport->bfa, BFA_STATUS_EINVAL); - return BFA_STATUS_EINVAL; + /* + * Check to see if IOC is down + */ + if (!bfa_iocfc_is_operational(bfa)) + return BFA_STATUS_IOC_NON_OP; + + /* + * Check if dport is busy + */ + if (bfa_dport_is_sending_req(dport)) + return BFA_STATUS_DEVBUSY; + + /* + * Check if dport is in enabled state. + */ + if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { + bfa_trc(dport->bfa, 0); + return BFA_STATUS_DPORT_DISABLED; + } + + /* + * Check if there is SFP + */ + if (dport->test_state == BFA_DPORT_ST_NO_SFP) + return BFA_STATUS_DPORT_INV_SFP; + + memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s)); + return BFA_STATUS_OK; } diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 5af64de1..ef07365 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -551,6 +551,7 @@ void bfa_fcport_event_register(struct bfa_s *bfa, enum bfa_port_linkstate event), void *event_cbarg); bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa); +bfa_boolean_t bfa_fcport_is_ddport(struct bfa_s *bfa); bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw); enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); @@ -715,10 +716,18 @@ struct bfa_fcdiag_lb_s { struct bfa_dport_s { struct bfa_s *bfa; /* Back pointer to BFA */ bfa_sm_t sm; /* finite state machine */ - u32 msgtag; /* firmware msg tag for reply */ struct bfa_reqq_wait_s reqq_wait; bfa_cb_diag_t cbfn; void *cbarg; + union bfi_diag_dport_msg_u i2hmsg; + u8 test_state; /* enum dport_test_state */ + u8 dynamic; /* boolean_t */ + u8 rsvd[2]; + u32 lpcnt; + u32 payload; /* user defined payload pattern */ + wwn_t rp_pwwn; + wwn_t rp_nwwn; + struct bfa_diag_dport_result_s result; }; struct bfa_fcdiag_s { @@ -742,11 +751,13 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore, u32 queue, struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn, void *cbarg); bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); -bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, - void *cbarg); +bfa_status_t bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, + bfa_cb_diag_t cbfn, void *cbarg); bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg); -bfa_status_t bfa_dport_get_state(struct bfa_s *bfa, - enum bfa_dport_state *state); +bfa_status_t bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, + bfa_cb_diag_t cbfn, void *cbarg); +bfa_status_t bfa_dport_show(struct bfa_s *bfa, + struct bfa_diag_dport_result_s *result); #endif /* __BFA_SVC_H__ */ diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index bda1500..f31acfa 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -1785,51 +1785,87 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) } int -bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd) +bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd) { - struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; + struct bfa_bsg_dport_enable_s *iocmd = + (struct bfa_bsg_dport_enable_s *)pcmd; unsigned long flags; struct bfad_hal_comp fcomp; init_completion(&fcomp.comp); spin_lock_irqsave(&bfad->bfad_lock, flags); - if (cmd == IOCMD_DIAG_DPORT_ENABLE) - iocmd->status = bfa_dport_enable(&bfad->bfa, - bfad_hcb_comp, &fcomp); - else if (cmd == IOCMD_DIAG_DPORT_DISABLE) - iocmd->status = bfa_dport_disable(&bfad->bfa, - bfad_hcb_comp, &fcomp); + iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt, + iocmd->pat, bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if (iocmd->status != BFA_STATUS_OK) + bfa_trc(bfad, iocmd->status); else { - bfa_trc(bfad, 0); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); - return -EINVAL; + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; } - spin_unlock_irqrestore(&bfad->bfad_lock, flags); + return 0; +} +int +bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd) +{ + struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; + unsigned long flags; + struct bfad_hal_comp fcomp; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (iocmd->status != BFA_STATUS_OK) bfa_trc(bfad, iocmd->status); else { wait_for_completion(&fcomp.comp); iocmd->status = fcomp.status; } + return 0; +} + +int +bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd) +{ + struct bfa_bsg_dport_enable_s *iocmd = + (struct bfa_bsg_dport_enable_s *)pcmd; + unsigned long flags; + struct bfad_hal_comp fcomp; + + init_completion(&fcomp.comp); + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt, + iocmd->pat, bfad_hcb_comp, + &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (iocmd->status != BFA_STATUS_OK) { + bfa_trc(bfad, iocmd->status); + } else { + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; + } return 0; } int -bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) +bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) { - struct bfa_bsg_diag_dport_get_state_s *iocmd = - (struct bfa_bsg_diag_dport_get_state_s *)pcmd; - unsigned long flags; + struct bfa_bsg_diag_dport_show_s *iocmd = + (struct bfa_bsg_diag_dport_show_s *)pcmd; + unsigned long flags; spin_lock_irqsave(&bfad->bfad_lock, flags); - iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); + iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result); spin_unlock_irqrestore(&bfad->bfad_lock, flags); return 0; } + int bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) { @@ -2934,11 +2970,16 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); break; case IOCMD_DIAG_DPORT_ENABLE: + rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); + break; case IOCMD_DIAG_DPORT_DISABLE: - rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); + rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); + break; + case IOCMD_DIAG_DPORT_SHOW: + rc = bfad_iocmd_diag_dport_show(bfad, iocmd); break; - case IOCMD_DIAG_DPORT_GET_STATE: - rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); + case IOCMD_DIAG_DPORT_START: + rc = bfad_iocmd_diag_dport_start(bfad, iocmd); break; case IOCMD_PHY_GET_ATTR: rc = bfad_iocmd_phy_get_attr(bfad, iocmd); diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 612463b..3ef321c 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -144,7 +144,6 @@ enum { IOCMD_FCPIM_LUNMASK_DELETE, IOCMD_DIAG_DPORT_ENABLE, IOCMD_DIAG_DPORT_DISABLE, - IOCMD_DIAG_DPORT_GET_STATE, IOCMD_QOS_SET_BW, IOCMD_FCPIM_THROTTLE_QUERY, IOCMD_FCPIM_THROTTLE_SET, @@ -153,6 +152,8 @@ enum { IOCMD_FRUVPD_READ, IOCMD_FRUVPD_UPDATE, IOCMD_FRUVPD_GET_MAX_SIZE, + IOCMD_DIAG_DPORT_SHOW, + IOCMD_DIAG_DPORT_START, }; struct bfa_bsg_gen_s { @@ -593,6 +594,21 @@ struct bfa_bsg_diag_loopback_s { struct bfa_diag_loopback_result_s result; }; +struct bfa_bsg_diag_dport_show_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + struct bfa_diag_dport_result_s result; +}; + +struct bfa_bsg_dport_enable_s { + bfa_status_t status; + u16 bfad_num; + u16 rsvd; + u16 lpcnt; + u16 pat; +}; + struct bfa_bsg_diag_fwping_s { bfa_status_t status; u16 bfad_num; @@ -640,13 +656,6 @@ struct bfa_bsg_diag_lb_stat_s { u16 rsvd; }; -struct bfa_bsg_diag_dport_get_state_s { - bfa_status_t status; - u16 bfad_num; - u16 rsvd; - enum bfa_dport_state state; -}; - struct bfa_bsg_phy_attr_s { bfa_status_t status; u16 bfad_num; diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 57b146b..e70e083 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -973,6 +973,7 @@ enum bfi_diag_i2h { BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT), + BFI_DIAG_I2H_DPORT_SCN = BFA_I2HM(8), }; #define BFI_DIAG_MAX_SGES 2 @@ -1064,16 +1065,73 @@ struct bfi_diag_qtest_req_s { enum bfi_dport_req { BFI_DPORT_DISABLE = 0, /* disable dport request */ BFI_DPORT_ENABLE = 1, /* enable dport request */ + BFI_DPORT_START = 2, /* start dport request */ + BFI_DPORT_SHOW = 3, /* show dport request */ + BFI_DPORT_DYN_DISABLE = 4, /* disable dynamic dport request */ +}; + +enum bfi_dport_scn { + BFI_DPORT_SCN_TESTSTART = 1, + BFI_DPORT_SCN_TESTCOMP = 2, + BFI_DPORT_SCN_SFP_REMOVED = 3, + BFI_DPORT_SCN_DDPORT_ENABLE = 4, + BFI_DPORT_SCN_DDPORT_DISABLE = 5, + BFI_DPORT_SCN_FCPORT_DISABLE = 6, + BFI_DPORT_SCN_SUBTESTSTART = 7, + BFI_DPORT_SCN_TESTSKIP = 8, + BFI_DPORT_SCN_DDPORT_DISABLED = 9, }; struct bfi_diag_dport_req_s { struct bfi_mhdr_s mh; /* 4 bytes */ - u8 req; /* request 1: enable 0: disable */ - u8 status; /* reply status */ - u8 rsvd[2]; - u32 msgtag; /* msgtag for reply */ + u8 req; /* request 1: enable 0: disable */ + u8 rsvd[3]; + u32 lpcnt; + u32 payload; +}; + +struct bfi_diag_dport_rsp_s { + struct bfi_mhdr_s mh; /* header 4 bytes */ + bfa_status_t status; /* reply status */ + wwn_t pwwn; /* switch port wwn. 8 bytes */ + wwn_t nwwn; /* switch node wwn. 8 bytes */ +}; + +struct bfi_diag_dport_scn_teststart_s { + wwn_t pwwn; /* switch port wwn. 8 bytes */ + wwn_t nwwn; /* switch node wwn. 8 bytes */ + u8 type; /* bfa_diag_dport_test_type_e */ + u8 rsvd[3]; + u32 numfrm; /* from switch uint in 1M */ +}; + +struct bfi_diag_dport_scn_testcomp_s { + u8 status; /* bfa_diag_dport_test_status_e */ + u8 speed; /* bfa_port_speed_t */ + u16 numbuffer; /* from switch */ + u8 subtest_status[DPORT_TEST_MAX]; /* 4 bytes */ + u32 latency; /* from switch */ + u32 distance; /* from swtich unit in meters */ + /* Buffers required to saturate the link */ + u16 frm_sz; /* from switch for buf_reqd */ + u8 rsvd[2]; +}; + +struct bfi_diag_dport_scn_s { /* max size == RDS_RMESZ */ + struct bfi_mhdr_s mh; /* header 4 bytes */ + u8 state; /* new state */ + u8 rsvd[3]; + union { + struct bfi_diag_dport_scn_teststart_s teststart; + struct bfi_diag_dport_scn_testcomp_s testcomp; + } info; +}; + +union bfi_diag_dport_msg_u { + struct bfi_diag_dport_req_s req; + struct bfi_diag_dport_rsp_s rsp; + struct bfi_diag_dport_scn_s scn; }; -#define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s /* * PHY module specific -- cgit v1.1 From 1287641e945de1bf533178c2e0e31eed287b4a60 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:22 -0700 Subject: [SCSI] bfa: Fix WARN_ON condition check The WARN_ON condition check in IO completion path is wrong. IOtags returned by the firmware is compared with driver/bfa iotag after masking the retry count bits. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcpim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 27b5609..d7385d1 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -2882,7 +2882,7 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m) iotag = be16_to_cpu(rsp->io_tag); ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); - WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); + WARN_ON(ioim->iotag != iotag); bfa_ioim_cb_profile_comp(fcpim, ioim); -- cgit v1.1 From d7cbc3044f2b28837dd4a46824274294f8fa9d60 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:23 -0700 Subject: [SCSI] bfa: FDMI enhancements Update addl. fields in FDMI to confirm to FC-GS6 standard for RPA and RHBA commands. Signed-off-by: Anil Gurumurthy Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fc.h | 15 ++++ drivers/scsi/bfa/bfa_fcs.h | 21 ++++- drivers/scsi/bfa/bfa_fcs_lport.c | 190 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index bea821b..562ef73 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -1531,6 +1531,12 @@ enum fdmi_hba_attribute_type { FDMI_HBA_ATTRIB_FW_VERSION, /* 0x0009 */ FDMI_HBA_ATTRIB_OS_NAME, /* 0x000A */ FDMI_HBA_ATTRIB_MAX_CT, /* 0x000B */ + FDMI_HBA_ATTRIB_NODE_SYM_NAME, /* 0x000C */ + FDMI_HBA_ATTRIB_VENDOR_INFO, /* 0x000D */ + FDMI_HBA_ATTRIB_NUM_PORTS, /* 0x000E */ + FDMI_HBA_ATTRIB_FABRIC_NAME, /* 0x000F */ + FDMI_HBA_ATTRIB_BIOS_VER, /* 0x0010 */ + FDMI_HBA_ATTRIB_VENDOR_ID = 0x00E0, FDMI_HBA_ATTRIB_MAX_TYPE }; @@ -1545,6 +1551,15 @@ enum fdmi_port_attribute_type { FDMI_PORT_ATTRIB_FRAME_SIZE, /* 0x0004 */ FDMI_PORT_ATTRIB_DEV_NAME, /* 0x0005 */ FDMI_PORT_ATTRIB_HOST_NAME, /* 0x0006 */ + FDMI_PORT_ATTRIB_NODE_NAME, /* 0x0007 */ + FDMI_PORT_ATTRIB_PORT_NAME, /* 0x0008 */ + FDMI_PORT_ATTRIB_PORT_SYM_NAME, /* 0x0009 */ + FDMI_PORT_ATTRIB_PORT_TYPE, /* 0x000A */ + FDMI_PORT_ATTRIB_SUPP_COS, /* 0x000B */ + FDMI_PORT_ATTRIB_PORT_FAB_NAME, /* 0x000C */ + FDMI_PORT_ATTRIB_PORT_FC4_TYPE, /* 0x000D */ + FDMI_PORT_ATTRIB_PORT_STATE = 0x101, /* 0x0101 */ + FDMI_PORT_ATTRIB_PORT_NUM_RPRT = 0x102, /* 0x0102 */ FDMI_PORT_ATTR_MAX_TYPE }; diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 1369682..4f1e650 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -627,6 +627,9 @@ void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, #define BFA_FCS_FDMI_SUPP_SPEEDS_10G FDMI_TRANS_SPEED_10G +#define BFA_FCS_FDMI_VENDOR_INFO_LEN 8 +#define BFA_FCS_FDMI_FC4_TYPE_LEN 32 + /* * HBA Attribute Block : BFA internal representation. Note : Some variable * sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based @@ -637,25 +640,39 @@ struct bfa_fcs_fdmi_hba_attr_s { u8 manufacturer[64]; u8 serial_num[64]; u8 model[16]; - u8 model_desc[256]; + u8 model_desc[128]; u8 hw_version[8]; u8 driver_version[BFA_VERSION_LEN]; u8 option_rom_ver[BFA_VERSION_LEN]; u8 fw_version[BFA_VERSION_LEN]; u8 os_name[256]; __be32 max_ct_pyld; + struct bfa_lport_symname_s node_sym_name; + u8 vendor_info[BFA_FCS_FDMI_VENDOR_INFO_LEN]; + __be32 num_ports; + wwn_t fabric_name; + u8 bios_ver[BFA_VERSION_LEN]; }; /* * Port Attribute Block */ struct bfa_fcs_fdmi_port_attr_s { - u8 supp_fc4_types[32]; /* supported FC4 types */ + u8 supp_fc4_types[BFA_FCS_FDMI_FC4_TYPE_LEN]; __be32 supp_speed; /* supported speed */ __be32 curr_speed; /* current Speed */ __be32 max_frm_size; /* max frame size */ u8 os_device_name[256]; /* OS device Name */ u8 host_name[256]; /* host name */ + wwn_t port_name; + wwn_t node_name; + struct bfa_lport_symname_s port_sym_name; + __be32 port_type; + enum fc_cos scos; + wwn_t port_fabric_name; + u8 port_act_fc4_type[BFA_FCS_FDMI_FC4_TYPE_LEN]; + __be32 port_state; + __be32 num_ports; }; struct bfa_fcs_stats_s { diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 1224d04..8773d5e 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -2048,10 +2048,71 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); templen = sizeof(fcs_hba_attr->max_ct_pyld); memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; len += templen; count++; attr->len = cpu_to_be16(templen + sizeof(attr->type) + sizeof(templen)); + /* + * Send extended attributes ( FOS 7.1 support ) + */ + if (fdmi->retry_cnt == 0) { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME); + templen = sizeof(fcs_hba_attr->node_sym_name); + memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID); + templen = sizeof(fcs_hba_attr->vendor_info); + memcpy(attr->value, &fcs_hba_attr->vendor_info, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS); + templen = sizeof(fcs_hba_attr->num_ports); + memcpy(attr->value, &fcs_hba_attr->num_ports, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME); + templen = sizeof(fcs_hba_attr->fabric_name); + memcpy(attr->value, &fcs_hba_attr->fabric_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER); + templen = sizeof(fcs_hba_attr->bios_ver); + memcpy(attr->value, &fcs_hba_attr->bios_ver, templen); + templen = fc_roundup(attr->len, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + count++; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + } /* * Update size of payload @@ -2252,6 +2313,113 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, sizeof(templen)); } + if (fdmi->retry_cnt == 0) { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME); + templen = sizeof(fcs_port_attr.node_name); + memcpy(attr->value, &fcs_port_attr.node_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME); + templen = sizeof(fcs_port_attr.port_name); + memcpy(attr->value, &fcs_port_attr.port_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + if (fcs_port_attr.port_sym_name.symname[0] != '\0') { + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = + cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME); + templen = sizeof(fcs_port_attr.port_sym_name); + memcpy(attr->value, + &fcs_port_attr.port_sym_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + + sizeof(attr->type) + sizeof(templen)); + } + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE); + templen = sizeof(fcs_port_attr.port_type); + memcpy(attr->value, &fcs_port_attr.port_type, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS); + templen = sizeof(fcs_port_attr.scos); + memcpy(attr->value, &fcs_port_attr.scos, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME); + templen = sizeof(fcs_port_attr.port_fabric_name); + memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE); + templen = sizeof(fcs_port_attr.port_act_fc4_type); + memcpy(attr->value, fcs_port_attr.port_act_fc4_type, + templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE); + templen = sizeof(fcs_port_attr.port_state); + memcpy(attr->value, &fcs_port_attr.port_state, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + + attr = (struct fdmi_attr_s *) curr_ptr; + attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT); + templen = sizeof(fcs_port_attr.num_ports); + memcpy(attr->value, &fcs_port_attr.num_ports, templen); + templen = fc_roundup(templen, sizeof(u32)); + curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; + len += templen; + ++count; + attr->len = cpu_to_be16(templen + sizeof(attr->type) + + sizeof(templen)); + } + /* * Update size of payload */ @@ -2458,6 +2626,15 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, /* Retrieve the max frame size from the port attr */ bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; + + strncpy(hba_attr->node_sym_name.symname, + port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); + strcpy(hba_attr->vendor_info, "BROCADE"); + hba_attr->num_ports = + cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); + hba_attr->fabric_name = port->fabric->lps->pr_nwwn; + strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); + } static void @@ -2467,6 +2644,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, struct bfa_fcs_lport_s *port = fdmi->ms->port; struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; struct bfa_port_attr_s pport_attr; + struct bfa_lport_attr_s lport_attr; memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); @@ -2531,6 +2709,18 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, sizeof(port_attr->host_name)); + port_attr->node_name = bfa_fcs_lport_get_nwwn(port); + port_attr->port_name = bfa_fcs_lport_get_pwwn(port); + + strncpy(port_attr->port_sym_name.symname, + (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN); + bfa_fcs_lport_get_attr(port, &lport_attr); + port_attr->port_type = cpu_to_be32(lport_attr.port_type); + port_attr->scos = pport_attr.cos_supported; + port_attr->port_fabric_name = port->fabric->lps->pr_nwwn; + fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type); + port_attr->port_state = cpu_to_be32(pport_attr.port_state); + port_attr->num_ports = cpu_to_be32(port->num_rports); } /* -- cgit v1.1 From e1aaab89dee184646f7001850e1fe6d55090a728 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:24 -0700 Subject: [SCSI] bfa: Fix 1860 port initialize when ATC is enabled On Xen kernels, if ATC (address translation cache) is enabled, the first PCIe DMA read from the adapter fails with an error. This is due to a bug ASIC, which leads to a failure of 1860 ports to be initialised. This patch includes the fix to disable Invalidated Tag Match Enable capability by setting the bit 26 of CHIP_MISC_PRG to 0, by default it is set to 1. Signed-off-by: Anil Gurumurthy Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_ioc_ct.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index de4e726..a8e52a1 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -918,6 +918,16 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) } } + /* + * The very first PCIe DMA Read done by LPU fails with a fatal error, + * when Address Translation Cache (ATC) has been enabled by system BIOS. + * + * Workaround: + * Disable Invalidated Tag Match Enable capability by setting the bit 26 + * of CHIP_MISC_PRG to 0, by default it is set to 1. + */ + r32 = readl(rb + CT2_CHIP_MISC_PRG); + writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG)); /* * Mask the interrupts and clear any -- cgit v1.1 From f2a0cc3ffd5ee123086b8e76522a85a937d89878 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:25 -0700 Subject: [SCSI] bfa: Fix FDISC timeout handling Retry FDISC a max of 6 times. Introduce new events to handle vport login fails due to max logins to fabric/switch. Signed-off-by: Anil Gurumurthy Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcs_lport.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 8773d5e..2f61a5a 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -5988,6 +5988,7 @@ enum bfa_fcs_vport_event { BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ + BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */ }; static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, @@ -6173,6 +6174,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, break; case BFA_FCS_VPORT_SM_RSP_FAILED: + case BFA_FCS_VPORT_SM_FABRIC_MAX: bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); break; @@ -6243,6 +6245,7 @@ bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, case BFA_FCS_VPORT_SM_OFFLINE: case BFA_FCS_VPORT_SM_RSP_ERROR: case BFA_FCS_VPORT_SM_RSP_FAILED: + case BFA_FCS_VPORT_SM_FABRIC_MAX: case BFA_FCS_VPORT_SM_RSP_DUP_WWN: bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); @@ -6528,7 +6531,7 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) else { bfa_fcs_vport_aen_post(&vport->lport, BFA_LPORT_AEN_NPIV_FABRIC_MAX); - bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX); } break; @@ -6914,7 +6917,19 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) break; } - bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + else + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); + + break; + + case BFA_STATUS_ETIMER: + vport->vport_stats.fdisc_timeouts++; + if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); + else + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); break; case BFA_STATUS_FABRIC_RJT: -- cgit v1.1 From c679b599afa5dd38d20e058aa68bc94c1c1416a1 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:26 -0700 Subject: [SCSI] bfa: kdump fix on 815 and 825 adapters Root cause: When kernel crashes, On brocade 815/825 adapters, bfa IOC state machine and FW doesn't get a notification and hence are not cleanly shutdown. So registers holding driver/IOC state information are not reset back to valid disabled/parking values. This causes subsequent driver initialization to fail during kdump kernel boot. Fix description: during the initialization of first PCI function, reset corresponding register when unclean shutown is detect by reading chip registers. This will make sure that ioc/fw gets clean re-initialization. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_ioc.c | 42 ++++++++++++--------- drivers/scsi/bfa/bfa_ioc.h | 6 +++ drivers/scsi/bfa/bfa_ioc_cb.c | 86 +++++++++++++++++++++++++++++++++++++++---- drivers/scsi/bfa/bfa_ioc_ct.c | 36 ++++++++++++++++++ drivers/scsi/bfa/bfi.h | 4 ++ 5 files changed, 150 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 0116c10..8928b68 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -67,6 +67,14 @@ BFA_TRC_FILE(CNA, IOC); ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) #define bfa_ioc_sync_complete(__ioc) \ ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) +#define bfa_ioc_set_cur_ioc_fwstate(__ioc, __fwstate) \ + ((__ioc)->ioc_hwif->ioc_set_fwstate(__ioc, __fwstate)) +#define bfa_ioc_get_cur_ioc_fwstate(__ioc) \ + ((__ioc)->ioc_hwif->ioc_get_fwstate(__ioc)) +#define bfa_ioc_set_alt_ioc_fwstate(__ioc, __fwstate) \ + ((__ioc)->ioc_hwif->ioc_set_alt_fwstate(__ioc, __fwstate)) +#define bfa_ioc_get_alt_ioc_fwstate(__ioc) \ + ((__ioc)->ioc_hwif->ioc_get_alt_fwstate(__ioc)) #define bfa_ioc_mbox_cmd_pending(__ioc) \ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ @@ -698,7 +706,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) } /* h/w sem init */ - fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); + fwstate = bfa_ioc_get_cur_ioc_fwstate(iocpf->ioc); if (fwstate == BFI_IOC_UNINIT) { writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg); goto sem_get; @@ -725,8 +733,8 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) bfa_trc(iocpf->ioc, fwstate); bfa_trc(iocpf->ioc, swab32(fwhdr.exec)); - writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate); - writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.alt_ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT); + bfa_ioc_set_alt_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT); /* * Unlock the hw semaphore. Should be here only once per boot. @@ -1037,7 +1045,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) */ case IOCPF_E_TIMEOUT: - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); break; @@ -1138,7 +1146,7 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) case IOCPF_E_SEMLOCKED: bfa_ioc_notify_fail(ioc); bfa_ioc_sync_leave(ioc); - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); writel(1, ioc->ioc_regs.ioc_sem_reg); bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); break; @@ -1227,7 +1235,7 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) bfa_ioc_notify_fail(ioc); if (!iocpf->auto_recover) { bfa_ioc_sync_leave(ioc); - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); writel(1, ioc->ioc_regs.ioc_sem_reg); bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); } else { @@ -1519,7 +1527,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) u32 boot_type; u32 boot_env; - ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); if (force) ioc_fwstate = BFI_IOC_UNINIT; @@ -2006,11 +2014,11 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) * Initialize IOC state of all functions on a chip reset. */ if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) { - writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate); - writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST); + bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST); } else { - writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate); - writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING); + bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING); } bfa_ioc_msgflush(ioc); @@ -2038,7 +2046,7 @@ bfa_ioc_is_operational(struct bfa_ioc_s *ioc) bfa_boolean_t bfa_ioc_is_initialized(struct bfa_ioc_s *ioc) { - u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); + u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc); return ((r32 != BFI_IOC_UNINIT) && (r32 != BFI_IOC_INITING) && @@ -2430,12 +2438,12 @@ bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) return BFA_FALSE; - ioc_state = readl(ioc->ioc_regs.ioc_fwstate); + ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc); if (!bfa_ioc_state_disabled(ioc_state)) return BFA_FALSE; if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) { - ioc_state = readl(ioc->ioc_regs.alt_ioc_fwstate); + ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc); if (!bfa_ioc_state_disabled(ioc_state)) return BFA_FALSE; } @@ -2449,8 +2457,8 @@ bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) void bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) { - writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); - writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); + bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT); + bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT); } #define BFA_MFG_NAME "Brocade" @@ -2917,7 +2925,7 @@ bfa_iocpf_sem_timeout(void *ioc_arg) static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) { - u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate); + u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); bfa_trc(ioc, fwstate); diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 23a90e7..de62b68 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -346,6 +346,12 @@ struct bfa_ioc_hwif_s { void (*ioc_sync_ack) (struct bfa_ioc_s *ioc); bfa_boolean_t (*ioc_sync_complete) (struct bfa_ioc_s *ioc); bfa_boolean_t (*ioc_lpu_read_stat) (struct bfa_ioc_s *ioc); + void (*ioc_set_fwstate) (struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate); + enum bfi_ioc_state (*ioc_get_fwstate) (struct bfa_ioc_s *ioc); + void (*ioc_set_alt_fwstate) (struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate); + enum bfi_ioc_state (*ioc_get_alt_fwstate) (struct bfa_ioc_s *ioc); }; /* diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 30df8a2..e3b9287 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -22,6 +22,8 @@ BFA_TRC_FILE(CNA, IOC_CB); +#define bfa_ioc_cb_join_pos(__ioc) ((u32) (1 << BFA_IOC_CB_JOIN_SH)) + /* * forward declarations */ @@ -37,6 +39,12 @@ static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_set_cur_ioc_fwstate( + struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); +static enum bfi_ioc_state bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_set_alt_ioc_fwstate( + struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); +static enum bfi_ioc_state bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); static struct bfa_ioc_hwif_s hwif_cb; @@ -59,6 +67,10 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete; + hwif_cb.ioc_set_fwstate = bfa_ioc_cb_set_cur_ioc_fwstate; + hwif_cb.ioc_get_fwstate = bfa_ioc_cb_get_cur_ioc_fwstate; + hwif_cb.ioc_set_alt_fwstate = bfa_ioc_cb_set_alt_ioc_fwstate; + hwif_cb.ioc_get_alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate; ioc->ioc_hwif = &hwif_cb; } @@ -187,6 +199,20 @@ bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc) { + u32 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + + /** + * Driver load time. If the join bit is set, + * it is due to an unclean exit by the driver for this + * PCI fn in the previous incarnation. Whoever comes here first + * should clean it up, no matter which PCI fn. + */ + if (ioc_fwstate & BFA_IOC_CB_JOIN_MASK) { + writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); + writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); + return BFA_TRUE; + } + return bfa_ioc_cb_sync_complete(ioc); } @@ -212,24 +238,66 @@ bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc) static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc) { + u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); + u32 join_pos = bfa_ioc_cb_join_pos(ioc); + + writel((r32 | join_pos), ioc->ioc_regs.ioc_fwstate); } static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc) { + u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); + u32 join_pos = bfa_ioc_cb_join_pos(ioc); + + writel((r32 & ~join_pos), ioc->ioc_regs.ioc_fwstate); +} + +static void +bfa_ioc_cb_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); + + writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)), + ioc->ioc_regs.ioc_fwstate); +} + +static enum bfi_ioc_state +bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) +{ + return (enum bfi_ioc_state)(readl(ioc->ioc_regs.ioc_fwstate) & + BFA_IOC_CB_FWSTATE_MASK); +} + +static void +bfa_ioc_cb_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate) +{ + u32 r32 = readl(ioc->ioc_regs.alt_ioc_fwstate); + + writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)), + ioc->ioc_regs.alt_ioc_fwstate); +} + +static enum bfi_ioc_state +bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) +{ + return (enum bfi_ioc_state)(readl(ioc->ioc_regs.alt_ioc_fwstate) & + BFA_IOC_CB_FWSTATE_MASK); } static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc) { - writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_ioc_cb_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); } static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc) { - uint32_t fwstate, alt_fwstate; - fwstate = readl(ioc->ioc_regs.ioc_fwstate); + u32 fwstate, alt_fwstate; + fwstate = bfa_ioc_cb_get_cur_ioc_fwstate(ioc); /* * At this point, this IOC is hoding the hw sem in the @@ -257,7 +325,7 @@ bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc) fwstate == BFI_IOC_OP) return BFA_TRUE; else { - alt_fwstate = readl(ioc->ioc_regs.alt_ioc_fwstate); + alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate(ioc); if (alt_fwstate == BFI_IOC_FAIL || alt_fwstate == BFI_IOC_DISABLED || alt_fwstate == BFI_IOC_UNINIT || @@ -272,7 +340,7 @@ bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc) bfa_status_t bfa_ioc_cb_pll_init(void __iomem *rb, enum bfi_asic_mode fcmode) { - u32 pll_sclk, pll_fclk; + u32 pll_sclk, pll_fclk, join_bits; pll_sclk = __APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_P0_1(3U) | @@ -282,8 +350,12 @@ bfa_ioc_cb_pll_init(void __iomem *rb, enum bfi_asic_mode fcmode) __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) | __APP_PLL_LCLK_JITLMT0_1(3U) | __APP_PLL_LCLK_CNTLMT0_1(3U); - writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG)); - writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG)); + join_bits = readl(rb + BFA_IOC0_STATE_REG) & + BFA_IOC_CB_JOIN_MASK; + writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC0_STATE_REG)); + join_bits = readl(rb + BFA_IOC1_STATE_REG) & + BFA_IOC_CB_JOIN_MASK; + writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC1_STATE_REG)); writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index a8e52a1..bd53150 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -43,6 +43,12 @@ static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_set_cur_ioc_fwstate( + struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); +static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_set_alt_ioc_fwstate( + struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); +static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); static struct bfa_ioc_hwif_s hwif_ct; static struct bfa_ioc_hwif_s hwif_ct2; @@ -512,6 +518,10 @@ bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif) hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; + hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate; + hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate; + hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate; + hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate; } /** @@ -959,3 +969,29 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) return BFA_STATUS_OK; } + +static void +bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate) +{ + writel(fwstate, ioc->ioc_regs.ioc_fwstate); +} + +static enum bfi_ioc_state +bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) +{ + return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate); +} + +static void +bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, + enum bfi_ioc_state fwstate) +{ + writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate); +} + +static enum bfi_ioc_state +bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) +{ + return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate); +} diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index e70e083..bf0a58d 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -374,6 +374,10 @@ enum bfi_ioc_state { BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ }; +#define BFA_IOC_CB_JOIN_SH 16 +#define BFA_IOC_CB_FWSTATE_MASK 0x0000ffff +#define BFA_IOC_CB_JOIN_MASK 0xffff0000 + #define BFI_IOC_ENDIAN_SIG 0x12345678 enum { -- cgit v1.1 From bccd2683df56ddce98964f93f6984df743004240 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:27 -0700 Subject: [SCSI] bfa: driver compatibility with 32bit libs Replaced usage of void * with u64 in data structure shared between brocade user space libraries and the bfa driver to address pointer size changes across 32-bit vs 64-bit to have the compatibility between 32bit library and 64bit driver and vice versa. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfad_bsg.c | 7 ++++--- drivers/scsi/bfa/bfad_bsg.h | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index f31acfa..9863b1c 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -3371,7 +3371,8 @@ bfad_im_bsg_els_ct_request(struct fc_bsg_job *job) goto out; } - if (copy_from_user((uint8_t *)bsg_fcpt, bsg_data->payload, + if (copy_from_user((uint8_t *)bsg_fcpt, + (void *)(unsigned long)bsg_data->payload, bsg_data->payload_len)) { kfree(bsg_fcpt); rc = -EIO; @@ -3525,8 +3526,8 @@ out_free_mem: kfree(rsp_kbuf); /* Need a copy to user op */ - if (copy_to_user(bsg_data->payload, (void *) bsg_fcpt, - bsg_data->payload_len)) + if (copy_to_user((void *)(unsigned long)bsg_data->payload, + (void *)bsg_fcpt, bsg_data->payload_len)) rc = -EIO; kfree(bsg_fcpt); diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 3ef321c..b0b5ac7 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -819,10 +819,12 @@ struct bfa_bsg_fcpt_s { }; #define bfa_bsg_fcpt_t struct bfa_bsg_fcpt_s +#pragma pack(1) struct bfa_bsg_data { int payload_len; - void *payload; + u64 payload; }; +#pragma pack() #define bfad_chk_iocmd_sz(__payload_len, __hdrsz, __bufsz) \ (((__payload_len) != ((__hdrsz) + (__bufsz))) ? \ -- cgit v1.1 From 079bcbc35ca9241abf212a795a000b2d6c2038cd Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:28 -0700 Subject: [SCSI] bfa: fru vpd date update changes 1. While FRU VPD data update, inform firmware to send a completion event on I2C bus. Without this change, firmware used to send completion message on I2C bus for every chunk of FRU VPD update. 2. Support for FRU VPN update on CHINOOK2 cards. 3. Append port count to the model name to differentiate between single port and dual port model of 1860. 4. Update the size of the model name to 16bytes Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs.h | 9 +++++++-- drivers/scsi/bfa/bfa_fcs.h | 8 ++++---- drivers/scsi/bfa/bfa_ioc.c | 29 +++++++++++++++++++++-------- drivers/scsi/bfa/bfa_ioc.h | 3 ++- drivers/scsi/bfa/bfad_bsg.c | 2 +- drivers/scsi/bfa/bfad_bsg.h | 4 +++- drivers/scsi/bfa/bfi.h | 6 +++++- 7 files changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index d65a9b4..bef16d2 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -45,6 +45,7 @@ enum { BFA_MFG_TYPE_PROWLER_C = 1710, /* Prowler CNA only cards */ BFA_MFG_TYPE_PROWLER_D = 1860, /* Prowler Dual cards */ BFA_MFG_TYPE_CHINOOK = 1867, /* Chinook cards */ + BFA_MFG_TYPE_CHINOOK2 = 1869, /*!< Chinook2 cards */ BFA_MFG_TYPE_INVALID = 0, /* Invalid card type */ }; @@ -59,7 +60,8 @@ enum { (type) == BFA_MFG_TYPE_ASTRA || \ (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \ (type) == BFA_MFG_TYPE_LIGHTNING || \ - (type) == BFA_MFG_TYPE_CHINOOK)) + (type) == BFA_MFG_TYPE_CHINOOK || \ + (type) == BFA_MFG_TYPE_CHINOOK2)) /* * Check if the card having old wwn/mac handling @@ -263,6 +265,7 @@ enum { BFA_ADAPTER_MFG_NAME_LEN = 8, /* manufacturer name length */ BFA_ADAPTER_SYM_NAME_LEN = 64, /* adapter symbolic name length */ BFA_ADAPTER_OS_TYPE_LEN = 64, /* adapter os type length */ + BFA_ADAPTER_UUID_LEN = 16, /* adapter uuid length */ }; struct bfa_adapter_attr_s { @@ -296,6 +299,7 @@ struct bfa_adapter_attr_s { u8 mfg_month; /* manufacturing month */ u16 mfg_year; /* manufacturing year */ u16 rsvd; + u8 uuid[BFA_ADAPTER_UUID_LEN]; }; /* @@ -409,7 +413,8 @@ struct bfa_ioc_attr_s { u8 port_mode; /* bfa_mode_s */ u8 cap_bm; /* capability */ u8 port_mode_cfg; /* bfa_mode_s */ - u8 rsvd[4]; /* 64bit align */ + u8 def_fn; /* 1 if default fn */ + u8 rsvd[3]; /* 64bit align */ }; /* diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 4f1e650..94d5d01 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -243,19 +243,19 @@ struct bfa_fcs_fabric_s; * Symbolic Name. * * Physical Port's symbolic name Format : (Total 128 bytes) - * Adapter Model number/name : 12 bytes + * Adapter Model number/name : 16 bytes * Driver Version : 10 bytes * Host Machine Name : 30 bytes - * Host OS Info : 48 bytes + * Host OS Info : 44 bytes * Host OS PATCH Info : 16 bytes * ( remaining 12 bytes reserved to be used for separator) */ #define BFA_FCS_PORT_SYMBNAME_SEPARATOR " | " -#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ 12 +#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ 16 #define BFA_FCS_PORT_SYMBNAME_VERSION_SZ 10 #define BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ 30 -#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 48 +#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 44 #define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ 16 /* diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 8928b68..c31cb3c 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -2508,6 +2508,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, ad_attr->mfg_day = ioc_attr->mfg_day; ad_attr->mfg_month = ioc_attr->mfg_month; ad_attr->mfg_year = ioc_attr->mfg_year; + memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN); } enum bfa_ioc_type_e @@ -2572,13 +2573,19 @@ void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) { struct bfi_ioc_attr_s *ioc_attr; + u8 nports = bfa_ioc_get_nports(ioc); WARN_ON(!model); memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); ioc_attr = ioc->attr; - snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", + if (bfa_asic_id_ct2(ioc->pcidev.device_id) && + (!bfa_mfg_is_mezz(ioc_attr->card_type))) + snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s", + BFA_MFG_NAME, ioc_attr->card_type, nports, "p"); + else + snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", BFA_MFG_NAME, ioc_attr->card_type); } @@ -2628,7 +2635,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); ioc_attr->state = bfa_ioc_get_state(ioc); - ioc_attr->port_id = ioc->port_id; + ioc_attr->port_id = bfa_ioc_portid(ioc); ioc_attr->port_mode = ioc->port_mode; ioc_attr->port_mode_cfg = ioc->port_mode_cfg; ioc_attr->cap_bm = ioc->ad_cap_bm; @@ -2637,8 +2644,9 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); - ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; - ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; + ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc); + ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc); + ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc)); bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); } @@ -6018,6 +6026,7 @@ bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) */ msg->last = (len == fru->residue) ? 1 : 0; + msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0; bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); bfa_alen_set(&msg->alen, len, fru->dbuf_pa); @@ -6132,13 +6141,14 @@ bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa, */ bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, - bfa_cb_fru_t cbfn, void *cbarg) + bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl) { bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ); bfa_trc(fru, len); bfa_trc(fru, offset); - if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) + if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 && + fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2) return BFA_STATUS_FRU_NOT_PRESENT; if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) @@ -6160,6 +6170,7 @@ bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, fru->offset = 0; fru->addr_off = offset; fru->ubuf = buf; + fru->trfr_cmpl = trfr_cmpl; bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ); @@ -6189,7 +6200,8 @@ bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) return BFA_STATUS_FRU_NOT_PRESENT; - if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) + if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK && + fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2) return BFA_STATUS_CMD_NOTSUPP; if (!bfa_ioc_is_operational(fru->ioc)) @@ -6230,7 +6242,8 @@ bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size) if (!bfa_ioc_is_operational(fru->ioc)) return BFA_STATUS_IOC_NON_OP; - if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK) + if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK || + fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2) *max_size = BFA_FRU_CHINOOK_MAX_SIZE; else return BFA_STATUS_CMD_NOTSUPP; diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index de62b68..90814fe 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -731,6 +731,7 @@ struct bfa_fru_s { struct bfa_mbox_cmd_s mb; /* mailbox */ struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ struct bfa_mem_dma_s fru_dma; + u8 trfr_cmpl; }; #define BFA_FRU(__bfa) (&(__bfa)->modules.fru) @@ -738,7 +739,7 @@ struct bfa_fru_s { bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, - bfa_cb_fru_t cbfn, void *cbarg); + bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl); bfa_status_t bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, bfa_cb_fru_t cbfn, void *cbarg); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 9863b1c..0467c34 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -2716,7 +2716,7 @@ bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) spin_lock_irqsave(&bfad->bfad_lock, flags); iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), &iocmd->data, iocmd->len, iocmd->offset, - bfad_hcb_comp, &fcomp); + bfad_hcb_comp, &fcomp, iocmd->trfr_cmpl); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (iocmd->status == BFA_STATUS_OK) { wait_for_completion(&fcomp.comp); diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index b0b5ac7..05f0fc9 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h @@ -794,10 +794,12 @@ struct bfa_bsg_tfru_s { struct bfa_bsg_fruvpd_s { bfa_status_t status; u16 bfad_num; - u16 rsvd; + u16 rsvd1; u32 offset; u32 len; u8 data[BFA_MAX_FRUVPD_TRANSFER_SIZE]; + u8 trfr_cmpl; + u8 rsvd2[3]; }; struct bfa_bsg_fruvpd_max_size_s { diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index bf0a58d..37bd256 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h @@ -264,6 +264,7 @@ struct bfi_ioc_getattr_req_s { union bfi_addr_u attr_addr; }; +#define BFI_IOC_ATTR_UUID_SZ 16 struct bfi_ioc_attr_s { wwn_t mfg_pwwn; /* Mfg port wwn */ wwn_t mfg_nwwn; /* Mfg node wwn */ @@ -292,6 +293,7 @@ struct bfi_ioc_attr_s { u8 mfg_day; /* manufacturing day */ u8 mfg_month; /* manufacturing month */ u16 mfg_year; /* manufacturing year */ + u8 uuid[BFI_IOC_ATTR_UUID_SZ]; /*!< chinook uuid */ }; /* @@ -1253,7 +1255,9 @@ enum bfi_fru_i2h_msgs { struct bfi_fru_write_req_s { struct bfi_mhdr_s mh; /* Common msg header */ u8 last; - u8 rsv[3]; + u8 rsv_1[3]; + u8 trfr_cmpl; + u8 rsv_2[3]; u32 offset; u32 length; struct bfi_alen_s alen; -- cgit v1.1 From f52c98d4079df695ece1b2cd82fb5dc9372badf6 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:29 -0700 Subject: [SCSI] bfa: firmware statistics update Get RDS drop interrupts and REC (Read Exchange Concise) related stats from firmware. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs_svc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 2f20ba5..638f441f 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -105,6 +105,9 @@ struct bfa_fw_ioim_stats_s { * an error condition*/ u32 wait_for_si; /* FW wait for SI */ u32 rec_rsp_inval; /* REC rsp invalid */ + u32 rec_rsp_xchg_comp; /* REC rsp xchg complete */ + u32 rec_rsp_rd_si_ownd; /* REC rsp read si owned */ + u32 seqr_io_abort; /* target does not know cmd so abort */ u32 seqr_io_retry; /* SEQR failed so retry IO */ @@ -483,6 +486,14 @@ struct bfa_fw_ct_mod_stats_s { }; /* + * RDS mod stats + */ +struct bfa_fw_rds_stats_s { + u32 no_fid_drop_err; /* RDS no fid drop error */ + u32 rsvd; /* 64bit align */ +}; + +/* * IOC firmware stats */ struct bfa_fw_stats_s { @@ -497,6 +508,7 @@ struct bfa_fw_stats_s { struct bfa_fw_mac_mod_stats_s macmod_stats; struct bfa_fw_ct_mod_stats_s ctmod_stats; struct bfa_fw_eth_sndrcv_stats_s ethsndrcv_stats; + struct bfa_fw_rds_stats_s rds_stats; }; #define BFA_IOCFC_PATHTOV_MAX 60 -- cgit v1.1 From ea3837a7121a18f5a4f3be2b8c66ab78d8263988 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:30 -0700 Subject: [SCSI] bfa: Allow rsp queue process during ioc disable Allow processing completions from firmware during IOC_DISABLE request is being processed by the firmware, by setting the queue_process flag appropriately. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 342d7d9..520540a 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -1432,6 +1432,7 @@ bfa_iocfc_disable_cbfn(void *bfa_arg) { struct bfa_s *bfa = bfa_arg; + bfa->queue_process = BFA_FALSE; bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_DISABLED); } @@ -1567,7 +1568,6 @@ bfa_iocfc_start(struct bfa_s *bfa) void bfa_iocfc_stop(struct bfa_s *bfa) { - bfa->queue_process = BFA_FALSE; bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_STOP); } @@ -1674,7 +1674,6 @@ bfa_iocfc_disable(struct bfa_s *bfa) bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, "IOC Disable"); - bfa->queue_process = BFA_FALSE; bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DISABLE); } -- cgit v1.1 From 36ec9712d5c353636f3be959c153f9b2199854de Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:31 -0700 Subject: [SCSI] bfa: Fix bug_on condition in RPSC rsp handling Fix bug_on condition check in RPSC (Report Port Speed Capabilities) response processing. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcs_rport.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 62713a7..2035b0d 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -3430,9 +3430,10 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, num_ents = be16_to_cpu(rpsc2_acc->num_pids); bfa_trc(rport->fcs, num_ents); if (num_ents > 0) { - WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid); + WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) != + bfa_ntoh3b(rport->pid)); bfa_trc(rport->fcs, - be16_to_cpu(rpsc2_acc->port_info[0].pid)); + be32_to_cpu(rpsc2_acc->port_info[0].pid)); bfa_trc(rport->fcs, be16_to_cpu(rpsc2_acc->port_info[0].speed)); bfa_trc(rport->fcs, -- cgit v1.1 From ba1340788ff3023b1b083db96d82f546b8401ffd Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:32 -0700 Subject: [SCSI] bfa: fix endianess issue for firmware stats Fix endianess issue on Big-endian architecture for firmware statistics Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index c31cb3c..a4f3741 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1858,7 +1858,7 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz) bfa_trc(ioc, len); for (i = 0; i < len; i++) { r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); - buf[i] = be32_to_cpu(r32); + buf[i] = swab32(r32); loff += sizeof(u32); /* -- cgit v1.1 From f9c867b45c7c1be4c4920471250a52a053c7a8c2 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:33 -0700 Subject: [SCSI] bfa: Support for chinook-quad port card This patch enables support for chinook quad port 16G FC card (falcon) Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_defs.h | 5 ++++- drivers/scsi/bfa/bfa_ioc.c | 1 + drivers/scsi/bfa/bfad.c | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index bef16d2..d40a79f 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h @@ -637,6 +637,7 @@ enum { BFA_PCI_DEVICE_ID_CT = 0x14, BFA_PCI_DEVICE_ID_CT_FC = 0x21, BFA_PCI_DEVICE_ID_CT2 = 0x22, + BFA_PCI_DEVICE_ID_CT2_QUAD = 0x23, }; #define bfa_asic_id_cb(__d) \ @@ -645,7 +646,9 @@ enum { #define bfa_asic_id_ct(__d) \ ((__d) == BFA_PCI_DEVICE_ID_CT || \ (__d) == BFA_PCI_DEVICE_ID_CT_FC) -#define bfa_asic_id_ct2(__d) ((__d) == BFA_PCI_DEVICE_ID_CT2) +#define bfa_asic_id_ct2(__d) \ + ((__d) == BFA_PCI_DEVICE_ID_CT2 || \ + (__d) == BFA_PCI_DEVICE_ID_CT2_QUAD) #define bfa_asic_id_ctc(__d) \ (bfa_asic_id_ct(__d) || bfa_asic_id_ct2(__d)) diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index a4f3741..f78bcb6 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -2196,6 +2196,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, break; case BFA_PCI_DEVICE_ID_CT2: + case BFA_PCI_DEVICE_ID_CT2_QUAD: ioc->asic_gen = BFI_ASIC_GEN_CT2; if (clscode == BFI_PCIFN_CLASS_FC && pcidev->ssid == BFA_PCI_CT2_SSID_FC) { diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index a5f7690..bf5c5d3 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -1720,6 +1720,14 @@ struct pci_device_id bfad_id_table[] = { .class_mask = ~0, }, + { + .vendor = BFA_PCI_VENDOR_ID_BROCADE, + .device = BFA_PCI_DEVICE_ID_CT2_QUAD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_SERIAL_FIBER << 8), + .class_mask = ~0, + }, {0, 0}, }; -- cgit v1.1 From 4dde506944f8ea3431bf4a250c13621c8f3939bb Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:34 -0700 Subject: [SCSI] bfa: dis-associate bfa path_tov with dev_loss_tmo Disassoicate path_tov in the driver with the dev_loss_tmo set by the application. Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfad_attr.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 72f5dc3..e9a681d 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -335,23 +335,10 @@ bfad_im_reset_stats(struct Scsi_Host *shost) } /* - * FC transport template entry, get rport loss timeout. - */ -static void -bfad_im_get_rport_loss_tmo(struct fc_rport *rport) -{ - struct bfad_itnim_data_s *itnim_data = rport->dd_data; - struct bfad_itnim_s *itnim = itnim_data->itnim; - struct bfad_s *bfad = itnim->im->bfad; - unsigned long flags; - - spin_lock_irqsave(&bfad->bfad_lock, flags); - rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); -} - -/* * FC transport template entry, set rport loss timeout. + * Update dev_loss_tmo based on the value pushed down by the stack + * In case it is lesser than path_tov of driver, set it to path_tov + 1 + * to ensure that the driver times out before the application */ static void bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) @@ -359,15 +346,11 @@ bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) struct bfad_itnim_data_s *itnim_data = rport->dd_data; struct bfad_itnim_s *itnim = itnim_data->itnim; struct bfad_s *bfad = itnim->im->bfad; - unsigned long flags; - - if (timeout > 0) { - spin_lock_irqsave(&bfad->bfad_lock, flags); - bfa_fcpim_path_tov_set(&bfad->bfa, timeout); - rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); - } + uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa); + rport->dev_loss_tmo = timeout; + if (timeout < path_tov) + rport->dev_loss_tmo = path_tov + 1; } static int @@ -665,7 +648,6 @@ struct fc_function_template bfad_im_fc_function_template = { .show_rport_maxframe_size = 1, .show_rport_supported_classes = 1, .show_rport_dev_loss_tmo = 1, - .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, .issue_fc_host_lip = bfad_im_issue_fc_host_lip, .vport_create = bfad_im_vport_create, @@ -723,7 +705,6 @@ struct fc_function_template bfad_im_vport_fc_function_template = { .show_rport_maxframe_size = 1, .show_rport_supported_classes = 1, .show_rport_dev_loss_tmo = 1, - .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, }; -- cgit v1.1 From 607be2cff4f4899f47ef906eba5b147abc3c5da4 Mon Sep 17 00:00:00 2001 From: Vijaya Mohan Guvva Date: Mon, 13 May 2013 02:33:35 -0700 Subject: [SCSI] bfa: Update the driver version to 3.2.21.1 Update bfa driver version to 3.2.21.1 Update bfa to use firmware image versions 3.2.1.0 Signed-off-by: Vijaya Mohan Guvva Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfad.c | 6 +++--- drivers/scsi/bfa/bfad_drv.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index bf5c5d3..9611195 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -63,9 +63,9 @@ int max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS; u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; u32 *bfi_image_cb, *bfi_image_ct, *bfi_image_ct2; -#define BFAD_FW_FILE_CB "cbfw-3.1.0.0.bin" -#define BFAD_FW_FILE_CT "ctfw-3.1.0.0.bin" -#define BFAD_FW_FILE_CT2 "ct2fw-3.1.0.0.bin" +#define BFAD_FW_FILE_CB "cbfw-3.2.1.0.bin" +#define BFAD_FW_FILE_CT "ctfw-3.2.1.0.bin" +#define BFAD_FW_FILE_CT2 "ct2fw-3.2.1.0.bin" static u32 *bfad_load_fwimg(struct pci_dev *pdev); static void bfad_free_fwimg(void); diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 0c64a04..78d3401 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -57,7 +57,7 @@ #ifdef BFA_DRIVER_VERSION #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION #else -#define BFAD_DRIVER_VERSION "3.1.2.1" +#define BFAD_DRIVER_VERSION "3.2.21.1" #endif #define BFAD_PROTO_NAME FCPI_NAME -- cgit v1.1 From 5d65f91896197bd047f97ed8e7792b06de491eac Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 30 May 2013 10:50:46 +0300 Subject: [SCSI] fnic: potential dead lock in fnic_is_abts_pending() There is an unlock missing if the == FNIC_IOREQ_ABTS_PENDING is false. Signed-off-by: Dan Carpenter Acked-by: Hiral Patel Signed-off-by: James Bottomley --- drivers/scsi/fnic/fnic_scsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index be99e75..a97e6e5 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2432,11 +2432,9 @@ int fnic_is_abts_pending(struct fnic *fnic, struct scsi_cmnd *lr_sc) "Found IO in %s on lun\n", fnic_ioreq_state_to_str(CMD_STATE(sc))); - if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { - spin_unlock_irqrestore(io_lock, flags); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) ret = 1; - continue; - } + spin_unlock_irqrestore(io_lock, flags); } return ret; -- cgit v1.1 From 66c28f97120e8a621afd5aa7a31c4b85c547d33d Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 6 Jun 2013 22:15:55 -0400 Subject: [SCSI] sd: Update WRITE SAME heuristics SATA drives located behind a SAS controller would incorrectly receive WRITE SAME commands. Tweak the heuristics so that: - If REPORT SUPPORTED OPERATION CODES is provided we will use that to choose between WRITE SAME(16), WRITE SAME(10) and disabled. This also fixes an issue with the old code which would issue WRITE SAME(10) despite the command not being whitelisted in REPORT SUPPORTED OPERATION CODES. - If REPORT SUPPORTED OPERATION CODES is not provided we will fall back to WRITE SAME(10) unless the device has an ATA Information VPD page. The assumption is that a SATL which is smart enough to implement WRITE SAME would also provide REPORT SUPPORTED OPERATION CODES. To facilitate the new heuristics scsi_report_opcode() has been modified to so we can distinguish between "operation not supported" and "RSOC not supported". Reported-by: H. Peter Anvin Tested-by: Bernd Schubert Signed-off-by: Martin K. Petersen Cc: Signed-off-by: James Bottomley --- drivers/scsi/scsi.c | 8 ++++---- drivers/scsi/sd.c | 46 ++++++++++++++++++++++++++++++++-------------- drivers/scsi/sd.h | 1 + 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2c0d0ec..3b1ea34 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1070,8 +1070,8 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page); * @opcode: opcode for command to look up * * Uses the REPORT SUPPORTED OPERATION CODES to look up the given - * opcode. Returns 0 if RSOC fails or if the command opcode is - * unsupported. Returns 1 if the device claims to support the command. + * opcode. Returns -EINVAL if RSOC fails, 0 if the command opcode is + * unsupported and 1 if the device claims to support the command. */ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, unsigned int len, unsigned char opcode) @@ -1081,7 +1081,7 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, int result; if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) - return 0; + return -EINVAL; memset(cmd, 0, 16); cmd[0] = MAINTENANCE_IN; @@ -1097,7 +1097,7 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, if (result && scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) - return 0; + return -EINVAL; if ((buffer[1] & 3) == 3) /* Command supported */ return 1; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 91e8a95..34da1a1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -442,8 +442,10 @@ sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, if (max == 0) sdp->no_write_same = 1; - else if (max <= SD_MAX_WS16_BLOCKS) + else if (max <= SD_MAX_WS16_BLOCKS) { + sdp->no_write_same = 0; sdkp->max_ws_blocks = max; + } sd_config_write_same(sdkp); @@ -750,7 +752,6 @@ static void sd_config_write_same(struct scsi_disk *sdkp) { struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; - unsigned int blocks = 0; if (sdkp->device->no_write_same) { sdkp->max_ws_blocks = 0; @@ -762,18 +763,20 @@ static void sd_config_write_same(struct scsi_disk *sdkp) * blocks per I/O unless the device explicitly advertises a * bigger limit. */ - if (sdkp->max_ws_blocks == 0) - sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; - - if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) - blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); - else - blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); + if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) + sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); + else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes) + sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); + else { + sdkp->device->no_write_same = 1; + sdkp->max_ws_blocks = 0; + } out: - blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); + blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks * + (logical_block_size >> 9)); } /** @@ -2645,9 +2648,24 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) { - if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, - WRITE_SAME_16)) + struct scsi_device *sdev = sdkp->device; + + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) { + sdev->no_report_opcodes = 1; + + /* Disable WRITE SAME if REPORT SUPPORTED OPERATION + * CODES is unsupported and the device has an ATA + * Information VPD page (SAT). + */ + if (!scsi_get_vpd_page(sdev, 0x89, buffer, SD_BUF_SIZE)) + sdev->no_write_same = 1; + } + + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16) == 1) sdkp->ws16 = 1; + + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME) == 1) + sdkp->ws10 = 1; } static int sd_try_extended_inquiry(struct scsi_device *sdp) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 2386aeb..7a049de 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -84,6 +84,7 @@ struct scsi_disk { unsigned lbpws : 1; unsigned lbpws10 : 1; unsigned lbpvpd : 1; + unsigned ws10 : 1; unsigned ws16 : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) -- cgit v1.1 From ed7bd6612e67103f5ee4d8cfffe80cea6df096b9 Mon Sep 17 00:00:00 2001 From: "wenxiong@linux.vnet.ibm.com" Date: Tue, 4 Jun 2013 18:57:35 -0500 Subject: [SCSI] ipr: IOA Status Code(IOASC) update Signed-off-by: Wen Xiong Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 0d43176..6601e03 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -281,12 +281,22 @@ struct ipr_error_table_t ipr_error_table[] = { "FFF6: Failure prediction threshold exceeded"}, {0x015D9200, 0, IPR_DEFAULT_LOG_LEVEL, "8009: Impending cache battery pack failure"}, + {0x02040100, 0, 0, + "Logical Unit in process of becoming ready"}, + {0x02040200, 0, 0, + "Initializing command required"}, {0x02040400, 0, 0, "34FF: Disk device format in progress"}, + {0x02040C00, 0, 0, + "Logical unit not accessible, target port in unavailable state"}, {0x02048000, 0, IPR_DEFAULT_LOG_LEVEL, "9070: IOA requested reset"}, {0x023F0000, 0, 0, "Synchronization required"}, + {0x02408500, 0, 0, + "IOA microcode download required"}, + {0x02408600, 0, 0, + "Device bus connection is prohibited by host"}, {0x024E0000, 0, 0, "No ready, IOA shutdown"}, {0x025A0000, 0, 0, @@ -385,6 +395,8 @@ struct ipr_error_table_t ipr_error_table[] = { "4030: Incorrect multipath connection"}, {0x04679000, 0, IPR_DEFAULT_LOG_LEVEL, "4110: Unsupported enclosure function"}, + {0x04679800, 0, IPR_DEFAULT_LOG_LEVEL, + "4120: SAS cable VPD cannot be read"}, {0x046E0000, 0, IPR_DEFAULT_LOG_LEVEL, "FFF4: Command to logical unit failed"}, {0x05240000, 1, 0, @@ -407,10 +419,18 @@ struct ipr_error_table_t ipr_error_table[] = { "Illegal request, command sequence error"}, {0x052C8000, 1, 0, "Illegal request, dual adapter support not enabled"}, + {0x052C8100, 1, 0, + "Illegal request, another cable connector was physically disabled"}, + {0x054E8000, 1, 0, + "Illegal request, inconsistent group id/group count"}, {0x06040500, 0, IPR_DEFAULT_LOG_LEVEL, "9031: Array protection temporarily suspended, protection resuming"}, {0x06040600, 0, IPR_DEFAULT_LOG_LEVEL, "9040: Array protection temporarily suspended, protection resuming"}, + {0x060B0100, 0, IPR_DEFAULT_LOG_LEVEL, + "4080: IOA exceeded maximum operating temperature"}, + {0x060B8000, 0, IPR_DEFAULT_LOG_LEVEL, + "4085: Service required"}, {0x06288000, 0, IPR_DEFAULT_LOG_LEVEL, "3140: Device bus not ready to ready transition"}, {0x06290000, 0, IPR_DEFAULT_LOG_LEVEL, @@ -423,6 +443,8 @@ struct ipr_error_table_t ipr_error_table[] = { "FFFB: SCSI bus was reset by another initiator"}, {0x063F0300, 0, IPR_DEFAULT_LOG_LEVEL, "3029: A device replacement has occurred"}, + {0x063F8300, 0, IPR_DEFAULT_LOG_LEVEL, + "4102: Device bus fabric performance degradation"}, {0x064C8000, 0, IPR_DEFAULT_LOG_LEVEL, "9051: IOA cache data exists for a missing or failed device"}, {0x064C8100, 0, IPR_DEFAULT_LOG_LEVEL, @@ -445,6 +467,14 @@ struct ipr_error_table_t ipr_error_table[] = { "9076: Configuration error, missing remote IOA"}, {0x06679100, 0, IPR_DEFAULT_LOG_LEVEL, "4050: Enclosure does not support a required multipath function"}, + {0x06679800, 0, IPR_DEFAULT_LOG_LEVEL, + "4121: Configuration error, required cable is missing"}, + {0x06679900, 0, IPR_DEFAULT_LOG_LEVEL, + "4122: Cable is not plugged into the correct location on remote IOA"}, + {0x06679A00, 0, IPR_DEFAULT_LOG_LEVEL, + "4123: Configuration error, invalid cable vital product data"}, + {0x06679B00, 0, IPR_DEFAULT_LOG_LEVEL, + "4124: Configuration error, both cable ends are plugged into the same IOA"}, {0x06690000, 0, IPR_DEFAULT_LOG_LEVEL, "4070: Logically bad block written on device"}, {0x06690200, 0, IPR_DEFAULT_LOG_LEVEL, @@ -507,10 +537,18 @@ struct ipr_error_table_t ipr_error_table[] = { "9062: One or more disks are missing from an array"}, {0x07279900, 0, IPR_DEFAULT_LOG_LEVEL, "9063: Maximum number of functional arrays has been exceeded"}, + {0x07279A00, 0, 0, + "Data protect, other volume set problem"}, {0x0B260000, 0, 0, "Aborted command, invalid descriptor"}, + {0x0B3F9000, 0, 0, + "Target operating conditions have changed, dual adapter takeover"}, + {0x0B530200, 0, 0, + "Aborted command, medium removal prevented"}, {0x0B5A0000, 0, 0, - "Command terminated by host"} + "Command terminated by host"}, + {0x0B5B8000, 0, 0, + "Aborted command, command terminated by host"} }; static const struct ipr_ses_table_entry ipr_ses_table[] = { -- cgit v1.1 From c5bebd829dd95602c15f8da8cc50fa938b5e0254 Mon Sep 17 00:00:00 2001 From: Mahesh Rajashekhara Date: Tue, 18 Jun 2013 17:02:07 +0530 Subject: [SCSI] aacraid: Fix for arrays are going offline in the system. System hangs One of the customer had reported that the set of raid logical arrays will become unavailable (I/O offline) after a long hours of IO stress test. The OS wouldn`t be accessible afterwards and require a hard reset. This driver patch has a fix for race condition between the doorbell and the circular buffer. The driver is modified to do an extra read after clearing the doorbell in case there had been a completion posted during the small timing window. With this fix, we ran IO stress for ~13 days. There were no IO failures. Signed-off-by: Mahesh Rajashekhara Cc: Signed-off-by: James Bottomley --- drivers/scsi/aacraid/src.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 0f56d8d..7e17107 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -93,6 +93,9 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) int send_it = 0; extern int aac_sync_mode; + src_writel(dev, MUnit.ODR_C, bellbits); + src_readl(dev, MUnit.ODR_C); + if (!aac_sync_mode) { src_writel(dev, MUnit.ODR_C, bellbits); src_readl(dev, MUnit.ODR_C); -- cgit v1.1 From 3b9373e95a6019cf89abe6c8b17c07828db96ad4 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Thu, 20 Jun 2013 10:21:26 -0700 Subject: [SCSI] libiscsi: Added new boot entries in the session sysfs This is the kernel part of the modification to extract the net params from the ibft sysfs to the iface struct used for the connection request upon sync_session in the open-iscsi util. Three new session sysfs params are defined: boot_root - holds the name of the /sys/firmware/ibft or iscsi_rootN boot_nic - holds the ethernetN name boot_target - holds the targetN name Signed-off-by: Eddie Wai Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 18 ++++++++++++++++++ drivers/scsi/scsi_transport_iscsi.c | 12 ++++++++++++ include/scsi/iscsi_if.h | 5 +++++ include/scsi/libiscsi.h | 4 ++++ 4 files changed, 39 insertions(+) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5de9469..ae69dfc 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2808,6 +2808,9 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->targetname); kfree(session->targetalias); kfree(session->initiatorname); + kfree(session->boot_root); + kfree(session->boot_nic); + kfree(session->boot_target); kfree(session->ifacename); iscsi_destroy_session(cls_session); @@ -3248,6 +3251,12 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn, return iscsi_switch_str_param(&session->ifacename, buf); case ISCSI_PARAM_INITIATOR_NAME: return iscsi_switch_str_param(&session->initiatorname, buf); + case ISCSI_PARAM_BOOT_ROOT: + return iscsi_switch_str_param(&session->boot_root, buf); + case ISCSI_PARAM_BOOT_NIC: + return iscsi_switch_str_param(&session->boot_nic, buf); + case ISCSI_PARAM_BOOT_TARGET: + return iscsi_switch_str_param(&session->boot_target, buf); default: return -ENOSYS; } @@ -3326,6 +3335,15 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session, case ISCSI_PARAM_INITIATOR_NAME: len = sprintf(buf, "%s\n", session->initiatorname); break; + case ISCSI_PARAM_BOOT_ROOT: + len = sprintf(buf, "%s\n", session->boot_root); + break; + case ISCSI_PARAM_BOOT_NIC: + len = sprintf(buf, "%s\n", session->boot_nic); + break; + case ISCSI_PARAM_BOOT_TARGET: + len = sprintf(buf, "%s\n", session->boot_target); + break; default: return -ENOSYS; } diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 133926b..abf7c40 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -3473,6 +3473,9 @@ iscsi_session_attr(tgt_reset_tmo, ISCSI_PARAM_TGT_RESET_TMO, 0); iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0); iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0); iscsi_session_attr(targetalias, ISCSI_PARAM_TARGET_ALIAS, 0); +iscsi_session_attr(boot_root, ISCSI_PARAM_BOOT_ROOT, 0); +iscsi_session_attr(boot_nic, ISCSI_PARAM_BOOT_NIC, 0); +iscsi_session_attr(boot_target, ISCSI_PARAM_BOOT_TARGET, 0); static ssize_t show_priv_session_state(struct device *dev, struct device_attribute *attr, @@ -3568,6 +3571,9 @@ static struct attribute *iscsi_session_attrs[] = { &dev_attr_sess_ifacename.attr, &dev_attr_sess_initiatorname.attr, &dev_attr_sess_targetalias.attr, + &dev_attr_sess_boot_root.attr, + &dev_attr_sess_boot_nic.attr, + &dev_attr_sess_boot_target.attr, &dev_attr_priv_sess_recovery_tmo.attr, &dev_attr_priv_sess_state.attr, &dev_attr_priv_sess_creator.attr, @@ -3631,6 +3637,12 @@ static umode_t iscsi_session_attr_is_visible(struct kobject *kobj, param = ISCSI_PARAM_INITIATOR_NAME; else if (attr == &dev_attr_sess_targetalias.attr) param = ISCSI_PARAM_TARGET_ALIAS; + else if (attr == &dev_attr_sess_boot_root.attr) + param = ISCSI_PARAM_BOOT_ROOT; + else if (attr == &dev_attr_sess_boot_nic.attr) + param = ISCSI_PARAM_BOOT_NIC; + else if (attr == &dev_attr_sess_boot_target.attr) + param = ISCSI_PARAM_BOOT_TARGET; else if (attr == &dev_attr_priv_sess_recovery_tmo.attr) return S_IRUGO | S_IWUSR; else if (attr == &dev_attr_priv_sess_state.attr) diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index fe7f06c..9d28ded 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -489,6 +489,11 @@ enum iscsi_param { ISCSI_PARAM_CHAP_IN_IDX, ISCSI_PARAM_CHAP_OUT_IDX, + + ISCSI_PARAM_BOOT_ROOT, + ISCSI_PARAM_BOOT_NIC, + ISCSI_PARAM_BOOT_TARGET, + /* must always be last */ ISCSI_PARAM_MAX, }; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 09c041e..4265a4b 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -287,6 +287,10 @@ struct iscsi_session { char *targetalias; char *ifacename; char *initiatorname; + char *boot_root; + char *boot_nic; + char *boot_target; + /* control data */ struct iscsi_transport *tt; struct Scsi_Host *host; -- cgit v1.1 From 839cb99e8f748391059d10388c8aea48a88c142c Mon Sep 17 00:00:00 2001 From: Khalid Aziz Date: Thu, 16 May 2013 19:44:13 -0600 Subject: [SCSI] BusLogic: Fix style issues Fix CamelCase and extra long lines in the buslogic driver. Signed-off-by: Khalid Aziz Signed-off-by: James Bottomley --- drivers/scsi/BusLogic.c | 4453 ++++++++++++++++++++++++--------------------- drivers/scsi/BusLogic.h | 1482 ++++++++------- drivers/scsi/FlashPoint.c | 35 +- 3 files changed, 3105 insertions(+), 2865 deletions(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 344d875..6ec36d8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -26,8 +26,8 @@ */ -#define BusLogic_DriverVersion "2.1.16" -#define BusLogic_DriverDate "18 July 2002" +#define blogic_drvr_version "2.1.16" +#define blogic_drvr_date "18 July 2002" #include #include @@ -60,24 +60,24 @@ #define FAILURE (-1) #endif -static struct scsi_host_template Bus_Logic_template; +static struct scsi_host_template blogic_template; /* - BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver + blogic_drvr_options_count is a count of the number of BusLogic Driver Options specifications provided via the Linux Kernel Command Line or via the Loadable Kernel Module Installation Facility. */ -static int BusLogic_DriverOptionsCount; +static int blogic_drvr_options_count; /* - BusLogic_DriverOptions is an array of Driver Options structures representing + blogic_drvr_options is an array of Driver Options structures representing BusLogic Driver Options specifications provided via the Linux Kernel Command Line or via the Loadable Kernel Module Installation Facility. */ -static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters]; +static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS]; /* @@ -92,241 +92,251 @@ module_param(BusLogic, charp, 0); /* - BusLogic_ProbeOptions is a set of Probe Options to be applied across + blogic_probe_options is a set of Probe Options to be applied across all BusLogic Host Adapters. */ -static struct BusLogic_ProbeOptions BusLogic_ProbeOptions; +static struct blogic_probe_options blogic_probe_options; /* - BusLogic_GlobalOptions is a set of Global Options to be applied across + blogic_global_options is a set of Global Options to be applied across all BusLogic Host Adapters. */ -static struct BusLogic_GlobalOptions BusLogic_GlobalOptions; +static struct blogic_global_options blogic_global_options; -static LIST_HEAD(BusLogic_host_list); +static LIST_HEAD(blogic_host_list); /* - BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList. + blogic_probeinfo_count is the number of entries in blogic_probeinfo_list. */ -static int BusLogic_ProbeInfoCount; +static int blogic_probeinfo_count; /* - BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information + blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information to be checked for potential BusLogic Host Adapters. It is initialized by interrogating the PCI Configuration Space on PCI machines as well as from the list of standard BusLogic I/O Addresses. */ -static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList; +static struct blogic_probeinfo *blogic_probeinfo_list; /* - BusLogic_CommandFailureReason holds a string identifying the reason why a - call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command + blogic_cmd_failure_reason holds a string identifying the reason why a + call to blogic_cmd failed. It is only non-NULL when blogic_cmd returns a failure code. */ -static char *BusLogic_CommandFailureReason; +static char *blogic_cmd_failure_reason; /* - BusLogic_AnnounceDriver announces the Driver Version and Date, Author's + blogic_announce_drvr announces the Driver Version and Date, Author's Name, Copyright Notice, and Electronic Mail Address. */ -static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter) +static void blogic_announce_drvr(struct blogic_adapter *adapter) { - BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter); - BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "\n", HostAdapter); + blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter); + blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff " "\n", adapter); } /* - BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI + blogic_drvr_info returns the Host Adapter Name to identify this SCSI Driver and Host Adapter. */ -static const char *BusLogic_DriverInfo(struct Scsi_Host *Host) +static const char *blogic_drvr_info(struct Scsi_Host *host) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; - return HostAdapter->FullModelName; + struct blogic_adapter *adapter = + (struct blogic_adapter *) host->hostdata; + return adapter->full_model; } /* - BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs) - for Host Adapter from the BlockSize bytes located at BlockPointer. The newly + blogic_init_ccbs initializes a group of Command Control Blocks (CCBs) + for Host Adapter from the blk_size bytes located at blk_pointer. The newly created CCBs are added to Host Adapter's free list. */ -static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle) +static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer, + int blk_size, dma_addr_t blkp) { - struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer; + struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer; unsigned int offset = 0; - memset(BlockPointer, 0, BlockSize); - CCB->AllocationGroupHead = BlockPointerHandle; - CCB->AllocationGroupSize = BlockSize; - while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) { - CCB->Status = BusLogic_CCB_Free; - CCB->HostAdapter = HostAdapter; - CCB->DMA_Handle = (u32) BlockPointerHandle + offset; - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - CCB->CallbackFunction = BusLogic_QueueCompletedCCB; - CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress; + memset(blk_pointer, 0, blk_size); + ccb->allocgrp_head = blkp; + ccb->allocgrp_size = blk_size; + while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) { + ccb->status = BLOGIC_CCB_FREE; + ccb->adapter = adapter; + ccb->dma_handle = (u32) blkp + offset; + if (blogic_flashpoint_type(adapter)) { + ccb->callback = blogic_qcompleted_ccb; + ccb->base_addr = adapter->fpinfo.base_addr; } - CCB->Next = HostAdapter->Free_CCBs; - CCB->NextAll = HostAdapter->All_CCBs; - HostAdapter->Free_CCBs = CCB; - HostAdapter->All_CCBs = CCB; - HostAdapter->AllocatedCCBs++; - CCB++; - offset += sizeof(struct BusLogic_CCB); + ccb->next = adapter->free_ccbs; + ccb->next_all = adapter->all_ccbs; + adapter->free_ccbs = ccb; + adapter->all_ccbs = ccb; + adapter->alloc_ccbs++; + ccb++; + offset += sizeof(struct blogic_ccb); } } /* - BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. + blogic_create_initccbs allocates the initial CCBs for Host Adapter. */ -static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter) +static bool __init blogic_create_initccbs(struct blogic_adapter *adapter) { - int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); - void *BlockPointer; - dma_addr_t BlockPointerHandle; - while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) { - BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle); - if (BlockPointer == NULL) { - BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter); + int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb); + void *blk_pointer; + dma_addr_t blkp; + + while (adapter->alloc_ccbs < adapter->initccbs) { + blk_pointer = pci_alloc_consistent(adapter->pci_device, + blk_size, &blkp); + if (blk_pointer == NULL) { + blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", + adapter); return false; } - BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle); + blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp); } return true; } /* - BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter. + blogic_destroy_ccbs deallocates the CCBs for Host Adapter. */ -static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter) +static void blogic_destroy_ccbs(struct blogic_adapter *adapter) { - struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL; - HostAdapter->All_CCBs = NULL; - HostAdapter->Free_CCBs = NULL; - while ((CCB = NextCCB) != NULL) { - NextCCB = CCB->NextAll; - if (CCB->AllocationGroupHead) { - if (Last_CCB) - pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead); - Last_CCB = CCB; + struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL; + adapter->all_ccbs = NULL; + adapter->free_ccbs = NULL; + while ((ccb = next_ccb) != NULL) { + next_ccb = ccb->next_all; + if (ccb->allocgrp_head) { + if (lastccb) + pci_free_consistent(adapter->pci_device, + lastccb->allocgrp_size, lastccb, + lastccb->allocgrp_head); + lastccb = ccb; } } - if (Last_CCB) - pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead); + if (lastccb) + pci_free_consistent(adapter->pci_device, lastccb->allocgrp_size, + lastccb, lastccb->allocgrp_head); } /* - BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If + blogic_create_addlccbs allocates Additional CCBs for Host Adapter. If allocation fails and there are no remaining CCBs available, the Driver Queue Depth is decreased to a known safe value to avoid potential deadlocks when multiple host adapters share the same IRQ Channel. */ -static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP) +static void blogic_create_addlccbs(struct blogic_adapter *adapter, + int addl_ccbs, bool print_success) { - int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); - int PreviouslyAllocated = HostAdapter->AllocatedCCBs; - void *BlockPointer; - dma_addr_t BlockPointerHandle; - if (AdditionalCCBs <= 0) + int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb); + int prev_alloc = adapter->alloc_ccbs; + void *blk_pointer; + dma_addr_t blkp; + if (addl_ccbs <= 0) return; - while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) { - BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle); - if (BlockPointer == NULL) + while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) { + blk_pointer = pci_alloc_consistent(adapter->pci_device, + blk_size, &blkp); + if (blk_pointer == NULL) break; - BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle); + blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp); } - if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) { - if (SuccessMessageP) - BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", HostAdapter, HostAdapter->AllocatedCCBs - PreviouslyAllocated, HostAdapter->AllocatedCCBs); + if (adapter->alloc_ccbs > prev_alloc) { + if (print_success) + blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs); return; } - BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter); - if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) { - HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount; - HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; + blogic_notice("Failed to allocate additional CCBs\n", adapter); + if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) { + adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count; + adapter->scsi_host->can_queue = adapter->drvr_qdepth; } } /* - BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list, + blogic_alloc_ccb allocates a CCB from Host Adapter's free list, allocating more memory from the Kernel if necessary. The Host Adapter's Lock should already have been acquired by the caller. */ -static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter - *HostAdapter) +static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter) { - static unsigned long SerialNumber = 0; - struct BusLogic_CCB *CCB; - CCB = HostAdapter->Free_CCBs; - if (CCB != NULL) { - CCB->SerialNumber = ++SerialNumber; - HostAdapter->Free_CCBs = CCB->Next; - CCB->Next = NULL; - if (HostAdapter->Free_CCBs == NULL) - BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true); - return CCB; - } - BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true); - CCB = HostAdapter->Free_CCBs; - if (CCB == NULL) + static unsigned long serial; + struct blogic_ccb *ccb; + ccb = adapter->free_ccbs; + if (ccb != NULL) { + ccb->serial = ++serial; + adapter->free_ccbs = ccb->next; + ccb->next = NULL; + if (adapter->free_ccbs == NULL) + blogic_create_addlccbs(adapter, adapter->inc_ccbs, + true); + return ccb; + } + blogic_create_addlccbs(adapter, adapter->inc_ccbs, true); + ccb = adapter->free_ccbs; + if (ccb == NULL) return NULL; - CCB->SerialNumber = ++SerialNumber; - HostAdapter->Free_CCBs = CCB->Next; - CCB->Next = NULL; - return CCB; + ccb->serial = ++serial; + adapter->free_ccbs = ccb->next; + ccb->next = NULL; + return ccb; } /* - BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's + blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's free list. The Host Adapter's Lock should already have been acquired by the caller. */ -static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB) +static void blogic_dealloc_ccb(struct blogic_ccb *ccb) { - struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; + struct blogic_adapter *adapter = ccb->adapter; - scsi_dma_unmap(CCB->Command); - pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer, - CCB->SenseDataLength, PCI_DMA_FROMDEVICE); + scsi_dma_unmap(ccb->command); + pci_unmap_single(adapter->pci_device, ccb->sensedata, + ccb->sense_datalen, PCI_DMA_FROMDEVICE); - CCB->Command = NULL; - CCB->Status = BusLogic_CCB_Free; - CCB->Next = HostAdapter->Free_CCBs; - HostAdapter->Free_CCBs = CCB; + ccb->command = NULL; + ccb->status = BLOGIC_CCB_FREE; + ccb->next = adapter->free_ccbs; + adapter->free_ccbs = ccb; } /* - BusLogic_Command sends the command OperationCode to HostAdapter, optionally - providing ParameterLength bytes of ParameterData and receiving at most - ReplyLength bytes of ReplyData; any excess reply data is received but + blogic_cmd sends the command opcode to adapter, optionally + providing paramlen bytes of param and receiving at most + replylen bytes of reply; any excess reply data is received but discarded. On success, this function returns the number of reply bytes read from the Host Adapter (including any discarded data); on failure, it returns -1 if the command was invalid, or -2 if a timeout occurred. - BusLogic_Command is called exclusively during host adapter detection and + blogic_cmd is called exclusively during host adapter detection and initialization, so performance and latency are not critical, and exclusive access to the Host Adapter hardware is assumed. Once the host adapter and driver are initialized, the only Host Adapter command that is issued is the @@ -334,255 +344,274 @@ static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB) waiting for the Host Adapter Ready bit to be set in the Status Register. */ -static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength) +static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode, + void *param, int paramlen, void *reply, int replylen) { - unsigned char *ParameterPointer = (unsigned char *) ParameterData; - unsigned char *ReplyPointer = (unsigned char *) ReplyData; - union BusLogic_StatusRegister StatusRegister; - union BusLogic_InterruptRegister InterruptRegister; - unsigned long ProcessorFlags = 0; - int ReplyBytes = 0, Result; - long TimeoutCounter; + unsigned char *param_p = (unsigned char *) param; + unsigned char *reply_p = (unsigned char *) reply; + union blogic_stat_reg statusreg; + union blogic_int_reg intreg; + unsigned long processor_flag = 0; + int reply_b = 0, result; + long timeout; /* Clear out the Reply Data if provided. */ - if (ReplyLength > 0) - memset(ReplyData, 0, ReplyLength); + if (replylen > 0) + memset(reply, 0, replylen); /* - If the IRQ Channel has not yet been acquired, then interrupts must be - disabled while issuing host adapter commands since a Command Complete - interrupt could occur if the IRQ Channel was previously enabled by another - BusLogic Host Adapter or another driver sharing the same IRQ Channel. + If the IRQ Channel has not yet been acquired, then interrupts + must be disabled while issuing host adapter commands since a + Command Complete interrupt could occur if the IRQ Channel was + previously enabled by another BusLogic Host Adapter or another + driver sharing the same IRQ Channel. */ - if (!HostAdapter->IRQ_ChannelAcquired) - local_irq_save(ProcessorFlags); + if (!adapter->irq_acquired) + local_irq_save(processor_flag); /* - Wait for the Host Adapter Ready bit to be set and the Command/Parameter - Register Busy bit to be reset in the Status Register. + Wait for the Host Adapter Ready bit to be set and the + Command/Parameter Register Busy bit to be reset in the Status + Register. */ - TimeoutCounter = 10000; - while (--TimeoutCounter >= 0) { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy) + timeout = 10000; + while (--timeout >= 0) { + statusreg.all = blogic_rdstatus(adapter); + if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy) break; udelay(100); } - if (TimeoutCounter < 0) { - BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready"; - Result = -2; - goto Done; + if (timeout < 0) { + blogic_cmd_failure_reason = + "Timeout waiting for Host Adapter Ready"; + result = -2; + goto done; } /* - Write the OperationCode to the Command/Parameter Register. + Write the opcode to the Command/Parameter Register. */ - HostAdapter->HostAdapterCommandCompleted = false; - BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode); + adapter->adapter_cmd_complete = false; + blogic_setcmdparam(adapter, opcode); /* Write any additional Parameter Bytes. */ - TimeoutCounter = 10000; - while (ParameterLength > 0 && --TimeoutCounter >= 0) { + timeout = 10000; + while (paramlen > 0 && --timeout >= 0) { /* - Wait 100 microseconds to give the Host Adapter enough time to determine - whether the last value written to the Command/Parameter Register was - valid or not. If the Command Complete bit is set in the Interrupt - Register, then the Command Invalid bit in the Status Register will be - reset if the Operation Code or Parameter was valid and the command - has completed, or set if the Operation Code or Parameter was invalid. - If the Data In Register Ready bit is set in the Status Register, then - the Operation Code was valid, and data is waiting to be read back - from the Host Adapter. Otherwise, wait for the Command/Parameter - Register Busy bit in the Status Register to be reset. + Wait 100 microseconds to give the Host Adapter enough + time to determine whether the last value written to the + Command/Parameter Register was valid or not. If the + Command Complete bit is set in the Interrupt Register, + then the Command Invalid bit in the Status Register will + be reset if the Operation Code or Parameter was valid + and the command has completed, or set if the Operation + Code or Parameter was invalid. If the Data In Register + Ready bit is set in the Status Register, then the + Operation Code was valid, and data is waiting to be read + back from the Host Adapter. Otherwise, wait for the + Command/Parameter Register Busy bit in the Status + Register to be reset. */ udelay(100); - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (InterruptRegister.ir.CommandComplete) + intreg.all = blogic_rdint(adapter); + statusreg.all = blogic_rdstatus(adapter); + if (intreg.ir.cmd_complete) break; - if (HostAdapter->HostAdapterCommandCompleted) + if (adapter->adapter_cmd_complete) break; - if (StatusRegister.sr.DataInRegisterReady) + if (statusreg.sr.datain_ready) break; - if (StatusRegister.sr.CommandParameterRegisterBusy) + if (statusreg.sr.cmd_param_busy) continue; - BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++); - ParameterLength--; - } - if (TimeoutCounter < 0) { - BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance"; - Result = -2; - goto Done; - } - /* - The Modify I/O Address command does not cause a Command Complete Interrupt. - */ - if (OperationCode == BusLogic_ModifyIOAddress) { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.CommandInvalid) { - BusLogic_CommandFailureReason = "Modify I/O Address Invalid"; - Result = -1; - goto Done; + blogic_setcmdparam(adapter, *param_p++); + paramlen--; + } + if (timeout < 0) { + blogic_cmd_failure_reason = + "Timeout waiting for Parameter Acceptance"; + result = -2; + goto done; + } + /* + The Modify I/O Address command does not cause a Command Complete + Interrupt. + */ + if (opcode == BLOGIC_MOD_IOADDR) { + statusreg.all = blogic_rdstatus(adapter); + if (statusreg.sr.cmd_invalid) { + blogic_cmd_failure_reason = + "Modify I/O Address Invalid"; + result = -1; + goto done; } - if (BusLogic_GlobalOptions.TraceConfiguration) - BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All); - Result = 0; - goto Done; + if (blogic_global_options.trace_config) + blogic_notice("blogic_cmd(%02X) Status = %02X: " "(Modify I/O Address)\n", adapter, opcode, statusreg.all); + result = 0; + goto done; } /* Select an appropriate timeout value for awaiting command completion. */ - switch (OperationCode) { - case BusLogic_InquireInstalledDevicesID0to7: - case BusLogic_InquireInstalledDevicesID8to15: - case BusLogic_InquireTargetDevices: + switch (opcode) { + case BLOGIC_INQ_DEV0TO7: + case BLOGIC_INQ_DEV8TO15: + case BLOGIC_INQ_DEV: /* Approximately 60 seconds. */ - TimeoutCounter = 60 * 10000; + timeout = 60 * 10000; break; default: /* Approximately 1 second. */ - TimeoutCounter = 10000; + timeout = 10000; break; } /* - Receive any Reply Bytes, waiting for either the Command Complete bit to - be set in the Interrupt Register, or for the Interrupt Handler to set the - Host Adapter Command Completed bit in the Host Adapter structure. + Receive any Reply Bytes, waiting for either the Command + Complete bit to be set in the Interrupt Register, or for the + Interrupt Handler to set the Host Adapter Command Completed + bit in the Host Adapter structure. */ - while (--TimeoutCounter >= 0) { - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (InterruptRegister.ir.CommandComplete) + while (--timeout >= 0) { + intreg.all = blogic_rdint(adapter); + statusreg.all = blogic_rdstatus(adapter); + if (intreg.ir.cmd_complete) break; - if (HostAdapter->HostAdapterCommandCompleted) + if (adapter->adapter_cmd_complete) break; - if (StatusRegister.sr.DataInRegisterReady) { - if (++ReplyBytes <= ReplyLength) - *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter); + if (statusreg.sr.datain_ready) { + if (++reply_b <= replylen) + *reply_p++ = blogic_rddatain(adapter); else - BusLogic_ReadDataInRegister(HostAdapter); + blogic_rddatain(adapter); } - if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady) + if (opcode == BLOGIC_FETCH_LOCALRAM && + statusreg.sr.adapter_ready) break; udelay(100); } - if (TimeoutCounter < 0) { - BusLogic_CommandFailureReason = "Timeout waiting for Command Complete"; - Result = -2; - goto Done; + if (timeout < 0) { + blogic_cmd_failure_reason = + "Timeout waiting for Command Complete"; + result = -2; + goto done; } /* Clear any pending Command Complete Interrupt. */ - BusLogic_InterruptReset(HostAdapter); + blogic_intreset(adapter); /* Provide tracing information if requested. */ - if (BusLogic_GlobalOptions.TraceConfiguration) { + if (blogic_global_options.trace_config) { int i; - BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes); - if (ReplyLength > ReplyBytes) - ReplyLength = ReplyBytes; - for (i = 0; i < ReplyLength; i++) - BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]); - BusLogic_Notice("\n", HostAdapter); + blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:", + adapter, opcode, statusreg.all, replylen, + reply_b); + if (replylen > reply_b) + replylen = reply_b; + for (i = 0; i < replylen; i++) + blogic_notice(" %02X", adapter, + ((unsigned char *) reply)[i]); + blogic_notice("\n", adapter); } /* Process Command Invalid conditions. */ - if (StatusRegister.sr.CommandInvalid) { + if (statusreg.sr.cmd_invalid) { /* - Some early BusLogic Host Adapters may not recover properly from - a Command Invalid condition, so if this appears to be the case, - a Soft Reset is issued to the Host Adapter. Potentially invalid - commands are never attempted after Mailbox Initialization is - performed, so there should be no Host Adapter state lost by a + Some early BusLogic Host Adapters may not recover + properly from a Command Invalid condition, so if this + appears to be the case, a Soft Reset is issued to the + Host Adapter. Potentially invalid commands are never + attempted after Mailbox Initialization is performed, + so there should be no Host Adapter state lost by a Soft Reset in response to a Command Invalid condition. */ udelay(1000); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.CommandInvalid || - StatusRegister.sr.Reserved || - StatusRegister.sr.DataInRegisterReady || - StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) { - BusLogic_SoftReset(HostAdapter); + statusreg.all = blogic_rdstatus(adapter); + if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd || + statusreg.sr.datain_ready || + statusreg.sr.cmd_param_busy || + !statusreg.sr.adapter_ready || + !statusreg.sr.init_reqd || + statusreg.sr.diag_active || + statusreg.sr.diag_failed) { + blogic_softreset(adapter); udelay(1000); } - BusLogic_CommandFailureReason = "Command Invalid"; - Result = -1; - goto Done; + blogic_cmd_failure_reason = "Command Invalid"; + result = -1; + goto done; } /* Handle Excess Parameters Supplied conditions. */ - if (ParameterLength > 0) { - BusLogic_CommandFailureReason = "Excess Parameters Supplied"; - Result = -1; - goto Done; + if (paramlen > 0) { + blogic_cmd_failure_reason = "Excess Parameters Supplied"; + result = -1; + goto done; } /* Indicate the command completed successfully. */ - BusLogic_CommandFailureReason = NULL; - Result = ReplyBytes; + blogic_cmd_failure_reason = NULL; + result = reply_b; /* Restore the interrupt status if necessary and return. */ - Done: - if (!HostAdapter->IRQ_ChannelAcquired) - local_irq_restore(ProcessorFlags); - return Result; +done: + if (!adapter->irq_acquired) + local_irq_restore(processor_flag); + return result; } /* - BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list + blogic_add_probeaddr_isa appends a single ISA I/O Address to the list of I/O Address and Bus Probe Information to be checked for potential BusLogic Host Adapters. */ -static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address) +static void __init blogic_add_probeaddr_isa(unsigned long io_addr) { - struct BusLogic_ProbeInfo *ProbeInfo; - if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) + struct blogic_probeinfo *probeinfo; + if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS) return; - ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Device = NULL; + probeinfo = &blogic_probeinfo_list[blogic_probeinfo_count++]; + probeinfo->adapter_type = BLOGIC_MULTIMASTER; + probeinfo->adapter_bus_type = BLOGIC_ISA_BUS; + probeinfo->io_addr = io_addr; + probeinfo->pci_device = NULL; } /* - BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and + blogic_init_probeinfo_isa initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters only from the list of standard BusLogic MultiMaster ISA I/O Addresses. */ -static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter - *PrototypeHostAdapter) +static void __init blogic_init_probeinfo_isa(struct blogic_adapter *adapter) { /* - If BusLogic Driver Options specifications requested that ISA Bus Probes - be inhibited, do not proceed further. + If BusLogic Driver Options specifications requested that ISA + Bus Probes be inhibited, do not proceed further. */ - if (BusLogic_ProbeOptions.NoProbeISA) + if (blogic_probe_options.noprobe_isa) return; /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses. */ - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330) - BusLogic_AppendProbeAddressISA(0x330); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334) - BusLogic_AppendProbeAddressISA(0x334); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230) - BusLogic_AppendProbeAddressISA(0x230); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234) - BusLogic_AppendProbeAddressISA(0x234); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130) - BusLogic_AppendProbeAddressISA(0x130); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134) - BusLogic_AppendProbeAddressISA(0x134); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe330) + blogic_add_probeaddr_isa(0x330); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe334) + blogic_add_probeaddr_isa(0x334); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe230) + blogic_add_probeaddr_isa(0x230); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe234) + blogic_add_probeaddr_isa(0x234); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe130) + blogic_add_probeaddr_isa(0x130); + if (!blogic_probe_options.limited_isa || blogic_probe_options.probe134) + blogic_add_probeaddr_isa(0x134); } @@ -590,25 +619,35 @@ static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapt /* - BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order + blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order of increasing PCI Bus and Device Number. */ -static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount) +static void __init blogic_sort_probeinfo(struct blogic_probeinfo + *probeinfo_list, int probeinfo_cnt) { - int LastInterchange = ProbeInfoCount - 1, Bound, j; - while (LastInterchange > 0) { - Bound = LastInterchange; - LastInterchange = 0; - for (j = 0; j < Bound; j++) { - struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j]; - struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1]; - if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) { - struct BusLogic_ProbeInfo TempProbeInfo; - memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo)); - memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo)); - memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo)); - LastInterchange = j; + int last_exchange = probeinfo_cnt - 1, bound, j; + + while (last_exchange > 0) { + bound = last_exchange; + last_exchange = 0; + for (j = 0; j < bound; j++) { + struct blogic_probeinfo *probeinfo1 = + &probeinfo_list[j]; + struct blogic_probeinfo *probeinfo2 = + &probeinfo_list[j + 1]; + if (probeinfo1->bus > probeinfo2->bus || + (probeinfo1->bus == probeinfo2->bus && + (probeinfo1->dev > probeinfo2->dev))) { + struct blogic_probeinfo tmp_probeinfo; + + memcpy(&tmp_probeinfo, probeinfo1, + sizeof(struct blogic_probeinfo)); + memcpy(probeinfo1, probeinfo2, + sizeof(struct blogic_probeinfo)); + memcpy(probeinfo2, &tmp_probeinfo, + sizeof(struct blogic_probeinfo)); + last_exchange = j; } } } @@ -616,84 +655,88 @@ static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoLi /* - BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address + blogic_init_mm_probeinfo initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic MultiMaster SCSI Host Adapters by interrogating the PCI Configuration Space on PCI machines as well as from the list of standard BusLogic MultiMaster ISA I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found. */ -static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter - *PrototypeHostAdapter) +static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter) { - struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; - int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; - int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; - bool ForceBusDeviceScanningOrder = false; - bool ForceBusDeviceScanningOrderChecked = false; - bool StandardAddressSeen[6]; - struct pci_dev *PCI_Device = NULL; + struct blogic_probeinfo *pr_probeinfo = + &blogic_probeinfo_list[blogic_probeinfo_count]; + int nonpr_mmindex = blogic_probeinfo_count + 1; + int nonpr_mmcount = 0, mmcount = 0; + bool force_scan_order = false; + bool force_scan_order_checked = false; + bool addr_seen[6]; + struct pci_dev *pci_device = NULL; int i; - if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) + if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS) return 0; - BusLogic_ProbeInfoCount++; + blogic_probeinfo_count++; for (i = 0; i < 6; i++) - StandardAddressSeen[i] = false; - /* - Iterate over the MultiMaster PCI Host Adapters. For each enumerated host - adapter, determine whether its ISA Compatible I/O Port is enabled and if - so, whether it is assigned the Primary I/O Address. A host adapter that is - assigned the Primary I/O Address will always be the preferred boot device. - The MultiMaster BIOS will first recognize a host adapter at the Primary I/O - Address, then any other PCI host adapters, and finally any host adapters - located at the remaining standard ISA I/O Addresses. When a PCI host - adapter is found with its ISA Compatible I/O Port enabled, a command is - issued to disable the ISA Compatible I/O Port, and it is noted that the + addr_seen[i] = false; + /* + Iterate over the MultiMaster PCI Host Adapters. For each + enumerated host adapter, determine whether its ISA Compatible + I/O Port is enabled and if so, whether it is assigned the + Primary I/O Address. A host adapter that is assigned the + Primary I/O Address will always be the preferred boot device. + The MultiMaster BIOS will first recognize a host adapter at + the Primary I/O Address, then any other PCI host adapters, + and finally any host adapters located at the remaining + standard ISA I/O Addresses. When a PCI host adapter is found + with its ISA Compatible I/O Port enabled, a command is issued + to disable the ISA Compatible I/O Port, and it is noted that the particular standard ISA I/O Address need not be probed. */ - PrimaryProbeInfo->IO_Address = 0; - while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) { - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; - enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest; - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long BaseAddress0; - unsigned long BaseAddress1; - unsigned long IO_Address; - unsigned long PCI_Address; - - if (pci_enable_device(PCI_Device)) + pr_probeinfo->io_addr = 0; + while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, + PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, + pci_device)) != NULL) { + struct blogic_adapter *adapter = adapter; + struct blogic_adapter_info adapter_info; + enum blogic_isa_ioport mod_ioaddr_req; + unsigned char bus; + unsigned char device; + unsigned int irq_ch; + unsigned long base_addr0; + unsigned long base_addr1; + unsigned long io_addr; + unsigned long pci_addr; + + if (pci_enable_device(pci_device)) continue; - if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32) )) + if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32))) continue; - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); - PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); + bus = pci_device->bus->number; + device = pci_device->devfn >> 3; + irq_ch = pci_device->irq; + io_addr = base_addr0 = pci_resource_start(pci_device, 0); + pci_addr = base_addr1 = pci_resource_start(pci_device, 1); - if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { - BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) { + blogic_err("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, base_addr0); + blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr); continue; } - if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) { - BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1); - BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address); + if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) { + blogic_err("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, base_addr1); + blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr); continue; } - if (IRQ_Channel == 0) { - BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + if (irq_ch == 0) { + blogic_err("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, irq_ch); + blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr); continue; } - if (BusLogic_GlobalOptions.TraceProbe) { - BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL); - BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address); + if (blogic_global_options.trace_probe) { + blogic_notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL); + blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr); } /* Issue the Inquire PCI Host Adapter Information command to determine @@ -701,238 +744,258 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd known and enabled, note that the particular Standard ISA I/O Address should not be probed. */ - HostAdapter->IO_Address = IO_Address; - BusLogic_InterruptReset(HostAdapter); - if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation)) - == sizeof(PCIHostAdapterInformation)) { - if (PCIHostAdapterInformation.ISACompatibleIOPort < 6) - StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true; + adapter->io_addr = io_addr; + blogic_intreset(adapter); + if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0, + &adapter_info, sizeof(adapter_info)) == + sizeof(adapter_info)) { + if (adapter_info.isa_port < 6) + addr_seen[adapter_info.isa_port] = true; } else - PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable; + adapter_info.isa_port = BLOGIC_IO_DISABLE; /* - * Issue the Modify I/O Address command to disable the ISA Compatible - * I/O Port. On PCI Host Adapters, the Modify I/O Address command - * allows modification of the ISA compatible I/O Address that the Host - * Adapter responds to; it does not affect the PCI compliant I/O Address - * assigned at system initialization. + Issue the Modify I/O Address command to disable the + ISA Compatible I/O Port. On PCI Host Adapters, the + Modify I/O Address command allows modification of the + ISA compatible I/O Address that the Host Adapter + responds to; it does not affect the PCI compliant + I/O Address assigned at system initialization. */ - ModifyIOAddressRequest = BusLogic_IO_Disable; - BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0); + mod_ioaddr_req = BLOGIC_IO_DISABLE; + blogic_cmd(adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req, + sizeof(mod_ioaddr_req), NULL, 0); /* - For the first MultiMaster Host Adapter enumerated, issue the Fetch - Host Adapter Local RAM command to read byte 45 of the AutoSCSI area, - for the setting of the "Use Bus And Device # For PCI Scanning Seq." - option. Issue the Inquire Board ID command since this option is + For the first MultiMaster Host Adapter enumerated, + issue the Fetch Host Adapter Local RAM command to read + byte 45 of the AutoSCSI area, for the setting of the + "Use Bus And Device # For PCI Scanning Seq." option. + Issue the Inquire Board ID command since this option is only valid for the BT-948/958/958D. */ - if (!ForceBusDeviceScanningOrderChecked) { - struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; - struct BusLogic_AutoSCSIByte45 AutoSCSIByte45; - struct BusLogic_BoardID BoardID; - FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45; - FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45); - BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45)); - BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)); - if (BoardID.FirmwareVersion1stDigit == '5') - ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder; - ForceBusDeviceScanningOrderChecked = true; + if (!force_scan_order_checked) { + struct blogic_fetch_localram fetch_localram; + struct blogic_autoscsi_byte45 autoscsi_byte45; + struct blogic_board_id id; + + fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45; + fetch_localram.count = sizeof(autoscsi_byte45); + blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, + &fetch_localram, sizeof(fetch_localram), + &autoscsi_byte45, + sizeof(autoscsi_byte45)); + blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id, + sizeof(id)); + if (id.fw_ver_digit1 == '5') + force_scan_order = + autoscsi_byte45.force_scan_order; + force_scan_order_checked = true; } /* - Determine whether this MultiMaster Host Adapter has its ISA - Compatible I/O Port enabled and is assigned the Primary I/O Address. - If it does, then it is the Primary MultiMaster Host Adapter and must - be recognized first. If it does not, then it is added to the list - for probing after any Primary MultiMaster Host Adapter is probed. + Determine whether this MultiMaster Host Adapter has its + ISA Compatible I/O Port enabled and is assigned the + Primary I/O Address. If it does, then it is the Primary + MultiMaster Host Adapter and must be recognized first. + If it does not, then it is added to the list for probing + after any Primary MultiMaster Host Adapter is probed. */ - if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) { - PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; - PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - PrimaryProbeInfo->IO_Address = IO_Address; - PrimaryProbeInfo->PCI_Address = PCI_Address; - PrimaryProbeInfo->Bus = Bus; - PrimaryProbeInfo->Device = Device; - PrimaryProbeInfo->IRQ_Channel = IRQ_Channel; - PrimaryProbeInfo->PCI_Device = pci_dev_get(PCI_Device); - PCIMultiMasterCount++; - } else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; - ProbeInfo->Bus = Bus; - ProbeInfo->Device = Device; - ProbeInfo->IRQ_Channel = IRQ_Channel; - ProbeInfo->PCI_Device = pci_dev_get(PCI_Device); - NonPrimaryPCIMultiMasterCount++; - PCIMultiMasterCount++; + if (adapter_info.isa_port == BLOGIC_IO_330) { + pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER; + pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS; + pr_probeinfo->io_addr = io_addr; + pr_probeinfo->pci_addr = pci_addr; + pr_probeinfo->bus = bus; + pr_probeinfo->dev = device; + pr_probeinfo->irq_ch = irq_ch; + pr_probeinfo->pci_device = pci_dev_get(pci_device); + mmcount++; + } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) { + struct blogic_probeinfo *probeinfo = + &blogic_probeinfo_list[blogic_probeinfo_count++]; + probeinfo->adapter_type = BLOGIC_MULTIMASTER; + probeinfo->adapter_bus_type = BLOGIC_PCI_BUS; + probeinfo->io_addr = io_addr; + probeinfo->pci_addr = pci_addr; + probeinfo->bus = bus; + probeinfo->dev = device; + probeinfo->irq_ch = irq_ch; + probeinfo->pci_device = pci_dev_get(pci_device); + nonpr_mmcount++; + mmcount++; } else - BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL); - } - /* - If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON - for the first enumerated MultiMaster Host Adapter, and if that host adapter - is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster - Host Adapters in the order of increasing PCI Bus and Device Number. In - that case, sort the probe information into the same order the BIOS uses. - If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster - Host Adapters in the order they are enumerated by the PCI BIOS, and hence - no sorting is necessary. - */ - if (ForceBusDeviceScanningOrder) - BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount); - /* - If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address, - then the Primary I/O Address must be probed explicitly before any PCI - host adapters are probed. - */ - if (!BusLogic_ProbeOptions.NoProbeISA) - if (PrimaryProbeInfo->IO_Address == 0 && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe330)) { - PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; - PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - PrimaryProbeInfo->IO_Address = 0x330; + blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL); + } + /* + If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." + option is ON for the first enumerated MultiMaster Host Adapter, + and if that host adapter is a BT-948/958/958D, then the + MultiMaster BIOS will recognize MultiMaster Host Adapters in + the order of increasing PCI Bus and Device Number. In that case, + sort the probe information into the same order the BIOS uses. + If this option is OFF, then the MultiMaster BIOS will recognize + MultiMaster Host Adapters in the order they are enumerated by + the PCI BIOS, and hence no sorting is necessary. + */ + if (force_scan_order) + blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex], + nonpr_mmcount); + /* + If no PCI MultiMaster Host Adapter is assigned the Primary + I/O Address, then the Primary I/O Address must be probed + explicitly before any PCI host adapters are probed. + */ + if (!blogic_probe_options.noprobe_isa) + if (pr_probeinfo->io_addr == 0 && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe330)) { + pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER; + pr_probeinfo->adapter_bus_type = BLOGIC_ISA_BUS; + pr_probeinfo->io_addr = 0x330; } /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses, omitting the Primary I/O Address which has already been handled. */ - if (!BusLogic_ProbeOptions.NoProbeISA) { - if (!StandardAddressSeen[1] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe334)) - BusLogic_AppendProbeAddressISA(0x334); - if (!StandardAddressSeen[2] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe230)) - BusLogic_AppendProbeAddressISA(0x230); - if (!StandardAddressSeen[3] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe234)) - BusLogic_AppendProbeAddressISA(0x234); - if (!StandardAddressSeen[4] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe130)) - BusLogic_AppendProbeAddressISA(0x130); - if (!StandardAddressSeen[5] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe134)) - BusLogic_AppendProbeAddressISA(0x134); + if (!blogic_probe_options.noprobe_isa) { + if (!addr_seen[1] && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe334)) + blogic_add_probeaddr_isa(0x334); + if (!addr_seen[2] && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe230)) + blogic_add_probeaddr_isa(0x230); + if (!addr_seen[3] && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe234)) + blogic_add_probeaddr_isa(0x234); + if (!addr_seen[4] && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe130)) + blogic_add_probeaddr_isa(0x130); + if (!addr_seen[5] && + (!blogic_probe_options.limited_isa || + blogic_probe_options.probe134)) + blogic_add_probeaddr_isa(0x134); } /* Iterate over the older non-compliant MultiMaster PCI Host Adapters, noting the PCI bus location and assigned IRQ Channel. */ - PCI_Device = NULL; - while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) { - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long IO_Address; + pci_device = NULL; + while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, + PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, + pci_device)) != NULL) { + unsigned char bus; + unsigned char device; + unsigned int irq_ch; + unsigned long io_addr; - if (pci_enable_device(PCI_Device)) + if (pci_enable_device(pci_device)) continue; - if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32))) + if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32))) continue; - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = pci_resource_start(PCI_Device, 0); + bus = pci_device->bus->number; + device = pci_device->devfn >> 3; + irq_ch = pci_device->irq; + io_addr = pci_resource_start(pci_device, 0); - if (IO_Address == 0 || IRQ_Channel == 0) + if (io_addr == 0 || irq_ch == 0) continue; - for (i = 0; i < BusLogic_ProbeInfoCount; i++) { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i]; - if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) { - ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - ProbeInfo->PCI_Address = 0; - ProbeInfo->Bus = Bus; - ProbeInfo->Device = Device; - ProbeInfo->IRQ_Channel = IRQ_Channel; - ProbeInfo->PCI_Device = pci_dev_get(PCI_Device); + for (i = 0; i < blogic_probeinfo_count; i++) { + struct blogic_probeinfo *probeinfo = + &blogic_probeinfo_list[i]; + if (probeinfo->io_addr == io_addr && + probeinfo->adapter_type == BLOGIC_MULTIMASTER) { + probeinfo->adapter_bus_type = BLOGIC_PCI_BUS; + probeinfo->pci_addr = 0; + probeinfo->bus = bus; + probeinfo->dev = device; + probeinfo->irq_ch = irq_ch; + probeinfo->pci_device = pci_dev_get(pci_device); break; } } } - return PCIMultiMasterCount; + return mmcount; } /* - BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address + blogic_init_fp_probeinfo initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic FlashPoint Host Adapters by interrogating the PCI Configuration Space. It returns the number of FlashPoint Host Adapters found. */ -static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter - *PrototypeHostAdapter) +static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter) { - int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; - struct pci_dev *PCI_Device = NULL; + int fpindex = blogic_probeinfo_count, fpcount = 0; + struct pci_dev *pci_device = NULL; /* Interrogate PCI Configuration Space for any FlashPoint Host Adapters. */ - while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) { - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long BaseAddress0; - unsigned long BaseAddress1; - unsigned long IO_Address; - unsigned long PCI_Address; - - if (pci_enable_device(PCI_Device)) + while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, + PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, + pci_device)) != NULL) { + unsigned char bus; + unsigned char device; + unsigned int irq_ch; + unsigned long base_addr0; + unsigned long base_addr1; + unsigned long io_addr; + unsigned long pci_addr; + + if (pci_enable_device(pci_device)) continue; - if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32))) + if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32))) continue; - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); - PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); + bus = pci_device->bus->number; + device = pci_device->devfn >> 3; + irq_ch = pci_device->irq; + io_addr = base_addr0 = pci_resource_start(pci_device, 0); + pci_addr = base_addr1 = pci_resource_start(pci_device, 1); #ifdef CONFIG_SCSI_FLASHPOINT - if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { - BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) { + blogic_err("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, base_addr0); + blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr); continue; } - if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) { - BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1); - BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address); + if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) { + blogic_err("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, base_addr1); + blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr); continue; } - if (IRQ_Channel == 0) { - BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + if (irq_ch == 0) { + blogic_err("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, irq_ch); + blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr); continue; } - if (BusLogic_GlobalOptions.TraceProbe) { - BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL); - BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address); + if (blogic_global_options.trace_probe) { + blogic_notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL); + blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr); } - if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_FlashPoint; - ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; - ProbeInfo->Bus = Bus; - ProbeInfo->Device = Device; - ProbeInfo->IRQ_Channel = IRQ_Channel; - ProbeInfo->PCI_Device = pci_dev_get(PCI_Device); - FlashPointCount++; + if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) { + struct blogic_probeinfo *probeinfo = + &blogic_probeinfo_list[blogic_probeinfo_count++]; + probeinfo->adapter_type = BLOGIC_FLASHPOINT; + probeinfo->adapter_bus_type = BLOGIC_PCI_BUS; + probeinfo->io_addr = io_addr; + probeinfo->pci_addr = pci_addr; + probeinfo->bus = bus; + probeinfo->dev = device; + probeinfo->irq_ch = irq_ch; + probeinfo->pci_device = pci_dev_get(pci_device); + fpcount++; } else - BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL); + blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL); #else - BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device); - BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel); - BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL); + blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, bus, device); + blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch); + blogic_err("BusLogic: support was omitted in this kernel " "configuration.\n", NULL); #endif } /* @@ -940,13 +1003,13 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda increasing PCI Bus and Device Number, so sort the probe information into the same order the BIOS uses. */ - BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount); - return FlashPointCount; + blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount); + return fpcount; } /* - BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus + blogic_init_probeinfo_list initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters by interrogating the PCI Configuration Space on PCI machines as well as from the list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both @@ -958,104 +1021,125 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda a particular probe order. */ -static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter - *PrototypeHostAdapter) +static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter) { /* - If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint - Host Adapters; otherwise, default to the standard ISA MultiMaster probe. - */ - if (!BusLogic_ProbeOptions.NoProbePCI) { - if (BusLogic_ProbeOptions.MultiMasterFirst) { - BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); - BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - } else if (BusLogic_ProbeOptions.FlashPointFirst) { - BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); + If a PCI BIOS is present, interrogate it for MultiMaster and + FlashPoint Host Adapters; otherwise, default to the standard + ISA MultiMaster probe. + */ + if (!blogic_probe_options.noprobe_pci) { + if (blogic_probe_options.multimaster_first) { + blogic_init_mm_probeinfo(adapter); + blogic_init_fp_probeinfo(adapter); + } else if (blogic_probe_options.flashpoint_first) { + blogic_init_fp_probeinfo(adapter); + blogic_init_mm_probeinfo(adapter); } else { - int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); - if (FlashPointCount > 0 && PCIMultiMasterCount > 0) { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount]; - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; - struct BusLogic_BIOSDriveMapByte Drive0MapByte; - while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus) - ProbeInfo++; - HostAdapter->IO_Address = ProbeInfo->IO_Address; - FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0; - FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte); - BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte)); + int fpcount = blogic_init_fp_probeinfo(adapter); + int mmcount = blogic_init_mm_probeinfo(adapter); + if (fpcount > 0 && mmcount > 0) { + struct blogic_probeinfo *probeinfo = + &blogic_probeinfo_list[fpcount]; + struct blogic_adapter *myadapter = adapter; + struct blogic_fetch_localram fetch_localram; + struct blogic_bios_drvmap d0_mapbyte; + + while (probeinfo->adapter_bus_type != + BLOGIC_PCI_BUS) + probeinfo++; + myadapter->io_addr = probeinfo->io_addr; + fetch_localram.offset = + BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP; + fetch_localram.count = sizeof(d0_mapbyte); + blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM, + &fetch_localram, + sizeof(fetch_localram), + &d0_mapbyte, + sizeof(d0_mapbyte)); /* - If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0 - is controlled by this PCI MultiMaster Host Adapter, then - reverse the probe order so that MultiMaster Host Adapters are - probed before FlashPoint Host Adapters. + If the Map Byte for BIOS Drive 0 indicates + that BIOS Drive 0 is controlled by this + PCI MultiMaster Host Adapter, then reverse + the probe order so that MultiMaster Host + Adapters are probed before FlashPoint Host + Adapters. */ - if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) { - struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters]; - int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount; - memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo)); - memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo)); - memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo)); + if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) { + struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS]; + int mmcount = blogic_probeinfo_count - fpcount; + + memcpy(saved_probeinfo, + blogic_probeinfo_list, + blogic_probeinfo_count * sizeof(struct blogic_probeinfo)); + memcpy(&blogic_probeinfo_list[0], + &saved_probeinfo[fpcount], + mmcount * sizeof(struct blogic_probeinfo)); + memcpy(&blogic_probeinfo_list[mmcount], + &saved_probeinfo[0], + fpcount * sizeof(struct blogic_probeinfo)); } } } - } else - BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter); + } else { + blogic_init_probeinfo_isa(adapter); + } } #else -#define BusLogic_InitializeProbeInfoList(adapter) \ - BusLogic_InitializeProbeInfoListISA(adapter) +#define blogic_init_probeinfo_list(adapter) \ + blogic_init_probeinfo_isa(adapter) #endif /* CONFIG_PCI */ /* - BusLogic_Failure prints a standardized error message, and then returns false. + blogic_failure prints a standardized error message, and then returns false. */ -static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage) +static bool blogic_failure(struct blogic_adapter *adapter, char *msg) { - BusLogic_AnnounceDriver(HostAdapter); - if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) { - BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter); - BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device, HostAdapter->IO_Address, HostAdapter->PCI_Address); + blogic_announce_drvr(adapter); + if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) { + blogic_err("While configuring BusLogic PCI Host Adapter at\n", + adapter); + blogic_err("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr); } else - BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address); - BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage); - if (BusLogic_CommandFailureReason != NULL) - BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason); + blogic_err("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", adapter, adapter->io_addr); + blogic_err("%s FAILED - DETACHING\n", adapter, msg); + if (blogic_cmd_failure_reason != NULL) + blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter, + blogic_cmd_failure_reason); return false; } /* - BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter. + blogic_probe probes for a BusLogic Host Adapter. */ -static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter) +static bool __init blogic_probe(struct blogic_adapter *adapter) { - union BusLogic_StatusRegister StatusRegister; - union BusLogic_InterruptRegister InterruptRegister; - union BusLogic_GeometryRegister GeometryRegister; + union blogic_stat_reg statusreg; + union blogic_int_reg intreg; + union blogic_geo_reg georeg; /* FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address; - FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel; - FlashPointInfo->Present = false; - if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) { - BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device); - BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address); - BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter); + if (blogic_flashpoint_type(adapter)) { + struct fpoint_info *fpinfo = &adapter->fpinfo; + fpinfo->base_addr = (u32) adapter->io_addr; + fpinfo->irq_ch = adapter->irq_ch; + fpinfo->present = false; + if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 && + fpinfo->present)) { + blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev); + blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr); + blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter); return false; } - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address); + if (blogic_global_options.trace_probe) + blogic_notice("BusLogic_Probe(0x%X): FlashPoint Found\n", adapter, adapter->io_addr); /* Indicate the Host Adapter Probe completed successfully. */ @@ -1068,28 +1152,32 @@ static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAd case there is definitely no BusLogic Host Adapter at this base I/O Address. The test here is a subset of that used by the BusLogic Host Adapter BIOS. */ - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, InterruptRegister.All, GeometryRegister.All); - if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0) + statusreg.all = blogic_rdstatus(adapter); + intreg.all = blogic_rdint(adapter); + georeg.all = blogic_rdgeom(adapter); + if (blogic_global_options.trace_probe) + blogic_notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all); + if (statusreg.all == 0 || statusreg.sr.diag_active || + statusreg.sr.cmd_param_busy || statusreg.sr.rsvd || + statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0) return false; /* - Check the undocumented Geometry Register to test if there is an I/O port - that responded. Adaptec Host Adapters do not implement the Geometry - Register, so this test helps serve to avoid incorrectly recognizing an - Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C - series does respond to the Geometry Register I/O port, but it will be - rejected later when the Inquire Extended Setup Information command is - issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a - BusLogic clone that implements the same interface as earlier BusLogic - Host Adapters, including the undocumented commands, and is therefore - supported by this driver. However, the AMI FastDisk always returns 0x00 - upon reading the Geometry Register, so the extended translation option - should always be left disabled on the AMI FastDisk. - */ - if (GeometryRegister.All == 0xFF) + Check the undocumented Geometry Register to test if there is + an I/O port that responded. Adaptec Host Adapters do not + implement the Geometry Register, so this test helps serve to + avoid incorrectly recognizing an Adaptec 1542A or 1542B as a + BusLogic. Unfortunately, the Adaptec 1542C series does respond + to the Geometry Register I/O port, but it will be rejected + later when the Inquire Extended Setup Information command is + issued in blogic_checkadapter. The AMI FastDisk Host Adapter + is a BusLogic clone that implements the same interface as + earlier BusLogic Host Adapters, including the undocumented + commands, and is therefore supported by this driver. However, + the AMI FastDisk always returns 0x00 upon reading the Geometry + Register, so the extended translation option should always be + left disabled on the AMI FastDisk. + */ + if (georeg.all == 0xFF) return false; /* Indicate the Host Adapter Probe completed successfully. @@ -1099,27 +1187,28 @@ static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAd /* - BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter - and waits for Host Adapter Diagnostics to complete. If HardReset is true, a + blogic_hwreset issues a Hardware Reset to the Host Adapter + and waits for Host Adapter Diagnostics to complete. If hard_reset is true, a Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a Soft Reset is performed which only resets the Host Adapter without forcing a SCSI Bus Reset. */ -static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter - *HostAdapter, bool HardReset) +static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset) { - union BusLogic_StatusRegister StatusRegister; - int TimeoutCounter; + union blogic_stat_reg statusreg; + int timeout; /* - FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager. + FlashPoint Host Adapters are Hard Reset by the FlashPoint + SCCB Manager. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - FlashPointInfo->HostSoftReset = !HardReset; - FlashPointInfo->ReportDataUnderrun = true; - HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo); - if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) + if (blogic_flashpoint_type(adapter)) { + struct fpoint_info *fpinfo = &adapter->fpinfo; + fpinfo->softreset = !hard_reset; + fpinfo->report_underrun = true; + adapter->cardhandle = + FlashPoint_HardwareResetHostAdapter(fpinfo); + if (adapter->cardhandle == FPOINT_BADCARD_HANDLE) return false; /* Indicate the Host Adapter Hard Reset completed successfully. @@ -1127,26 +1216,27 @@ static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter return true; } /* - Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host - Adapter should respond by setting Diagnostic Active in the Status Register. + Issue a Hard Reset or Soft Reset Command to the Host Adapter. + The Host Adapter should respond by setting Diagnostic Active in + the Status Register. */ - if (HardReset) - BusLogic_HardReset(HostAdapter); + if (hard_reset) + blogic_hardreset(adapter); else - BusLogic_SoftReset(HostAdapter); + blogic_softreset(adapter); /* Wait until Diagnostic Active is set in the Status Register. */ - TimeoutCounter = 5 * 10000; - while (--TimeoutCounter >= 0) { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.DiagnosticActive) + timeout = 5 * 10000; + while (--timeout >= 0) { + statusreg.all = blogic_rdstatus(adapter); + if (statusreg.sr.diag_active) break; udelay(100); } - if (BusLogic_GlobalOptions.TraceHardwareReset) - BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); - if (TimeoutCounter < 0) + if (blogic_global_options.trace_hw_reset) + blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all); + if (timeout < 0) return false; /* Wait 100 microseconds to allow completion of any initial diagnostic @@ -1157,45 +1247,47 @@ static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter /* Wait until Diagnostic Active is reset in the Status Register. */ - TimeoutCounter = 10 * 10000; - while (--TimeoutCounter >= 0) { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (!StatusRegister.sr.DiagnosticActive) + timeout = 10 * 10000; + while (--timeout >= 0) { + statusreg.all = blogic_rdstatus(adapter); + if (!statusreg.sr.diag_active) break; udelay(100); } - if (BusLogic_GlobalOptions.TraceHardwareReset) - BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); - if (TimeoutCounter < 0) + if (blogic_global_options.trace_hw_reset) + blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all); + if (timeout < 0) return false; /* - Wait until at least one of the Diagnostic Failure, Host Adapter Ready, - or Data In Register Ready bits is set in the Status Register. + Wait until at least one of the Diagnostic Failure, Host Adapter + Ready, or Data In Register Ready bits is set in the Status Register. */ - TimeoutCounter = 10000; - while (--TimeoutCounter >= 0) { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady) + timeout = 10000; + while (--timeout >= 0) { + statusreg.all = blogic_rdstatus(adapter); + if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready || + statusreg.sr.datain_ready) break; udelay(100); } - if (BusLogic_GlobalOptions.TraceHardwareReset) - BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); - if (TimeoutCounter < 0) + if (blogic_global_options.trace_hw_reset) + blogic_notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all); + if (timeout < 0) return false; /* - If Diagnostic Failure is set or Host Adapter Ready is reset, then an - error occurred during the Host Adapter diagnostics. If Data In Register - Ready is set, then there is an Error Code available. - */ - if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) { - BusLogic_CommandFailureReason = NULL; - BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS"); - BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All); - if (StatusRegister.sr.DataInRegisterReady) { - unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter); - BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode); - } + If Diagnostic Failure is set or Host Adapter Ready is reset, + then an error occurred during the Host Adapter diagnostics. + If Data In Register Ready is set, then there is an Error Code + available. + */ + if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) { + blogic_cmd_failure_reason = NULL; + blogic_failure(adapter, "HARD RESET DIAGNOSTICS"); + blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter, + statusreg.all); + if (statusreg.sr.datain_ready) + blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter, + blogic_rddatain(adapter)); return false; } /* @@ -1206,161 +1298,175 @@ static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter /* - BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic + blogic_checkadapter checks to be sure this really is a BusLogic Host Adapter. */ -static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter) +static bool __init blogic_checkadapter(struct blogic_adapter *adapter) { - struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; - unsigned char RequestedReplyLength; - bool Result = true; + struct blogic_ext_setup ext_setupinfo; + unsigned char req_replylen; + bool result = true; /* FlashPoint Host Adapters do not require this protection. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + if (blogic_flashpoint_type(adapter)) return true; /* - Issue the Inquire Extended Setup Information command. Only genuine - BusLogic Host Adapters and true clones support this command. Adaptec 1542C - series Host Adapters that respond to the Geometry Register I/O port will - fail this command. + Issue the Inquire Extended Setup Information command. Only genuine + BusLogic Host Adapters and true clones support this command. + Adaptec 1542C series Host Adapters that respond to the Geometry + Register I/O port will fail this command. */ - RequestedReplyLength = sizeof(ExtendedSetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation)) - != sizeof(ExtendedSetupInformation)) - Result = false; + req_replylen = sizeof(ext_setupinfo); + if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen, + sizeof(req_replylen), &ext_setupinfo, + sizeof(ext_setupinfo)) != sizeof(ext_setupinfo)) + result = false; /* Provide tracing information if requested and return. */ - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found")); - return Result; + if (blogic_global_options.trace_probe) + blogic_notice("BusLogic_Check(0x%X): MultiMaster %s\n", adapter, + adapter->io_addr, + (result ? "Found" : "Not Found")); + return result; } /* - BusLogic_ReadHostAdapterConfiguration reads the Configuration Information + blogic_rdconfig reads the Configuration Information from Host Adapter and initializes the Host Adapter structure. */ -static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter - *HostAdapter) +static bool __init blogic_rdconfig(struct blogic_adapter *adapter) { - struct BusLogic_BoardID BoardID; - struct BusLogic_Configuration Configuration; - struct BusLogic_SetupInformation SetupInformation; - struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; - unsigned char HostAdapterModelNumber[5]; - unsigned char FirmwareVersion3rdDigit; - unsigned char FirmwareVersionLetter; - struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; - struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; - struct BusLogic_AutoSCSIData AutoSCSIData; - union BusLogic_GeometryRegister GeometryRegister; - unsigned char RequestedReplyLength; - unsigned char *TargetPointer, Character; - int TargetID, i; - /* - Configuration Information for FlashPoint Host Adapters is provided in the - FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function. - Initialize fields in the Host Adapter structure from the FlashPoint_Info - structure. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - TargetPointer = HostAdapter->ModelName; - *TargetPointer++ = 'B'; - *TargetPointer++ = 'T'; - *TargetPointer++ = '-'; - for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++) - *TargetPointer++ = FlashPointInfo->ModelNumber[i]; - *TargetPointer++ = '\0'; - strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion); - HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID; - HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled; - HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled; - HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset; - HostAdapter->LevelSensitiveInterrupt = true; - HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI; - HostAdapter->HostDifferentialSCSI = false; - HostAdapter->HostSupportsSCAM = true; - HostAdapter->HostUltraSCSI = true; - HostAdapter->ExtendedLUNSupport = true; - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated; - HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated; - HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled; - HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2; - HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; - HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); - HostAdapter->MaxLogicalUnits = 32; - HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; - HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; - HostAdapter->DriverQueueDepth = 255; - HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth; - HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted; - HostAdapter->FastPermitted = FlashPointInfo->FastPermitted; - HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted; - HostAdapter->WidePermitted = FlashPointInfo->WidePermitted; - HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted; - HostAdapter->TaggedQueuingPermitted = 0xFFFF; - goto Common; + struct blogic_board_id id; + struct blogic_config config; + struct blogic_setup_info setupinfo; + struct blogic_ext_setup ext_setupinfo; + unsigned char model[5]; + unsigned char fw_ver_digit3; + unsigned char fw_ver_letter; + struct blogic_adapter_info adapter_info; + struct blogic_fetch_localram fetch_localram; + struct blogic_autoscsi autoscsi; + union blogic_geo_reg georeg; + unsigned char req_replylen; + unsigned char *tgt, ch; + int tgt_id, i; + /* + Configuration Information for FlashPoint Host Adapters is + provided in the fpoint_info structure by the FlashPoint + SCCB Manager's Probe Function. Initialize fields in the + Host Adapter structure from the fpoint_info structure. + */ + if (blogic_flashpoint_type(adapter)) { + struct fpoint_info *fpinfo = &adapter->fpinfo; + tgt = adapter->model; + *tgt++ = 'B'; + *tgt++ = 'T'; + *tgt++ = '-'; + for (i = 0; i < sizeof(fpinfo->model); i++) + *tgt++ = fpinfo->model[i]; + *tgt++ = '\0'; + strcpy(adapter->fw_ver, FLASHPOINT_FW_VER); + adapter->scsi_id = fpinfo->scsi_id; + adapter->ext_trans_enable = fpinfo->ext_trans_enable; + adapter->parity = fpinfo->parity; + adapter->reset_enabled = !fpinfo->softreset; + adapter->level_int = true; + adapter->wide = fpinfo->wide; + adapter->differential = false; + adapter->scam = true; + adapter->ultra = true; + adapter->ext_lun = true; + adapter->terminfo_valid = true; + adapter->low_term = fpinfo->low_term; + adapter->high_term = fpinfo->high_term; + adapter->scam_enabled = fpinfo->scam_enabled; + adapter->scam_lev2 = fpinfo->scam_lev2; + adapter->drvr_sglimit = BLOGIC_SG_LIMIT; + adapter->maxdev = (adapter->wide ? 16 : 8); + adapter->maxlun = 32; + adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE; + adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE; + adapter->drvr_qdepth = 255; + adapter->adapter_qdepth = adapter->drvr_qdepth; + adapter->sync_ok = fpinfo->sync_ok; + adapter->fast_ok = fpinfo->fast_ok; + adapter->ultra_ok = fpinfo->ultra_ok; + adapter->wide_ok = fpinfo->wide_ok; + adapter->discon_ok = fpinfo->discon_ok; + adapter->tagq_ok = 0xFFFF; + goto common; } /* Issue the Inquire Board ID command. */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID)) - return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID"); + if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id, + sizeof(id)) != sizeof(id)) + return blogic_failure(adapter, "INQUIRE BOARD ID"); /* Issue the Inquire Configuration command. */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration)) - != sizeof(Configuration)) - return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION"); + if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config, + sizeof(config)) + != sizeof(config)) + return blogic_failure(adapter, "INQUIRE CONFIGURATION"); /* Issue the Inquire Setup Information command. */ - RequestedReplyLength = sizeof(SetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation)) - != sizeof(SetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); + req_replylen = sizeof(setupinfo); + if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen, + sizeof(req_replylen), &setupinfo, + sizeof(setupinfo)) != sizeof(setupinfo)) + return blogic_failure(adapter, "INQUIRE SETUP INFORMATION"); /* Issue the Inquire Extended Setup Information command. */ - RequestedReplyLength = sizeof(ExtendedSetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation)) - != sizeof(ExtendedSetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION"); + req_replylen = sizeof(ext_setupinfo); + if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen, + sizeof(req_replylen), &ext_setupinfo, + sizeof(ext_setupinfo)) != sizeof(ext_setupinfo)) + return blogic_failure(adapter, + "INQUIRE EXTENDED SETUP INFORMATION"); /* Issue the Inquire Firmware Version 3rd Digit command. */ - FirmwareVersion3rdDigit = '\0'; - if (BoardID.FirmwareVersion1stDigit > '0') - if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit)) - != sizeof(FirmwareVersion3rdDigit)) - return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT"); + fw_ver_digit3 = '\0'; + if (id.fw_ver_digit1 > '0') + if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0, + &fw_ver_digit3, + sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3)) + return blogic_failure(adapter, + "INQUIRE FIRMWARE 3RD DIGIT"); /* Issue the Inquire Host Adapter Model Number command. */ - if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2') + if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2') /* BusLogic BT-542B ISA 2.xx */ - strcpy(HostAdapterModelNumber, "542B"); - else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0'))) + strcpy(model, "542B"); + else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' && + (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' && + fw_ver_digit3 == '0'))) /* BusLogic BT-742A EISA 2.1x or 2.20 */ - strcpy(HostAdapterModelNumber, "742A"); - else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0') + strcpy(model, "742A"); + else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0') /* AMI FastDisk EISA Series 441 0.x */ - strcpy(HostAdapterModelNumber, "747A"); + strcpy(model, "747A"); else { - RequestedReplyLength = sizeof(HostAdapterModelNumber); - if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber)) - != sizeof(HostAdapterModelNumber)) - return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER"); + req_replylen = sizeof(model); + if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen, + sizeof(req_replylen), &model, + sizeof(model)) != sizeof(model)) + return blogic_failure(adapter, + "INQUIRE HOST ADAPTER MODEL NUMBER"); } /* - BusLogic MultiMaster Host Adapters can be identified by their model number - and the major version number of their firmware as follows: + BusLogic MultiMaster Host Adapters can be identified by their + model number and the major version number of their firmware + as follows: 5.xx BusLogic "W" Series Host Adapters: BT-948/958/958D @@ -1374,497 +1480,535 @@ static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAda 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter */ /* - Save the Model Name and Host Adapter Name in the Host Adapter structure. + Save the Model Name and Host Adapter Name in the Host Adapter + structure. */ - TargetPointer = HostAdapter->ModelName; - *TargetPointer++ = 'B'; - *TargetPointer++ = 'T'; - *TargetPointer++ = '-'; - for (i = 0; i < sizeof(HostAdapterModelNumber); i++) { - Character = HostAdapterModelNumber[i]; - if (Character == ' ' || Character == '\0') + tgt = adapter->model; + *tgt++ = 'B'; + *tgt++ = 'T'; + *tgt++ = '-'; + for (i = 0; i < sizeof(model); i++) { + ch = model[i]; + if (ch == ' ' || ch == '\0') break; - *TargetPointer++ = Character; + *tgt++ = ch; } - *TargetPointer++ = '\0'; + *tgt++ = '\0'; /* Save the Firmware Version in the Host Adapter structure. */ - TargetPointer = HostAdapter->FirmwareVersion; - *TargetPointer++ = BoardID.FirmwareVersion1stDigit; - *TargetPointer++ = '.'; - *TargetPointer++ = BoardID.FirmwareVersion2ndDigit; - if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0') - *TargetPointer++ = FirmwareVersion3rdDigit; - *TargetPointer = '\0'; + tgt = adapter->fw_ver; + *tgt++ = id.fw_ver_digit1; + *tgt++ = '.'; + *tgt++ = id.fw_ver_digit2; + if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0') + *tgt++ = fw_ver_digit3; + *tgt = '\0'; /* Issue the Inquire Firmware Version Letter command. */ - if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) { - if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter)) - != sizeof(FirmwareVersionLetter)) - return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER"); - if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0') - *TargetPointer++ = FirmwareVersionLetter; - *TargetPointer = '\0'; + if (strcmp(adapter->fw_ver, "3.3") >= 0) { + if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0, + &fw_ver_letter, + sizeof(fw_ver_letter)) != sizeof(fw_ver_letter)) + return blogic_failure(adapter, + "INQUIRE FIRMWARE VERSION LETTER"); + if (fw_ver_letter != ' ' && fw_ver_letter != '\0') + *tgt++ = fw_ver_letter; + *tgt = '\0'; } /* Save the Host Adapter SCSI ID in the Host Adapter structure. */ - HostAdapter->SCSI_ID = Configuration.HostAdapterID; - /* - Determine the Bus Type and save it in the Host Adapter structure, determine - and save the IRQ Channel if necessary, and determine and save the DMA - Channel for ISA Host Adapters. - */ - HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4']; - if (HostAdapter->IRQ_Channel == 0) { - if (Configuration.IRQ_Channel9) - HostAdapter->IRQ_Channel = 9; - else if (Configuration.IRQ_Channel10) - HostAdapter->IRQ_Channel = 10; - else if (Configuration.IRQ_Channel11) - HostAdapter->IRQ_Channel = 11; - else if (Configuration.IRQ_Channel12) - HostAdapter->IRQ_Channel = 12; - else if (Configuration.IRQ_Channel14) - HostAdapter->IRQ_Channel = 14; - else if (Configuration.IRQ_Channel15) - HostAdapter->IRQ_Channel = 15; - } - if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) { - if (Configuration.DMA_Channel5) - HostAdapter->DMA_Channel = 5; - else if (Configuration.DMA_Channel6) - HostAdapter->DMA_Channel = 6; - else if (Configuration.DMA_Channel7) - HostAdapter->DMA_Channel = 7; + adapter->scsi_id = config.id; + /* + Determine the Bus Type and save it in the Host Adapter structure, + determine and save the IRQ Channel if necessary, and determine + and save the DMA Channel for ISA Host Adapters. + */ + adapter->adapter_bus_type = + blogic_adater_bus_types[adapter->model[3] - '4']; + if (adapter->irq_ch == 0) { + if (config.irq_ch9) + adapter->irq_ch = 9; + else if (config.irq_ch10) + adapter->irq_ch = 10; + else if (config.irq_ch11) + adapter->irq_ch = 11; + else if (config.irq_ch12) + adapter->irq_ch = 12; + else if (config.irq_ch14) + adapter->irq_ch = 14; + else if (config.irq_ch15) + adapter->irq_ch = 15; + } + if (adapter->adapter_bus_type == BLOGIC_ISA_BUS) { + if (config.dma_ch5) + adapter->dma_ch = 5; + else if (config.dma_ch6) + adapter->dma_ch = 6; + else if (config.dma_ch7) + adapter->dma_ch = 7; } /* Determine whether Extended Translation is enabled and save it in the Host Adapter structure. */ - GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); - HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled; + georeg.all = blogic_rdgeom(adapter); + adapter->ext_trans_enable = georeg.gr.ext_trans_enable; /* Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide SCSI flag, Differential SCSI flag, SCAM Supported flag, and Ultra SCSI flag in the Host Adapter structure. */ - HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit; - HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit; - if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit) - HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; - if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt) - HostAdapter->LevelSensitiveInterrupt = true; - HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI; - HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI; - HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM; - HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI; + adapter->adapter_sglimit = ext_setupinfo.sg_limit; + adapter->drvr_sglimit = adapter->adapter_sglimit; + if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT) + adapter->drvr_sglimit = BLOGIC_SG_LIMIT; + if (ext_setupinfo.misc.level_int) + adapter->level_int = true; + adapter->wide = ext_setupinfo.wide; + adapter->differential = ext_setupinfo.differential; + adapter->scam = ext_setupinfo.scam; + adapter->ultra = ext_setupinfo.ultra; /* Determine whether Extended LUN Format CCBs are supported and save the information in the Host Adapter structure. */ - if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI)) - HostAdapter->ExtendedLUNSupport = true; + if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' && + adapter->wide)) + adapter->ext_lun = true; /* Issue the Inquire PCI Host Adapter Information command to read the Termination Information from "W" series MultiMaster Host Adapters. */ - if (HostAdapter->FirmwareVersion[0] == '5') { - if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation)) - != sizeof(PCIHostAdapterInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION"); + if (adapter->fw_ver[0] == '5') { + if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0, + &adapter_info, + sizeof(adapter_info)) != sizeof(adapter_info)) + return blogic_failure(adapter, + "INQUIRE PCI HOST ADAPTER INFORMATION"); /* - Save the Termination Information in the Host Adapter structure. + Save the Termination Information in the Host Adapter + structure. */ - if (PCIHostAdapterInformation.GenericInfoValid) { - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated; - HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated; + if (adapter_info.genericinfo_valid) { + adapter->terminfo_valid = true; + adapter->low_term = adapter_info.low_term; + adapter->high_term = adapter_info.high_term; } } /* - Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data - from "W" and "C" series MultiMaster Host Adapters. + Issue the Fetch Host Adapter Local RAM command to read the + AutoSCSI data from "W" and "C" series MultiMaster Host Adapters. */ - if (HostAdapter->FirmwareVersion[0] >= '4') { - FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset; - FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData); - if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData)) - != sizeof(AutoSCSIData)) - return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM"); + if (adapter->fw_ver[0] >= '4') { + fetch_localram.offset = BLOGIC_AUTOSCSI_BASE; + fetch_localram.count = sizeof(autoscsi); + if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram, + sizeof(fetch_localram), &autoscsi, + sizeof(autoscsi)) != sizeof(autoscsi)) + return blogic_failure(adapter, + "FETCH HOST ADAPTER LOCAL RAM"); /* - Save the Parity Checking Enabled, Bus Reset Enabled, and Termination - Information in the Host Adapter structure. + Save the Parity Checking Enabled, Bus Reset Enabled, + and Termination Information in the Host Adapter structure. */ - HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled; - HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled; - if (HostAdapter->FirmwareVersion[0] == '4') { - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated; - HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated; + adapter->parity = autoscsi.parity; + adapter->reset_enabled = autoscsi.reset_enabled; + if (adapter->fw_ver[0] == '4') { + adapter->terminfo_valid = true; + adapter->low_term = autoscsi.low_term; + adapter->high_term = autoscsi.high_term; } /* - Save the Wide Permitted, Fast Permitted, Synchronous Permitted, - Disconnect Permitted, Ultra Permitted, and SCAM Information in the - Host Adapter structure. + Save the Wide Permitted, Fast Permitted, Synchronous + Permitted, Disconnect Permitted, Ultra Permitted, and + SCAM Information in the Host Adapter structure. */ - HostAdapter->WidePermitted = AutoSCSIData.WidePermitted; - HostAdapter->FastPermitted = AutoSCSIData.FastPermitted; - HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted; - HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted; - if (HostAdapter->HostUltraSCSI) - HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted; - if (HostAdapter->HostSupportsSCAM) { - HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled; - HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2; + adapter->wide_ok = autoscsi.wide_ok; + adapter->fast_ok = autoscsi.fast_ok; + adapter->sync_ok = autoscsi.sync_ok; + adapter->discon_ok = autoscsi.discon_ok; + if (adapter->ultra) + adapter->ultra_ok = autoscsi.ultra_ok; + if (adapter->scam) { + adapter->scam_enabled = autoscsi.scam_enabled; + adapter->scam_lev2 = autoscsi.scam_lev2; } } /* - Initialize fields in the Host Adapter structure for "S" and "A" series - MultiMaster Host Adapters. + Initialize fields in the Host Adapter structure for "S" and "A" + series MultiMaster Host Adapters. */ - if (HostAdapter->FirmwareVersion[0] < '4') { - if (SetupInformation.SynchronousInitiationEnabled) { - HostAdapter->SynchronousPermitted = 0xFF; - if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) { - if (ExtendedSetupInformation.Misc.FastOnEISA) - HostAdapter->FastPermitted = 0xFF; - if (strcmp(HostAdapter->ModelName, "BT-757") == 0) - HostAdapter->WidePermitted = 0xFF; + if (adapter->fw_ver[0] < '4') { + if (setupinfo.sync) { + adapter->sync_ok = 0xFF; + if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) { + if (ext_setupinfo.misc.fast_on_eisa) + adapter->fast_ok = 0xFF; + if (strcmp(adapter->model, "BT-757") == 0) + adapter->wide_ok = 0xFF; } } - HostAdapter->DisconnectPermitted = 0xFF; - HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled; - HostAdapter->BusResetEnabled = true; + adapter->discon_ok = 0xFF; + adapter->parity = setupinfo.parity; + adapter->reset_enabled = true; } /* - Determine the maximum number of Target IDs and Logical Units supported by - this driver for Wide and Narrow Host Adapters. + Determine the maximum number of Target IDs and Logical Units + supported by this driver for Wide and Narrow Host Adapters. */ - HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); - HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8); + adapter->maxdev = (adapter->wide ? 16 : 8); + adapter->maxlun = (adapter->ext_lun ? 32 : 8); /* Select appropriate values for the Mailbox Count, Driver Queue Depth, - Initial CCBs, and Incremental CCBs variables based on whether or not Strict - Round Robin Mode is supported. If Strict Round Robin Mode is supported, - then there is no performance degradation in using the maximum possible - number of Outgoing and Incoming Mailboxes and allowing the Tagged and - Untagged Queue Depths to determine the actual utilization. If Strict Round - Robin Mode is not supported, then the Host Adapter must scan all the - Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can - cause a substantial performance penalty. The host adapters actually have - room to store the following number of CCBs internally; that is, they can - internally queue and manage this many active commands on the SCSI bus - simultaneously. Performance measurements demonstrate that the Driver Queue - Depth should be set to the Mailbox Count, rather than the Host Adapter - Queue Depth (internal CCB capacity), as it is more efficient to have the - queued commands waiting in Outgoing Mailboxes if necessary than to block - the process in the higher levels of the SCSI Subsystem. + Initial CCBs, and Incremental CCBs variables based on whether + or not Strict Round Robin Mode is supported. If Strict Round + Robin Mode is supported, then there is no performance degradation + in using the maximum possible number of Outgoing and Incoming + Mailboxes and allowing the Tagged and Untagged Queue Depths to + determine the actual utilization. If Strict Round Robin Mode is + not supported, then the Host Adapter must scan all the Outgoing + Mailboxes whenever an Outgoing Mailbox entry is made, which can + cause a substantial performance penalty. The host adapters + actually have room to store the following number of CCBs + internally; that is, they can internally queue and manage this + many active commands on the SCSI bus simultaneously. Performance + measurements demonstrate that the Driver Queue Depth should be + set to the Mailbox Count, rather than the Host Adapter Queue + Depth (internal CCB capacity), as it is more efficient to have the + queued commands waiting in Outgoing Mailboxes if necessary than + to block the process in the higher levels of the SCSI Subsystem. 192 BT-948/958/958D 100 BT-946C/956C/956CD/747C/757C/757CD/445C 50 BT-545C/540CF 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A */ - if (HostAdapter->FirmwareVersion[0] == '5') - HostAdapter->HostAdapterQueueDepth = 192; - else if (HostAdapter->FirmwareVersion[0] == '4') - HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50); + if (adapter->fw_ver[0] == '5') + adapter->adapter_qdepth = 192; + else if (adapter->fw_ver[0] == '4') + adapter->adapter_qdepth = (adapter->adapter_bus_type != + BLOGIC_ISA_BUS ? 100 : 50); else - HostAdapter->HostAdapterQueueDepth = 30; - if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) { - HostAdapter->StrictRoundRobinModeSupport = true; - HostAdapter->MailboxCount = BusLogic_MaxMailboxes; + adapter->adapter_qdepth = 30; + if (strcmp(adapter->fw_ver, "3.31") >= 0) { + adapter->strict_rr = true; + adapter->mbox_count = BLOGIC_MAX_MAILBOX; } else { - HostAdapter->StrictRoundRobinModeSupport = false; - HostAdapter->MailboxCount = 32; + adapter->strict_rr = false; + adapter->mbox_count = 32; } - HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount; - HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; - HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; + adapter->drvr_qdepth = adapter->mbox_count; + adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE; + adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE; /* - Tagged Queuing support is available and operates properly on all "W" series - MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with - firmware version 4.22 and above, and on "S" series MultiMaster Host - Adapters with firmware version 3.35 and above. + Tagged Queuing support is available and operates properly on + all "W" series MultiMaster Host Adapters, on "C" series + MultiMaster Host Adapters with firmware version 4.22 and above, + and on "S" series MultiMaster Host Adapters with firmware version + 3.35 and above. */ - HostAdapter->TaggedQueuingPermitted = 0; - switch (HostAdapter->FirmwareVersion[0]) { + adapter->tagq_ok = 0; + switch (adapter->fw_ver[0]) { case '5': - HostAdapter->TaggedQueuingPermitted = 0xFFFF; + adapter->tagq_ok = 0xFFFF; break; case '4': - if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0) - HostAdapter->TaggedQueuingPermitted = 0xFFFF; + if (strcmp(adapter->fw_ver, "4.22") >= 0) + adapter->tagq_ok = 0xFFFF; break; case '3': - if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0) - HostAdapter->TaggedQueuingPermitted = 0xFFFF; + if (strcmp(adapter->fw_ver, "3.35") >= 0) + adapter->tagq_ok = 0xFFFF; break; } /* Determine the Host Adapter BIOS Address if the BIOS is enabled and save it in the Host Adapter structure. The BIOS is disabled if the - BIOS_Address is 0. + bios_addr is 0. */ - HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12; + adapter->bios_addr = ext_setupinfo.bios_addr << 12; /* - ISA Host Adapters require Bounce Buffers if there is more than 16MB memory. + ISA Host Adapters require Bounce Buffers if there is more than + 16MB memory. */ - if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS) - HostAdapter->BounceBuffersRequired = true; + if (adapter->adapter_bus_type == BLOGIC_ISA_BUS && + (void *) high_memory > (void *) MAX_DMA_ADDRESS) + adapter->need_bouncebuf = true; /* - BusLogic BT-445S Host Adapters prior to board revision E have a hardware - bug whereby when the BIOS is enabled, transfers to/from the same address - range the BIOS occupies modulo 16MB are handled incorrectly. Only properly - functioning BT-445S Host Adapters have firmware version 3.37, so require - that ISA Bounce Buffers be used for the buggy BT-445S models if there is - more than 16MB memory. + BusLogic BT-445S Host Adapters prior to board revision E have a + hardware bug whereby when the BIOS is enabled, transfers to/from + the same address range the BIOS occupies modulo 16MB are handled + incorrectly. Only properly functioning BT-445S Host Adapters + have firmware version 3.37, so require that ISA Bounce Buffers + be used for the buggy BT-445S models if there is more than 16MB + memory. */ - if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS) - HostAdapter->BounceBuffersRequired = true; + if (adapter->bios_addr > 0 && strcmp(adapter->model, "BT-445S") == 0 && + strcmp(adapter->fw_ver, "3.37") < 0 && + (void *) high_memory > (void *) MAX_DMA_ADDRESS) + adapter->need_bouncebuf = true; /* - Initialize parameters common to MultiMaster and FlashPoint Host Adapters. + Initialize parameters common to MultiMaster and FlashPoint + Host Adapters. */ - Common: +common: /* Initialize the Host Adapter Full Model Name from the Model Name. */ - strcpy(HostAdapter->FullModelName, "BusLogic "); - strcat(HostAdapter->FullModelName, HostAdapter->ModelName); + strcpy(adapter->full_model, "BusLogic "); + strcat(adapter->full_model, adapter->model); /* Select an appropriate value for the Tagged Queue Depth either from a BusLogic Driver Options specification, or based on whether this Host - Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth - is left at 0 for automatic determination in BusLogic_SelectQueueDepths. - Initialize the Untagged Queue Depth. - */ - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) { - unsigned char QueueDepth = 0; - if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0) - QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID]; - else if (HostAdapter->BounceBuffersRequired) - QueueDepth = BusLogic_TaggedQueueDepthBB; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - } - if (HostAdapter->BounceBuffersRequired) - HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB; + Adapter requires that ISA Bounce Buffers be used. The Tagged Queue + Depth is left at 0 for automatic determination in + BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth. + */ + for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) { + unsigned char qdepth = 0; + if (adapter->drvr_opts != NULL && + adapter->drvr_opts->qdepth[tgt_id] > 0) + qdepth = adapter->drvr_opts->qdepth[tgt_id]; + else if (adapter->need_bouncebuf) + qdepth = BLOGIC_TAG_DEPTH_BB; + adapter->qdepth[tgt_id] = qdepth; + } + if (adapter->need_bouncebuf) + adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH_BB; else - HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth; - if (HostAdapter->DriverOptions != NULL) - HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth; - if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth) - HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth; + adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH; + if (adapter->drvr_opts != NULL) + adapter->common_qdepth = adapter->drvr_opts->common_qdepth; + if (adapter->common_qdepth > 0 && + adapter->common_qdepth < adapter->untag_qdepth) + adapter->untag_qdepth = adapter->common_qdepth; /* Tagged Queuing is only allowed if Disconnect/Reconnect is permitted. Therefore, mask the Tagged Queuing Permitted Default bits with the Disconnect/Reconnect Permitted bits. */ - HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted; + adapter->tagq_ok &= adapter->discon_ok; /* - Combine the default Tagged Queuing Permitted bits with any BusLogic Driver - Options Tagged Queuing specification. + Combine the default Tagged Queuing Permitted bits with any + BusLogic Driver Options Tagged Queuing specification. */ - if (HostAdapter->DriverOptions != NULL) - HostAdapter->TaggedQueuingPermitted = - (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask); + if (adapter->drvr_opts != NULL) + adapter->tagq_ok = (adapter->drvr_opts->tagq_ok & + adapter->drvr_opts->tagq_ok_mask) | + (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask); /* - Select an appropriate value for Bus Settle Time either from a BusLogic - Driver Options specification, or from BusLogic_DefaultBusSettleTime. + Select an appropriate value for Bus Settle Time either from a + BusLogic Driver Options specification, or from + BLOGIC_BUS_SETTLE_TIME. */ - if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0) - HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime; + if (adapter->drvr_opts != NULL && + adapter->drvr_opts->bus_settle_time > 0) + adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time; else - HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime; + adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME; /* - Indicate reading the Host Adapter Configuration completed successfully. + Indicate reading the Host Adapter Configuration completed + successfully. */ return true; } /* - BusLogic_ReportHostAdapterConfiguration reports the configuration of - Host Adapter. + blogic_reportconfig reports the configuration of Host Adapter. */ -static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter - *HostAdapter) +static bool __init blogic_reportconfig(struct blogic_adapter *adapter) { - unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; - unsigned short SynchronousPermitted, FastPermitted; - unsigned short UltraPermitted, WidePermitted; - unsigned short DisconnectPermitted, TaggedQueuingPermitted; - bool CommonSynchronousNegotiation, CommonTaggedQueueDepth; - char SynchronousString[BusLogic_MaxTargetDevices + 1]; - char WideString[BusLogic_MaxTargetDevices + 1]; - char DisconnectString[BusLogic_MaxTargetDevices + 1]; - char TaggedQueuingString[BusLogic_MaxTargetDevices + 1]; - char *SynchronousMessage = SynchronousString; - char *WideMessage = WideString; - char *DisconnectMessage = DisconnectString; - char *TaggedQueuingMessage = TaggedQueuingString; - int TargetID; - BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", - HostAdapter, HostAdapter->ModelName, - BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : "")); - BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", HostAdapter, HostAdapter->FirmwareVersion, HostAdapter->IO_Address, HostAdapter->IRQ_Channel, (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge")); - if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) { - BusLogic_Info(" DMA Channel: ", HostAdapter); - if (HostAdapter->DMA_Channel > 0) - BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel); + unsigned short alltgt_mask = (1 << adapter->maxdev) - 1; + unsigned short sync_ok, fast_ok; + unsigned short ultra_ok, wide_ok; + unsigned short discon_ok, tagq_ok; + bool common_syncneg, common_tagq_depth; + char syncstr[BLOGIC_MAXDEV + 1]; + char widestr[BLOGIC_MAXDEV + 1]; + char discon_str[BLOGIC_MAXDEV + 1]; + char tagq_str[BLOGIC_MAXDEV + 1]; + char *syncmsg = syncstr; + char *widemsg = widestr; + char *discon_msg = discon_str; + char *tagq_msg = tagq_str; + int tgt_id; + + blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : "")); + blogic_info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge")); + if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) { + blogic_info(" DMA Channel: ", adapter); + if (adapter->dma_ch > 0) + blogic_info("%d, ", adapter, adapter->dma_ch); else - BusLogic_Info("None, ", HostAdapter); - if (HostAdapter->BIOS_Address > 0) - BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address); + blogic_info("None, ", adapter); + if (adapter->bios_addr > 0) + blogic_info("BIOS Address: 0x%X, ", adapter, + adapter->bios_addr); else - BusLogic_Info("BIOS Address: None, ", HostAdapter); + blogic_info("BIOS Address: None, ", adapter); } else { - BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device); - if (HostAdapter->PCI_Address > 0) - BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address); + blogic_info(" PCI Bus: %d, Device: %d, Address: ", adapter, + adapter->bus, adapter->dev); + if (adapter->pci_addr > 0) + blogic_info("0x%X, ", adapter, adapter->pci_addr); else - BusLogic_Info("Unassigned, ", HostAdapter); - } - BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID); - BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled")); - AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID); - SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask; - FastPermitted = HostAdapter->FastPermitted & AllTargetsMask; - UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask; - if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) { - CommonSynchronousNegotiation = false; - if (SynchronousPermitted == 0) { - SynchronousMessage = "Disabled"; - CommonSynchronousNegotiation = true; - } else if (SynchronousPermitted == AllTargetsMask) { - if (FastPermitted == 0) { - SynchronousMessage = "Slow"; - CommonSynchronousNegotiation = true; - } else if (FastPermitted == AllTargetsMask) { - if (UltraPermitted == 0) { - SynchronousMessage = "Fast"; - CommonSynchronousNegotiation = true; - } else if (UltraPermitted == AllTargetsMask) { - SynchronousMessage = "Ultra"; - CommonSynchronousNegotiation = true; + blogic_info("Unassigned, ", adapter); + } + blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id); + blogic_info(" Parity Checking: %s, Extended Translation: %s\n", + adapter, (adapter->parity ? "Enabled" : "Disabled"), + (adapter->ext_trans_enable ? "Enabled" : "Disabled")); + alltgt_mask &= ~(1 << adapter->scsi_id); + sync_ok = adapter->sync_ok & alltgt_mask; + fast_ok = adapter->fast_ok & alltgt_mask; + ultra_ok = adapter->ultra_ok & alltgt_mask; + if ((blogic_multimaster_type(adapter) && + (adapter->fw_ver[0] >= '4' || + adapter->adapter_bus_type == BLOGIC_EISA_BUS)) || + blogic_flashpoint_type(adapter)) { + common_syncneg = false; + if (sync_ok == 0) { + syncmsg = "Disabled"; + common_syncneg = true; + } else if (sync_ok == alltgt_mask) { + if (fast_ok == 0) { + syncmsg = "Slow"; + common_syncneg = true; + } else if (fast_ok == alltgt_mask) { + if (ultra_ok == 0) { + syncmsg = "Fast"; + common_syncneg = true; + } else if (ultra_ok == alltgt_mask) { + syncmsg = "Ultra"; + common_syncneg = true; } } } - if (!CommonSynchronousNegotiation) { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U'))); - SynchronousString[HostAdapter->SCSI_ID] = '#'; - SynchronousString[HostAdapter->MaxTargetDevices] = '\0'; + if (!common_syncneg) { + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U'))); + syncstr[adapter->scsi_id] = '#'; + syncstr[adapter->maxdev] = '\0'; } } else - SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled"); - WidePermitted = HostAdapter->WidePermitted & AllTargetsMask; - if (WidePermitted == 0) - WideMessage = "Disabled"; - else if (WidePermitted == AllTargetsMask) - WideMessage = "Enabled"; + syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled"); + wide_ok = adapter->wide_ok & alltgt_mask; + if (wide_ok == 0) + widemsg = "Disabled"; + else if (wide_ok == alltgt_mask) + widemsg = "Enabled"; else { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N'); - WideString[HostAdapter->SCSI_ID] = '#'; - WideString[HostAdapter->MaxTargetDevices] = '\0'; - } - DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask; - if (DisconnectPermitted == 0) - DisconnectMessage = "Disabled"; - else if (DisconnectPermitted == AllTargetsMask) - DisconnectMessage = "Enabled"; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N'); + widestr[adapter->scsi_id] = '#'; + widestr[adapter->maxdev] = '\0'; + } + discon_ok = adapter->discon_ok & alltgt_mask; + if (discon_ok == 0) + discon_msg = "Disabled"; + else if (discon_ok == alltgt_mask) + discon_msg = "Enabled"; else { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N'); - DisconnectString[HostAdapter->SCSI_ID] = '#'; - DisconnectString[HostAdapter->MaxTargetDevices] = '\0'; - } - TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask; - if (TaggedQueuingPermitted == 0) - TaggedQueuingMessage = "Disabled"; - else if (TaggedQueuingPermitted == AllTargetsMask) - TaggedQueuingMessage = "Enabled"; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N'); + discon_str[adapter->scsi_id] = '#'; + discon_str[adapter->maxdev] = '\0'; + } + tagq_ok = adapter->tagq_ok & alltgt_mask; + if (tagq_ok == 0) + tagq_msg = "Disabled"; + else if (tagq_ok == alltgt_mask) + tagq_msg = "Enabled"; else { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N'); - TaggedQueuingString[HostAdapter->SCSI_ID] = '#'; - TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0'; - } - BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage); - BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage); - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { - BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount); - BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth); + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N'); + tagq_str[adapter->scsi_id] = '#'; + tagq_str[adapter->maxdev] = '\0'; + } + blogic_info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", + adapter, syncmsg, widemsg); + blogic_info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter, + discon_msg, tagq_msg); + if (blogic_multimaster_type(adapter)) { + blogic_info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count); + blogic_info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth); } else - BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit); - BusLogic_Info(" Tagged Queue Depth: ", HostAdapter); - CommonTaggedQueueDepth = true; - for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) { - CommonTaggedQueueDepth = false; + blogic_info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit); + blogic_info(" Tagged Queue Depth: ", adapter); + common_tagq_depth = true; + for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++) + if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) { + common_tagq_depth = false; break; } - if (CommonTaggedQueueDepth) { - if (HostAdapter->QueueDepth[0] > 0) - BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]); + if (common_tagq_depth) { + if (adapter->qdepth[0] > 0) + blogic_info("%d", adapter, adapter->qdepth[0]); else - BusLogic_Info("Automatic", HostAdapter); + blogic_info("Automatic", adapter); } else - BusLogic_Info("Individual", HostAdapter); - BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth); - if (HostAdapter->TerminationInfoValid) { - if (HostAdapter->HostWideSCSI) - BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled") - : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled"))); + blogic_info("Individual", adapter); + blogic_info(", Untagged Queue Depth: %d\n", adapter, + adapter->untag_qdepth); + if (adapter->terminfo_valid) { + if (adapter->wide) + blogic_info(" SCSI Bus Termination: %s", adapter, + (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled"))); else - BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled")); - if (HostAdapter->HostSupportsSCAM) - BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1") - : "Disabled")); - BusLogic_Info("\n", HostAdapter); + blogic_info(" SCSI Bus Termination: %s", adapter, + (adapter->low_term ? "Enabled" : "Disabled")); + if (adapter->scam) + blogic_info(", SCAM: %s", adapter, + (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled")); + blogic_info("\n", adapter); } /* - Indicate reporting the Host Adapter configuration completed successfully. + Indicate reporting the Host Adapter configuration completed + successfully. */ return true; } /* - BusLogic_AcquireResources acquires the system resources necessary to use + blogic_getres acquires the system resources necessary to use Host Adapter. */ -static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter) +static bool __init blogic_getres(struct blogic_adapter *adapter) { - if (HostAdapter->IRQ_Channel == 0) { - BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter); + if (adapter->irq_ch == 0) { + blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", + adapter); return false; } /* Acquire shared access to the IRQ Channel. */ - if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) { - BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel); + if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED, + adapter->full_model, adapter) < 0) { + blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", + adapter, adapter->irq_ch); return false; } - HostAdapter->IRQ_ChannelAcquired = true; + adapter->irq_acquired = true; /* Acquire exclusive access to the DMA Channel. */ - if (HostAdapter->DMA_Channel > 0) { - if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) { - BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel); + if (adapter->dma_ch > 0) { + if (request_dma(adapter->dma_ch, adapter->full_model) < 0) { + blogic_err("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", adapter, adapter->dma_ch); return false; } - set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE); - enable_dma(HostAdapter->DMA_Channel); - HostAdapter->DMA_ChannelAcquired = true; + set_dma_mode(adapter->dma_ch, DMA_MODE_CASCADE); + enable_dma(adapter->dma_ch); + adapter->dma_chan_acquired = true; } /* Indicate the System Resource Acquisition completed successfully, @@ -1874,127 +2018,146 @@ static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAd /* - BusLogic_ReleaseResources releases any system resources previously acquired - by BusLogic_AcquireResources. + blogic_relres releases any system resources previously acquired + by blogic_getres. */ -static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter) +static void blogic_relres(struct blogic_adapter *adapter) { /* Release shared access to the IRQ Channel. */ - if (HostAdapter->IRQ_ChannelAcquired) - free_irq(HostAdapter->IRQ_Channel, HostAdapter); + if (adapter->irq_acquired) + free_irq(adapter->irq_ch, adapter); /* Release exclusive access to the DMA Channel. */ - if (HostAdapter->DMA_ChannelAcquired) - free_dma(HostAdapter->DMA_Channel); + if (adapter->dma_chan_acquired) + free_dma(adapter->dma_ch); /* Release any allocated memory structs not released elsewhere */ - if (HostAdapter->MailboxSpace) - pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle); - pci_dev_put(HostAdapter->PCI_Device); - HostAdapter->MailboxSpace = NULL; - HostAdapter->MailboxSpaceHandle = 0; - HostAdapter->MailboxSize = 0; + if (adapter->mbox_space) + pci_free_consistent(adapter->pci_device, adapter->mbox_sz, + adapter->mbox_space, adapter->mbox_space_handle); + pci_dev_put(adapter->pci_device); + adapter->mbox_space = NULL; + adapter->mbox_space_handle = 0; + adapter->mbox_sz = 0; } /* - BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only + blogic_initadapter initializes Host Adapter. This is the only function called during SCSI Host Adapter detection which modifies the state of the Host Adapter from its initial power on or hard reset state. */ -static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter - *HostAdapter) +static bool blogic_initadapter(struct blogic_adapter *adapter) { - struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest; - enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest; - enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest; - int TargetID; + struct blogic_extmbox_req extmbox_req; + enum blogic_rr_req rr_req; + enum blogic_setccb_fmt setccb_fmt; + int tgt_id; + /* - Initialize the pointers to the first and last CCBs that are queued for - completion processing. + Initialize the pointers to the first and last CCBs that are + queued for completion processing. */ - HostAdapter->FirstCompletedCCB = NULL; - HostAdapter->LastCompletedCCB = NULL; + adapter->firstccb = NULL; + adapter->lastccb = NULL; + /* Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active, Command Successful Flag, Active Commands, and Commands Since Reset for each Target Device. */ - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; - HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; - HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false; - HostAdapter->ActiveCommands[TargetID] = 0; - HostAdapter->CommandsSinceReset[TargetID] = 0; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) { + adapter->bdr_pend[tgt_id] = NULL; + adapter->tgt_flags[tgt_id].tagq_active = false; + adapter->tgt_flags[tgt_id].cmd_good = false; + adapter->active_cmds[tgt_id] = 0; + adapter->cmds_since_rst[tgt_id] = 0; } + /* FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - goto Done; + if (blogic_flashpoint_type(adapter)) + goto done; + /* Initialize the Outgoing and Incoming Mailbox pointers. */ - HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox)); - HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle); - if (HostAdapter->MailboxSpace == NULL) - return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION"); - HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace; - HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1; - HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; - HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1); - HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1; - HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; + adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox)); + adapter->mbox_space = pci_alloc_consistent(adapter->pci_device, + adapter->mbox_sz, &adapter->mbox_space_handle); + if (adapter->mbox_space == NULL) + return blogic_failure(adapter, "MAILBOX ALLOCATION"); + adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space; + adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1; + adapter->next_outbox = adapter->first_outbox; + adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1); + adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1; + adapter->next_inbox = adapter->first_inbox; /* Initialize the Outgoing and Incoming Mailbox structures. */ - memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox)); - memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox)); + memset(adapter->first_outbox, 0, + adapter->mbox_count * sizeof(struct blogic_outbox)); + memset(adapter->first_inbox, 0, + adapter->mbox_count * sizeof(struct blogic_inbox)); + /* - Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes. + Initialize the Host Adapter's Pointer to the Outgoing/Incoming + Mailboxes. */ - ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount; - ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle; - if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION"); + extmbox_req.mbox_count = adapter->mbox_count; + extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle; + if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req, + sizeof(extmbox_req), NULL, 0) < 0) + return blogic_failure(adapter, "MAILBOX INITIALIZATION"); /* - Enable Strict Round Robin Mode if supported by the Host Adapter. In - Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing - Mailbox for each new command, rather than scanning through all the - Outgoing Mailboxes to find any that have new commands in them. Strict - Round Robin Mode is significantly more efficient. + Enable Strict Round Robin Mode if supported by the Host Adapter. In + Strict Round Robin Mode, the Host Adapter only looks at the next + Outgoing Mailbox for each new command, rather than scanning + through all the Outgoing Mailboxes to find any that have new + commands in them. Strict Round Robin Mode is significantly more + efficient. */ - if (HostAdapter->StrictRoundRobinModeSupport) { - RoundRobinModeRequest = BusLogic_StrictRoundRobinMode; - if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE"); + if (adapter->strict_rr) { + rr_req = BLOGIC_STRICT_RR_MODE; + if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req, + sizeof(rr_req), NULL, 0) < 0) + return blogic_failure(adapter, + "ENABLE STRICT ROUND ROBIN MODE"); } + /* - For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB - Format command to allow 32 Logical Units per Target Device. + For Host Adapters that support Extended LUN Format CCBs, issue the + Set CCB Format command to allow 32 Logical Units per Target Device. */ - if (HostAdapter->ExtendedLUNSupport) { - SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB; - if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "SET CCB FORMAT"); + if (adapter->ext_lun) { + setccb_fmt = BLOGIC_EXT_LUN_CCB; + if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt, + sizeof(setccb_fmt), NULL, 0) < 0) + return blogic_failure(adapter, "SET CCB FORMAT"); } + /* Announce Successful Initialization. */ - Done: - if (!HostAdapter->HostAdapterInitialized) { - BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName); - BusLogic_Info("\n", HostAdapter); +done: + if (!adapter->adapter_initd) { + blogic_info("*** %s Initialized Successfully ***\n", adapter, + adapter->full_model); + blogic_info("\n", adapter); } else - BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName); - HostAdapter->HostAdapterInitialized = true; + blogic_warn("*** %s Initialized Successfully ***\n", adapter, + adapter->full_model); + adapter->adapter_initd = true; + /* Indicate the Host Adapter Initialization completed successfully. */ @@ -2003,109 +2166,116 @@ static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter /* - BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible + blogic_inquiry inquires about the Target Devices accessible through Host Adapter. */ -static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter - *HostAdapter) +static bool __init blogic_inquiry(struct blogic_adapter *adapter) { - u16 InstalledDevices; - u8 InstalledDevicesID0to7[8]; - struct BusLogic_SetupInformation SetupInformation; - u8 SynchronousPeriod[BusLogic_MaxTargetDevices]; - unsigned char RequestedReplyLength; - int TargetID; + u16 installed_devs; + u8 installed_devs0to7[8]; + struct blogic_setup_info setupinfo; + u8 sync_period[BLOGIC_MAXDEV]; + unsigned char req_replylen; + int tgt_id; + /* - Wait a few seconds between the Host Adapter Hard Reset which initiates - a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get - confused if they receive SCSI Commands too soon after a SCSI Bus Reset. + Wait a few seconds between the Host Adapter Hard Reset which + initiates a SCSI Bus Reset and issuing any SCSI Commands. Some + SCSI devices get confused if they receive SCSI Commands too soon + after a SCSI Bus Reset. */ - BusLogic_Delay(HostAdapter->BusSettleTime); + blogic_delay(adapter->bus_settle_time); /* FlashPoint Host Adapters do not provide for Target Device Inquiry. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + if (blogic_flashpoint_type(adapter)) return true; /* Inhibit the Target Device Inquiry if requested. */ - if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry) + if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry) return true; /* - Issue the Inquire Target Devices command for host adapters with firmware - version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command - for older host adapters. This is necessary to force Synchronous Transfer - Negotiation so that the Inquire Setup Information and Inquire Synchronous - Period commands will return valid data. The Inquire Target Devices command - is preferable to Inquire Installed Devices ID 0 to 7 since it only probes - Logical Unit 0 of each Target Device. + Issue the Inquire Target Devices command for host adapters with + firmware version 4.25 or later, or the Inquire Installed Devices + ID 0 to 7 command for older host adapters. This is necessary to + force Synchronous Transfer Negotiation so that the Inquire Setup + Information and Inquire Synchronous Period commands will return + valid data. The Inquire Target Devices command is preferable to + Inquire Installed Devices ID 0 to 7 since it only probes Logical + Unit 0 of each Target Device. */ - if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) { + if (strcmp(adapter->fw_ver, "4.25") >= 0) { /* - * Issue a Inquire Target Devices command. Inquire Target Devices only - * tests Logical Unit 0 of each Target Device unlike the Inquire Installed - * Devices commands which test Logical Units 0 - 7. Two bytes are - * returned, where byte 0 bit 0 set indicates that Target Device 0 exists, - * and so on. + Issue a Inquire Target Devices command. Inquire Target + Devices only tests Logical Unit 0 of each Target Device + unlike the Inquire Installed Devices commands which test + Logical Units 0 - 7. Two bytes are returned, where byte + 0 bit 0 set indicates that Target Device 0 exists, and so on. */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices)) - != sizeof(InstalledDevices)) - return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false); + if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0, + &installed_devs, sizeof(installed_devs)) + != sizeof(installed_devs)) + return blogic_failure(adapter, "INQUIRE TARGET DEVICES"); + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + adapter->tgt_flags[tgt_id].tgt_exists = + (installed_devs & (1 << tgt_id) ? true : false); } else { /* - * Issue an Inquire Installed Devices command. For each Target Device, - * a byte is returned where bit 0 set indicates that Logical Unit 0 - * exists, bit 1 set indicates that Logical Unit 1 exists, and so on. + Issue an Inquire Installed Devices command. For each + Target Device, a byte is returned where bit 0 set + indicates that Logical Unit 0 * exists, bit 1 set + indicates that Logical Unit 1 exists, and so on. */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7)) - != sizeof(InstalledDevicesID0to7)) - return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7"); - for (TargetID = 0; TargetID < 8; TargetID++) - HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false); + if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0, + &installed_devs0to7, sizeof(installed_devs0to7)) + != sizeof(installed_devs0to7)) + return blogic_failure(adapter, + "INQUIRE INSTALLED DEVICES ID 0 TO 7"); + for (tgt_id = 0; tgt_id < 8; tgt_id++) + adapter->tgt_flags[tgt_id].tgt_exists = + (installed_devs0to7[tgt_id] != 0 ? true : false); } /* Issue the Inquire Setup Information command. */ - RequestedReplyLength = sizeof(SetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation)) - != sizeof(SetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset); - if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0) - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID) - ? true : false) - : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8)) - ? true : false)); + req_replylen = sizeof(setupinfo); + if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen, + sizeof(req_replylen), &setupinfo, sizeof(setupinfo)) + != sizeof(setupinfo)) + return blogic_failure(adapter, "INQUIRE SETUP INFORMATION"); + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset); + if (strcmp(adapter->fw_ver, "5.06L") >= 0) + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false)); /* Issue the Inquire Synchronous Period command. */ - if (HostAdapter->FirmwareVersion[0] >= '3') { + if (adapter->fw_ver[0] >= '3') { - /* Issue a Inquire Synchronous Period command. For each Target Device, - * a byte is returned which represents the Synchronous Transfer Period - * in units of 10 nanoseconds. + /* Issue a Inquire Synchronous Period command. For each + Target Device, a byte is returned which represents the + Synchronous Transfer Period in units of 10 nanoseconds. */ - RequestedReplyLength = sizeof(SynchronousPeriod); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod)) - != sizeof(SynchronousPeriod)) - return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID]; + req_replylen = sizeof(sync_period); + if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen, + sizeof(req_replylen), &sync_period, + sizeof(sync_period)) != sizeof(sync_period)) + return blogic_failure(adapter, + "INQUIRE SYNCHRONOUS PERIOD"); + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + adapter->sync_period[tgt_id] = sync_period[tgt_id]; } else - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0) - HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID] - .TransferPeriod; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + if (setupinfo.sync0to7[tgt_id].offset > 0) + adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period; /* Indicate the Target Device Inquiry completed successfully. */ @@ -2113,7 +2283,7 @@ static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter } /* - BusLogic_InitializeHostStructure initializes the fields in the SCSI Host + blogic_inithoststruct initializes the fields in the SCSI Host structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the SCSI Host structure are intentionally left uninitialized, as this driver handles acquisition and release of these resources explicitly, as well as @@ -2121,517 +2291,556 @@ static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter through explicit acquisition and release of the Host Adapter's Lock. */ -static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter - *HostAdapter, struct Scsi_Host *Host) +static void __init blogic_inithoststruct(struct blogic_adapter *adapter, + struct Scsi_Host *host) { - Host->max_id = HostAdapter->MaxTargetDevices; - Host->max_lun = HostAdapter->MaxLogicalUnits; - Host->max_channel = 0; - Host->unique_id = HostAdapter->IO_Address; - Host->this_id = HostAdapter->SCSI_ID; - Host->can_queue = HostAdapter->DriverQueueDepth; - Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit; - Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired; - Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth; + host->max_id = adapter->maxdev; + host->max_lun = adapter->maxlun; + host->max_channel = 0; + host->unique_id = adapter->io_addr; + host->this_id = adapter->scsi_id; + host->can_queue = adapter->drvr_qdepth; + host->sg_tablesize = adapter->drvr_sglimit; + host->unchecked_isa_dma = adapter->need_bouncebuf; + host->cmd_per_lun = adapter->untag_qdepth; } /* - BusLogic_SlaveConfigure will actually set the queue depth on individual + blogic_slaveconfig will actually set the queue depth on individual scsi devices as they are permanently added to the device chain. We shamelessly rip off the SelectQueueDepths code to make this work mostly like it used to. Since we don't get called once at the end of the scan but instead get called for each device, we have to do things a bit differently. */ -static int BusLogic_SlaveConfigure(struct scsi_device *Device) +static int blogic_slaveconfig(struct scsi_device *dev) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata; - int TargetID = Device->id; - int QueueDepth = HostAdapter->QueueDepth[TargetID]; - - if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) { - if (QueueDepth == 0) - QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth); + struct blogic_adapter *adapter = + (struct blogic_adapter *) dev->host->hostdata; + int tgt_id = dev->id; + int qdepth = adapter->qdepth[tgt_id]; + + if (adapter->tgt_flags[tgt_id].tagq_ok && + (adapter->tagq_ok & (1 << tgt_id))) { + if (qdepth == 0) + qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH; + adapter->qdepth[tgt_id] = qdepth; + scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, qdepth); } else { - HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID); - QueueDepth = HostAdapter->UntaggedQueueDepth; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - scsi_adjust_queue_depth(Device, 0, QueueDepth); - } - QueueDepth = 0; - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (HostAdapter->TargetFlags[TargetID].TargetExists) { - QueueDepth += HostAdapter->QueueDepth[TargetID]; - } - if (QueueDepth > HostAdapter->AllocatedCCBs) - BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false); + adapter->tagq_ok &= ~(1 << tgt_id); + qdepth = adapter->untag_qdepth; + adapter->qdepth[tgt_id] = qdepth; + scsi_adjust_queue_depth(dev, 0, qdepth); + } + qdepth = 0; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) + if (adapter->tgt_flags[tgt_id].tgt_exists) + qdepth += adapter->qdepth[tgt_id]; + if (qdepth > adapter->alloc_ccbs) + blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs, + false); return 0; } /* - BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard + blogic_init probes for BusLogic Host Adapters at the standard I/O Addresses where they may be located, initializing, registering, and reporting the configuration of each BusLogic Host Adapter it finds. It returns the number of BusLogic Host Adapters successfully initialized and registered. */ -static int __init BusLogic_init(void) +static int __init blogic_init(void) { - int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex; - struct BusLogic_HostAdapter *PrototypeHostAdapter; + int adapter_count = 0, drvr_optindex = 0, probeindex; + struct blogic_adapter *adapter; int ret = 0; #ifdef MODULE if (BusLogic) - BusLogic_Setup(BusLogic); + blogic_setup(BusLogic); #endif - if (BusLogic_ProbeOptions.NoProbe) + if (blogic_probe_options.noprobe) return -ENODEV; - BusLogic_ProbeInfoList = - kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL); - if (BusLogic_ProbeInfoList == NULL) { - BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); + blogic_probeinfo_list = + kzalloc(BLOGIC_MAX_ADAPTERS * sizeof(struct blogic_probeinfo), + GFP_KERNEL); + if (blogic_probeinfo_list == NULL) { + blogic_err("BusLogic: Unable to allocate Probe Info List\n", + NULL); return -ENOMEM; } - PrototypeHostAdapter = - kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL); - if (PrototypeHostAdapter == NULL) { - kfree(BusLogic_ProbeInfoList); - BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); + adapter = + kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL); + if (adapter == NULL) { + kfree(blogic_probeinfo_list); + blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL); return -ENOMEM; } #ifdef MODULE if (BusLogic != NULL) - BusLogic_Setup(BusLogic); + blogic_setup(BusLogic); #endif - BusLogic_InitializeProbeInfoList(PrototypeHostAdapter); - for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex]; - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct Scsi_Host *Host; - if (ProbeInfo->IO_Address == 0) + blogic_init_probeinfo_list(adapter); + for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) { + struct blogic_probeinfo *probeinfo = + &blogic_probeinfo_list[probeindex]; + struct blogic_adapter *myadapter = adapter; + struct Scsi_Host *host; + + if (probeinfo->io_addr == 0) continue; - memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); - HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType; - HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType; - HostAdapter->IO_Address = ProbeInfo->IO_Address; - HostAdapter->PCI_Address = ProbeInfo->PCI_Address; - HostAdapter->Bus = ProbeInfo->Bus; - HostAdapter->Device = ProbeInfo->Device; - HostAdapter->PCI_Device = ProbeInfo->PCI_Device; - HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel; - HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType]; + memset(myadapter, 0, sizeof(struct blogic_adapter)); + myadapter->adapter_type = probeinfo->adapter_type; + myadapter->adapter_bus_type = probeinfo->adapter_bus_type; + myadapter->io_addr = probeinfo->io_addr; + myadapter->pci_addr = probeinfo->pci_addr; + myadapter->bus = probeinfo->bus; + myadapter->dev = probeinfo->dev; + myadapter->pci_device = probeinfo->pci_device; + myadapter->irq_ch = probeinfo->irq_ch; + myadapter->addr_count = + blogic_adapter_addr_count[myadapter->adapter_type]; /* Make sure region is free prior to probing. */ - if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, + if (!request_region(myadapter->io_addr, myadapter->addr_count, "BusLogic")) continue; /* - Probe the Host Adapter. If unsuccessful, abort further initialization. + Probe the Host Adapter. If unsuccessful, abort further + initialization. */ - if (!BusLogic_ProbeHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!blogic_probe(myadapter)) { + release_region(myadapter->io_addr, + myadapter->addr_count); continue; } /* Hard Reset the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!blogic_hwreset(myadapter, true)) { + release_region(myadapter->io_addr, + myadapter->addr_count); continue; } /* - Check the Host Adapter. If unsuccessful, abort further initialization. + Check the Host Adapter. If unsuccessful, abort further + initialization. */ - if (!BusLogic_CheckHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!blogic_checkadapter(myadapter)) { + release_region(myadapter->io_addr, + myadapter->addr_count); continue; } /* Initialize the Driver Options field if provided. */ - if (DriverOptionsIndex < BusLogic_DriverOptionsCount) - HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++]; + if (drvr_optindex < blogic_drvr_options_count) + myadapter->drvr_opts = + &blogic_drvr_options[drvr_optindex++]; /* - Announce the Driver Version and Date, Author's Name, Copyright Notice, - and Electronic Mail Address. + Announce the Driver Version and Date, Author's Name, + Copyright Notice, and Electronic Mail Address. */ - BusLogic_AnnounceDriver(HostAdapter); + blogic_announce_drvr(myadapter); /* Register the SCSI Host structure. */ - Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter)); - if (Host == NULL) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + host = scsi_host_alloc(&blogic_template, + sizeof(struct blogic_adapter)); + if (host == NULL) { + release_region(myadapter->io_addr, + myadapter->addr_count); continue; } - HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; - memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter)); - HostAdapter->SCSI_Host = Host; - HostAdapter->HostNumber = Host->host_no; + myadapter = (struct blogic_adapter *) host->hostdata; + memcpy(myadapter, adapter, sizeof(struct blogic_adapter)); + myadapter->scsi_host = host; + myadapter->host_no = host->host_no; /* - Add Host Adapter to the end of the list of registered BusLogic - Host Adapters. + Add Host Adapter to the end of the list of registered + BusLogic Host Adapters. */ - list_add_tail(&HostAdapter->host_list, &BusLogic_host_list); + list_add_tail(&myadapter->host_list, &blogic_host_list); /* - Read the Host Adapter Configuration, Configure the Host Adapter, - Acquire the System Resources necessary to use the Host Adapter, then - Create the Initial CCBs, Initialize the Host Adapter, and finally - perform Target Device Inquiry. - - From this point onward, any failure will be assumed to be due to a - problem with the Host Adapter, rather than due to having mistakenly - identified this port as belonging to a BusLogic Host Adapter. The - I/O Address range will not be released, thereby preventing it from - being incorrectly identified as any other type of Host Adapter. + Read the Host Adapter Configuration, Configure the Host + Adapter, Acquire the System Resources necessary to use + the Host Adapter, then Create the Initial CCBs, Initialize + the Host Adapter, and finally perform Target Device + Inquiry. From this point onward, any failure will be + assumed to be due to a problem with the Host Adapter, + rather than due to having mistakenly identified this port + as belonging to a BusLogic Host Adapter. The I/O Address + range will not be released, thereby preventing it from + being incorrectly identified as any other type of Host + Adapter. */ - if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) && - BusLogic_ReportHostAdapterConfiguration(HostAdapter) && - BusLogic_AcquireResources(HostAdapter) && - BusLogic_CreateInitialCCBs(HostAdapter) && - BusLogic_InitializeHostAdapter(HostAdapter) && - BusLogic_TargetDeviceInquiry(HostAdapter)) { + if (blogic_rdconfig(myadapter) && + blogic_reportconfig(myadapter) && + blogic_getres(myadapter) && + blogic_create_initccbs(myadapter) && + blogic_initadapter(myadapter) && + blogic_inquiry(myadapter)) { /* - Initialization has been completed successfully. Release and - re-register usage of the I/O Address range so that the Model - Name of the Host Adapter will appear, and initialize the SCSI - Host structure. + Initialization has been completed successfully. + Release and re-register usage of the I/O Address + range so that the Model Name of the Host Adapter + will appear, and initialize the SCSI Host structure. */ - release_region(HostAdapter->IO_Address, - HostAdapter->AddressCount); - if (!request_region(HostAdapter->IO_Address, - HostAdapter->AddressCount, - HostAdapter->FullModelName)) { + release_region(myadapter->io_addr, + myadapter->addr_count); + if (!request_region(myadapter->io_addr, + myadapter->addr_count, + myadapter->full_model)) { printk(KERN_WARNING "BusLogic: Release and re-register of " "port 0x%04lx failed \n", - (unsigned long)HostAdapter->IO_Address); - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - list_del(&HostAdapter->host_list); - scsi_host_put(Host); + (unsigned long)myadapter->io_addr); + blogic_destroy_ccbs(myadapter); + blogic_relres(myadapter); + list_del(&myadapter->host_list); + scsi_host_put(host); ret = -ENOMEM; } else { - BusLogic_InitializeHostStructure(HostAdapter, - Host); - if (scsi_add_host(Host, HostAdapter->PCI_Device - ? &HostAdapter->PCI_Device->dev + blogic_inithoststruct(myadapter, + host); + if (scsi_add_host(host, myadapter->pci_device + ? &myadapter->pci_device->dev : NULL)) { printk(KERN_WARNING "BusLogic: scsi_add_host()" "failed!\n"); - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - list_del(&HostAdapter->host_list); - scsi_host_put(Host); + blogic_destroy_ccbs(myadapter); + blogic_relres(myadapter); + list_del(&myadapter->host_list); + scsi_host_put(host); ret = -ENODEV; } else { - scsi_scan_host(Host); - BusLogicHostAdapterCount++; + scsi_scan_host(host); + adapter_count++; } } } else { /* - An error occurred during Host Adapter Configuration Querying, Host - Adapter Configuration, Resource Acquisition, CCB Creation, Host - Adapter Initialization, or Target Device Inquiry, so remove Host - Adapter from the list of registered BusLogic Host Adapters, destroy - the CCBs, Release the System Resources, and Unregister the SCSI + An error occurred during Host Adapter Configuration + Querying, Host Adapter Configuration, Resource + Acquisition, CCB Creation, Host Adapter + Initialization, or Target Device Inquiry, so + remove Host Adapter from the list of registered + BusLogic Host Adapters, destroy the CCBs, Release + the System Resources, and Unregister the SCSI Host. */ - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - list_del(&HostAdapter->host_list); - scsi_host_put(Host); + blogic_destroy_ccbs(myadapter); + blogic_relres(myadapter); + list_del(&myadapter->host_list); + scsi_host_put(host); ret = -ENODEV; } } - kfree(PrototypeHostAdapter); - kfree(BusLogic_ProbeInfoList); - BusLogic_ProbeInfoList = NULL; + kfree(adapter); + kfree(blogic_probeinfo_list); + blogic_probeinfo_list = NULL; return ret; } /* - BusLogic_ReleaseHostAdapter releases all resources previously acquired to + blogic_deladapter releases all resources previously acquired to support a specific Host Adapter, including the I/O Address range, and unregisters the BusLogic Host Adapter. */ -static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter) +static int __exit blogic_deladapter(struct blogic_adapter *adapter) { - struct Scsi_Host *Host = HostAdapter->SCSI_Host; + struct Scsi_Host *host = adapter->scsi_host; - scsi_remove_host(Host); + scsi_remove_host(host); /* FlashPoint Host Adapters must first be released by the FlashPoint SCCB Manager. */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle); + if (blogic_flashpoint_type(adapter)) + FlashPoint_ReleaseHostAdapter(adapter->cardhandle); /* Destroy the CCBs and release any system resources acquired to support Host Adapter. */ - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); + blogic_destroy_ccbs(adapter); + blogic_relres(adapter); /* Release usage of the I/O Address range. */ - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + release_region(adapter->io_addr, adapter->addr_count); /* - Remove Host Adapter from the list of registered BusLogic Host Adapters. + Remove Host Adapter from the list of registered BusLogic + Host Adapters. */ - list_del(&HostAdapter->host_list); + list_del(&adapter->host_list); - scsi_host_put(Host); + scsi_host_put(host); return 0; } /* - BusLogic_QueueCompletedCCB queues CCB for completion processing. + blogic_qcompleted_ccb queues CCB for completion processing. */ -static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB) +static void blogic_qcompleted_ccb(struct blogic_ccb *ccb) { - struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; - CCB->Status = BusLogic_CCB_Completed; - CCB->Next = NULL; - if (HostAdapter->FirstCompletedCCB == NULL) { - HostAdapter->FirstCompletedCCB = CCB; - HostAdapter->LastCompletedCCB = CCB; + struct blogic_adapter *adapter = ccb->adapter; + + ccb->status = BLOGIC_CCB_COMPLETE; + ccb->next = NULL; + if (adapter->firstccb == NULL) { + adapter->firstccb = ccb; + adapter->lastccb = ccb; } else { - HostAdapter->LastCompletedCCB->Next = CCB; - HostAdapter->LastCompletedCCB = CCB; + adapter->lastccb->next = ccb; + adapter->lastccb = ccb; } - HostAdapter->ActiveCommands[CCB->TargetID]--; + adapter->active_cmds[ccb->tgt_id]--; } /* - BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from + blogic_resultcode computes a SCSI Subsystem Result Code from the Host Adapter Status and Target Device Status. */ -static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus) +static int blogic_resultcode(struct blogic_adapter *adapter, + enum blogic_adapter_status adapter_status, + enum blogic_tgt_status tgt_status) { - int HostStatus; - switch (HostAdapterStatus) { - case BusLogic_CommandCompletedNormally: - case BusLogic_LinkedCommandCompleted: - case BusLogic_LinkedCommandCompletedWithFlag: - HostStatus = DID_OK; + int hoststatus; + + switch (adapter_status) { + case BLOGIC_CMD_CMPLT_NORMAL: + case BLOGIC_LINK_CMD_CMPLT: + case BLOGIC_LINK_CMD_CMPLT_FLAG: + hoststatus = DID_OK; break; - case BusLogic_SCSISelectionTimeout: - HostStatus = DID_TIME_OUT; + case BLOGIC_SELECT_TIMEOUT: + hoststatus = DID_TIME_OUT; break; - case BusLogic_InvalidOutgoingMailboxActionCode: - case BusLogic_InvalidCommandOperationCode: - case BusLogic_InvalidCommandParameter: - BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus); - case BusLogic_DataUnderRun: - case BusLogic_DataOverRun: - case BusLogic_UnexpectedBusFree: - case BusLogic_LinkedCCBhasInvalidLUN: - case BusLogic_AutoRequestSenseFailed: - case BusLogic_TaggedQueuingMessageRejected: - case BusLogic_UnsupportedMessageReceived: - case BusLogic_HostAdapterHardwareFailed: - case BusLogic_TargetDeviceReconnectedImproperly: - case BusLogic_AbortQueueGenerated: - case BusLogic_HostAdapterSoftwareError: - case BusLogic_HostAdapterHardwareTimeoutError: - case BusLogic_SCSIParityErrorDetected: - HostStatus = DID_ERROR; + case BLOGIC_INVALID_OUTBOX_CODE: + case BLOGIC_INVALID_CMD_CODE: + case BLOGIC_BAD_CMD_PARAM: + blogic_warn("BusLogic Driver Protocol Error 0x%02X\n", + adapter, adapter_status); + case BLOGIC_DATA_UNDERRUN: + case BLOGIC_DATA_OVERRUN: + case BLOGIC_NOEXPECT_BUSFREE: + case BLOGIC_LINKCCB_BADLUN: + case BLOGIC_AUTOREQSENSE_FAIL: + case BLOGIC_TAGQUEUE_REJECT: + case BLOGIC_BAD_MSG_RCVD: + case BLOGIC_HW_FAIL: + case BLOGIC_BAD_RECONNECT: + case BLOGIC_ABRT_QUEUE: + case BLOGIC_ADAPTER_SW_ERROR: + case BLOGIC_HW_TIMEOUT: + case BLOGIC_PARITY_ERR: + hoststatus = DID_ERROR; break; - case BusLogic_InvalidBusPhaseRequested: - case BusLogic_TargetFailedResponseToATN: - case BusLogic_HostAdapterAssertedRST: - case BusLogic_OtherDeviceAssertedRST: - case BusLogic_HostAdapterAssertedBusDeviceReset: - HostStatus = DID_RESET; + case BLOGIC_INVALID_BUSPHASE: + case BLOGIC_NORESPONSE_TO_ATN: + case BLOGIC_HW_RESET: + case BLOGIC_RST_FROM_OTHERDEV: + case BLOGIC_HW_BDR: + hoststatus = DID_RESET; break; default: - BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus); - HostStatus = DID_ERROR; + blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter, + adapter_status); + hoststatus = DID_ERROR; break; } - return (HostStatus << 16) | TargetDeviceStatus; + return (hoststatus << 16) | tgt_status; } /* - BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any + blogic_scan_inbox scans the Incoming Mailboxes saving any Incoming Mailbox entries for completion processing. */ -static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter) +static void blogic_scan_inbox(struct blogic_adapter *adapter) { /* - Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving - any completed CCBs for further processing. It is essential that for each - CCB and SCSI Command issued, command completion processing is performed - exactly once. Therefore, only Incoming Mailboxes with completion code - Command Completed Without Error, Command Completed With Error, or Command - Aborted At Host Request are saved for completion processing. When an - Incoming Mailbox has a completion code of Aborted Command Not Found, the - CCB had already completed or been aborted before the current Abort request - was processed, and so completion processing has already occurred and no - further action should be taken. - */ - struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox; - enum BusLogic_CompletionCode CompletionCode; - while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) { + Scan through the Incoming Mailboxes in Strict Round Robin + fashion, saving any completed CCBs for further processing. It + is essential that for each CCB and SCSI Command issued, command + completion processing is performed exactly once. Therefore, + only Incoming Mailboxes with completion code Command Completed + Without Error, Command Completed With Error, or Command Aborted + At Host Request are saved for completion processing. When an + Incoming Mailbox has a completion code of Aborted Command Not + Found, the CCB had already completed or been aborted before the + current Abort request was processed, and so completion processing + has already occurred and no further action should be taken. + */ + struct blogic_inbox *next_inbox = adapter->next_inbox; + enum blogic_cmplt_code comp_code; + + while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) { /* - We are only allowed to do this because we limit our architectures we - run on to machines where bus_to_virt() actually works. There *needs* - to be a dma_addr_to_virt() in the new PCI DMA mapping interface to - replace bus_to_virt() or else this code is going to become very + We are only allowed to do this because we limit our + architectures we run on to machines where bus_to_virt( + actually works. There *needs* to be a dma_addr_to_virt() + in the new PCI DMA mapping interface to replace + bus_to_virt() or else this code is going to become very innefficient. */ - struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB); - if (CompletionCode != BusLogic_AbortedCommandNotFound) { - if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) { + struct blogic_ccb *ccb = + (struct blogic_ccb *) bus_to_virt(next_inbox->ccb); + if (comp_code != BLOGIC_CMD_NOTFOUND) { + if (ccb->status == BLOGIC_CCB_ACTIVE || + ccb->status == BLOGIC_CCB_RESET) { /* - Save the Completion Code for this CCB and queue the CCB - for completion processing. + Save the Completion Code for this CCB and + queue the CCB for completion processing. */ - CCB->CompletionCode = CompletionCode; - BusLogic_QueueCompletedCCB(CCB); + ccb->comp_code = comp_code; + blogic_qcompleted_ccb(ccb); } else { /* - If a CCB ever appears in an Incoming Mailbox and is not marked - as status Active or Reset, then there is most likely a bug in + If a CCB ever appears in an Incoming Mailbox + and is not marked as status Active or Reset, + then there is most likely a bug in the Host Adapter firmware. */ - BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status); + blogic_warn("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", adapter, ccb->serial, ccb->status); } } - NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree; - if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox) - NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; + next_inbox->comp_code = BLOGIC_INBOX_FREE; + if (++next_inbox > adapter->last_inbox) + next_inbox = adapter->first_inbox; } - HostAdapter->NextIncomingMailbox = NextIncomingMailbox; + adapter->next_inbox = next_inbox; } /* - BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host + blogic_process_ccbs iterates over the completed CCBs for Host Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock should already have been acquired by the caller. */ -static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter) +static void blogic_process_ccbs(struct blogic_adapter *adapter) { - if (HostAdapter->ProcessCompletedCCBsActive) + if (adapter->processing_ccbs) return; - HostAdapter->ProcessCompletedCCBsActive = true; - while (HostAdapter->FirstCompletedCCB != NULL) { - struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB; - struct scsi_cmnd *Command = CCB->Command; - HostAdapter->FirstCompletedCCB = CCB->Next; - if (HostAdapter->FirstCompletedCCB == NULL) - HostAdapter->LastCompletedCCB = NULL; + adapter->processing_ccbs = true; + while (adapter->firstccb != NULL) { + struct blogic_ccb *ccb = adapter->firstccb; + struct scsi_cmnd *command = ccb->command; + adapter->firstccb = ccb->next; + if (adapter->firstccb == NULL) + adapter->lastccb = NULL; /* Process the Completed CCB. */ - if (CCB->Opcode == BusLogic_BusDeviceReset) { - int TargetID = CCB->TargetID; - BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted); - HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; - HostAdapter->CommandsSinceReset[TargetID] = 0; - HostAdapter->LastResetCompleted[TargetID] = jiffies; + if (ccb->opcode == BLOGIC_BDR) { + int tgt_id = ccb->tgt_id; + + blogic_warn("Bus Device Reset CCB #%ld to Target " "%d Completed\n", adapter, ccb->serial, tgt_id); + blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done); + adapter->tgt_flags[tgt_id].tagq_active = false; + adapter->cmds_since_rst[tgt_id] = 0; + adapter->last_resetdone[tgt_id] = jiffies; /* Place CCB back on the Host Adapter's free list. */ - BusLogic_DeallocateCCB(CCB); + blogic_dealloc_ccb(ccb); #if 0 /* this needs to be redone different for new EH */ /* - Bus Device Reset CCBs have the Command field non-NULL only when a - Bus Device Reset was requested for a Command that did not have a - currently active CCB in the Host Adapter (i.e., a Synchronous - Bus Device Reset), and hence would not have its Completion Routine - called otherwise. + Bus Device Reset CCBs have the command field + non-NULL only when a Bus Device Reset was requested + for a command that did not have a currently active + CCB in the Host Adapter (i.e., a Synchronous Bus + Device Reset), and hence would not have its + Completion Routine called otherwise. */ - while (Command != NULL) { - struct scsi_cmnd *NextCommand = Command->reset_chain; - Command->reset_chain = NULL; - Command->result = DID_RESET << 16; - Command->scsi_done(Command); - Command = NextCommand; + while (command != NULL) { + struct scsi_cmnd *nxt_cmd = + command->reset_chain; + command->reset_chain = NULL; + command->result = DID_RESET << 16; + command->scsi_done(command); + command = nxt_cmd; } #endif /* - Iterate over the CCBs for this Host Adapter performing completion - processing for any CCBs marked as Reset for this Target. + Iterate over the CCBs for this Host Adapter + performing completion processing for any CCBs + marked as Reset for this Target. */ - for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) - if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) { - Command = CCB->Command; - BusLogic_DeallocateCCB(CCB); - HostAdapter->ActiveCommands[TargetID]--; - Command->result = DID_RESET << 16; - Command->scsi_done(Command); + for (ccb = adapter->all_ccbs; ccb != NULL; + ccb = ccb->next_all) + if (ccb->status == BLOGIC_CCB_RESET && + ccb->tgt_id == tgt_id) { + command = ccb->command; + blogic_dealloc_ccb(ccb); + adapter->active_cmds[tgt_id]--; + command->result = DID_RESET << 16; + command->scsi_done(command); } - HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; + adapter->bdr_pend[tgt_id] = NULL; } else { /* - Translate the Completion Code, Host Adapter Status, and Target - Device Status into a SCSI Subsystem Result Code. + Translate the Completion Code, Host Adapter Status, + and Target Device Status into a SCSI Subsystem + Result Code. */ - switch (CCB->CompletionCode) { - case BusLogic_IncomingMailboxFree: - case BusLogic_AbortedCommandNotFound: - case BusLogic_InvalidCCB: - BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID); + switch (ccb->comp_code) { + case BLOGIC_INBOX_FREE: + case BLOGIC_CMD_NOTFOUND: + case BLOGIC_INVALID_CCB: + blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id); break; - case BusLogic_CommandCompletedWithoutError: - HostAdapter->TargetStatistics[CCB->TargetID] - .CommandsCompleted++; - HostAdapter->TargetFlags[CCB->TargetID] - .CommandSuccessfulFlag = true; - Command->result = DID_OK << 16; + case BLOGIC_CMD_COMPLETE_GOOD: + adapter->tgt_stats[ccb->tgt_id] + .cmds_complete++; + adapter->tgt_flags[ccb->tgt_id] + .cmd_good = true; + command->result = DID_OK << 16; break; - case BusLogic_CommandAbortedAtHostRequest: - BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID); - BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID] - .CommandAbortsCompleted); - Command->result = DID_ABORT << 16; + case BLOGIC_CMD_ABORT_BY_HOST: + blogic_warn("CCB #%ld to Target %d Aborted\n", + adapter, ccb->serial, ccb->tgt_id); + blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done); + command->result = DID_ABORT << 16; break; - case BusLogic_CommandCompletedWithError: - Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus); - if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) { - HostAdapter->TargetStatistics[CCB->TargetID] - .CommandsCompleted++; - if (BusLogic_GlobalOptions.TraceErrors) { + case BLOGIC_CMD_COMPLETE_ERROR: + command->result = blogic_resultcode(adapter, + ccb->adapter_status, ccb->tgt_status); + if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) { + adapter->tgt_stats[ccb->tgt_id] + .cmds_complete++; + if (blogic_global_options.trace_err) { int i; - BusLogic_Notice("CCB #%ld Target %d: Result %X Host " - "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus); - BusLogic_Notice("CDB ", HostAdapter); - for (i = 0; i < CCB->CDB_Length; i++) - BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]); - BusLogic_Notice("\n", HostAdapter); - BusLogic_Notice("Sense ", HostAdapter); - for (i = 0; i < CCB->SenseDataLength; i++) - BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]); - BusLogic_Notice("\n", HostAdapter); + blogic_notice("CCB #%ld Target %d: Result %X Host " + "Adapter Status %02X " "Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status); + blogic_notice("CDB ", adapter); + for (i = 0; i < ccb->cdblen; i++) + blogic_notice(" %02X", adapter, ccb->cdb[i]); + blogic_notice("\n", adapter); + blogic_notice("Sense ", adapter); + for (i = 0; i < ccb->sense_datalen; i++) + blogic_notice(" %02X", adapter, command->sense_buffer[i]); + blogic_notice("\n", adapter); } } break; @@ -2641,141 +2850,145 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit Wide Data Transfers Supported) bits. */ - if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID]; - struct SCSI_Inquiry *InquiryResult = - (struct SCSI_Inquiry *) scsi_sglist(Command); - TargetFlags->TargetExists = true; - TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue; - TargetFlags->WideTransfersSupported = InquiryResult->WBus16; + if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 && + ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) { + struct blogic_tgt_flags *tgt_flags = + &adapter->tgt_flags[ccb->tgt_id]; + struct scsi_inquiry *inquiry = + (struct scsi_inquiry *) scsi_sglist(command); + tgt_flags->tgt_exists = true; + tgt_flags->tagq_ok = inquiry->CmdQue; + tgt_flags->wide_ok = inquiry->WBus16; } /* Place CCB back on the Host Adapter's free list. */ - BusLogic_DeallocateCCB(CCB); + blogic_dealloc_ccb(ccb); /* Call the SCSI Command Completion Routine. */ - Command->scsi_done(Command); + command->scsi_done(command); } } - HostAdapter->ProcessCompletedCCBsActive = false; + adapter->processing_ccbs = false; } /* - BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host + blogic_inthandler handles hardware interrupts from BusLogic Host Adapters. */ -static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier) +static irqreturn_t blogic_inthandler(int irq_ch, void *devid) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier; - unsigned long ProcessorFlags; + struct blogic_adapter *adapter = (struct blogic_adapter *) devid; + unsigned long processor_flag; /* Acquire exclusive access to Host Adapter. */ - spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags); + spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag); /* Handle Interrupts appropriately for each Host Adapter type. */ - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { - union BusLogic_InterruptRegister InterruptRegister; + if (blogic_multimaster_type(adapter)) { + union blogic_int_reg intreg; /* Read the Host Adapter Interrupt Register. */ - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - if (InterruptRegister.ir.InterruptValid) { + intreg.all = blogic_rdint(adapter); + if (intreg.ir.int_valid) { /* Acknowledge the interrupt and reset the Host Adapter Interrupt Register. */ - BusLogic_InterruptReset(HostAdapter); + blogic_intreset(adapter); /* - Process valid External SCSI Bus Reset and Incoming Mailbox - Loaded Interrupts. Command Complete Interrupts are noted, - and Outgoing Mailbox Available Interrupts are ignored, as - they are never enabled. + Process valid External SCSI Bus Reset and Incoming + Mailbox Loaded Interrupts. Command Complete + Interrupts are noted, and Outgoing Mailbox Available + Interrupts are ignored, as they are never enabled. */ - if (InterruptRegister.ir.ExternalBusReset) - HostAdapter->HostAdapterExternalReset = true; - else if (InterruptRegister.ir.IncomingMailboxLoaded) - BusLogic_ScanIncomingMailboxes(HostAdapter); - else if (InterruptRegister.ir.CommandComplete) - HostAdapter->HostAdapterCommandCompleted = true; + if (intreg.ir.ext_busreset) + adapter->adapter_extreset = true; + else if (intreg.ir.mailin_loaded) + blogic_scan_inbox(adapter); + else if (intreg.ir.cmd_complete) + adapter->adapter_cmd_complete = true; } } else { /* Check if there is a pending interrupt for this Host Adapter. */ - if (FlashPoint_InterruptPending(HostAdapter->CardHandle)) - switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) { - case FlashPoint_NormalInterrupt: + if (FlashPoint_InterruptPending(adapter->cardhandle)) + switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) { + case FPOINT_NORMAL_INT: break; - case FlashPoint_ExternalBusReset: - HostAdapter->HostAdapterExternalReset = true; + case FPOINT_EXT_RESET: + adapter->adapter_extreset = true; break; - case FlashPoint_InternalError: - BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter); - HostAdapter->HostAdapterInternalError = true; + case FPOINT_INTERN_ERR: + blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter); + adapter->adapter_intern_err = true; break; } } /* Process any completed CCBs. */ - if (HostAdapter->FirstCompletedCCB != NULL) - BusLogic_ProcessCompletedCCBs(HostAdapter); + if (adapter->firstccb != NULL) + blogic_process_ccbs(adapter); /* Reset the Host Adapter if requested. */ - if (HostAdapter->HostAdapterExternalReset) { - BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName); - BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets); - BusLogic_ResetHostAdapter(HostAdapter, false); - HostAdapter->HostAdapterExternalReset = false; - } else if (HostAdapter->HostAdapterInternalError) { - BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName); - BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors); - BusLogic_ResetHostAdapter(HostAdapter, true); - HostAdapter->HostAdapterInternalError = false; + if (adapter->adapter_extreset) { + blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model); + blogic_inc_count(&adapter->ext_resets); + blogic_resetadapter(adapter, false); + adapter->adapter_extreset = false; + } else if (adapter->adapter_intern_err) { + blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model); + blogic_inc_count(&adapter->adapter_intern_errors); + blogic_resetadapter(adapter, true); + adapter->adapter_intern_err = false; } /* Release exclusive access to Host Adapter. */ - spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags); + spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag); return IRQ_HANDLED; } /* - BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing + blogic_write_outbox places CCB and Action Code into an Outgoing Mailbox for execution by Host Adapter. The Host Adapter's Lock should already have been acquired by the caller. */ -static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter - *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB) +static bool blogic_write_outbox(struct blogic_adapter *adapter, + enum blogic_action action, struct blogic_ccb *ccb) { - struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; - NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox; - if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) { - CCB->Status = BusLogic_CCB_Active; + struct blogic_outbox *next_outbox; + + next_outbox = adapter->next_outbox; + if (next_outbox->action == BLOGIC_OUTBOX_FREE) { + ccb->status = BLOGIC_CCB_ACTIVE; /* - The CCB field must be written before the Action Code field since - the Host Adapter is operating asynchronously and the locking code - does not protect against simultaneous access by the Host Adapter. + The CCB field must be written before the Action Code field + since the Host Adapter is operating asynchronously and the + locking code does not protect against simultaneous access + by the Host Adapter. */ - NextOutgoingMailbox->CCB = CCB->DMA_Handle; - NextOutgoingMailbox->ActionCode = ActionCode; - BusLogic_StartMailboxCommand(HostAdapter); - if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox) - NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; - HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox; - if (ActionCode == BusLogic_MailboxStartCommand) { - HostAdapter->ActiveCommands[CCB->TargetID]++; - if (CCB->Opcode != BusLogic_BusDeviceReset) - HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++; + next_outbox->ccb = ccb->dma_handle; + next_outbox->action = action; + blogic_execmbox(adapter); + if (++next_outbox > adapter->last_outbox) + next_outbox = adapter->first_outbox; + adapter->next_outbox = next_outbox; + if (action == BLOGIC_MBOX_START) { + adapter->active_cmds[ccb->tgt_id]++; + if (ccb->opcode != BLOGIC_BDR) + adapter->tgt_stats[ccb->tgt_id].cmds_tried++; } return true; } @@ -2784,65 +2997,72 @@ static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter /* Error Handling (EH) support */ -static int BusLogic_host_reset(struct scsi_cmnd * SCpnt) +static int blogic_hostreset(struct scsi_cmnd *SCpnt) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata; + struct blogic_adapter *adapter = + (struct blogic_adapter *) SCpnt->device->host->hostdata; unsigned int id = SCpnt->device->id; - struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id]; + struct blogic_tgt_stats *stats = &adapter->tgt_stats[id]; int rc; spin_lock_irq(SCpnt->device->host->host_lock); - BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested); + blogic_inc_count(&stats->adatper_reset_req); - rc = BusLogic_ResetHostAdapter(HostAdapter, false); + rc = blogic_resetadapter(adapter, false); spin_unlock_irq(SCpnt->device->host->host_lock); return rc; } /* - BusLogic_QueueCommand creates a CCB for Command and places it into an + blogic_qcmd creates a CCB for Command and places it into an Outgoing Mailbox for execution by the associated Host Adapter. */ -static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *)) +static int blogic_qcmd_lck(struct scsi_cmnd *command, + void (*comp_cb) (struct scsi_cmnd *)) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata; - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id]; - struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics; - unsigned char *CDB = Command->cmnd; - int CDB_Length = Command->cmd_len; - int TargetID = Command->device->id; - int LogicalUnit = Command->device->lun; - int BufferLength = scsi_bufflen(Command); - int Count; - struct BusLogic_CCB *CCB; - /* - SCSI REQUEST_SENSE commands will be executed automatically by the Host - Adapter for any errors, so they should not be executed explicitly unless - the Sense Data is zero indicating that no error occurred. - */ - if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) { - Command->result = DID_OK << 16; - CompletionRoutine(Command); + struct blogic_adapter *adapter = + (struct blogic_adapter *) command->device->host->hostdata; + struct blogic_tgt_flags *tgt_flags = + &adapter->tgt_flags[command->device->id]; + struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats; + unsigned char *cdb = command->cmnd; + int cdblen = command->cmd_len; + int tgt_id = command->device->id; + int lun = command->device->lun; + int buflen = scsi_bufflen(command); + int count; + struct blogic_ccb *ccb; + + /* + SCSI REQUEST_SENSE commands will be executed automatically by the + Host Adapter for any errors, so they should not be executed + explicitly unless the Sense Data is zero indicating that no error + occurred. + */ + if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) { + command->result = DID_OK << 16; + comp_cb(command); return 0; } /* - Allocate a CCB from the Host Adapter's free list. In the unlikely event - that there are none available and memory allocation fails, wait 1 second - and try again. If that fails, the Host Adapter is probably hung so signal - an error as a Host Adapter Hard Reset should be initiated soon. - */ - CCB = BusLogic_AllocateCCB(HostAdapter); - if (CCB == NULL) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); - BusLogic_Delay(1); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); - CCB = BusLogic_AllocateCCB(HostAdapter); - if (CCB == NULL) { - Command->result = DID_ERROR << 16; - CompletionRoutine(Command); + Allocate a CCB from the Host Adapter's free list. In the unlikely + event that there are none available and memory allocation fails, + wait 1 second and try again. If that fails, the Host Adapter is + probably hung so signal an error as a Host Adapter Hard Reset + should be initiated soon. + */ + ccb = blogic_alloc_ccb(adapter); + if (ccb == NULL) { + spin_unlock_irq(adapter->scsi_host->host_lock); + blogic_delay(1); + spin_lock_irq(adapter->scsi_host->host_lock); + ccb = blogic_alloc_ccb(adapter); + if (ccb == NULL) { + command->result = DID_ERROR << 16; + comp_cb(command); return 0; } } @@ -2850,217 +3070,241 @@ static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*Completio /* Initialize the fields in the BusLogic Command Control Block (CCB). */ - Count = scsi_dma_map(Command); - BUG_ON(Count < 0); - if (Count) { + count = scsi_dma_map(command); + BUG_ON(count < 0); + if (count) { struct scatterlist *sg; int i; - CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather; - CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment); - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB); + ccb->opcode = BLOGIC_INITIATOR_CCB_SG; + ccb->datalen = count * sizeof(struct blogic_sg_seg); + if (blogic_multimaster_type(adapter)) + ccb->data = (unsigned int) ccb->dma_handle + + ((unsigned long) &ccb->sglist - + (unsigned long) ccb); else - CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList); + ccb->data = virt_to_32bit_virt(ccb->sglist); - scsi_for_each_sg(Command, sg, Count, i) { - CCB->ScatterGatherList[i].SegmentByteCount = - sg_dma_len(sg); - CCB->ScatterGatherList[i].SegmentDataPointer = - sg_dma_address(sg); + scsi_for_each_sg(command, sg, count, i) { + ccb->sglist[i].segbytes = sg_dma_len(sg); + ccb->sglist[i].segdata = sg_dma_address(sg); } - } else if (!Count) { - CCB->Opcode = BusLogic_InitiatorCCB; - CCB->DataLength = BufferLength; - CCB->DataPointer = 0; + } else if (!count) { + ccb->opcode = BLOGIC_INITIATOR_CCB; + ccb->datalen = buflen; + ccb->data = 0; } - switch (CDB[0]) { + switch (cdb[0]) { case READ_6: case READ_10: - CCB->DataDirection = BusLogic_DataInLengthChecked; - TargetStatistics[TargetID].ReadCommands++; - BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength); - BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength); + ccb->datadir = BLOGIC_DATAIN_CHECKED; + tgt_stats[tgt_id].read_cmds++; + blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen); + blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen); break; case WRITE_6: case WRITE_10: - CCB->DataDirection = BusLogic_DataOutLengthChecked; - TargetStatistics[TargetID].WriteCommands++; - BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength); - BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength); + ccb->datadir = BLOGIC_DATAOUT_CHECKED; + tgt_stats[tgt_id].write_cmds++; + blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen); + blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen); break; default: - CCB->DataDirection = BusLogic_UncheckedDataTransfer; + ccb->datadir = BLOGIC_UNCHECKED_TX; break; } - CCB->CDB_Length = CDB_Length; - CCB->HostAdapterStatus = 0; - CCB->TargetDeviceStatus = 0; - CCB->TargetID = TargetID; - CCB->LogicalUnit = LogicalUnit; - CCB->TagEnable = false; - CCB->LegacyTagEnable = false; - /* - BusLogic recommends that after a Reset the first couple of commands that - are sent to a Target Device be sent in a non Tagged Queue fashion so that - the Host Adapter and Target Device can establish Synchronous and Wide - Transfer before Queue Tag messages can interfere with the Synchronous and - Wide Negotiation messages. By waiting to enable Tagged Queuing until after - the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is - assured that after a Reset any pending commands are requeued before Tagged - Queuing is enabled and that the Tagged Queuing message will not occur while - the partition table is being printed. In addition, some devices do not - properly handle the transition from non-tagged to tagged commands, so it is - necessary to wait until there are no pending commands for a target device + ccb->cdblen = cdblen; + ccb->adapter_status = 0; + ccb->tgt_status = 0; + ccb->tgt_id = tgt_id; + ccb->lun = lun; + ccb->tag_enable = false; + ccb->legacytag_enable = false; + /* + BusLogic recommends that after a Reset the first couple of + commands that are sent to a Target Device be sent in a non + Tagged Queue fashion so that the Host Adapter and Target Device + can establish Synchronous and Wide Transfer before Queue Tag + messages can interfere with the Synchronous and Wide Negotiation + messages. By waiting to enable Tagged Queuing until after the + first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is + assured that after a Reset any pending commands are requeued + before Tagged Queuing is enabled and that the Tagged Queuing + message will not occur while the partition table is being printed. + In addition, some devices do not properly handle the transition + from non-tagged to tagged commands, so it is necessary to wait + until there are no pending commands for a target device before queuing tagged commands. */ - if (HostAdapter->CommandsSinceReset[TargetID]++ >= - BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) { - TargetFlags->TaggedQueuingActive = true; - BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID); - } - if (TargetFlags->TaggedQueuingActive) { - enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag; + if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH && + !tgt_flags->tagq_active && + adapter->active_cmds[tgt_id] == 0 + && tgt_flags->tagq_ok && + (adapter->tagq_ok & (1 << tgt_id))) { + tgt_flags->tagq_active = true; + blogic_notice("Tagged Queuing now active for Target %d\n", + adapter, tgt_id); + } + if (tgt_flags->tagq_active) { + enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG; /* - When using Tagged Queuing with Simple Queue Tags, it appears that disk - drive controllers do not guarantee that a queued command will not - remain in a disconnected state indefinitely if commands that read or - write nearer the head position continue to arrive without interruption. - Therefore, for each Target Device this driver keeps track of the last - time either the queue was empty or an Ordered Queue Tag was issued. If - more than 4 seconds (one fifth of the 20 second disk timeout) have - elapsed since this last sequence point, this command will be issued - with an Ordered Queue Tag rather than a Simple Queue Tag, which forces - the Target Device to complete all previously queued commands before - this command may be executed. + When using Tagged Queuing with Simple Queue Tags, it + appears that disk drive controllers do not guarantee that + a queued command will not remain in a disconnected state + indefinitely if commands that read or write nearer the + head position continue to arrive without interruption. + Therefore, for each Target Device this driver keeps track + of the last time either the queue was empty or an Ordered + Queue Tag was issued. If more than 4 seconds (one fifth + of the 20 second disk timeout) have elapsed since this + last sequence point, this command will be issued with an + Ordered Queue Tag rather than a Simple Queue Tag, which + forces the Target Device to complete all previously + queued commands before this command may be executed. */ - if (HostAdapter->ActiveCommands[TargetID] == 0) - HostAdapter->LastSequencePoint[TargetID] = jiffies; - else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) { - HostAdapter->LastSequencePoint[TargetID] = jiffies; - QueueTag = BusLogic_OrderedQueueTag; + if (adapter->active_cmds[tgt_id] == 0) + adapter->last_seqpoint[tgt_id] = jiffies; + else if (time_after(jiffies, + adapter->last_seqpoint[tgt_id] + 4 * HZ)) { + adapter->last_seqpoint[tgt_id] = jiffies; + queuetag = BLOGIC_ORDEREDTAG; } - if (HostAdapter->ExtendedLUNSupport) { - CCB->TagEnable = true; - CCB->QueueTag = QueueTag; + if (adapter->ext_lun) { + ccb->tag_enable = true; + ccb->queuetag = queuetag; } else { - CCB->LegacyTagEnable = true; - CCB->LegacyQueueTag = QueueTag; + ccb->legacytag_enable = true; + ccb->legacy_tag = queuetag; } } - memcpy(CCB->CDB, CDB, CDB_Length); - CCB->SenseDataLength = SCSI_SENSE_BUFFERSIZE; - CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE); - CCB->Command = Command; - Command->scsi_done = CompletionRoutine; - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + memcpy(ccb->cdb, cdb, cdblen); + ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE; + ccb->sensedata = pci_map_single(adapter->pci_device, + command->sense_buffer, ccb->sense_datalen, + PCI_DMA_FROMDEVICE); + ccb->command = command; + command->scsi_done = comp_cb; + if (blogic_multimaster_type(adapter)) { /* - Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI - Subsystem should not attempt to queue more commands than can be placed - in Outgoing Mailboxes, so there should always be one free. In the - unlikely event that there are none available, wait 1 second and try - again. If that fails, the Host Adapter is probably hung so signal an - error as a Host Adapter Hard Reset should be initiated soon. + Place the CCB in an Outgoing Mailbox. The higher levels + of the SCSI Subsystem should not attempt to queue more + commands than can be placed in Outgoing Mailboxes, so + there should always be one free. In the unlikely event + that there are none available, wait 1 second and try + again. If that fails, the Host Adapter is probably hung + so signal an error as a Host Adapter Hard Reset should + be initiated soon. */ - if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); - BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter); - BusLogic_Delay(1); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); - if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { - BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter); - BusLogic_DeallocateCCB(CCB); - Command->result = DID_ERROR << 16; - Command->scsi_done(Command); + if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) { + spin_unlock_irq(adapter->scsi_host->host_lock); + blogic_warn("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", adapter); + blogic_delay(1); + spin_lock_irq(adapter->scsi_host->host_lock); + if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, + ccb)) { + blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter); + blogic_dealloc_ccb(ccb); + command->result = DID_ERROR << 16; + command->scsi_done(command); } } } else { /* - Call the FlashPoint SCCB Manager to start execution of the CCB. + Call the FlashPoint SCCB Manager to start execution of + the CCB. */ - CCB->Status = BusLogic_CCB_Active; - HostAdapter->ActiveCommands[TargetID]++; - TargetStatistics[TargetID].CommandsAttempted++; - FlashPoint_StartCCB(HostAdapter->CardHandle, CCB); + ccb->status = BLOGIC_CCB_ACTIVE; + adapter->active_cmds[tgt_id]++; + tgt_stats[tgt_id].cmds_tried++; + FlashPoint_StartCCB(adapter->cardhandle, ccb); /* - The Command may have already completed and BusLogic_QueueCompletedCCB - been called, or it may still be pending. + The Command may have already completed and + blogic_qcompleted_ccb been called, or it may still be + pending. */ - if (CCB->Status == BusLogic_CCB_Completed) - BusLogic_ProcessCompletedCCBs(HostAdapter); + if (ccb->status == BLOGIC_CCB_COMPLETE) + blogic_process_ccbs(adapter); } return 0; } -static DEF_SCSI_QCMD(BusLogic_QueueCommand) +static DEF_SCSI_QCMD(blogic_qcmd) #if 0 /* - BusLogic_AbortCommand aborts Command if possible. + blogic_abort aborts Command if possible. */ -static int BusLogic_AbortCommand(struct scsi_cmnd *Command) +static int blogic_abort(struct scsi_cmnd *command) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata; + struct blogic_adapter *adapter = + (struct blogic_adapter *) command->device->host->hostdata; + + int tgt_id = command->device->id; + struct blogic_ccb *ccb; + blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request); - int TargetID = Command->device->id; - struct BusLogic_CCB *CCB; - BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested); /* - Attempt to find an Active CCB for this Command. If no Active CCB for this - Command is found, then no Abort is necessary. + Attempt to find an Active CCB for this Command. If no Active + CCB for this Command is found, then no Abort is necessary. */ - for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) - if (CCB->Command == Command) + for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all) + if (ccb->command == command) break; - if (CCB == NULL) { - BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID); + if (ccb == NULL) { + blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id); return SUCCESS; - } else if (CCB->Status == BusLogic_CCB_Completed) { - BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID); + } else if (ccb->status == BLOGIC_CCB_COMPLETE) { + blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id); return SUCCESS; - } else if (CCB->Status == BusLogic_CCB_Reset) { - BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID); + } else if (ccb->status == BLOGIC_CCB_RESET) { + blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id); return SUCCESS; } - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + if (blogic_multimaster_type(adapter)) { /* - Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx - do not generate Abort Tag messages, but only generate the non-tagged - Abort message. Since non-tagged commands are not sent by the Host - Adapter until the queue of outstanding tagged commands has completed, - and the Abort message is treated as a non-tagged command, it is - effectively impossible to abort commands when Tagged Queuing is active. - Firmware version 5.xx does generate Abort Tag messages, so it is - possible to abort commands when Tagged Queuing is active. + Attempt to Abort this CCB. MultiMaster Firmware versions + prior to 5.xx do not generate Abort Tag messages, but only + generate the non-tagged Abort message. Since non-tagged + commands are not sent by the Host Adapter until the queue + of outstanding tagged commands has completed, and the + Abort message is treated as a non-tagged command, it is + effectively impossible to abort commands when Tagged + Queuing is active. Firmware version 5.xx does generate + Abort Tag messages, so it is possible to abort commands + when Tagged Queuing is active. */ - if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') { - BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID); + if (adapter->tgt_flags[tgt_id].tagq_active && + adapter->fw_ver[0] < '5') { + blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id); return FAILURE; - } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) { - BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); + } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT, + ccb)) { + blogic_warn("Aborting CCB #%ld to Target %d\n", + adapter, ccb->serial, tgt_id); + blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried); return SUCCESS; } else { - BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID); + blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id); return FAILURE; } } else { /* - Call the FlashPoint SCCB Manager to abort execution of the CCB. + Call the FlashPoint SCCB Manager to abort execution of + the CCB. */ - BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); - FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB); + blogic_warn("Aborting CCB #%ld to Target %d\n", adapter, + ccb->serial, tgt_id); + blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried); + FlashPoint_AbortCCB(adapter->cardhandle, ccb); /* The Abort may have already been completed and - BusLogic_QueueCompletedCCB been called, or it + blogic_qcompleted_ccb been called, or it may still be pending. */ - if (CCB->Status == BusLogic_CCB_Completed) { - BusLogic_ProcessCompletedCCBs(HostAdapter); - } + if (ccb->status == BLOGIC_CCB_COMPLETE) + blogic_process_ccbs(adapter); return SUCCESS; } return SUCCESS; @@ -3068,21 +3312,23 @@ static int BusLogic_AbortCommand(struct scsi_cmnd *Command) #endif /* - BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all + blogic_resetadapter resets Host Adapter if possible, marking all currently executing SCSI Commands as having been Reset. */ -static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset) +static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset) { - struct BusLogic_CCB *CCB; - int TargetID; + struct blogic_ccb *ccb; + int tgt_id; /* * Attempt to Reset and Reinitialize the Host Adapter. */ - if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) { - BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName); + if (!(blogic_hwreset(adapter, hard_reset) && + blogic_initadapter(adapter))) { + blogic_err("Resetting %s Failed\n", adapter, + adapter->full_model); return FAILURE; } @@ -3090,9 +3336,9 @@ static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, b * Deallocate all currently executing CCBs. */ - for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) - if (CCB->Status == BusLogic_CCB_Active) - BusLogic_DeallocateCCB(CCB); + for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all) + if (ccb->status == BLOGIC_CCB_ACTIVE) + blogic_dealloc_ccb(ccb); /* * Wait a few seconds between the Host Adapter Hard Reset which * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some @@ -3100,21 +3346,21 @@ static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, b * after a SCSI Bus Reset. */ - if (HardReset) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); - BusLogic_Delay(HostAdapter->BusSettleTime); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); + if (hard_reset) { + spin_unlock_irq(adapter->scsi_host->host_lock); + blogic_delay(adapter->bus_settle_time); + spin_lock_irq(adapter->scsi_host->host_lock); } - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - HostAdapter->LastResetAttempted[TargetID] = jiffies; - HostAdapter->LastResetCompleted[TargetID] = jiffies; + for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) { + adapter->last_resettried[tgt_id] = jiffies; + adapter->last_resetdone[tgt_id] = jiffies; } return SUCCESS; } /* - BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk + blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and the appropriate number of cylinders so as not to exceed drive capacity. In order for disks equal to or larger than 1 GB to be addressable by the BIOS @@ -3130,66 +3376,70 @@ static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, b the BIOS, and a warning may be displayed. */ -static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters) +static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev, + sector_t capacity, int *params) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata; - struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters; + struct blogic_adapter *adapter = + (struct blogic_adapter *) sdev->host->hostdata; + struct bios_diskparam *diskparam = (struct bios_diskparam *) params; unsigned char *buf; - if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) { - if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */ ) { - DiskParameters->Heads = 255; - DiskParameters->Sectors = 63; + + if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) { + if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) { + diskparam->heads = 255; + diskparam->sectors = 63; } else { - DiskParameters->Heads = 128; - DiskParameters->Sectors = 32; + diskparam->heads = 128; + diskparam->sectors = 32; } } else { - DiskParameters->Heads = 64; - DiskParameters->Sectors = 32; + diskparam->heads = 64; + diskparam->sectors = 32; } - DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors); - buf = scsi_bios_ptable(Device); + diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors); + buf = scsi_bios_ptable(dev); if (buf == NULL) return 0; /* - If the boot sector partition table flag is valid, search for a partition - table entry whose end_head matches one of the standard BusLogic geometry - translations (64/32, 128/32, or 255/63). + If the boot sector partition table flag is valid, search for + a partition table entry whose end_head matches one of the + standard BusLogic geometry translations (64/32, 128/32, or 255/63). */ if (*(unsigned short *) (buf + 64) == 0xAA55) { - struct partition *FirstPartitionEntry = (struct partition *) buf; - struct partition *PartitionEntry = FirstPartitionEntry; - int SavedCylinders = DiskParameters->Cylinders, PartitionNumber; - unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0; - for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) { - PartitionEntryEndHead = PartitionEntry->end_head; - PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F; - if (PartitionEntryEndHead == 64 - 1) { - DiskParameters->Heads = 64; - DiskParameters->Sectors = 32; + struct partition *part1_entry = (struct partition *) buf; + struct partition *part_entry = part1_entry; + int saved_cyl = diskparam->cylinders, part_no; + unsigned char part_end_head = 0, part_end_sector = 0; + + for (part_no = 0; part_no < 4; part_no++) { + part_end_head = part_entry->end_head; + part_end_sector = part_entry->end_sector & 0x3F; + if (part_end_head == 64 - 1) { + diskparam->heads = 64; + diskparam->sectors = 32; break; - } else if (PartitionEntryEndHead == 128 - 1) { - DiskParameters->Heads = 128; - DiskParameters->Sectors = 32; + } else if (part_end_head == 128 - 1) { + diskparam->heads = 128; + diskparam->sectors = 32; break; - } else if (PartitionEntryEndHead == 255 - 1) { - DiskParameters->Heads = 255; - DiskParameters->Sectors = 63; + } else if (part_end_head == 255 - 1) { + diskparam->heads = 255; + diskparam->sectors = 63; break; } - PartitionEntry++; + part_entry++; } - if (PartitionNumber == 4) { - PartitionEntryEndHead = FirstPartitionEntry->end_head; - PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F; + if (part_no == 4) { + part_end_head = part1_entry->end_head; + part_end_sector = part1_entry->end_sector & 0x3F; } - DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors); - if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) { - if (DiskParameters->Cylinders != SavedCylinders) - BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors); - } else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) { - BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector); - BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors); + diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors); + if (part_no < 4 && part_end_sector == diskparam->sectors) { + if (diskparam->cylinders != saved_cyl) + blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors); + } else if (part_end_head > 0 || part_end_sector > 0) { + blogic_warn("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector); + blogic_warn("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors); } } kfree(buf); @@ -3201,92 +3451,94 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_de BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/. */ -static int BusLogic_write_info(struct Scsi_Host *shost, char *ProcBuffer, int BytesAvailable) +static int blogic_write_info(struct Scsi_Host *shost, char *procbuf, + int bytes_avail) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata; - struct BusLogic_TargetStatistics *TargetStatistics; - - TargetStatistics = HostAdapter->TargetStatistics; - HostAdapter->ExternalHostAdapterResets = 0; - HostAdapter->HostAdapterInternalErrors = 0; - memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics)); + struct blogic_adapter *adapter = + (struct blogic_adapter *) shost->hostdata; + struct blogic_tgt_stats *tgt_stats; + + tgt_stats = adapter->tgt_stats; + adapter->ext_resets = 0; + adapter->adapter_intern_errors = 0; + memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats)); return 0; } -static int BusLogic_show_info(struct seq_file *m, struct Scsi_Host *shost) +static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata; - struct BusLogic_TargetStatistics *TargetStatistics; - int TargetID; + struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata; + struct blogic_tgt_stats *tgt_stats; + int tgt; - TargetStatistics = HostAdapter->TargetStatistics; - seq_write(m, HostAdapter->MessageBuffer, HostAdapter->MessageBufferLength); + tgt_stats = adapter->tgt_stats; + seq_write(m, adapter->msgbuf, adapter->msgbuflen); seq_printf(m, "\n\ Current Driver Queue Depth: %d\n\ -Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs); +Currently Allocated CCBs: %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs); seq_printf(m, "\n\n\ DATA TRANSFER STATISTICS\n\ \n\ Target Tagged Queuing Queue Depth Active Attempted Completed\n\ ====== ============== =========== ====== ========= =========\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) + for (tgt = 0; tgt < adapter->maxdev; tgt++) { + struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt]; + if (!tgt_flags->tgt_exists) continue; - seq_printf(m, " %2d %s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? " Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID) + seq_printf(m, " %2d %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? " Active" : (adapter->tagq_ok & (1 << tgt) ? " Permitted" : " Disabled")) : "Not Supported")); seq_printf(m, - " %3d %3u %9u %9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted); + " %3d %3u %9u %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete); } seq_printf(m, "\n\ Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\ ====== ============= ============== =================== ===================\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) + for (tgt = 0; tgt < adapter->maxdev; tgt++) { + struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt]; + if (!tgt_flags->tgt_exists) continue; - seq_printf(m, " %2d %9u %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands); - if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0) - seq_printf(m, " %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units); + seq_printf(m, " %2d %9u %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds); + if (tgt_stats[tgt].bytesread.billions > 0) + seq_printf(m, " %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units); else - seq_printf(m, " %9u", TargetStatistics[TargetID].TotalBytesRead.Units); - if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0) - seq_printf(m, " %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units); + seq_printf(m, " %9u", tgt_stats[tgt].bytesread.units); + if (tgt_stats[tgt].byteswritten.billions > 0) + seq_printf(m, " %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units); else - seq_printf(m, " %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units); + seq_printf(m, " %9u\n", tgt_stats[tgt].byteswritten.units); } seq_printf(m, "\n\ Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\ ====== ======= ========= ========= ========= ========= =========\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) + for (tgt = 0; tgt < adapter->maxdev; tgt++) { + struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt]; + if (!tgt_flags->tgt_exists) continue; seq_printf(m, - " %2d Read %9u %9u %9u %9u %9u\n", TargetID, - TargetStatistics[TargetID].ReadCommandSizeBuckets[0], - TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]); + " %2d Read %9u %9u %9u %9u %9u\n", tgt, + tgt_stats[tgt].read_sz_buckets[0], + tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]); seq_printf(m, - " %2d Write %9u %9u %9u %9u %9u\n", TargetID, - TargetStatistics[TargetID].WriteCommandSizeBuckets[0], - TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]); + " %2d Write %9u %9u %9u %9u %9u\n", tgt, + tgt_stats[tgt].write_sz_buckets[0], + tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]); } seq_printf(m, "\n\ Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\ ====== ======= ========= ========= ========= ========= =========\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) + for (tgt = 0; tgt < adapter->maxdev; tgt++) { + struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt]; + if (!tgt_flags->tgt_exists) continue; seq_printf(m, - " %2d Read %9u %9u %9u %9u %9u\n", TargetID, - TargetStatistics[TargetID].ReadCommandSizeBuckets[5], - TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]); + " %2d Read %9u %9u %9u %9u %9u\n", tgt, + tgt_stats[tgt].read_sz_buckets[5], + tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]); seq_printf(m, - " %2d Write %9u %9u %9u %9u %9u\n", TargetID, - TargetStatistics[TargetID].WriteCommandSizeBuckets[5], - TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]); + " %2d Write %9u %9u %9u %9u %9u\n", tgt, + tgt_stats[tgt].write_sz_buckets[5], + tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]); } seq_printf(m, "\n\n\ ERROR RECOVERY STATISTICS\n\ @@ -3295,84 +3547,86 @@ Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\ Target Requested Completed Requested Completed Requested Completed\n\ ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\ ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) + for (tgt = 0; tgt < adapter->maxdev; tgt++) { + struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt]; + if (!tgt_flags->tgt_exists) continue; seq_printf(m, "\ - %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted); + %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", tgt, tgt_stats[tgt].aborts_request, tgt_stats[tgt].aborts_tried, tgt_stats[tgt].aborts_done, tgt_stats[tgt].bdr_request, tgt_stats[tgt].bdr_tried, tgt_stats[tgt].bdr_done, tgt_stats[tgt].adatper_reset_req, tgt_stats[tgt].adapter_reset_attempt, tgt_stats[tgt].adapter_reset_done); } - seq_printf(m, "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets); - seq_printf(m, "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors); + seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets); + seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors); return 0; } /* - BusLogic_Message prints Driver Messages. + blogic_msg prints Driver Messages. */ -static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...) +static void blogic_msg(enum blogic_msglevel msglevel, char *fmt, + struct blogic_adapter *adapter, ...) { - static char Buffer[BusLogic_LineBufferSize]; - static bool BeginningOfLine = true; - va_list Arguments; - int Length = 0; - va_start(Arguments, HostAdapter); - Length = vsprintf(Buffer, Format, Arguments); - va_end(Arguments); - if (MessageLevel == BusLogic_AnnounceLevel) { - static int AnnouncementLines = 0; - strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer); - HostAdapter->MessageBufferLength += Length; - if (++AnnouncementLines <= 2) - printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer); - } else if (MessageLevel == BusLogic_InfoLevel) { - strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer); - HostAdapter->MessageBufferLength += Length; - if (BeginningOfLine) { - if (Buffer[0] != '\n' || Length > 1) - printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer); + static char buf[BLOGIC_LINEBUF_SIZE]; + static bool begin = true; + va_list args; + int len = 0; + + va_start(args, adapter); + len = vsprintf(buf, fmt, args); + va_end(args); + if (msglevel == BLOGIC_ANNOUNCE_LEVEL) { + static int msglines = 0; + strcpy(&adapter->msgbuf[adapter->msgbuflen], buf); + adapter->msgbuflen += len; + if (++msglines <= 2) + printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf); + } else if (msglevel == BLOGIC_INFO_LEVEL) { + strcpy(&adapter->msgbuf[adapter->msgbuflen], buf); + adapter->msgbuflen += len; + if (begin) { + if (buf[0] != '\n' || len > 1) + printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf); } else - printk("%s", Buffer); + printk("%s", buf); } else { - if (BeginningOfLine) { - if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized) - printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer); + if (begin) { + if (adapter != NULL && adapter->adapter_initd) + printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf); else - printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer); + printk("%s%s", blogic_msglevelmap[msglevel], buf); } else - printk("%s", Buffer); + printk("%s", buf); } - BeginningOfLine = (Buffer[Length - 1] == '\n'); + begin = (buf[len - 1] == '\n'); } /* - BusLogic_ParseKeyword parses an individual option keyword. It returns true + blogic_parse parses an individual option keyword. It returns true and updates the pointer if the keyword is recognized and false otherwise. */ -static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword) +static bool __init blogic_parse(char **str, char *keyword) { - char *Pointer = *StringPointer; - while (*Keyword != '\0') { - char StringChar = *Pointer++; - char KeywordChar = *Keyword++; - if (StringChar >= 'A' && StringChar <= 'Z') - StringChar += 'a' - 'Z'; - if (KeywordChar >= 'A' && KeywordChar <= 'Z') - KeywordChar += 'a' - 'Z'; - if (StringChar != KeywordChar) + char *pointer = *str; + while (*keyword != '\0') { + char strch = *pointer++; + char keywordch = *keyword++; + if (strch >= 'A' && strch <= 'Z') + strch += 'a' - 'Z'; + if (keywordch >= 'A' && keywordch <= 'Z') + keywordch += 'a' - 'Z'; + if (strch != keywordch) return false; } - *StringPointer = Pointer; + *str = pointer; return true; } /* - BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options + blogic_parseopts handles processing of BusLogic Driver Options specifications. BusLogic Driver Options may be specified either via the Linux Kernel Command @@ -3388,164 +3642,177 @@ static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword) . */ -static int __init BusLogic_ParseDriverOptions(char *OptionsString) +static int __init blogic_parseopts(char *options) { while (true) { - struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++]; - int TargetID; - memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions)); - while (*OptionsString != '\0' && *OptionsString != ';') { + struct blogic_drvr_options *drvr_opts = + &blogic_drvr_options[blogic_drvr_options_count++]; + int tgt_id; + + memset(drvr_opts, 0, sizeof(struct blogic_drvr_options)); + while (*options != '\0' && *options != ';') { /* Probing Options. */ - if (BusLogic_ParseKeyword(&OptionsString, "IO:")) { - unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0); - BusLogic_ProbeOptions.LimitedProbeISA = true; - switch (IO_Address) { + if (blogic_parse(&options, "IO:")) { + unsigned long io_addr = simple_strtoul(options, + &options, 0); + blogic_probe_options.limited_isa = true; + switch (io_addr) { case 0x330: - BusLogic_ProbeOptions.Probe330 = true; + blogic_probe_options.probe330 = true; break; case 0x334: - BusLogic_ProbeOptions.Probe334 = true; + blogic_probe_options.probe334 = true; break; case 0x230: - BusLogic_ProbeOptions.Probe230 = true; + blogic_probe_options.probe230 = true; break; case 0x234: - BusLogic_ProbeOptions.Probe234 = true; + blogic_probe_options.probe234 = true; break; case 0x130: - BusLogic_ProbeOptions.Probe130 = true; + blogic_probe_options.probe130 = true; break; case 0x134: - BusLogic_ProbeOptions.Probe134 = true; + blogic_probe_options.probe134 = true; break; default: - BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address); + blogic_err("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, io_addr); return 0; } - } else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA")) - BusLogic_ProbeOptions.NoProbeISA = true; - else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI")) - BusLogic_ProbeOptions.NoProbePCI = true; - else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe")) - BusLogic_ProbeOptions.NoProbe = true; - else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI")) - BusLogic_ProbeOptions.NoSortPCI = true; - else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst")) - BusLogic_ProbeOptions.MultiMasterFirst = true; - else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst")) - BusLogic_ProbeOptions.FlashPointFirst = true; + } else if (blogic_parse(&options, "NoProbeISA")) + blogic_probe_options.noprobe_isa = true; + else if (blogic_parse(&options, "NoProbePCI")) + blogic_probe_options.noprobe_pci = true; + else if (blogic_parse(&options, "NoProbe")) + blogic_probe_options.noprobe = true; + else if (blogic_parse(&options, "NoSortPCI")) + blogic_probe_options.nosort_pci = true; + else if (blogic_parse(&options, "MultiMasterFirst")) + blogic_probe_options.multimaster_first = true; + else if (blogic_parse(&options, "FlashPointFirst")) + blogic_probe_options.flashpoint_first = true; /* Tagged Queuing Options. */ - else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) { - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) { - unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0); - if (QueueDepth > BusLogic_MaxTaggedQueueDepth) { - BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth); + else if (blogic_parse(&options, "QueueDepth:[") || + blogic_parse(&options, "QD:[")) { + for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) { + unsigned short qdepth = simple_strtoul(options, &options, 0); + if (qdepth > BLOGIC_MAX_TAG_DEPTH) { + blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth); return 0; } - DriverOptions->QueueDepth[TargetID] = QueueDepth; - if (*OptionsString == ',') - OptionsString++; - else if (*OptionsString == ']') + drvr_opts->qdepth[tgt_id] = qdepth; + if (*options == ',') + options++; + else if (*options == ']') break; else { - BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString); + blogic_err("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, options); return 0; } } - if (*OptionsString != ']') { - BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString); + if (*options != ']') { + blogic_err("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, options); return 0; } else - OptionsString++; - } else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) { - unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0); - if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) { - BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth); + options++; + } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) { + unsigned short qdepth = simple_strtoul(options, &options, 0); + if (qdepth == 0 || + qdepth > BLOGIC_MAX_TAG_DEPTH) { + blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth); return 0; } - DriverOptions->CommonQueueDepth = QueueDepth; - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) - DriverOptions->QueueDepth[TargetID] = QueueDepth; - } else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) { - if (BusLogic_ParseKeyword(&OptionsString, "Default")) { - DriverOptions->TaggedQueuingPermitted = 0x0000; - DriverOptions->TaggedQueuingPermittedMask = 0x0000; - } else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) { - DriverOptions->TaggedQueuingPermitted = 0xFFFF; - DriverOptions->TaggedQueuingPermittedMask = 0xFFFF; - } else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) { - DriverOptions->TaggedQueuingPermitted = 0x0000; - DriverOptions->TaggedQueuingPermittedMask = 0xFFFF; + drvr_opts->common_qdepth = qdepth; + for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) + drvr_opts->qdepth[tgt_id] = qdepth; + } else if (blogic_parse(&options, "TaggedQueuing:") || + blogic_parse(&options, "TQ:")) { + if (blogic_parse(&options, "Default")) { + drvr_opts->tagq_ok = 0x0000; + drvr_opts->tagq_ok_mask = 0x0000; + } else if (blogic_parse(&options, "Enable")) { + drvr_opts->tagq_ok = 0xFFFF; + drvr_opts->tagq_ok_mask = 0xFFFF; + } else if (blogic_parse(&options, "Disable")) { + drvr_opts->tagq_ok = 0x0000; + drvr_opts->tagq_ok_mask = 0xFFFF; } else { - unsigned short TargetBit; - for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1) - switch (*OptionsString++) { + unsigned short tgt_bit; + for (tgt_id = 0, tgt_bit = 1; + tgt_id < BLOGIC_MAXDEV; + tgt_id++, tgt_bit <<= 1) + switch (*options++) { case 'Y': - DriverOptions->TaggedQueuingPermitted |= TargetBit; - DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + drvr_opts->tagq_ok |= tgt_bit; + drvr_opts->tagq_ok_mask |= tgt_bit; break; case 'N': - DriverOptions->TaggedQueuingPermitted &= ~TargetBit; - DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + drvr_opts->tagq_ok &= ~tgt_bit; + drvr_opts->tagq_ok_mask |= tgt_bit; break; case 'X': break; default: - OptionsString--; - TargetID = BusLogic_MaxTargetDevices; + options--; + tgt_id = BLOGIC_MAXDEV; break; } } } /* Miscellaneous Options. */ - else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) { - unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0); - if (BusSettleTime > 5 * 60) { - BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime); + else if (blogic_parse(&options, "BusSettleTime:") || + blogic_parse(&options, "BST:")) { + unsigned short bus_settle_time = + simple_strtoul(options, &options, 0); + if (bus_settle_time > 5 * 60) { + blogic_err("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, bus_settle_time); return 0; } - DriverOptions->BusSettleTime = BusSettleTime; - } else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry")) - DriverOptions->LocalOptions.InhibitTargetInquiry = true; + drvr_opts->bus_settle_time = bus_settle_time; + } else if (blogic_parse(&options, + "InhibitTargetInquiry")) + drvr_opts->stop_tgt_inquiry = true; /* Debugging Options. */ - else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe")) - BusLogic_GlobalOptions.TraceProbe = true; - else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset")) - BusLogic_GlobalOptions.TraceHardwareReset = true; - else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration")) - BusLogic_GlobalOptions.TraceConfiguration = true; - else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors")) - BusLogic_GlobalOptions.TraceErrors = true; - else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) { - BusLogic_GlobalOptions.TraceProbe = true; - BusLogic_GlobalOptions.TraceHardwareReset = true; - BusLogic_GlobalOptions.TraceConfiguration = true; - BusLogic_GlobalOptions.TraceErrors = true; + else if (blogic_parse(&options, "TraceProbe")) + blogic_global_options.trace_probe = true; + else if (blogic_parse(&options, "TraceHardwareReset")) + blogic_global_options.trace_hw_reset = true; + else if (blogic_parse(&options, "TraceConfiguration")) + blogic_global_options.trace_config = true; + else if (blogic_parse(&options, "TraceErrors")) + blogic_global_options.trace_err = true; + else if (blogic_parse(&options, "Debug")) { + blogic_global_options.trace_probe = true; + blogic_global_options.trace_hw_reset = true; + blogic_global_options.trace_config = true; + blogic_global_options.trace_err = true; } - if (*OptionsString == ',') - OptionsString++; - else if (*OptionsString != ';' && *OptionsString != '\0') { - BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString); - *OptionsString = '\0'; + if (*options == ',') + options++; + else if (*options != ';' && *options != '\0') { + blogic_err("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, options); + *options = '\0'; } } - if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) { - BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL); + if (!(blogic_drvr_options_count == 0 || + blogic_probeinfo_count == 0 || + blogic_drvr_options_count == blogic_probeinfo_count)) { + blogic_err("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL); return 0; } /* Tagged Queuing is disabled when the Queue Depth is 1 since queuing multiple commands is not possible. */ - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) - if (DriverOptions->QueueDepth[TargetID] == 1) { - unsigned short TargetBit = 1 << TargetID; - DriverOptions->TaggedQueuingPermitted &= ~TargetBit; - DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) + if (drvr_opts->qdepth[tgt_id] == 1) { + unsigned short tgt_bit = 1 << tgt_id; + drvr_opts->tagq_ok &= ~tgt_bit; + drvr_opts->tagq_ok_mask |= tgt_bit; } - if (*OptionsString == ';') - OptionsString++; - if (*OptionsString == '\0') + if (*options == ';') + options++; + if (*options == '\0') return 0; } return 1; @@ -3555,19 +3822,19 @@ static int __init BusLogic_ParseDriverOptions(char *OptionsString) Get it all started */ -static struct scsi_host_template Bus_Logic_template = { +static struct scsi_host_template blogic_template = { .module = THIS_MODULE, .proc_name = "BusLogic", - .write_info = BusLogic_write_info, - .show_info = BusLogic_show_info, + .write_info = blogic_write_info, + .show_info = blogic_show_info, .name = "BusLogic", - .info = BusLogic_DriverInfo, - .queuecommand = BusLogic_QueueCommand, - .slave_configure = BusLogic_SlaveConfigure, - .bios_param = BusLogic_BIOSDiskParameters, - .eh_host_reset_handler = BusLogic_host_reset, + .info = blogic_drvr_info, + .queuecommand = blogic_qcmd, + .slave_configure = blogic_slaveconfig, + .bios_param = blogic_diskparam, + .eh_host_reset_handler = blogic_hostreset, #if 0 - .eh_abort_handler = BusLogic_AbortCommand, + .eh_abort_handler = blogic_abort, #endif .unchecked_isa_dma = 1, .max_sectors = 128, @@ -3575,40 +3842,40 @@ static struct scsi_host_template Bus_Logic_template = { }; /* - BusLogic_Setup handles processing of Kernel Command Line Arguments. + blogic_setup handles processing of Kernel Command Line Arguments. */ -static int __init BusLogic_Setup(char *str) +static int __init blogic_setup(char *str) { int ints[3]; (void) get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] != 0) { - BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL); + blogic_err("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL); return 0; } if (str == NULL || *str == '\0') return 0; - return BusLogic_ParseDriverOptions(str); + return blogic_parseopts(str); } /* * Exit function. Deletes all hosts associated with this driver. */ -static void __exit BusLogic_exit(void) +static void __exit blogic_exit(void) { - struct BusLogic_HostAdapter *ha, *next; + struct blogic_adapter *ha, *next; - list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list) - BusLogic_ReleaseHostAdapter(ha); + list_for_each_entry_safe(ha, next, &blogic_host_list, host_list) + blogic_deladapter(ha); } -__setup("BusLogic=", BusLogic_Setup); +__setup("BusLogic=", blogic_setup); #ifdef MODULE -static struct pci_device_id BusLogic_pci_tbl[] = { +/*static struct pci_device_id blogic_pci_tbl[] = { { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, @@ -3616,9 +3883,15 @@ static struct pci_device_id BusLogic_pci_tbl[] = { { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } +};*/ +static DEFINE_PCI_DEVICE_TABLE(blogic_pci_tbl) = { + {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)}, + {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)}, + {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)}, + {0, }, }; #endif -MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl); +MODULE_DEVICE_TABLE(pci, blogic_pci_tbl); -module_init(BusLogic_init); -module_exit(BusLogic_exit); +module_init(blogic_init); +module_exit(blogic_exit); diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 6c6c13c..8349c0f 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -37,14 +37,14 @@ Define the maximum number of BusLogic Host Adapters supported by this driver. */ -#define BusLogic_MaxHostAdapters 16 +#define BLOGIC_MAX_ADAPTERS 16 /* Define the maximum number of Target Devices supported by this driver. */ -#define BusLogic_MaxTargetDevices 16 +#define BLOGIC_MAXDEV 16 /* @@ -53,7 +53,7 @@ large as the largest single request generated by the I/O Subsystem. */ -#define BusLogic_ScatterGatherLimit 128 +#define BLOGIC_SG_LIMIT 128 /* @@ -62,12 +62,12 @@ Tagged Queuing and whether or not ISA Bounce Buffers are required. */ -#define BusLogic_MaxTaggedQueueDepth 64 -#define BusLogic_MaxAutomaticTaggedQueueDepth 28 -#define BusLogic_MinAutomaticTaggedQueueDepth 7 -#define BusLogic_TaggedQueueDepthBB 3 -#define BusLogic_UntaggedQueueDepth 3 -#define BusLogic_UntaggedQueueDepthBB 2 +#define BLOGIC_MAX_TAG_DEPTH 64 +#define BLOGIC_MAX_AUTO_TAG_DEPTH 28 +#define BLOGIC_MIN_AUTO_TAG_DEPTH 7 +#define BLOGIC_TAG_DEPTH_BB 3 +#define BLOGIC_UNTAG_DEPTH 3 +#define BLOGIC_UNTAG_DEPTH_BB 2 /* @@ -77,7 +77,7 @@ a SCSI Bus Reset. */ -#define BusLogic_DefaultBusSettleTime 2 +#define BLOGIC_BUS_SETTLE_TIME 2 /* @@ -87,7 +87,7 @@ does not cross an allocation block size boundary. */ -#define BusLogic_MaxMailboxes 211 +#define BLOGIC_MAX_MAILBOX 211 /* @@ -95,50 +95,50 @@ Kernel memory allocation. */ -#define BusLogic_CCB_AllocationGroupSize 7 +#define BLOGIC_CCB_GRP_ALLOCSIZE 7 /* Define the Host Adapter Line and Message Buffer Sizes. */ -#define BusLogic_LineBufferSize 100 -#define BusLogic_MessageBufferSize 9700 +#define BLOGIC_LINEBUF_SIZE 100 +#define BLOGIC_MSGBUF_SIZE 9700 /* Define the Driver Message Levels. */ -enum BusLogic_MessageLevel { - BusLogic_AnnounceLevel = 0, - BusLogic_InfoLevel = 1, - BusLogic_NoticeLevel = 2, - BusLogic_WarningLevel = 3, - BusLogic_ErrorLevel = 4 +enum blogic_msglevel { + BLOGIC_ANNOUNCE_LEVEL = 0, + BLOGIC_INFO_LEVEL = 1, + BLOGIC_NOTICE_LEVEL = 2, + BLOGIC_WARN_LEVEL = 3, + BLOGIC_ERR_LEVEL = 4 }; -static char *BusLogic_MessageLevelMap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR }; +static char *blogic_msglevelmap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR }; /* Define Driver Message macros. */ -#define BusLogic_Announce(Format, Arguments...) \ - BusLogic_Message(BusLogic_AnnounceLevel, Format, ##Arguments) +#define blogic_announce(format, args...) \ + blogic_msg(BLOGIC_ANNOUNCE_LEVEL, format, ##args) -#define BusLogic_Info(Format, Arguments...) \ - BusLogic_Message(BusLogic_InfoLevel, Format, ##Arguments) +#define blogic_info(format, args...) \ + blogic_msg(BLOGIC_INFO_LEVEL, format, ##args) -#define BusLogic_Notice(Format, Arguments...) \ - BusLogic_Message(BusLogic_NoticeLevel, Format, ##Arguments) +#define blogic_notice(format, args...) \ + blogic_msg(BLOGIC_NOTICE_LEVEL, format, ##args) -#define BusLogic_Warning(Format, Arguments...) \ - BusLogic_Message(BusLogic_WarningLevel, Format, ##Arguments) +#define blogic_warn(format, args...) \ + blogic_msg(BLOGIC_WARN_LEVEL, format, ##args) -#define BusLogic_Error(Format, Arguments...) \ - BusLogic_Message(BusLogic_ErrorLevel, Format, ##Arguments) +#define blogic_err(format, args...) \ + blogic_msg(BLOGIC_ERR_LEVEL, format, ##args) /* @@ -146,15 +146,15 @@ static char *BusLogic_MessageLevelMap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTIC of I/O Addresses required by each type. */ -enum BusLogic_HostAdapterType { - BusLogic_MultiMaster = 1, - BusLogic_FlashPoint = 2 +enum blogic_adapter_type { + BLOGIC_MULTIMASTER = 1, + BLOGIC_FLASHPOINT = 2 } PACKED; -#define BusLogic_MultiMasterAddressCount 4 -#define BusLogic_FlashPointAddressCount 256 +#define BLOGIC_MULTIMASTER_ADDR_COUNT 4 +#define BLOGIC_FLASHPOINT_ADDR_COUNT 256 -static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddressCount, BusLogic_FlashPointAddressCount }; +static int blogic_adapter_addr_count[3] = { 0, BLOGIC_MULTIMASTER_ADDR_COUNT, BLOGIC_FLASHPOINT_ADDR_COUNT }; /* @@ -163,19 +163,16 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres #ifdef CONFIG_SCSI_FLASHPOINT -#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ - (HostAdapter->HostAdapterType == BusLogic_MultiMaster) +#define blogic_multimaster_type(adapter) \ + (adapter->adapter_type == BLOGIC_MULTIMASTER) -#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ - (HostAdapter->HostAdapterType == BusLogic_FlashPoint) +#define blogic_flashpoint_type(adapter) \ + (adapter->adapter_type == BLOGIC_FLASHPOINT) #else -#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ - (true) - -#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ - (false) +#define blogic_multimaster_type(adapter) (true) +#define blogic_flashpoint_type(adapter) (false) #endif @@ -184,35 +181,35 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres Define the possible Host Adapter Bus Types. */ -enum BusLogic_HostAdapterBusType { - BusLogic_Unknown_Bus = 0, - BusLogic_ISA_Bus = 1, - BusLogic_EISA_Bus = 2, - BusLogic_PCI_Bus = 3, - BusLogic_VESA_Bus = 4, - BusLogic_MCA_Bus = 5 +enum blogic_adapter_bus_type { + BLOGIC_UNKNOWN_BUS = 0, + BLOGIC_ISA_BUS = 1, + BLOGIC_EISA_BUS = 2, + BLOGIC_PCI_BUS = 3, + BLOGIC_VESA_BUS = 4, + BLOGIC_MCA_BUS = 5 } PACKED; -static char *BusLogic_HostAdapterBusNames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" }; +static char *blogic_adapter_busnames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" }; -static enum BusLogic_HostAdapterBusType BusLogic_HostAdapterBusTypes[] = { - BusLogic_VESA_Bus, /* BT-4xx */ - BusLogic_ISA_Bus, /* BT-5xx */ - BusLogic_MCA_Bus, /* BT-6xx */ - BusLogic_EISA_Bus, /* BT-7xx */ - BusLogic_Unknown_Bus, /* BT-8xx */ - BusLogic_PCI_Bus /* BT-9xx */ +static enum blogic_adapter_bus_type blogic_adater_bus_types[] = { + BLOGIC_VESA_BUS, /* BT-4xx */ + BLOGIC_ISA_BUS, /* BT-5xx */ + BLOGIC_MCA_BUS, /* BT-6xx */ + BLOGIC_EISA_BUS, /* BT-7xx */ + BLOGIC_UNKNOWN_BUS, /* BT-8xx */ + BLOGIC_PCI_BUS /* BT-9xx */ }; /* Define the possible Host Adapter BIOS Disk Geometry Translations. */ -enum BusLogic_BIOS_DiskGeometryTranslation { - BusLogic_BIOS_Disk_Not_Installed = 0, - BusLogic_BIOS_Disk_Installed_64x32 = 1, - BusLogic_BIOS_Disk_Installed_128x32 = 2, - BusLogic_BIOS_Disk_Installed_255x63 = 3 +enum blogic_bios_diskgeometry { + BLOGIC_BIOS_NODISK = 0, + BLOGIC_BIOS_DISK64x32 = 1, + BLOGIC_BIOS_DISK128x32 = 2, + BLOGIC_BIOS_DISK255x63 = 3 } PACKED; @@ -220,9 +217,9 @@ enum BusLogic_BIOS_DiskGeometryTranslation { Define a 10^18 Statistics Byte Counter data type. */ -struct BusLogic_ByteCounter { - unsigned int Units; - unsigned int Billions; +struct blogic_byte_count { + unsigned int units; + unsigned int billions; }; @@ -230,79 +227,71 @@ struct BusLogic_ByteCounter { Define the structure for I/O Address and Bus Probing Information. */ -struct BusLogic_ProbeInfo { - enum BusLogic_HostAdapterType HostAdapterType; - enum BusLogic_HostAdapterBusType HostAdapterBusType; - unsigned long IO_Address; - unsigned long PCI_Address; - struct pci_dev *PCI_Device; - unsigned char Bus; - unsigned char Device; - unsigned char IRQ_Channel; +struct blogic_probeinfo { + enum blogic_adapter_type adapter_type; + enum blogic_adapter_bus_type adapter_bus_type; + unsigned long io_addr; + unsigned long pci_addr; + struct pci_dev *pci_device; + unsigned char bus; + unsigned char dev; + unsigned char irq_ch; }; /* Define the Probe Options. */ -struct BusLogic_ProbeOptions { - bool NoProbe:1; /* Bit 0 */ - bool NoProbeISA:1; /* Bit 1 */ - bool NoProbePCI:1; /* Bit 2 */ - bool NoSortPCI:1; /* Bit 3 */ - bool MultiMasterFirst:1;/* Bit 4 */ - bool FlashPointFirst:1; /* Bit 5 */ - bool LimitedProbeISA:1; /* Bit 6 */ - bool Probe330:1; /* Bit 7 */ - bool Probe334:1; /* Bit 8 */ - bool Probe230:1; /* Bit 9 */ - bool Probe234:1; /* Bit 10 */ - bool Probe130:1; /* Bit 11 */ - bool Probe134:1; /* Bit 12 */ +struct blogic_probe_options { + bool noprobe:1; /* Bit 0 */ + bool noprobe_isa:1; /* Bit 1 */ + bool noprobe_pci:1; /* Bit 2 */ + bool nosort_pci:1; /* Bit 3 */ + bool multimaster_first:1; /* Bit 4 */ + bool flashpoint_first:1; /* Bit 5 */ + bool limited_isa:1; /* Bit 6 */ + bool probe330:1; /* Bit 7 */ + bool probe334:1; /* Bit 8 */ + bool probe230:1; /* Bit 9 */ + bool probe234:1; /* Bit 10 */ + bool probe130:1; /* Bit 11 */ + bool probe134:1; /* Bit 12 */ }; /* Define the Global Options. */ -struct BusLogic_GlobalOptions { - bool TraceProbe:1; /* Bit 0 */ - bool TraceHardwareReset:1; /* Bit 1 */ - bool TraceConfiguration:1; /* Bit 2 */ - bool TraceErrors:1; /* Bit 3 */ -}; - -/* - Define the Local Options. -*/ - -struct BusLogic_LocalOptions { - bool InhibitTargetInquiry:1; /* Bit 0 */ +struct blogic_global_options { + bool trace_probe:1; /* Bit 0 */ + bool trace_hw_reset:1; /* Bit 1 */ + bool trace_config:1; /* Bit 2 */ + bool trace_err:1; /* Bit 3 */ }; /* Define the BusLogic SCSI Host Adapter I/O Register Offsets. */ -#define BusLogic_ControlRegisterOffset 0 /* WO register */ -#define BusLogic_StatusRegisterOffset 0 /* RO register */ -#define BusLogic_CommandParameterRegisterOffset 1 /* WO register */ -#define BusLogic_DataInRegisterOffset 1 /* RO register */ -#define BusLogic_InterruptRegisterOffset 2 /* RO register */ -#define BusLogic_GeometryRegisterOffset 3 /* RO register */ +#define BLOGIC_CNTRL_REG 0 /* WO register */ +#define BLOGIC_STATUS_REG 0 /* RO register */ +#define BLOGIC_CMD_PARM_REG 1 /* WO register */ +#define BLOGIC_DATAIN_REG 1 /* RO register */ +#define BLOGIC_INT_REG 2 /* RO register */ +#define BLOGIC_GEOMETRY_REG 3 /* RO register */ /* Define the structure of the write-only Control Register. */ -union BusLogic_ControlRegister { - unsigned char All; +union blogic_cntrl_reg { + unsigned char all; struct { unsigned char:4; /* Bits 0-3 */ - bool SCSIBusReset:1; /* Bit 4 */ - bool InterruptReset:1; /* Bit 5 */ - bool SoftReset:1; /* Bit 6 */ - bool HardReset:1; /* Bit 7 */ + bool bus_reset:1; /* Bit 4 */ + bool int_reset:1; /* Bit 5 */ + bool soft_reset:1; /* Bit 6 */ + bool hard_reset:1; /* Bit 7 */ } cr; }; @@ -310,17 +299,17 @@ union BusLogic_ControlRegister { Define the structure of the read-only Status Register. */ -union BusLogic_StatusRegister { - unsigned char All; +union blogic_stat_reg { + unsigned char all; struct { - bool CommandInvalid:1; /* Bit 0 */ - bool Reserved:1; /* Bit 1 */ - bool DataInRegisterReady:1; /* Bit 2 */ - bool CommandParameterRegisterBusy:1; /* Bit 3 */ - bool HostAdapterReady:1; /* Bit 4 */ - bool InitializationRequired:1; /* Bit 5 */ - bool DiagnosticFailure:1; /* Bit 6 */ - bool DiagnosticActive:1; /* Bit 7 */ + bool cmd_invalid:1; /* Bit 0 */ + bool rsvd:1; /* Bit 1 */ + bool datain_ready:1; /* Bit 2 */ + bool cmd_param_busy:1; /* Bit 3 */ + bool adapter_ready:1; /* Bit 4 */ + bool init_reqd:1; /* Bit 5 */ + bool diag_failed:1; /* Bit 6 */ + bool diag_active:1; /* Bit 7 */ } sr; }; @@ -328,15 +317,15 @@ union BusLogic_StatusRegister { Define the structure of the read-only Interrupt Register. */ -union BusLogic_InterruptRegister { - unsigned char All; +union blogic_int_reg { + unsigned char all; struct { - bool IncomingMailboxLoaded:1; /* Bit 0 */ - bool OutgoingMailboxAvailable:1;/* Bit 1 */ - bool CommandComplete:1; /* Bit 2 */ - bool ExternalBusReset:1; /* Bit 3 */ - unsigned char Reserved:3; /* Bits 4-6 */ - bool InterruptValid:1; /* Bit 7 */ + bool mailin_loaded:1; /* Bit 0 */ + bool mailout_avail:1; /* Bit 1 */ + bool cmd_complete:1; /* Bit 2 */ + bool ext_busreset:1; /* Bit 3 */ + unsigned char rsvd:3; /* Bits 4-6 */ + bool int_valid:1; /* Bit 7 */ } ir; }; @@ -344,13 +333,13 @@ union BusLogic_InterruptRegister { Define the structure of the read-only Geometry Register. */ -union BusLogic_GeometryRegister { - unsigned char All; +union blogic_geo_reg { + unsigned char all; struct { - enum BusLogic_BIOS_DiskGeometryTranslation Drive0Geometry:2; /* Bits 0-1 */ - enum BusLogic_BIOS_DiskGeometryTranslation Drive1Geometry:2; /* Bits 2-3 */ + enum blogic_bios_diskgeometry d0_geo:2; /* Bits 0-1 */ + enum blogic_bios_diskgeometry d1_geo:2; /* Bits 2-3 */ unsigned char:3; /* Bits 4-6 */ - bool ExtendedTranslationEnabled:1; /* Bit 7 */ + bool ext_trans_enable:1; /* Bit 7 */ } gr; }; @@ -358,82 +347,82 @@ union BusLogic_GeometryRegister { Define the BusLogic SCSI Host Adapter Command Register Operation Codes. */ -enum BusLogic_OperationCode { - BusLogic_TestCommandCompleteInterrupt = 0x00, - BusLogic_InitializeMailbox = 0x01, - BusLogic_ExecuteMailboxCommand = 0x02, - BusLogic_ExecuteBIOSCommand = 0x03, - BusLogic_InquireBoardID = 0x04, - BusLogic_EnableOutgoingMailboxAvailableInt = 0x05, - BusLogic_SetSCSISelectionTimeout = 0x06, - BusLogic_SetPreemptTimeOnBus = 0x07, - BusLogic_SetTimeOffBus = 0x08, - BusLogic_SetBusTransferRate = 0x09, - BusLogic_InquireInstalledDevicesID0to7 = 0x0A, - BusLogic_InquireConfiguration = 0x0B, - BusLogic_EnableTargetMode = 0x0C, - BusLogic_InquireSetupInformation = 0x0D, - BusLogic_WriteAdapterLocalRAM = 0x1A, - BusLogic_ReadAdapterLocalRAM = 0x1B, - BusLogic_WriteBusMasterChipFIFO = 0x1C, - BusLogic_ReadBusMasterChipFIFO = 0x1D, - BusLogic_EchoCommandData = 0x1F, - BusLogic_HostAdapterDiagnostic = 0x20, - BusLogic_SetAdapterOptions = 0x21, - BusLogic_InquireInstalledDevicesID8to15 = 0x23, - BusLogic_InquireTargetDevices = 0x24, - BusLogic_DisableHostAdapterInterrupt = 0x25, - BusLogic_InitializeExtendedMailbox = 0x81, - BusLogic_ExecuteSCSICommand = 0x83, - BusLogic_InquireFirmwareVersion3rdDigit = 0x84, - BusLogic_InquireFirmwareVersionLetter = 0x85, - BusLogic_InquirePCIHostAdapterInformation = 0x86, - BusLogic_InquireHostAdapterModelNumber = 0x8B, - BusLogic_InquireSynchronousPeriod = 0x8C, - BusLogic_InquireExtendedSetupInformation = 0x8D, - BusLogic_EnableStrictRoundRobinMode = 0x8F, - BusLogic_StoreHostAdapterLocalRAM = 0x90, - BusLogic_FetchHostAdapterLocalRAM = 0x91, - BusLogic_StoreLocalDataInEEPROM = 0x92, - BusLogic_UploadAutoSCSICode = 0x94, - BusLogic_ModifyIOAddress = 0x95, - BusLogic_SetCCBFormat = 0x96, - BusLogic_WriteInquiryBuffer = 0x9A, - BusLogic_ReadInquiryBuffer = 0x9B, - BusLogic_FlashROMUploadDownload = 0xA7, - BusLogic_ReadSCAMData = 0xA8, - BusLogic_WriteSCAMData = 0xA9 +enum blogic_opcode { + BLOGIC_TEST_CMP_COMPLETE = 0x00, + BLOGIC_INIT_MBOX = 0x01, + BLOGIC_EXEC_MBOX_CMD = 0x02, + BLOGIC_EXEC_BIOS_CMD = 0x03, + BLOGIC_GET_BOARD_ID = 0x04, + BLOGIC_ENABLE_OUTBOX_AVAIL_INT = 0x05, + BLOGIC_SET_SELECT_TIMEOUT = 0x06, + BLOGIC_SET_PREEMPT_TIME = 0x07, + BLOGIC_SET_TIMEOFF_BUS = 0x08, + BLOGIC_SET_TXRATE = 0x09, + BLOGIC_INQ_DEV0TO7 = 0x0A, + BLOGIC_INQ_CONFIG = 0x0B, + BLOGIC_TGT_MODE = 0x0C, + BLOGIC_INQ_SETUPINFO = 0x0D, + BLOGIC_WRITE_LOCALRAM = 0x1A, + BLOGIC_READ_LOCALRAM = 0x1B, + BLOGIC_WRITE_BUSMASTER_FIFO = 0x1C, + BLOGIC_READ_BUSMASTER_FIFO = 0x1D, + BLOGIC_ECHO_CMDDATA = 0x1F, + BLOGIC_ADAPTER_DIAG = 0x20, + BLOGIC_SET_OPTIONS = 0x21, + BLOGIC_INQ_DEV8TO15 = 0x23, + BLOGIC_INQ_DEV = 0x24, + BLOGIC_DISABLE_INT = 0x25, + BLOGIC_INIT_EXT_MBOX = 0x81, + BLOGIC_EXEC_SCS_CMD = 0x83, + BLOGIC_INQ_FWVER_D3 = 0x84, + BLOGIC_INQ_FWVER_LETTER = 0x85, + BLOGIC_INQ_PCI_INFO = 0x86, + BLOGIC_INQ_MODELNO = 0x8B, + BLOGIC_INQ_SYNC_PERIOD = 0x8C, + BLOGIC_INQ_EXTSETUP = 0x8D, + BLOGIC_STRICT_RR = 0x8F, + BLOGIC_STORE_LOCALRAM = 0x90, + BLOGIC_FETCH_LOCALRAM = 0x91, + BLOGIC_STORE_TO_EEPROM = 0x92, + BLOGIC_LOAD_AUTOSCSICODE = 0x94, + BLOGIC_MOD_IOADDR = 0x95, + BLOGIC_SETCCB_FMT = 0x96, + BLOGIC_WRITE_INQBUF = 0x9A, + BLOGIC_READ_INQBUF = 0x9B, + BLOGIC_FLASH_LOAD = 0xA7, + BLOGIC_READ_SCAMDATA = 0xA8, + BLOGIC_WRITE_SCAMDATA = 0xA9 }; /* Define the Inquire Board ID reply structure. */ -struct BusLogic_BoardID { - unsigned char BoardType; /* Byte 0 */ - unsigned char CustomFeatures; /* Byte 1 */ - unsigned char FirmwareVersion1stDigit; /* Byte 2 */ - unsigned char FirmwareVersion2ndDigit; /* Byte 3 */ +struct blogic_board_id { + unsigned char type; /* Byte 0 */ + unsigned char custom_features; /* Byte 1 */ + unsigned char fw_ver_digit1; /* Byte 2 */ + unsigned char fw_ver_digit2; /* Byte 3 */ }; /* Define the Inquire Configuration reply structure. */ -struct BusLogic_Configuration { +struct blogic_config { unsigned char:5; /* Byte 0 Bits 0-4 */ - bool DMA_Channel5:1; /* Byte 0 Bit 5 */ - bool DMA_Channel6:1; /* Byte 0 Bit 6 */ - bool DMA_Channel7:1; /* Byte 0 Bit 7 */ - bool IRQ_Channel9:1; /* Byte 1 Bit 0 */ - bool IRQ_Channel10:1; /* Byte 1 Bit 1 */ - bool IRQ_Channel11:1; /* Byte 1 Bit 2 */ - bool IRQ_Channel12:1; /* Byte 1 Bit 3 */ + bool dma_ch5:1; /* Byte 0 Bit 5 */ + bool dma_ch6:1; /* Byte 0 Bit 6 */ + bool dma_ch7:1; /* Byte 0 Bit 7 */ + bool irq_ch9:1; /* Byte 1 Bit 0 */ + bool irq_ch10:1; /* Byte 1 Bit 1 */ + bool irq_ch11:1; /* Byte 1 Bit 2 */ + bool irq_ch12:1; /* Byte 1 Bit 3 */ unsigned char:1; /* Byte 1 Bit 4 */ - bool IRQ_Channel14:1; /* Byte 1 Bit 5 */ - bool IRQ_Channel15:1; /* Byte 1 Bit 6 */ + bool irq_ch14:1; /* Byte 1 Bit 5 */ + bool irq_ch15:1; /* Byte 1 Bit 6 */ unsigned char:1; /* Byte 1 Bit 7 */ - unsigned char HostAdapterID:4; /* Byte 2 Bits 0-3 */ + unsigned char id:4; /* Byte 2 Bits 0-3 */ unsigned char:4; /* Byte 2 Bits 4-7 */ }; @@ -441,42 +430,42 @@ struct BusLogic_Configuration { Define the Inquire Setup Information reply structure. */ -struct BusLogic_SynchronousValue { - unsigned char Offset:4; /* Bits 0-3 */ - unsigned char TransferPeriod:3; /* Bits 4-6 */ - bool Synchronous:1; /* Bit 7 */ +struct blogic_syncval { + unsigned char offset:4; /* Bits 0-3 */ + unsigned char tx_period:3; /* Bits 4-6 */ + bool sync:1; /* Bit 7 */ }; -struct BusLogic_SetupInformation { - bool SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */ - bool ParityCheckingEnabled:1; /* Byte 0 Bit 1 */ - unsigned char:6; /* Byte 0 Bits 2-7 */ - unsigned char BusTransferRate; /* Byte 1 */ - unsigned char PreemptTimeOnBus; /* Byte 2 */ - unsigned char TimeOffBus; /* Byte 3 */ - unsigned char MailboxCount; /* Byte 4 */ - unsigned char MailboxAddress[3]; /* Bytes 5-7 */ - struct BusLogic_SynchronousValue SynchronousValuesID0to7[8]; /* Bytes 8-15 */ - unsigned char DisconnectPermittedID0to7; /* Byte 16 */ - unsigned char Signature; /* Byte 17 */ - unsigned char CharacterD; /* Byte 18 */ - unsigned char HostBusType; /* Byte 19 */ - unsigned char WideTransfersPermittedID0to7; /* Byte 20 */ - unsigned char WideTransfersActiveID0to7; /* Byte 21 */ - struct BusLogic_SynchronousValue SynchronousValuesID8to15[8]; /* Bytes 22-29 */ - unsigned char DisconnectPermittedID8to15; /* Byte 30 */ - unsigned char:8; /* Byte 31 */ - unsigned char WideTransfersPermittedID8to15; /* Byte 32 */ - unsigned char WideTransfersActiveID8to15; /* Byte 33 */ +struct blogic_setup_info { + bool sync:1; /* Byte 0 Bit 0 */ + bool parity:1; /* Byte 0 Bit 1 */ + unsigned char:6; /* Byte 0 Bits 2-7 */ + unsigned char tx_rate; /* Byte 1 */ + unsigned char preempt_time; /* Byte 2 */ + unsigned char timeoff_bus; /* Byte 3 */ + unsigned char mbox_count; /* Byte 4 */ + unsigned char mbox_addr[3]; /* Bytes 5-7 */ + struct blogic_syncval sync0to7[8]; /* Bytes 8-15 */ + unsigned char disconnect_ok0to7; /* Byte 16 */ + unsigned char sig; /* Byte 17 */ + unsigned char char_d; /* Byte 18 */ + unsigned char bus_type; /* Byte 19 */ + unsigned char wide_tx_ok0to7; /* Byte 20 */ + unsigned char wide_tx_active0to7; /* Byte 21 */ + struct blogic_syncval sync8to15[8]; /* Bytes 22-29 */ + unsigned char disconnect_ok8to15; /* Byte 30 */ + unsigned char:8; /* Byte 31 */ + unsigned char wide_tx_ok8to15; /* Byte 32 */ + unsigned char wide_tx_active8to15; /* Byte 33 */ }; /* Define the Initialize Extended Mailbox request structure. */ -struct BusLogic_ExtendedMailboxRequest { - unsigned char MailboxCount; /* Byte 0 */ - u32 BaseMailboxAddress; /* Bytes 1-4 */ +struct blogic_extmbox_req { + unsigned char mbox_count; /* Byte 0 */ + u32 base_mbox_addr; /* Bytes 1-4 */ } PACKED; @@ -486,63 +475,63 @@ struct BusLogic_ExtendedMailboxRequest { the Modify I/O Address command. */ -enum BusLogic_ISACompatibleIOPort { - BusLogic_IO_330 = 0, - BusLogic_IO_334 = 1, - BusLogic_IO_230 = 2, - BusLogic_IO_234 = 3, - BusLogic_IO_130 = 4, - BusLogic_IO_134 = 5, - BusLogic_IO_Disable = 6, - BusLogic_IO_Disable2 = 7 +enum blogic_isa_ioport { + BLOGIC_IO_330 = 0, + BLOGIC_IO_334 = 1, + BLOGIC_IO_230 = 2, + BLOGIC_IO_234 = 3, + BLOGIC_IO_130 = 4, + BLOGIC_IO_134 = 5, + BLOGIC_IO_DISABLE = 6, + BLOGIC_IO_DISABLE2 = 7 } PACKED; -struct BusLogic_PCIHostAdapterInformation { - enum BusLogic_ISACompatibleIOPort ISACompatibleIOPort; /* Byte 0 */ - unsigned char PCIAssignedIRQChannel; /* Byte 1 */ - bool LowByteTerminated:1; /* Byte 2 Bit 0 */ - bool HighByteTerminated:1; /* Byte 2 Bit 1 */ - unsigned char:2; /* Byte 2 Bits 2-3 */ - bool JP1:1; /* Byte 2 Bit 4 */ - bool JP2:1; /* Byte 2 Bit 5 */ - bool JP3:1; /* Byte 2 Bit 6 */ - bool GenericInfoValid:1;/* Byte 2 Bit 7 */ - unsigned char:8; /* Byte 3 */ +struct blogic_adapter_info { + enum blogic_isa_ioport isa_port; /* Byte 0 */ + unsigned char irq_ch; /* Byte 1 */ + bool low_term:1; /* Byte 2 Bit 0 */ + bool high_term:1; /* Byte 2 Bit 1 */ + unsigned char:2; /* Byte 2 Bits 2-3 */ + bool JP1:1; /* Byte 2 Bit 4 */ + bool JP2:1; /* Byte 2 Bit 5 */ + bool JP3:1; /* Byte 2 Bit 6 */ + bool genericinfo_valid:1; /* Byte 2 Bit 7 */ + unsigned char:8; /* Byte 3 */ }; /* Define the Inquire Extended Setup Information reply structure. */ -struct BusLogic_ExtendedSetupInformation { - unsigned char BusType; /* Byte 0 */ - unsigned char BIOS_Address; /* Byte 1 */ - unsigned short ScatterGatherLimit; /* Bytes 2-3 */ - unsigned char MailboxCount; /* Byte 4 */ - u32 BaseMailboxAddress; /* Bytes 5-8 */ +struct blogic_ext_setup { + unsigned char bus_type; /* Byte 0 */ + unsigned char bios_addr; /* Byte 1 */ + unsigned short sg_limit; /* Bytes 2-3 */ + unsigned char mbox_count; /* Byte 4 */ + u32 base_mbox_addr; /* Bytes 5-8 */ struct { unsigned char:2; /* Byte 9 Bits 0-1 */ - bool FastOnEISA:1; /* Byte 9 Bit 2 */ + bool fast_on_eisa:1; /* Byte 9 Bit 2 */ unsigned char:3; /* Byte 9 Bits 3-5 */ - bool LevelSensitiveInterrupt:1; /* Byte 9 Bit 6 */ + bool level_int:1; /* Byte 9 Bit 6 */ unsigned char:1; /* Byte 9 Bit 7 */ - } Misc; - unsigned char FirmwareRevision[3]; /* Bytes 10-12 */ - bool HostWideSCSI:1; /* Byte 13 Bit 0 */ - bool HostDifferentialSCSI:1; /* Byte 13 Bit 1 */ - bool HostSupportsSCAM:1; /* Byte 13 Bit 2 */ - bool HostUltraSCSI:1; /* Byte 13 Bit 3 */ - bool HostSmartTermination:1; /* Byte 13 Bit 4 */ - unsigned char:3; /* Byte 13 Bits 5-7 */ + } misc; + unsigned char fw_rev[3]; /* Bytes 10-12 */ + bool wide:1; /* Byte 13 Bit 0 */ + bool differential:1; /* Byte 13 Bit 1 */ + bool scam:1; /* Byte 13 Bit 2 */ + bool ultra:1; /* Byte 13 Bit 3 */ + bool smart_term:1; /* Byte 13 Bit 4 */ + unsigned char:3; /* Byte 13 Bits 5-7 */ } PACKED; /* Define the Enable Strict Round Robin Mode request type. */ -enum BusLogic_RoundRobinModeRequest { - BusLogic_AggressiveRoundRobinMode = 0, - BusLogic_StrictRoundRobinMode = 1 +enum blogic_rr_req { + BLOGIC_AGGRESSIVE_RR = 0, + BLOGIC_STRICT_RR_MODE = 1 } PACKED; @@ -550,95 +539,95 @@ enum BusLogic_RoundRobinModeRequest { Define the Fetch Host Adapter Local RAM request type. */ -#define BusLogic_BIOS_BaseOffset 0 -#define BusLogic_AutoSCSI_BaseOffset 64 +#define BLOGIC_BIOS_BASE 0 +#define BLOGIC_AUTOSCSI_BASE 64 -struct BusLogic_FetchHostAdapterLocalRAMRequest { - unsigned char ByteOffset; /* Byte 0 */ - unsigned char ByteCount; /* Byte 1 */ +struct blogic_fetch_localram { + unsigned char offset; /* Byte 0 */ + unsigned char count; /* Byte 1 */ }; /* Define the Host Adapter Local RAM AutoSCSI structure. */ -struct BusLogic_AutoSCSIData { - unsigned char InternalFactorySignature[2]; /* Bytes 0-1 */ - unsigned char InformationByteCount; /* Byte 2 */ - unsigned char HostAdapterType[6]; /* Bytes 3-8 */ - unsigned char:8; /* Byte 9 */ - bool FloppyEnabled:1; /* Byte 10 Bit 0 */ - bool FloppySecondary:1; /* Byte 10 Bit 1 */ - bool LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */ - unsigned char:2; /* Byte 10 Bits 3-4 */ - unsigned char SystemRAMAreaForBIOS:3; /* Byte 10 Bits 5-7 */ - unsigned char DMA_Channel:7; /* Byte 11 Bits 0-6 */ - bool DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */ - unsigned char IRQ_Channel:7; /* Byte 12 Bits 0-6 */ - bool IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */ - unsigned char DMA_TransferRate; /* Byte 13 */ - unsigned char SCSI_ID; /* Byte 14 */ - bool LowByteTerminated:1; /* Byte 15 Bit 0 */ - bool ParityCheckingEnabled:1; /* Byte 15 Bit 1 */ - bool HighByteTerminated:1; /* Byte 15 Bit 2 */ - bool NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */ - bool FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */ - bool BusResetEnabled:1; /* Byte 15 Bit 5 */ - bool:1; /* Byte 15 Bit 6 */ - bool ActiveNegationEnabled:1; /* Byte 15 Bit 7 */ - unsigned char BusOnDelay; /* Byte 16 */ - unsigned char BusOffDelay; /* Byte 17 */ - bool HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */ - bool BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */ - bool ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */ - bool MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */ - bool:1; /* Byte 18 Bit 4 */ - bool BIOSSupportsMoreThan2DrivesEnabled:1; /* Byte 18 Bit 5 */ - bool BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */ - bool FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */ - unsigned short DeviceEnabled; /* Bytes 19-20 */ - unsigned short WidePermitted; /* Bytes 21-22 */ - unsigned short FastPermitted; /* Bytes 23-24 */ - unsigned short SynchronousPermitted; /* Bytes 25-26 */ - unsigned short DisconnectPermitted; /* Bytes 27-28 */ - unsigned short SendStartUnitCommand; /* Bytes 29-30 */ - unsigned short IgnoreInBIOSScan; /* Bytes 31-32 */ - unsigned char PCIInterruptPin:2; /* Byte 33 Bits 0-1 */ - unsigned char HostAdapterIOPortAddress:2; /* Byte 33 Bits 2-3 */ - bool StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */ - bool VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */ - bool VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */ - bool VESABurstReadEnabled:1; /* Byte 33 Bit 7 */ - unsigned short UltraPermitted; /* Bytes 34-35 */ - unsigned int:32; /* Bytes 36-39 */ - unsigned char:8; /* Byte 40 */ - unsigned char AutoSCSIMaximumLUN; /* Byte 41 */ - bool:1; /* Byte 42 Bit 0 */ - bool SCAM_Dominant:1; /* Byte 42 Bit 1 */ - bool SCAM_Enabled:1; /* Byte 42 Bit 2 */ - bool SCAM_Level2:1; /* Byte 42 Bit 3 */ - unsigned char:4; /* Byte 42 Bits 4-7 */ - bool INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */ - bool:1; /* Byte 43 Bit 1 */ - bool CDROMBootEnabled:1; /* Byte 43 Bit 2 */ - unsigned char:5; /* Byte 43 Bits 3-7 */ - unsigned char BootTargetID:4; /* Byte 44 Bits 0-3 */ - unsigned char BootChannel:4; /* Byte 44 Bits 4-7 */ - unsigned char ForceBusDeviceScanningOrder:1; /* Byte 45 Bit 0 */ - unsigned char:7; /* Byte 45 Bits 1-7 */ - unsigned short NonTaggedToAlternateLUNPermitted; /* Bytes 46-47 */ - unsigned short RenegotiateSyncAfterCheckCondition; /* Bytes 48-49 */ - unsigned char Reserved[10]; /* Bytes 50-59 */ - unsigned char ManufacturingDiagnostic[2]; /* Bytes 60-61 */ - unsigned short Checksum; /* Bytes 62-63 */ +struct blogic_autoscsi { + unsigned char factory_sig[2]; /* Bytes 0-1 */ + unsigned char info_bytes; /* Byte 2 */ + unsigned char adapter_type[6]; /* Bytes 3-8 */ + unsigned char:8; /* Byte 9 */ + bool floppy:1; /* Byte 10 Bit 0 */ + bool floppy_sec:1; /* Byte 10 Bit 1 */ + bool level_int:1; /* Byte 10 Bit 2 */ + unsigned char:2; /* Byte 10 Bits 3-4 */ + unsigned char systemram_bios:3; /* Byte 10 Bits 5-7 */ + unsigned char dma_ch:7; /* Byte 11 Bits 0-6 */ + bool dma_autoconf:1; /* Byte 11 Bit 7 */ + unsigned char irq_ch:7; /* Byte 12 Bits 0-6 */ + bool irq_autoconf:1; /* Byte 12 Bit 7 */ + unsigned char dma_tx_rate; /* Byte 13 */ + unsigned char scsi_id; /* Byte 14 */ + bool low_term:1; /* Byte 15 Bit 0 */ + bool parity:1; /* Byte 15 Bit 1 */ + bool high_term:1; /* Byte 15 Bit 2 */ + bool noisy_cable:1; /* Byte 15 Bit 3 */ + bool fast_sync_neg:1; /* Byte 15 Bit 4 */ + bool reset_enabled:1; /* Byte 15 Bit 5 */ + bool:1; /* Byte 15 Bit 6 */ + bool active_negation:1; /* Byte 15 Bit 7 */ + unsigned char bus_on_delay; /* Byte 16 */ + unsigned char bus_off_delay; /* Byte 17 */ + bool bios_enabled:1; /* Byte 18 Bit 0 */ + bool int19_redir_enabled:1; /* Byte 18 Bit 1 */ + bool ext_trans_enable:1; /* Byte 18 Bit 2 */ + bool removable_as_fixed:1; /* Byte 18 Bit 3 */ + bool:1; /* Byte 18 Bit 4 */ + bool morethan2_drives:1; /* Byte 18 Bit 5 */ + bool bios_int:1; /* Byte 18 Bit 6 */ + bool floptical:1; /* Byte 19 Bit 7 */ + unsigned short dev_enabled; /* Bytes 19-20 */ + unsigned short wide_ok; /* Bytes 21-22 */ + unsigned short fast_ok; /* Bytes 23-24 */ + unsigned short sync_ok; /* Bytes 25-26 */ + unsigned short discon_ok; /* Bytes 27-28 */ + unsigned short send_start_unit; /* Bytes 29-30 */ + unsigned short ignore_bios_scan; /* Bytes 31-32 */ + unsigned char pci_int_pin:2; /* Byte 33 Bits 0-1 */ + unsigned char adapter_ioport:2; /* Byte 33 Bits 2-3 */ + bool strict_rr_enabled:1; /* Byte 33 Bit 4 */ + bool vesabus_33mhzplus:1; /* Byte 33 Bit 5 */ + bool vesa_burst_write:1; /* Byte 33 Bit 6 */ + bool vesa_burst_read:1; /* Byte 33 Bit 7 */ + unsigned short ultra_ok; /* Bytes 34-35 */ + unsigned int:32; /* Bytes 36-39 */ + unsigned char:8; /* Byte 40 */ + unsigned char autoscsi_maxlun; /* Byte 41 */ + bool:1; /* Byte 42 Bit 0 */ + bool scam_dominant:1; /* Byte 42 Bit 1 */ + bool scam_enabled:1; /* Byte 42 Bit 2 */ + bool scam_lev2:1; /* Byte 42 Bit 3 */ + unsigned char:4; /* Byte 42 Bits 4-7 */ + bool int13_exten:1; /* Byte 43 Bit 0 */ + bool:1; /* Byte 43 Bit 1 */ + bool cd_boot:1; /* Byte 43 Bit 2 */ + unsigned char:5; /* Byte 43 Bits 3-7 */ + unsigned char boot_id:4; /* Byte 44 Bits 0-3 */ + unsigned char boot_ch:4; /* Byte 44 Bits 4-7 */ + unsigned char force_scan_order:1; /* Byte 45 Bit 0 */ + unsigned char:7; /* Byte 45 Bits 1-7 */ + unsigned short nontagged_to_alt_ok; /* Bytes 46-47 */ + unsigned short reneg_sync_on_check; /* Bytes 48-49 */ + unsigned char rsvd[10]; /* Bytes 50-59 */ + unsigned char manuf_diag[2]; /* Bytes 60-61 */ + unsigned short cksum; /* Bytes 62-63 */ } PACKED; /* Define the Host Adapter Local RAM Auto SCSI Byte 45 structure. */ -struct BusLogic_AutoSCSIByte45 { - unsigned char ForceBusDeviceScanningOrder:1; /* Bit 0 */ +struct blogic_autoscsi_byte45 { + unsigned char force_scan_order:1; /* Bit 0 */ unsigned char:7; /* Bits 1-7 */ }; @@ -646,13 +635,13 @@ struct BusLogic_AutoSCSIByte45 { Define the Host Adapter Local RAM BIOS Drive Map Byte structure. */ -#define BusLogic_BIOS_DriveMapOffset 17 +#define BLOGIC_BIOS_DRVMAP 17 -struct BusLogic_BIOSDriveMapByte { - unsigned char TargetIDBit3:1; /* Bit 0 */ - unsigned char:2; /* Bits 1-2 */ - enum BusLogic_BIOS_DiskGeometryTranslation DiskGeometry:2; /* Bits 3-4 */ - unsigned char TargetID:3; /* Bits 5-7 */ +struct blogic_bios_drvmap { + unsigned char tgt_idbit3:1; /* Bit 0 */ + unsigned char:2; /* Bits 1-2 */ + enum blogic_bios_diskgeometry diskgeom:2; /* Bits 3-4 */ + unsigned char tgt_id:3; /* Bits 5-7 */ }; /* @@ -660,19 +649,19 @@ struct BusLogic_BIOSDriveMapByte { necessary to support more than 8 Logical Units per Target Device. */ -enum BusLogic_SetCCBFormatRequest { - BusLogic_LegacyLUNFormatCCB = 0, - BusLogic_ExtendedLUNFormatCCB = 1 +enum blogic_setccb_fmt { + BLOGIC_LEGACY_LUN_CCB = 0, + BLOGIC_EXT_LUN_CCB = 1 } PACKED; /* Define the Outgoing Mailbox Action Codes. */ -enum BusLogic_ActionCode { - BusLogic_OutgoingMailboxFree = 0x00, - BusLogic_MailboxStartCommand = 0x01, - BusLogic_MailboxAbortCommand = 0x02 +enum blogic_action { + BLOGIC_OUTBOX_FREE = 0x00, + BLOGIC_MBOX_START = 0x01, + BLOGIC_MBOX_ABORT = 0x02 } PACKED; @@ -682,26 +671,26 @@ enum BusLogic_ActionCode { completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5. */ -enum BusLogic_CompletionCode { - BusLogic_IncomingMailboxFree = 0x00, - BusLogic_CommandCompletedWithoutError = 0x01, - BusLogic_CommandAbortedAtHostRequest = 0x02, - BusLogic_AbortedCommandNotFound = 0x03, - BusLogic_CommandCompletedWithError = 0x04, - BusLogic_InvalidCCB = 0x05 +enum blogic_cmplt_code { + BLOGIC_INBOX_FREE = 0x00, + BLOGIC_CMD_COMPLETE_GOOD = 0x01, + BLOGIC_CMD_ABORT_BY_HOST = 0x02, + BLOGIC_CMD_NOTFOUND = 0x03, + BLOGIC_CMD_COMPLETE_ERROR = 0x04, + BLOGIC_INVALID_CCB = 0x05 } PACKED; /* Define the Command Control Block (CCB) Opcodes. */ -enum BusLogic_CCB_Opcode { - BusLogic_InitiatorCCB = 0x00, - BusLogic_TargetCCB = 0x01, - BusLogic_InitiatorCCB_ScatterGather = 0x02, - BusLogic_InitiatorCCB_ResidualDataLength = 0x03, - BusLogic_InitiatorCCB_ScatterGatherResidual = 0x04, - BusLogic_BusDeviceReset = 0x81 +enum blogic_ccb_opcode { + BLOGIC_INITIATOR_CCB = 0x00, + BLOGIC_TGT_CCB = 0x01, + BLOGIC_INITIATOR_CCB_SG = 0x02, + BLOGIC_INITIATOR_CCBB_RESIDUAL = 0x03, + BLOGIC_INITIATOR_CCB_SG_RESIDUAL = 0x04, + BLOGIC_BDR = 0x81 } PACKED; @@ -709,11 +698,11 @@ enum BusLogic_CCB_Opcode { Define the CCB Data Direction Codes. */ -enum BusLogic_DataDirection { - BusLogic_UncheckedDataTransfer = 0, - BusLogic_DataInLengthChecked = 1, - BusLogic_DataOutLengthChecked = 2, - BusLogic_NoDataTransfer = 3 +enum blogic_datadir { + BLOGIC_UNCHECKED_TX = 0, + BLOGIC_DATAIN_CHECKED = 1, + BLOGIC_DATAOUT_CHECKED = 2, + BLOGIC_NOTX = 3 }; @@ -722,32 +711,32 @@ enum BusLogic_DataDirection { return status code 0x0C; it uses 0x12 for both overruns and underruns. */ -enum BusLogic_HostAdapterStatus { - BusLogic_CommandCompletedNormally = 0x00, - BusLogic_LinkedCommandCompleted = 0x0A, - BusLogic_LinkedCommandCompletedWithFlag = 0x0B, - BusLogic_DataUnderRun = 0x0C, - BusLogic_SCSISelectionTimeout = 0x11, - BusLogic_DataOverRun = 0x12, - BusLogic_UnexpectedBusFree = 0x13, - BusLogic_InvalidBusPhaseRequested = 0x14, - BusLogic_InvalidOutgoingMailboxActionCode = 0x15, - BusLogic_InvalidCommandOperationCode = 0x16, - BusLogic_LinkedCCBhasInvalidLUN = 0x17, - BusLogic_InvalidCommandParameter = 0x1A, - BusLogic_AutoRequestSenseFailed = 0x1B, - BusLogic_TaggedQueuingMessageRejected = 0x1C, - BusLogic_UnsupportedMessageReceived = 0x1D, - BusLogic_HostAdapterHardwareFailed = 0x20, - BusLogic_TargetFailedResponseToATN = 0x21, - BusLogic_HostAdapterAssertedRST = 0x22, - BusLogic_OtherDeviceAssertedRST = 0x23, - BusLogic_TargetDeviceReconnectedImproperly = 0x24, - BusLogic_HostAdapterAssertedBusDeviceReset = 0x25, - BusLogic_AbortQueueGenerated = 0x26, - BusLogic_HostAdapterSoftwareError = 0x27, - BusLogic_HostAdapterHardwareTimeoutError = 0x30, - BusLogic_SCSIParityErrorDetected = 0x34 +enum blogic_adapter_status { + BLOGIC_CMD_CMPLT_NORMAL = 0x00, + BLOGIC_LINK_CMD_CMPLT = 0x0A, + BLOGIC_LINK_CMD_CMPLT_FLAG = 0x0B, + BLOGIC_DATA_UNDERRUN = 0x0C, + BLOGIC_SELECT_TIMEOUT = 0x11, + BLOGIC_DATA_OVERRUN = 0x12, + BLOGIC_NOEXPECT_BUSFREE = 0x13, + BLOGIC_INVALID_BUSPHASE = 0x14, + BLOGIC_INVALID_OUTBOX_CODE = 0x15, + BLOGIC_INVALID_CMD_CODE = 0x16, + BLOGIC_LINKCCB_BADLUN = 0x17, + BLOGIC_BAD_CMD_PARAM = 0x1A, + BLOGIC_AUTOREQSENSE_FAIL = 0x1B, + BLOGIC_TAGQUEUE_REJECT = 0x1C, + BLOGIC_BAD_MSG_RCVD = 0x1D, + BLOGIC_HW_FAIL = 0x20, + BLOGIC_NORESPONSE_TO_ATN = 0x21, + BLOGIC_HW_RESET = 0x22, + BLOGIC_RST_FROM_OTHERDEV = 0x23, + BLOGIC_BAD_RECONNECT = 0x24, + BLOGIC_HW_BDR = 0x25, + BLOGIC_ABRT_QUEUE = 0x26, + BLOGIC_ADAPTER_SW_ERROR = 0x27, + BLOGIC_HW_TIMEOUT = 0x30, + BLOGIC_PARITY_ERR = 0x34 } PACKED; @@ -755,30 +744,28 @@ enum BusLogic_HostAdapterStatus { Define the SCSI Target Device Status Codes. */ -enum BusLogic_TargetDeviceStatus { - BusLogic_OperationGood = 0x00, - BusLogic_CheckCondition = 0x02, - BusLogic_DeviceBusy = 0x08 +enum blogic_tgt_status { + BLOGIC_OP_GOOD = 0x00, + BLOGIC_CHECKCONDITION = 0x02, + BLOGIC_DEVBUSY = 0x08 } PACKED; /* Define the Queue Tag Codes. */ -enum BusLogic_QueueTag { - BusLogic_SimpleQueueTag = 0, - BusLogic_HeadOfQueueTag = 1, - BusLogic_OrderedQueueTag = 2, - BusLogic_ReservedQT = 3 +enum blogic_queuetag { + BLOGIC_SIMPLETAG = 0, + BLOGIC_HEADTAG = 1, + BLOGIC_ORDEREDTAG = 2, + BLOGIC_RSVDTAG = 3 }; /* Define the SCSI Command Descriptor Block (CDB). */ -#define BusLogic_CDB_MaxLength 12 - -typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength]; +#define BLOGIC_CDB_MAXLEN 12 /* @@ -786,20 +773,20 @@ typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength]; Firmware Interface and the FlashPoint SCCB Manager. */ -struct BusLogic_ScatterGatherSegment { - u32 SegmentByteCount; /* Bytes 0-3 */ - u32 SegmentDataPointer; /* Bytes 4-7 */ +struct blogic_sg_seg { + u32 segbytes; /* Bytes 0-3 */ + u32 segdata; /* Bytes 4-7 */ }; /* Define the Driver CCB Status Codes. */ -enum BusLogic_CCB_Status { - BusLogic_CCB_Free = 0, - BusLogic_CCB_Active = 1, - BusLogic_CCB_Completed = 2, - BusLogic_CCB_Reset = 3 +enum blogic_ccb_status { + BLOGIC_CCB_FREE = 0, + BLOGIC_CCB_ACTIVE = 1, + BLOGIC_CCB_COMPLETE = 2, + BLOGIC_CCB_RESET = 3 } PACKED; @@ -822,79 +809,78 @@ enum BusLogic_CCB_Status { 32 Logical Units per Target Device. */ -struct BusLogic_CCB { +struct blogic_ccb { /* MultiMaster Firmware and FlashPoint SCCB Manager Common Portion. */ - enum BusLogic_CCB_Opcode Opcode; /* Byte 0 */ - unsigned char:3; /* Byte 1 Bits 0-2 */ - enum BusLogic_DataDirection DataDirection:2; /* Byte 1 Bits 3-4 */ - bool TagEnable:1; /* Byte 1 Bit 5 */ - enum BusLogic_QueueTag QueueTag:2; /* Byte 1 Bits 6-7 */ - unsigned char CDB_Length; /* Byte 2 */ - unsigned char SenseDataLength; /* Byte 3 */ - u32 DataLength; /* Bytes 4-7 */ - u32 DataPointer; /* Bytes 8-11 */ - unsigned char:8; /* Byte 12 */ - unsigned char:8; /* Byte 13 */ - enum BusLogic_HostAdapterStatus HostAdapterStatus; /* Byte 14 */ - enum BusLogic_TargetDeviceStatus TargetDeviceStatus; /* Byte 15 */ - unsigned char TargetID; /* Byte 16 */ - unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */ - bool LegacyTagEnable:1; /* Byte 17 Bit 5 */ - enum BusLogic_QueueTag LegacyQueueTag:2; /* Byte 17 Bits 6-7 */ - SCSI_CDB_T CDB; /* Bytes 18-29 */ - unsigned char:8; /* Byte 30 */ - unsigned char:8; /* Byte 31 */ - unsigned int:32; /* Bytes 32-35 */ - u32 SenseDataPointer; /* Bytes 36-39 */ + enum blogic_ccb_opcode opcode; /* Byte 0 */ + unsigned char:3; /* Byte 1 Bits 0-2 */ + enum blogic_datadir datadir:2; /* Byte 1 Bits 3-4 */ + bool tag_enable:1; /* Byte 1 Bit 5 */ + enum blogic_queuetag queuetag:2; /* Byte 1 Bits 6-7 */ + unsigned char cdblen; /* Byte 2 */ + unsigned char sense_datalen; /* Byte 3 */ + u32 datalen; /* Bytes 4-7 */ + u32 data; /* Bytes 8-11 */ + unsigned char:8; /* Byte 12 */ + unsigned char:8; /* Byte 13 */ + enum blogic_adapter_status adapter_status; /* Byte 14 */ + enum blogic_tgt_status tgt_status; /* Byte 15 */ + unsigned char tgt_id; /* Byte 16 */ + unsigned char lun:5; /* Byte 17 Bits 0-4 */ + bool legacytag_enable:1; /* Byte 17 Bit 5 */ + enum blogic_queuetag legacy_tag:2; /* Byte 17 Bits 6-7 */ + unsigned char cdb[BLOGIC_CDB_MAXLEN]; /* Bytes 18-29 */ + unsigned char:8; /* Byte 30 */ + unsigned char:8; /* Byte 31 */ + unsigned int:32; /* Bytes 32-35 */ + u32 sensedata; /* Bytes 36-39 */ /* FlashPoint SCCB Manager Defined Portion. */ - void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */ - u32 BaseAddress; /* Bytes 44-47 */ - enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */ + void (*callback) (struct blogic_ccb *); /* Bytes 40-43 */ + u32 base_addr; /* Bytes 44-47 */ + enum blogic_cmplt_code comp_code; /* Byte 48 */ #ifdef CONFIG_SCSI_FLASHPOINT - unsigned char:8; /* Byte 49 */ - unsigned short OS_Flags; /* Bytes 50-51 */ - unsigned char Private[48]; /* Bytes 52-99 */ + unsigned char:8; /* Byte 49 */ + unsigned short os_flags; /* Bytes 50-51 */ + unsigned char private[48]; /* Bytes 52-99 */ #endif /* BusLogic Linux Driver Defined Portion. */ - dma_addr_t AllocationGroupHead; - unsigned int AllocationGroupSize; - u32 DMA_Handle; - enum BusLogic_CCB_Status Status; - unsigned long SerialNumber; - struct scsi_cmnd *Command; - struct BusLogic_HostAdapter *HostAdapter; - struct BusLogic_CCB *Next; - struct BusLogic_CCB *NextAll; - struct BusLogic_ScatterGatherSegment - ScatterGatherList[BusLogic_ScatterGatherLimit]; + dma_addr_t allocgrp_head; + unsigned int allocgrp_size; + u32 dma_handle; + enum blogic_ccb_status status; + unsigned long serial; + struct scsi_cmnd *command; + struct blogic_adapter *adapter; + struct blogic_ccb *next; + struct blogic_ccb *next_all; + struct blogic_sg_seg sglist[BLOGIC_SG_LIMIT]; }; /* Define the 32 Bit Mode Outgoing Mailbox structure. */ -struct BusLogic_OutgoingMailbox { - u32 CCB; /* Bytes 0-3 */ - unsigned int:24; /* Bytes 4-6 */ - enum BusLogic_ActionCode ActionCode; /* Byte 7 */ +struct blogic_outbox { + u32 ccb; /* Bytes 0-3 */ + unsigned int:24; /* Bytes 4-6 */ + enum blogic_action action; /* Byte 7 */ }; /* Define the 32 Bit Mode Incoming Mailbox structure. */ -struct BusLogic_IncomingMailbox { - u32 CCB; /* Bytes 0-3 */ - enum BusLogic_HostAdapterStatus HostAdapterStatus; /* Byte 4 */ - enum BusLogic_TargetDeviceStatus TargetDeviceStatus; /* Byte 5 */ +struct blogic_inbox { + u32 ccb; /* Bytes 0-3 */ + enum blogic_adapter_status adapter_status; /* Byte 4 */ + enum blogic_tgt_status tgt_status; /* Byte 5 */ unsigned char:8; /* Byte 6 */ - enum BusLogic_CompletionCode CompletionCode; /* Byte 7 */ + enum blogic_cmplt_code comp_code; /* Byte 7 */ }; @@ -902,64 +888,60 @@ struct BusLogic_IncomingMailbox { Define the BusLogic Driver Options structure. */ -struct BusLogic_DriverOptions { - unsigned short TaggedQueuingPermitted; - unsigned short TaggedQueuingPermittedMask; - unsigned short BusSettleTime; - struct BusLogic_LocalOptions LocalOptions; - unsigned char CommonQueueDepth; - unsigned char QueueDepth[BusLogic_MaxTargetDevices]; +struct blogic_drvr_options { + unsigned short tagq_ok; + unsigned short tagq_ok_mask; + unsigned short bus_settle_time; + unsigned short stop_tgt_inquiry; + unsigned char common_qdepth; + unsigned char qdepth[BLOGIC_MAXDEV]; }; /* Define the Host Adapter Target Flags structure. */ -struct BusLogic_TargetFlags { - bool TargetExists:1; - bool TaggedQueuingSupported:1; - bool WideTransfersSupported:1; - bool TaggedQueuingActive:1; - bool WideTransfersActive:1; - bool CommandSuccessfulFlag:1; - bool TargetInfoReported:1; +struct blogic_tgt_flags { + bool tgt_exists:1; + bool tagq_ok:1; + bool wide_ok:1; + bool tagq_active:1; + bool wide_active:1; + bool cmd_good:1; + bool tgt_info_in:1; }; /* Define the Host Adapter Target Statistics structure. */ -#define BusLogic_SizeBuckets 10 - -typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets]; - -struct BusLogic_TargetStatistics { - unsigned int CommandsAttempted; - unsigned int CommandsCompleted; - unsigned int ReadCommands; - unsigned int WriteCommands; - struct BusLogic_ByteCounter TotalBytesRead; - struct BusLogic_ByteCounter TotalBytesWritten; - BusLogic_CommandSizeBuckets_T ReadCommandSizeBuckets; - BusLogic_CommandSizeBuckets_T WriteCommandSizeBuckets; - unsigned short CommandAbortsRequested; - unsigned short CommandAbortsAttempted; - unsigned short CommandAbortsCompleted; - unsigned short BusDeviceResetsRequested; - unsigned short BusDeviceResetsAttempted; - unsigned short BusDeviceResetsCompleted; - unsigned short HostAdapterResetsRequested; - unsigned short HostAdapterResetsAttempted; - unsigned short HostAdapterResetsCompleted; +#define BLOGIC_SZ_BUCKETS 10 + +struct blogic_tgt_stats { + unsigned int cmds_tried; + unsigned int cmds_complete; + unsigned int read_cmds; + unsigned int write_cmds; + struct blogic_byte_count bytesread; + struct blogic_byte_count byteswritten; + unsigned int read_sz_buckets[BLOGIC_SZ_BUCKETS]; + unsigned int write_sz_buckets[BLOGIC_SZ_BUCKETS]; + unsigned short aborts_request; + unsigned short aborts_tried; + unsigned short aborts_done; + unsigned short bdr_request; + unsigned short bdr_tried; + unsigned short bdr_done; + unsigned short adatper_reset_req; + unsigned short adapter_reset_attempt; + unsigned short adapter_reset_done; }; /* Define the FlashPoint Card Handle data type. */ -#define FlashPoint_BadCardHandle 0xFFFFFFFF - -typedef unsigned int FlashPoint_CardHandle_T; +#define FPOINT_BADCARD_HANDLE 0xFFFFFFFF /* @@ -967,179 +949,179 @@ typedef unsigned int FlashPoint_CardHandle_T; by the FlashPoint SCCB Manager. */ -struct FlashPoint_Info { - u32 BaseAddress; /* Bytes 0-3 */ - bool Present; /* Byte 4 */ - unsigned char IRQ_Channel; /* Byte 5 */ - unsigned char SCSI_ID; /* Byte 6 */ - unsigned char SCSI_LUN; /* Byte 7 */ - unsigned short FirmwareRevision; /* Bytes 8-9 */ - unsigned short SynchronousPermitted; /* Bytes 10-11 */ - unsigned short FastPermitted; /* Bytes 12-13 */ - unsigned short UltraPermitted; /* Bytes 14-15 */ - unsigned short DisconnectPermitted; /* Bytes 16-17 */ - unsigned short WidePermitted; /* Bytes 18-19 */ - bool ParityCheckingEnabled:1; /* Byte 20 Bit 0 */ - bool HostWideSCSI:1; /* Byte 20 Bit 1 */ - bool HostSoftReset:1; /* Byte 20 Bit 2 */ - bool ExtendedTranslationEnabled:1; /* Byte 20 Bit 3 */ - bool LowByteTerminated:1; /* Byte 20 Bit 4 */ - bool HighByteTerminated:1; /* Byte 20 Bit 5 */ - bool ReportDataUnderrun:1; /* Byte 20 Bit 6 */ - bool SCAM_Enabled:1; /* Byte 20 Bit 7 */ - bool SCAM_Level2:1; /* Byte 21 Bit 0 */ - unsigned char:7; /* Byte 21 Bits 1-7 */ - unsigned char Family; /* Byte 22 */ - unsigned char BusType; /* Byte 23 */ - unsigned char ModelNumber[3]; /* Bytes 24-26 */ - unsigned char RelativeCardNumber; /* Byte 27 */ - unsigned char Reserved[4]; /* Bytes 28-31 */ - unsigned int OS_Reserved; /* Bytes 32-35 */ - unsigned char TranslationInfo[4]; /* Bytes 36-39 */ - unsigned int Reserved2[5]; /* Bytes 40-59 */ - unsigned int SecondaryRange; /* Bytes 60-63 */ +struct fpoint_info { + u32 base_addr; /* Bytes 0-3 */ + bool present; /* Byte 4 */ + unsigned char irq_ch; /* Byte 5 */ + unsigned char scsi_id; /* Byte 6 */ + unsigned char scsi_lun; /* Byte 7 */ + unsigned short fw_rev; /* Bytes 8-9 */ + unsigned short sync_ok; /* Bytes 10-11 */ + unsigned short fast_ok; /* Bytes 12-13 */ + unsigned short ultra_ok; /* Bytes 14-15 */ + unsigned short discon_ok; /* Bytes 16-17 */ + unsigned short wide_ok; /* Bytes 18-19 */ + bool parity:1; /* Byte 20 Bit 0 */ + bool wide:1; /* Byte 20 Bit 1 */ + bool softreset:1; /* Byte 20 Bit 2 */ + bool ext_trans_enable:1; /* Byte 20 Bit 3 */ + bool low_term:1; /* Byte 20 Bit 4 */ + bool high_term:1; /* Byte 20 Bit 5 */ + bool report_underrun:1; /* Byte 20 Bit 6 */ + bool scam_enabled:1; /* Byte 20 Bit 7 */ + bool scam_lev2:1; /* Byte 21 Bit 0 */ + unsigned char:7; /* Byte 21 Bits 1-7 */ + unsigned char family; /* Byte 22 */ + unsigned char bus_type; /* Byte 23 */ + unsigned char model[3]; /* Bytes 24-26 */ + unsigned char relative_cardnum; /* Byte 27 */ + unsigned char rsvd[4]; /* Bytes 28-31 */ + unsigned int os_rsvd; /* Bytes 32-35 */ + unsigned char translation_info[4]; /* Bytes 36-39 */ + unsigned int rsvd2[5]; /* Bytes 40-59 */ + unsigned int sec_range; /* Bytes 60-63 */ }; /* Define the BusLogic Driver Host Adapter structure. */ -struct BusLogic_HostAdapter { - struct Scsi_Host *SCSI_Host; - struct pci_dev *PCI_Device; - enum BusLogic_HostAdapterType HostAdapterType; - enum BusLogic_HostAdapterBusType HostAdapterBusType; - unsigned long IO_Address; - unsigned long PCI_Address; - unsigned short AddressCount; - unsigned char HostNumber; - unsigned char ModelName[9]; - unsigned char FirmwareVersion[6]; - unsigned char FullModelName[18]; - unsigned char Bus; - unsigned char Device; - unsigned char IRQ_Channel; - unsigned char DMA_Channel; - unsigned char SCSI_ID; - bool IRQ_ChannelAcquired:1; - bool DMA_ChannelAcquired:1; - bool ExtendedTranslationEnabled:1; - bool ParityCheckingEnabled:1; - bool BusResetEnabled:1; - bool LevelSensitiveInterrupt:1; - bool HostWideSCSI:1; - bool HostDifferentialSCSI:1; - bool HostSupportsSCAM:1; - bool HostUltraSCSI:1; - bool ExtendedLUNSupport:1; - bool TerminationInfoValid:1; - bool LowByteTerminated:1; - bool HighByteTerminated:1; - bool BounceBuffersRequired:1; - bool StrictRoundRobinModeSupport:1; - bool SCAM_Enabled:1; - bool SCAM_Level2:1; - bool HostAdapterInitialized:1; - bool HostAdapterExternalReset:1; - bool HostAdapterInternalError:1; - bool ProcessCompletedCCBsActive; - volatile bool HostAdapterCommandCompleted; - unsigned short HostAdapterScatterGatherLimit; - unsigned short DriverScatterGatherLimit; - unsigned short MaxTargetDevices; - unsigned short MaxLogicalUnits; - unsigned short MailboxCount; - unsigned short InitialCCBs; - unsigned short IncrementalCCBs; - unsigned short AllocatedCCBs; - unsigned short DriverQueueDepth; - unsigned short HostAdapterQueueDepth; - unsigned short UntaggedQueueDepth; - unsigned short CommonQueueDepth; - unsigned short BusSettleTime; - unsigned short SynchronousPermitted; - unsigned short FastPermitted; - unsigned short UltraPermitted; - unsigned short WidePermitted; - unsigned short DisconnectPermitted; - unsigned short TaggedQueuingPermitted; - unsigned short ExternalHostAdapterResets; - unsigned short HostAdapterInternalErrors; - unsigned short TargetDeviceCount; - unsigned short MessageBufferLength; - u32 BIOS_Address; - struct BusLogic_DriverOptions *DriverOptions; - struct FlashPoint_Info FlashPointInfo; - FlashPoint_CardHandle_T CardHandle; +struct blogic_adapter { + struct Scsi_Host *scsi_host; + struct pci_dev *pci_device; + enum blogic_adapter_type adapter_type; + enum blogic_adapter_bus_type adapter_bus_type; + unsigned long io_addr; + unsigned long pci_addr; + unsigned short addr_count; + unsigned char host_no; + unsigned char model[9]; + unsigned char fw_ver[6]; + unsigned char full_model[18]; + unsigned char bus; + unsigned char dev; + unsigned char irq_ch; + unsigned char dma_ch; + unsigned char scsi_id; + bool irq_acquired:1; + bool dma_chan_acquired:1; + bool ext_trans_enable:1; + bool parity:1; + bool reset_enabled:1; + bool level_int:1; + bool wide:1; + bool differential:1; + bool scam:1; + bool ultra:1; + bool ext_lun:1; + bool terminfo_valid:1; + bool low_term:1; + bool high_term:1; + bool need_bouncebuf:1; + bool strict_rr:1; + bool scam_enabled:1; + bool scam_lev2:1; + bool adapter_initd:1; + bool adapter_extreset:1; + bool adapter_intern_err:1; + bool processing_ccbs; + volatile bool adapter_cmd_complete; + unsigned short adapter_sglimit; + unsigned short drvr_sglimit; + unsigned short maxdev; + unsigned short maxlun; + unsigned short mbox_count; + unsigned short initccbs; + unsigned short inc_ccbs; + unsigned short alloc_ccbs; + unsigned short drvr_qdepth; + unsigned short adapter_qdepth; + unsigned short untag_qdepth; + unsigned short common_qdepth; + unsigned short bus_settle_time; + unsigned short sync_ok; + unsigned short fast_ok; + unsigned short ultra_ok; + unsigned short wide_ok; + unsigned short discon_ok; + unsigned short tagq_ok; + unsigned short ext_resets; + unsigned short adapter_intern_errors; + unsigned short tgt_count; + unsigned short msgbuflen; + u32 bios_addr; + struct blogic_drvr_options *drvr_opts; + struct fpoint_info fpinfo; + unsigned int cardhandle; struct list_head host_list; - struct BusLogic_CCB *All_CCBs; - struct BusLogic_CCB *Free_CCBs; - struct BusLogic_CCB *FirstCompletedCCB; - struct BusLogic_CCB *LastCompletedCCB; - struct BusLogic_CCB *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices]; - struct BusLogic_TargetFlags TargetFlags[BusLogic_MaxTargetDevices]; - unsigned char QueueDepth[BusLogic_MaxTargetDevices]; - unsigned char SynchronousPeriod[BusLogic_MaxTargetDevices]; - unsigned char SynchronousOffset[BusLogic_MaxTargetDevices]; - unsigned char ActiveCommands[BusLogic_MaxTargetDevices]; - unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices]; - unsigned long LastSequencePoint[BusLogic_MaxTargetDevices]; - unsigned long LastResetAttempted[BusLogic_MaxTargetDevices]; - unsigned long LastResetCompleted[BusLogic_MaxTargetDevices]; - struct BusLogic_OutgoingMailbox *FirstOutgoingMailbox; - struct BusLogic_OutgoingMailbox *LastOutgoingMailbox; - struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; - struct BusLogic_IncomingMailbox *FirstIncomingMailbox; - struct BusLogic_IncomingMailbox *LastIncomingMailbox; - struct BusLogic_IncomingMailbox *NextIncomingMailbox; - struct BusLogic_TargetStatistics TargetStatistics[BusLogic_MaxTargetDevices]; - unsigned char *MailboxSpace; - dma_addr_t MailboxSpaceHandle; - unsigned int MailboxSize; - unsigned long CCB_Offset; - char MessageBuffer[BusLogic_MessageBufferSize]; + struct blogic_ccb *all_ccbs; + struct blogic_ccb *free_ccbs; + struct blogic_ccb *firstccb; + struct blogic_ccb *lastccb; + struct blogic_ccb *bdr_pend[BLOGIC_MAXDEV]; + struct blogic_tgt_flags tgt_flags[BLOGIC_MAXDEV]; + unsigned char qdepth[BLOGIC_MAXDEV]; + unsigned char sync_period[BLOGIC_MAXDEV]; + unsigned char sync_offset[BLOGIC_MAXDEV]; + unsigned char active_cmds[BLOGIC_MAXDEV]; + unsigned int cmds_since_rst[BLOGIC_MAXDEV]; + unsigned long last_seqpoint[BLOGIC_MAXDEV]; + unsigned long last_resettried[BLOGIC_MAXDEV]; + unsigned long last_resetdone[BLOGIC_MAXDEV]; + struct blogic_outbox *first_outbox; + struct blogic_outbox *last_outbox; + struct blogic_outbox *next_outbox; + struct blogic_inbox *first_inbox; + struct blogic_inbox *last_inbox; + struct blogic_inbox *next_inbox; + struct blogic_tgt_stats tgt_stats[BLOGIC_MAXDEV]; + unsigned char *mbox_space; + dma_addr_t mbox_space_handle; + unsigned int mbox_sz; + unsigned long ccb_offset; + char msgbuf[BLOGIC_MSGBUF_SIZE]; }; /* Define a structure for the BIOS Disk Parameters. */ -struct BIOS_DiskParameters { - int Heads; - int Sectors; - int Cylinders; +struct bios_diskparam { + int heads; + int sectors; + int cylinders; }; /* Define a structure for the SCSI Inquiry command results. */ -struct SCSI_Inquiry { - unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ - unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ - unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ - bool RMB:1; /* Byte 1 Bit 7 */ - unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ - unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ - unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ - unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ - unsigned char:2; /* Byte 3 Bits 4-5 */ - bool TrmIOP:1; /* Byte 3 Bit 6 */ - bool AENC:1; /* Byte 3 Bit 7 */ - unsigned char AdditionalLength; /* Byte 4 */ - unsigned char:8; /* Byte 5 */ - unsigned char:8; /* Byte 6 */ - bool SftRe:1; /* Byte 7 Bit 0 */ - bool CmdQue:1; /* Byte 7 Bit 1 */ - bool:1; /* Byte 7 Bit 2 */ - bool Linked:1; /* Byte 7 Bit 3 */ - bool Sync:1; /* Byte 7 Bit 4 */ - bool WBus16:1; /* Byte 7 Bit 5 */ - bool WBus32:1; /* Byte 7 Bit 6 */ - bool RelAdr:1; /* Byte 7 Bit 7 */ - unsigned char VendorIdentification[8]; /* Bytes 8-15 */ - unsigned char ProductIdentification[16]; /* Bytes 16-31 */ - unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ +struct scsi_inquiry { + unsigned char devtype:5; /* Byte 0 Bits 0-4 */ + unsigned char dev_qual:3; /* Byte 0 Bits 5-7 */ + unsigned char dev_modifier:7; /* Byte 1 Bits 0-6 */ + bool rmb:1; /* Byte 1 Bit 7 */ + unsigned char ansi_ver:3; /* Byte 2 Bits 0-2 */ + unsigned char ecma_ver:3; /* Byte 2 Bits 3-5 */ + unsigned char iso_ver:2; /* Byte 2 Bits 6-7 */ + unsigned char resp_fmt:4; /* Byte 3 Bits 0-3 */ + unsigned char:2; /* Byte 3 Bits 4-5 */ + bool TrmIOP:1; /* Byte 3 Bit 6 */ + bool AENC:1; /* Byte 3 Bit 7 */ + unsigned char addl_len; /* Byte 4 */ + unsigned char:8; /* Byte 5 */ + unsigned char:8; /* Byte 6 */ + bool SftRe:1; /* Byte 7 Bit 0 */ + bool CmdQue:1; /* Byte 7 Bit 1 */ + bool:1; /* Byte 7 Bit 2 */ + bool linked:1; /* Byte 7 Bit 3 */ + bool sync:1; /* Byte 7 Bit 4 */ + bool WBus16:1; /* Byte 7 Bit 5 */ + bool WBus32:1; /* Byte 7 Bit 6 */ + bool RelAdr:1; /* Byte 7 Bit 7 */ + unsigned char vendor[8]; /* Bytes 8-15 */ + unsigned char product[16]; /* Bytes 16-31 */ + unsigned char product_rev[4]; /* Bytes 32-35 */ }; @@ -1148,184 +1130,170 @@ struct SCSI_Inquiry { Host Adapter I/O Registers. */ -static inline void BusLogic_SCSIBusReset(struct BusLogic_HostAdapter *HostAdapter) +static inline void blogic_busreset(struct blogic_adapter *adapter) { - union BusLogic_ControlRegister ControlRegister; - ControlRegister.All = 0; - ControlRegister.cr.SCSIBusReset = true; - outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); + union blogic_cntrl_reg cr; + cr.all = 0; + cr.cr.bus_reset = true; + outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG); } -static inline void BusLogic_InterruptReset(struct BusLogic_HostAdapter *HostAdapter) +static inline void blogic_intreset(struct blogic_adapter *adapter) { - union BusLogic_ControlRegister ControlRegister; - ControlRegister.All = 0; - ControlRegister.cr.InterruptReset = true; - outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); + union blogic_cntrl_reg cr; + cr.all = 0; + cr.cr.int_reset = true; + outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG); } -static inline void BusLogic_SoftReset(struct BusLogic_HostAdapter *HostAdapter) +static inline void blogic_softreset(struct blogic_adapter *adapter) { - union BusLogic_ControlRegister ControlRegister; - ControlRegister.All = 0; - ControlRegister.cr.SoftReset = true; - outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); + union blogic_cntrl_reg cr; + cr.all = 0; + cr.cr.soft_reset = true; + outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG); } -static inline void BusLogic_HardReset(struct BusLogic_HostAdapter *HostAdapter) +static inline void blogic_hardreset(struct blogic_adapter *adapter) { - union BusLogic_ControlRegister ControlRegister; - ControlRegister.All = 0; - ControlRegister.cr.HardReset = true; - outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); + union blogic_cntrl_reg cr; + cr.all = 0; + cr.cr.hard_reset = true; + outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG); } -static inline unsigned char BusLogic_ReadStatusRegister(struct BusLogic_HostAdapter *HostAdapter) +static inline unsigned char blogic_rdstatus(struct blogic_adapter *adapter) { - return inb(HostAdapter->IO_Address + BusLogic_StatusRegisterOffset); + return inb(adapter->io_addr + BLOGIC_STATUS_REG); } -static inline void BusLogic_WriteCommandParameterRegister(struct BusLogic_HostAdapter - *HostAdapter, unsigned char Value) +static inline void blogic_setcmdparam(struct blogic_adapter *adapter, + unsigned char value) { - outb(Value, HostAdapter->IO_Address + BusLogic_CommandParameterRegisterOffset); + outb(value, adapter->io_addr + BLOGIC_CMD_PARM_REG); } -static inline unsigned char BusLogic_ReadDataInRegister(struct BusLogic_HostAdapter *HostAdapter) +static inline unsigned char blogic_rddatain(struct blogic_adapter *adapter) { - return inb(HostAdapter->IO_Address + BusLogic_DataInRegisterOffset); + return inb(adapter->io_addr + BLOGIC_DATAIN_REG); } -static inline unsigned char BusLogic_ReadInterruptRegister(struct BusLogic_HostAdapter *HostAdapter) +static inline unsigned char blogic_rdint(struct blogic_adapter *adapter) { - return inb(HostAdapter->IO_Address + BusLogic_InterruptRegisterOffset); + return inb(adapter->io_addr + BLOGIC_INT_REG); } -static inline unsigned char BusLogic_ReadGeometryRegister(struct BusLogic_HostAdapter *HostAdapter) +static inline unsigned char blogic_rdgeom(struct blogic_adapter *adapter) { - return inb(HostAdapter->IO_Address + BusLogic_GeometryRegisterOffset); + return inb(adapter->io_addr + BLOGIC_GEOMETRY_REG); } /* - BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which + blogic_execmbox issues an Execute Mailbox Command, which notifies the Host Adapter that an entry has been made in an Outgoing Mailbox. */ -static inline void BusLogic_StartMailboxCommand(struct BusLogic_HostAdapter *HostAdapter) +static inline void blogic_execmbox(struct blogic_adapter *adapter) { - BusLogic_WriteCommandParameterRegister(HostAdapter, BusLogic_ExecuteMailboxCommand); + blogic_setcmdparam(adapter, BLOGIC_EXEC_MBOX_CMD); } /* - BusLogic_Delay waits for Seconds to elapse. + blogic_delay waits for Seconds to elapse. */ -static inline void BusLogic_Delay(int Seconds) -{ - mdelay(1000 * Seconds); -} - -/* - Virtual_to_Bus and Bus_to_Virtual map between Kernel Virtual Addresses - and PCI/VLB/EISA/ISA Bus Addresses. -*/ - -static inline u32 Virtual_to_Bus(void *VirtualAddress) -{ - return (u32) virt_to_bus(VirtualAddress); -} - -static inline void *Bus_to_Virtual(u32 BusAddress) +static inline void blogic_delay(int seconds) { - return (void *) bus_to_virt(BusAddress); + mdelay(1000 * seconds); } /* - Virtual_to_32Bit_Virtual maps between Kernel Virtual Addresses and + virt_to_32bit_virt maps between Kernel Virtual Addresses and 32 bit Kernel Virtual Addresses. This avoids compilation warnings on 64 bit architectures. */ -static inline u32 Virtual_to_32Bit_Virtual(void *VirtualAddress) +static inline u32 virt_to_32bit_virt(void *virt_addr) { - return (u32) (unsigned long) VirtualAddress; + return (u32) (unsigned long) virt_addr; } /* - BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at + blogic_inc_count increments counter by 1, stopping at 65535 rather than wrapping around to 0. */ -static inline void BusLogic_IncrementErrorCounter(unsigned short *ErrorCounter) +static inline void blogic_inc_count(unsigned short *count) { - if (*ErrorCounter < 65535) - (*ErrorCounter)++; + if (*count < 65535) + (*count)++; } /* - BusLogic_IncrementByteCounter increments Byte Counter by Amount. + blogic_addcount increments Byte Counter by Amount. */ -static inline void BusLogic_IncrementByteCounter(struct BusLogic_ByteCounter - *ByteCounter, unsigned int Amount) +static inline void blogic_addcount(struct blogic_byte_count *bytecount, + unsigned int amount) { - ByteCounter->Units += Amount; - if (ByteCounter->Units > 999999999) { - ByteCounter->Units -= 1000000000; - ByteCounter->Billions++; + bytecount->units += amount; + if (bytecount->units > 999999999) { + bytecount->units -= 1000000000; + bytecount->billions++; } } /* - BusLogic_IncrementSizeBucket increments the Bucket for Amount. + blogic_incszbucket increments the Bucket for Amount. */ -static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T CommandSizeBuckets, unsigned int Amount) +static inline void blogic_incszbucket(unsigned int *cmdsz_buckets, + unsigned int amount) { - int Index = 0; - if (Amount < 8 * 1024) { - if (Amount < 2 * 1024) - Index = (Amount < 1 * 1024 ? 0 : 1); + int index = 0; + if (amount < 8 * 1024) { + if (amount < 2 * 1024) + index = (amount < 1 * 1024 ? 0 : 1); else - Index = (Amount < 4 * 1024 ? 2 : 3); - } else if (Amount < 128 * 1024) { - if (Amount < 32 * 1024) - Index = (Amount < 16 * 1024 ? 4 : 5); + index = (amount < 4 * 1024 ? 2 : 3); + } else if (amount < 128 * 1024) { + if (amount < 32 * 1024) + index = (amount < 16 * 1024 ? 4 : 5); else - Index = (Amount < 64 * 1024 ? 6 : 7); + index = (amount < 64 * 1024 ? 6 : 7); } else - Index = (Amount < 256 * 1024 ? 8 : 9); - CommandSizeBuckets[Index]++; + index = (amount < 256 * 1024 ? 8 : 9); + cmdsz_buckets[index]++; } /* Define the version number of the FlashPoint Firmware (SCCB Manager). */ -#define FlashPoint_FirmwareVersion "5.02" +#define FLASHPOINT_FW_VER "5.02" /* Define the possible return values from FlashPoint_HandleInterrupt. */ -#define FlashPoint_NormalInterrupt 0x00 -#define FlashPoint_InternalError 0xFE -#define FlashPoint_ExternalBusReset 0xFF +#define FPOINT_NORMAL_INT 0x00 +#define FPOINT_INTERN_ERR 0xFE +#define FPOINT_EXT_RESET 0xFF /* Define prototypes for the forward referenced BusLogic Driver Internal Functions. */ -static const char *BusLogic_DriverInfo(struct Scsi_Host *); -static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *); -static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *); -static int BusLogic_SlaveConfigure(struct scsi_device *); -static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *); -static irqreturn_t BusLogic_InterruptHandler(int, void *); -static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, bool HardReset); -static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...); -static int __init BusLogic_Setup(char *); +static const char *blogic_drvr_info(struct Scsi_Host *); +static int blogic_qcmd(struct Scsi_Host *h, struct scsi_cmnd *); +static int blogic_diskparam(struct scsi_device *, struct block_device *, sector_t, int *); +static int blogic_slaveconfig(struct scsi_device *); +static void blogic_qcompleted_ccb(struct blogic_ccb *); +static irqreturn_t blogic_inthandler(int, void *); +static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset); +static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...); +static int __init blogic_setup(char *); #endif /* _BUSLOGIC_H */ diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index dcd716d..9029720 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -7573,47 +7573,47 @@ static unsigned char FPT_CalcLrc(unsigned char buffer[]) */ static inline unsigned char -FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo) +FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo) { return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo); } -static inline FlashPoint_CardHandle_T -FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo) +static inline unsigned int +FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo) { return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo); } static inline void -FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle) +FlashPoint__ReleaseHostAdapter(unsigned int CardHandle) { FlashPoint_ReleaseHostAdapter(CardHandle); } static inline void -FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, - struct BusLogic_CCB *CCB) +FlashPoint__StartCCB(unsigned int CardHandle, + struct blogic_ccb *CCB) { FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB); } static inline void -FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, - struct BusLogic_CCB *CCB) +FlashPoint__AbortCCB(unsigned int CardHandle, + struct blogic_ccb *CCB) { FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); } static inline bool -FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle) +FlashPoint__InterruptPending(unsigned int CardHandle) { return FlashPoint_InterruptPending(CardHandle); } static inline int -FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) +FlashPoint__HandleInterrupt(unsigned int CardHandle) { return FlashPoint_HandleInterrupt(CardHandle); } @@ -7632,13 +7632,12 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) Define prototypes for the FlashPoint SCCB Manager Functions. */ -extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *); -extern FlashPoint_CardHandle_T -FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *); -extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); -extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); -extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T); -extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); -extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); +extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *); +extern unsigned int FlashPoint_HardwareResetHostAdapter(struct fpoint_info *); +extern void FlashPoint_StartCCB(unsigned int, struct blogic_ccb *); +extern int FlashPoint_AbortCCB(unsigned int, struct blogic_ccb *); +extern bool FlashPoint_InterruptPending(unsigned int); +extern int FlashPoint_HandleInterrupt(unsigned int); +extern void FlashPoint_ReleaseHostAdapter(unsigned int); #endif /* CONFIG_SCSI_FLASHPOINT */ -- cgit v1.1 From 391e2f25601e34a7d7e5dc155e487bc58dffd8c6 Mon Sep 17 00:00:00 2001 From: Khalid Aziz Date: Thu, 16 May 2013 19:44:14 -0600 Subject: [SCSI] BusLogic: Port driver to 64-bit. [jejb: fix up pointer to int cast warning] Signed-off-by: Khalid Aziz Signed-off-by: James Bottomley --- drivers/scsi/BusLogic.c | 11 +- drivers/scsi/BusLogic.h | 43 ++-- drivers/scsi/FlashPoint.c | 619 +++++++++++++++++++++------------------------- drivers/scsi/Kconfig | 2 +- 4 files changed, 311 insertions(+), 364 deletions(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 6ec36d8..feab3a5 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -1208,7 +1208,7 @@ static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset) fpinfo->report_underrun = true; adapter->cardhandle = FlashPoint_HardwareResetHostAdapter(fpinfo); - if (adapter->cardhandle == FPOINT_BADCARD_HANDLE) + if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE) return false; /* Indicate the Host Adapter Hard Reset completed successfully. @@ -2372,8 +2372,7 @@ static int __init blogic_init(void) return -ENOMEM; } - adapter = - kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL); + adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL); if (adapter == NULL) { kfree(blogic_probeinfo_list); blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL); @@ -3079,11 +3078,11 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, ccb->opcode = BLOGIC_INITIATOR_CCB_SG; ccb->datalen = count * sizeof(struct blogic_sg_seg); if (blogic_multimaster_type(adapter)) - ccb->data = (unsigned int) ccb->dma_handle + + ccb->data = (void *)((unsigned int) ccb->dma_handle + ((unsigned long) &ccb->sglist - - (unsigned long) ccb); + (unsigned long) ccb)); else - ccb->data = virt_to_32bit_virt(ccb->sglist); + ccb->data = ccb->sglist; scsi_for_each_sg(command, sg, count, i) { ccb->sglist[i].segbytes = sg_dma_len(sg); diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 8349c0f..b53ec2f 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -821,7 +821,7 @@ struct blogic_ccb { unsigned char cdblen; /* Byte 2 */ unsigned char sense_datalen; /* Byte 3 */ u32 datalen; /* Bytes 4-7 */ - u32 data; /* Bytes 8-11 */ + void *data; /* Bytes 8-11 */ unsigned char:8; /* Byte 12 */ unsigned char:8; /* Byte 13 */ enum blogic_adapter_status adapter_status; /* Byte 14 */ @@ -833,7 +833,7 @@ struct blogic_ccb { unsigned char cdb[BLOGIC_CDB_MAXLEN]; /* Bytes 18-29 */ unsigned char:8; /* Byte 30 */ unsigned char:8; /* Byte 31 */ - unsigned int:32; /* Bytes 32-35 */ + u32 rsvd_int; /* Bytes 32-35 */ u32 sensedata; /* Bytes 36-39 */ /* FlashPoint SCCB Manager Defined Portion. @@ -843,8 +843,11 @@ struct blogic_ccb { enum blogic_cmplt_code comp_code; /* Byte 48 */ #ifdef CONFIG_SCSI_FLASHPOINT unsigned char:8; /* Byte 49 */ - unsigned short os_flags; /* Bytes 50-51 */ - unsigned char private[48]; /* Bytes 52-99 */ + u16 os_flags; /* Bytes 50-51 */ + unsigned char private[24]; /* Bytes 52-99 */ + void *rsvd1; + void *rsvd2; + unsigned char private2[16]; #endif /* BusLogic Linux Driver Defined Portion. @@ -867,7 +870,7 @@ struct blogic_ccb { struct blogic_outbox { u32 ccb; /* Bytes 0-3 */ - unsigned int:24; /* Bytes 4-6 */ + u32:24; /* Bytes 4-6 */ enum blogic_action action; /* Byte 7 */ }; @@ -876,11 +879,11 @@ struct blogic_outbox { */ struct blogic_inbox { - u32 ccb; /* Bytes 0-3 */ + u32 ccb; /* Bytes 0-3 */ enum blogic_adapter_status adapter_status; /* Byte 4 */ - enum blogic_tgt_status tgt_status; /* Byte 5 */ - unsigned char:8; /* Byte 6 */ - enum blogic_cmplt_code comp_code; /* Byte 7 */ + enum blogic_tgt_status tgt_status; /* Byte 5 */ + unsigned char:8; /* Byte 6 */ + enum blogic_cmplt_code comp_code; /* Byte 7 */ }; @@ -941,7 +944,7 @@ struct blogic_tgt_stats { Define the FlashPoint Card Handle data type. */ -#define FPOINT_BADCARD_HANDLE 0xFFFFFFFF +#define FPOINT_BADCARD_HANDLE 0xFFFFFFFFL /* @@ -955,12 +958,12 @@ struct fpoint_info { unsigned char irq_ch; /* Byte 5 */ unsigned char scsi_id; /* Byte 6 */ unsigned char scsi_lun; /* Byte 7 */ - unsigned short fw_rev; /* Bytes 8-9 */ - unsigned short sync_ok; /* Bytes 10-11 */ - unsigned short fast_ok; /* Bytes 12-13 */ - unsigned short ultra_ok; /* Bytes 14-15 */ - unsigned short discon_ok; /* Bytes 16-17 */ - unsigned short wide_ok; /* Bytes 18-19 */ + u16 fw_rev; /* Bytes 8-9 */ + u16 sync_ok; /* Bytes 10-11 */ + u16 fast_ok; /* Bytes 12-13 */ + u16 ultra_ok; /* Bytes 14-15 */ + u16 discon_ok; /* Bytes 16-17 */ + u16 wide_ok; /* Bytes 18-19 */ bool parity:1; /* Byte 20 Bit 0 */ bool wide:1; /* Byte 20 Bit 1 */ bool softreset:1; /* Byte 20 Bit 2 */ @@ -976,10 +979,10 @@ struct fpoint_info { unsigned char model[3]; /* Bytes 24-26 */ unsigned char relative_cardnum; /* Byte 27 */ unsigned char rsvd[4]; /* Bytes 28-31 */ - unsigned int os_rsvd; /* Bytes 32-35 */ + u32 os_rsvd; /* Bytes 32-35 */ unsigned char translation_info[4]; /* Bytes 36-39 */ - unsigned int rsvd2[5]; /* Bytes 40-59 */ - unsigned int sec_range; /* Bytes 60-63 */ + u32 rsvd2[5]; /* Bytes 40-59 */ + u32 sec_range; /* Bytes 60-63 */ }; /* @@ -1052,7 +1055,7 @@ struct blogic_adapter { u32 bios_addr; struct blogic_drvr_options *drvr_opts; struct fpoint_info fpinfo; - unsigned int cardhandle; + void *cardhandle; struct list_head host_list; struct blogic_ccb *all_ccbs; struct blogic_ccb *free_ccbs; diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 9029720..5c74e4c 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -29,27 +29,27 @@ struct sccb; typedef void (*CALL_BK_FN) (struct sccb *); struct sccb_mgr_info { - unsigned long si_baseaddr; + u32 si_baseaddr; unsigned char si_present; unsigned char si_intvect; unsigned char si_id; unsigned char si_lun; - unsigned short si_fw_revision; - unsigned short si_per_targ_init_sync; - unsigned short si_per_targ_fast_nego; - unsigned short si_per_targ_ultra_nego; - unsigned short si_per_targ_no_disc; - unsigned short si_per_targ_wide_nego; - unsigned short si_flags; + u16 si_fw_revision; + u16 si_per_targ_init_sync; + u16 si_per_targ_fast_nego; + u16 si_per_targ_ultra_nego; + u16 si_per_targ_no_disc; + u16 si_per_targ_wide_nego; + u16 si_flags; unsigned char si_card_family; unsigned char si_bustype; unsigned char si_card_model[3]; unsigned char si_relative_cardnum; unsigned char si_reserved[4]; - unsigned long si_OS_reserved; + u32 si_OS_reserved; unsigned char si_XlatInfo[4]; - unsigned long si_reserved2[5]; - unsigned long si_secondary_range; + u32 si_reserved2[5]; + u32 si_secondary_range; }; #define SCSI_PARITY_ENA 0x0001 @@ -70,14 +70,14 @@ struct sccb_mgr_info { * The UCB Manager treats the SCCB as it's 'native hardware structure' */ -#pragma pack(1) +/*#pragma pack(1)*/ struct sccb { unsigned char OperationCode; unsigned char ControlByte; unsigned char CdbLength; unsigned char RequestSenseLength; - unsigned long DataLength; - unsigned long DataPointer; + u32 DataLength; + void *DataPointer; unsigned char CcbRes[2]; unsigned char HostStatus; unsigned char TargetStatus; @@ -86,32 +86,32 @@ struct sccb { unsigned char Cdb[12]; unsigned char CcbRes1; unsigned char Reserved1; - unsigned long Reserved2; - unsigned long SensePointer; + u32 Reserved2; + u32 SensePointer; CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */ - unsigned long SccbIOPort; /* Identifies board base port */ + u32 SccbIOPort; /* Identifies board base port */ unsigned char SccbStatus; unsigned char SCCBRes2; - unsigned short SccbOSFlags; - - unsigned long Sccb_XferCnt; /* actual transfer count */ - unsigned long Sccb_ATC; - unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */ - unsigned long Sccb_res1; - unsigned short Sccb_MGRFlags; - unsigned short Sccb_sgseg; + u16 SccbOSFlags; + + u32 Sccb_XferCnt; /* actual transfer count */ + u32 Sccb_ATC; + u32 SccbVirtDataPtr; /* virtual addr for OS/2 */ + u32 Sccb_res1; + u16 Sccb_MGRFlags; + u16 Sccb_sgseg; unsigned char Sccb_scsimsg; /* identify msg for selection */ unsigned char Sccb_tag; unsigned char Sccb_scsistat; unsigned char Sccb_idmsg; /* image of last msg in */ struct sccb *Sccb_forwardlink; struct sccb *Sccb_backlink; - unsigned long Sccb_savedATC; + u32 Sccb_savedATC; unsigned char Save_Cdb[6]; unsigned char Save_CdbLen; unsigned char Sccb_XferState; - unsigned long Sccb_SGoffset; + u32 Sccb_SGoffset; }; #pragma pack() @@ -223,15 +223,21 @@ struct sccb_mgr_tar_info { }; struct nvram_info { - unsigned char niModel; /* Model No. of card */ - unsigned char niCardNo; /* Card no. */ - unsigned long niBaseAddr; /* Port Address of card */ - unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */ - unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */ - unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */ - unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */ - unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */ - unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */ + unsigned char niModel; /* Model No. of card */ + unsigned char niCardNo; /* Card no. */ + u32 niBaseAddr; /* Port Address of card */ + unsigned char niSysConf; /* Adapter Configuration byte - + Byte 16 of eeprom map */ + unsigned char niScsiConf; /* SCSI Configuration byte - + Byte 17 of eeprom map */ + unsigned char niScamConf; /* SCAM Configuration byte - + Byte 20 of eeprom map */ + unsigned char niAdapId; /* Host Adapter ID - + Byte 24 of eerpom map */ + unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte + of targets */ + unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name + string of Targets */ }; #define MODEL_LT 1 @@ -243,7 +249,7 @@ struct sccb_card { struct sccb *currentSCCB; struct sccb_mgr_info *cardInfo; - unsigned long ioPort; + u32 ioPort; unsigned short cmdCounter; unsigned char discQCount; @@ -780,37 +786,37 @@ typedef struct SCCBscam_info { #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE))) -static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, +static unsigned char FPT_sisyncn(u32 port, unsigned char p_card, unsigned char syncFlag); -static void FPT_ssel(unsigned long port, unsigned char p_card); -static void FPT_sres(unsigned long port, unsigned char p_card, +static void FPT_ssel(u32 port, unsigned char p_card); +static void FPT_sres(u32 port, unsigned char p_card, struct sccb_card *pCurrCard); -static void FPT_shandem(unsigned long port, unsigned char p_card, +static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB); -static void FPT_stsyncn(unsigned long port, unsigned char p_card); -static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, +static void FPT_stsyncn(u32 port, unsigned char p_card); +static void FPT_sisyncr(u32 port, unsigned char sync_pulse, unsigned char offset); -static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, +static void FPT_sssyncv(u32 p_port, unsigned char p_id, unsigned char p_sync_value, struct sccb_mgr_tar_info *currTar_Info); -static void FPT_sresb(unsigned long port, unsigned char p_card); -static void FPT_sxfrp(unsigned long p_port, unsigned char p_card); -static void FPT_schkdd(unsigned long port, unsigned char p_card); -static unsigned char FPT_RdStack(unsigned long port, unsigned char index); -static void FPT_WrStack(unsigned long portBase, unsigned char index, +static void FPT_sresb(u32 port, unsigned char p_card); +static void FPT_sxfrp(u32 p_port, unsigned char p_card); +static void FPT_schkdd(u32 port, unsigned char p_card); +static unsigned char FPT_RdStack(u32 port, unsigned char index); +static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data); -static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort); +static unsigned char FPT_ChkIfChipInitialized(u32 ioPort); -static void FPT_SendMsg(unsigned long port, unsigned char message); +static void FPT_SendMsg(u32 port, unsigned char message); static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg, unsigned char error_code); static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card); static void FPT_RNVRamData(struct nvram_info *pNvRamInfo); -static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card); -static void FPT_stwidn(unsigned long port, unsigned char p_card); -static void FPT_siwidr(unsigned long port, unsigned char width); +static unsigned char FPT_siwidn(u32 port, unsigned char p_card); +static void FPT_stwidn(u32 port, unsigned char p_card); +static void FPT_siwidr(u32 port, unsigned char width); static void FPT_queueSelectFail(struct sccb_card *pCurrCard, unsigned char p_card); @@ -827,45 +833,45 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB); static unsigned short FPT_CalcCrc16(unsigned char buffer[]); static unsigned char FPT_CalcLrc(unsigned char buffer[]); -static void FPT_Wait1Second(unsigned long p_port); -static void FPT_Wait(unsigned long p_port, unsigned char p_delay); -static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode); -static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, +static void FPT_Wait1Second(u32 p_port); +static void FPT_Wait(u32 p_port, unsigned char p_delay); +static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode); +static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data, unsigned short ee_addr); -static unsigned short FPT_utilEERead(unsigned long p_port, +static unsigned short FPT_utilEERead(u32 p_port, unsigned short ee_addr); -static unsigned short FPT_utilEEReadOrg(unsigned long p_port, +static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr); -static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, +static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd, unsigned short ee_addr); -static void FPT_phaseDataOut(unsigned long port, unsigned char p_card); -static void FPT_phaseDataIn(unsigned long port, unsigned char p_card); -static void FPT_phaseCommand(unsigned long port, unsigned char p_card); -static void FPT_phaseStatus(unsigned long port, unsigned char p_card); -static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card); -static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card); -static void FPT_phaseIllegal(unsigned long port, unsigned char p_card); +static void FPT_phaseDataOut(u32 port, unsigned char p_card); +static void FPT_phaseDataIn(u32 port, unsigned char p_card); +static void FPT_phaseCommand(u32 port, unsigned char p_card); +static void FPT_phaseStatus(u32 port, unsigned char p_card); +static void FPT_phaseMsgOut(u32 port, unsigned char p_card); +static void FPT_phaseMsgIn(u32 port, unsigned char p_card); +static void FPT_phaseIllegal(u32 port, unsigned char p_card); -static void FPT_phaseDecode(unsigned long port, unsigned char p_card); -static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card); -static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card); +static void FPT_phaseDecode(u32 port, unsigned char p_card); +static void FPT_phaseChkFifo(u32 port, unsigned char p_card); +static void FPT_phaseBusFree(u32 p_port, unsigned char p_card); -static void FPT_XbowInit(unsigned long port, unsigned char scamFlg); -static void FPT_BusMasterInit(unsigned long p_port); -static void FPT_DiagEEPROM(unsigned long p_port); +static void FPT_XbowInit(u32 port, unsigned char scamFlg); +static void FPT_BusMasterInit(u32 p_port); +static void FPT_DiagEEPROM(u32 p_port); -static void FPT_dataXferProcessor(unsigned long port, +static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard); -static void FPT_busMstrSGDataXferStart(unsigned long port, +static void FPT_busMstrSGDataXferStart(u32 port, struct sccb *pCurrSCCB); -static void FPT_busMstrDataXferStart(unsigned long port, +static void FPT_busMstrDataXferStart(u32 port, struct sccb *pCurrSCCB); -static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, +static void FPT_hostDataXferAbort(u32 port, unsigned char p_card, struct sccb *pCurrSCCB); static void FPT_hostDataXferRestart(struct sccb *currSCCB); -static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, +static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card, struct sccb_card *pCurrCard, unsigned short p_int); @@ -879,28 +885,28 @@ static void FPT_SccbMgrTableInitTarget(unsigned char p_card, static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up); -static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type); -static void FPT_scbusf(unsigned long p_port); -static void FPT_scsel(unsigned long p_port); -static void FPT_scasid(unsigned char p_card, unsigned long p_port); -static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data); -static unsigned char FPT_scsendi(unsigned long p_port, +static int FPT_scarb(u32 p_port, unsigned char p_sel_type); +static void FPT_scbusf(u32 p_port); +static void FPT_scsel(u32 p_port); +static void FPT_scasid(unsigned char p_card, u32 p_port); +static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data); +static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[]); -static unsigned char FPT_sciso(unsigned long p_port, +static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[]); -static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit); -static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit); +static void FPT_scwirod(u32 p_port, unsigned char p_data_bit); +static void FPT_scwiros(u32 p_port, unsigned char p_data_bit); static unsigned char FPT_scvalq(unsigned char p_quintet); -static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id); -static void FPT_scwtsel(unsigned long p_port); -static void FPT_inisci(unsigned char p_card, unsigned long p_port, +static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id); +static void FPT_scwtsel(u32 p_port); +static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id); -static void FPT_scsavdi(unsigned char p_card, unsigned long p_port); +static void FPT_scsavdi(unsigned char p_card, u32 p_port); static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]); -static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card); -static void FPT_autoLoadDefaultMap(unsigned long p_port); +static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card); +static void FPT_autoLoadDefaultMap(u32 p_port); static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { {{0}} }; @@ -918,7 +924,7 @@ static unsigned char FPT_scamHAString[] = static unsigned short FPT_default_intena = 0; -static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char) = { +static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = { 0}; /*--------------------------------------------------------------------- @@ -935,7 +941,7 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) unsigned char i, j, id, ScamFlg; unsigned short temp, temp2, temp3, temp4, temp5, temp6; - unsigned long ioport; + u32 ioport; struct nvram_info *pCurrNvRam; ioport = pCardInfo->si_baseaddr; @@ -1201,23 +1207,21 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) * *---------------------------------------------------------------------*/ -static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info +static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info *pCardInfo) { struct sccb_card *CurrCard = NULL; struct nvram_info *pCurrNvRam; unsigned char i, j, thisCard, ScamFlg; unsigned short temp, sync_bit_map, id; - unsigned long ioport; + u32 ioport; ioport = pCardInfo->si_baseaddr; for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) { - if (thisCard == MAX_CARDS) { - - return FAILURE; - } + if (thisCard == MAX_CARDS) + return (void *)FAILURE; if (FPT_BL_Card[thisCard].ioPort == ioport) { @@ -1384,16 +1388,16 @@ static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) | SCCB_MGR_PRESENT)); - return (unsigned long)CurrCard; + return (void *)CurrCard; } -static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard) +static void FlashPoint_ReleaseHostAdapter(void *pCurrCard) { unsigned char i; - unsigned long portBase; - unsigned long regOffset; - unsigned long scamData; - unsigned long *pScamTbl; + u32 portBase; + u32 regOffset; + u32 scamData; + u32 *pScamTbl; struct nvram_info *pCurrNvRam; pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo; @@ -1414,7 +1418,7 @@ static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard) for (i = 0; i < MAX_SCSI_TAR; i++) { regOffset = hp_aramBase + 64 + i * 4; - pScamTbl = (unsigned long *)&pCurrNvRam->niScamTbl[i]; + pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i]; scamData = *pScamTbl; WR_HARP32(portBase, regOffset, scamData); } @@ -1427,10 +1431,10 @@ static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard) static void FPT_RNVRamData(struct nvram_info *pNvRamInfo) { unsigned char i; - unsigned long portBase; - unsigned long regOffset; - unsigned long scamData; - unsigned long *pScamTbl; + u32 portBase; + u32 regOffset; + u32 scamData; + u32 *pScamTbl; pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0); pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1); @@ -1447,26 +1451,25 @@ static void FPT_RNVRamData(struct nvram_info *pNvRamInfo) for (i = 0; i < MAX_SCSI_TAR; i++) { regOffset = hp_aramBase + 64 + i * 4; RD_HARP32(portBase, regOffset, scamData); - pScamTbl = (unsigned long *)&pNvRamInfo->niScamTbl[i]; + pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i]; *pScamTbl = scamData; } } -static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index) +static unsigned char FPT_RdStack(u32 portBase, unsigned char index) { WR_HARPOON(portBase + hp_stack_addr, index); return RD_HARPOON(portBase + hp_stack_data); } -static void FPT_WrStack(unsigned long portBase, unsigned char index, - unsigned char data) +static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data) { WR_HARPOON(portBase + hp_stack_addr, index); WR_HARPOON(portBase + hp_stack_data, data); } -static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort) +static unsigned char FPT_ChkIfChipInitialized(u32 ioPort) { if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4)) return 0; @@ -1489,15 +1492,16 @@ static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort) * callback function. * *---------------------------------------------------------------------*/ -static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) +static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb) { - unsigned long ioport; + u32 ioport; unsigned char thisCard, lun; struct sccb *pSaveSccb; CALL_BK_FN callback; + struct sccb_card *pCurrCard = curr_card; - thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + thisCard = pCurrCard->cardIndex; + ioport = pCurrCard->ioPort; if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) { @@ -1512,18 +1516,18 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) FPT_sinits(p_Sccb, thisCard); - if (!((struct sccb_card *)pCurrCard)->cmdCounter) { + if (!pCurrCard->cmdCounter) { WR_HARPOON(ioport + hp_semaphore, (RD_HARPOON(ioport + hp_semaphore) | SCCB_MGR_ACTIVE)); - if (((struct sccb_card *)pCurrCard)->globalFlags & F_GREEN_PC) { + if (pCurrCard->globalFlags & F_GREEN_PC) { WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT); WR_HARPOON(ioport + hp_sys_ctrl, 0x00); } } - ((struct sccb_card *)pCurrCard)->cmdCounter++; + pCurrCard->cmdCounter++; if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) { @@ -1532,10 +1536,10 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) | TICKLE_ME)); if (p_Sccb->OperationCode == RESET_COMMAND) { pSaveSccb = - ((struct sccb_card *)pCurrCard)->currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; + pCurrCard->currentSCCB; + pCurrCard->currentSCCB = p_Sccb; FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = + pCurrCard->currentSCCB = pSaveSccb; } else { FPT_queueAddSccb(p_Sccb, thisCard); @@ -1546,10 +1550,10 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) if (p_Sccb->OperationCode == RESET_COMMAND) { pSaveSccb = - ((struct sccb_card *)pCurrCard)->currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; + pCurrCard->currentSCCB; + pCurrCard->currentSCCB = p_Sccb; FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = + pCurrCard->currentSCCB = pSaveSccb; } else { FPT_queueAddSccb(p_Sccb, thisCard); @@ -1560,34 +1564,29 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) MDISABLE_INT(ioport); - if ((((struct sccb_card *)pCurrCard)->globalFlags & F_CONLUN_IO) - && + if ((pCurrCard->globalFlags & F_CONLUN_IO) && ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID]. TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) lun = p_Sccb->Lun; else lun = 0; - if ((((struct sccb_card *)pCurrCard)->currentSCCB == NULL) && + if ((pCurrCard->currentSCCB == NULL) && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun] == 0)) { - ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb; + pCurrCard->currentSCCB = p_Sccb; FPT_ssel(p_Sccb->SccbIOPort, thisCard); } else { if (p_Sccb->OperationCode == RESET_COMMAND) { - pSaveSccb = - ((struct sccb_card *)pCurrCard)-> - currentSCCB; - ((struct sccb_card *)pCurrCard)->currentSCCB = - p_Sccb; + pSaveSccb = pCurrCard->currentSCCB; + pCurrCard->currentSCCB = p_Sccb; FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); - ((struct sccb_card *)pCurrCard)->currentSCCB = - pSaveSccb; + pCurrCard->currentSCCB = pSaveSccb; } else { FPT_queueAddSccb(p_Sccb, thisCard); } @@ -1607,9 +1606,9 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb) * callback function. * *---------------------------------------------------------------------*/ -static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb *p_Sccb) +static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb) { - unsigned long ioport; + u32 ioport; unsigned char thisCard; CALL_BK_FN callback; @@ -1715,9 +1714,9 @@ static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb *p_Sccb) * interrupt for this card and disable the IRQ Pin if so. * *---------------------------------------------------------------------*/ -static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard) +static unsigned char FlashPoint_InterruptPending(void *pCurrCard) { - unsigned long ioport; + u32 ioport; ioport = ((struct sccb_card *)pCurrCard)->ioPort; @@ -1739,38 +1738,36 @@ static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard) * us. * *---------------------------------------------------------------------*/ -static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) +static int FlashPoint_HandleInterrupt(void *pcard) { struct sccb *currSCCB; unsigned char thisCard, result, bm_status, bm_int_st; unsigned short hp_int; unsigned char i, target; - unsigned long ioport; + struct sccb_card *pCurrCard = pcard; + u32 ioport; - thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; - ioport = ((struct sccb_card *)pCurrCard)->ioPort; + thisCard = pCurrCard->cardIndex; + ioport = pCurrCard->ioPort; MDISABLE_INT(ioport); if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON) - bm_status = - RD_HARPOON(ioport + - hp_ext_status) & (unsigned char)BAD_EXT_STATUS; + bm_status = RD_HARPOON(ioport + hp_ext_status) & + (unsigned char)BAD_EXT_STATUS; else bm_status = 0; WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); - while ((hp_int = - RDW_HARPOON((ioport + - hp_intstat)) & FPT_default_intena) | bm_status) { + while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) & + FPT_default_intena) | bm_status) { - currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB; + currSCCB = pCurrCard->currentSCCB; if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) { result = - FPT_SccbMgr_bad_isr(ioport, thisCard, - ((struct sccb_card *)pCurrCard), + FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard, hp_int); WRW_HARPOON((ioport + hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL)); @@ -1796,8 +1793,7 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) (BUS_FREE | RSEL))) ; } - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) FPT_phaseChkFifo(ioport, thisCard); @@ -1813,14 +1809,11 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) else if (hp_int & ITAR_DISC) { - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { - + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) FPT_phaseChkFifo(ioport, thisCard); - } - - if (RD_HARPOON(ioport + hp_gp_reg_1) == SMSAVE_DATA_PTR) { + if (RD_HARPOON(ioport + hp_gp_reg_1) == + SMSAVE_DATA_PTR) { WR_HARPOON(ioport + hp_gp_reg_1, 0x00); currSCCB->Sccb_XferState |= F_NO_DATA_YET; @@ -1859,8 +1852,7 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) WRW_HARPOON((ioport + hp_intstat), (BUS_FREE | ITAR_DISC)); - ((struct sccb_card *)pCurrCard)->globalFlags |= - F_NEW_SCCB_CMD; + pCurrCard->globalFlags |= F_NEW_SCCB_CMD; } @@ -1870,10 +1862,8 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) (PROG_HLT | RSEL | PHASE | BUS_FREE)); if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) { - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) FPT_phaseChkFifo(ioport, thisCard); - } if (RD_HARPOON(ioport + hp_gp_reg_1) == SMSAVE_DATA_PTR) { @@ -1890,8 +1880,7 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) FPT_queueDisconnect(currSCCB, thisCard); } - FPT_sres(ioport, thisCard, - ((struct sccb_card *)pCurrCard)); + FPT_sres(ioport, thisCard, pCurrCard); FPT_phaseDecode(ioport, thisCard); } @@ -1948,8 +1937,7 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) WRW_HARPOON((ioport + hp_intstat), BUS_FREE); - if (((struct sccb_card *)pCurrCard)-> - globalFlags & F_HOST_XFER_ACT) { + if (pCurrCard->globalFlags & F_HOST_XFER_ACT) { FPT_hostDataXferAbort(ioport, thisCard, currSCCB); @@ -1961,27 +1949,19 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) else if (hp_int & ITICKLE) { WRW_HARPOON((ioport + hp_intstat), ITICKLE); - ((struct sccb_card *)pCurrCard)->globalFlags |= - F_NEW_SCCB_CMD; + pCurrCard->globalFlags |= F_NEW_SCCB_CMD; } if (((struct sccb_card *)pCurrCard)-> globalFlags & F_NEW_SCCB_CMD) { - ((struct sccb_card *)pCurrCard)->globalFlags &= - ~F_NEW_SCCB_CMD; + pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD; - if (((struct sccb_card *)pCurrCard)->currentSCCB == - NULL) { - - FPT_queueSearchSelect(((struct sccb_card *) - pCurrCard), thisCard); - } + if (pCurrCard->currentSCCB == NULL) + FPT_queueSearchSelect(pCurrCard, thisCard); - if (((struct sccb_card *)pCurrCard)->currentSCCB != - NULL) { - ((struct sccb_card *)pCurrCard)->globalFlags &= - ~F_NEW_SCCB_CMD; + if (pCurrCard->currentSCCB != NULL) { + pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD; FPT_ssel(ioport, thisCard); } @@ -2006,8 +1986,7 @@ static int FlashPoint_HandleInterrupt(unsigned long pCurrCard) * processing time. * *---------------------------------------------------------------------*/ -static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, - unsigned char p_card, +static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card, struct sccb_card *pCurrCard, unsigned short p_int) { @@ -2254,7 +2233,7 @@ static void FPT_SccbMgrTableInitTarget(unsigned char p_card, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB) +static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB) { unsigned char message; unsigned short TimeOutLoop; @@ -2322,12 +2301,12 @@ static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB) * *---------------------------------------------------------------------*/ -static void FPT_ssel(unsigned long port, unsigned char p_card) +static void FPT_ssel(u32 port, unsigned char p_card) { unsigned char auto_loaded, i, target, *theCCB; - unsigned long cdb_reg; + u32 cdb_reg; struct sccb_card *CurrCard; struct sccb *currSCCB; struct sccb_mgr_tar_info *currTar_Info; @@ -2621,7 +2600,7 @@ static void FPT_ssel(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_sres(unsigned long port, unsigned char p_card, +static void FPT_sres(u32 port, unsigned char p_card, struct sccb_card *pCurrCard) { @@ -2857,7 +2836,7 @@ static void FPT_sres(unsigned long port, unsigned char p_card, (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ; } -static void FPT_SendMsg(unsigned long port, unsigned char message) +static void FPT_SendMsg(u32 port, unsigned char message) { while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) { if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) { @@ -2904,8 +2883,7 @@ static void FPT_SendMsg(unsigned long port, unsigned char message) * target device. * *---------------------------------------------------------------------*/ -static void FPT_sdecm(unsigned char message, unsigned long port, - unsigned char p_card) +static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card) { struct sccb *currSCCB; struct sccb_card *CurrCard; @@ -3085,8 +3063,7 @@ static void FPT_sdecm(unsigned char message, unsigned long port, * Description: Decide what to do with the extended message. * *---------------------------------------------------------------------*/ -static void FPT_shandem(unsigned long port, unsigned char p_card, - struct sccb *pCurrSCCB) +static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB) { unsigned char length, message; @@ -3153,7 +3130,7 @@ static void FPT_shandem(unsigned long port, unsigned char p_card, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, +static unsigned char FPT_sisyncn(u32 port, unsigned char p_card, unsigned char syncFlag) { struct sccb *currSCCB; @@ -3234,7 +3211,7 @@ static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, * necessary. * *---------------------------------------------------------------------*/ -static void FPT_stsyncn(unsigned long port, unsigned char p_card) +static void FPT_stsyncn(u32 port, unsigned char p_card) { unsigned char sync_msg, offset, sync_reg, our_sync_msg; struct sccb *currSCCB; @@ -3363,7 +3340,7 @@ static void FPT_stsyncn(unsigned long port, unsigned char p_card) * Description: Answer the targets sync message. * *---------------------------------------------------------------------*/ -static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, +static void FPT_sisyncr(u32 port, unsigned char sync_pulse, unsigned char offset) { ARAM_ACCESS(port); @@ -3394,7 +3371,7 @@ static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse, * *---------------------------------------------------------------------*/ -static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card) +static unsigned char FPT_siwidn(u32 port, unsigned char p_card) { struct sccb *currSCCB; struct sccb_mgr_tar_info *currTar_Info; @@ -3449,7 +3426,7 @@ static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card) * necessary. * *---------------------------------------------------------------------*/ -static void FPT_stwidn(unsigned long port, unsigned char p_card) +static void FPT_stwidn(u32 port, unsigned char p_card) { unsigned char width; struct sccb *currSCCB; @@ -3520,7 +3497,7 @@ static void FPT_stwidn(unsigned long port, unsigned char p_card) * Description: Answer the targets Wide nego message. * *---------------------------------------------------------------------*/ -static void FPT_siwidr(unsigned long port, unsigned char width) +static void FPT_siwidr(u32 port, unsigned char width) { ARAM_ACCESS(port); WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); @@ -3548,7 +3525,7 @@ static void FPT_siwidr(unsigned long port, unsigned char width) * ID specified. * *---------------------------------------------------------------------*/ -static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, +static void FPT_sssyncv(u32 p_port, unsigned char p_id, unsigned char p_sync_value, struct sccb_mgr_tar_info *currTar_Info) { @@ -3620,7 +3597,7 @@ static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, * Description: Reset the desired card's SCSI bus. * *---------------------------------------------------------------------*/ -static void FPT_sresb(unsigned long port, unsigned char p_card) +static void FPT_sresb(u32 port, unsigned char p_card) { unsigned char scsiID, i; @@ -3713,7 +3690,7 @@ static void FPT_ssenss(struct sccb_card *pCurrCard) currSCCB->Cdb[4] = currSCCB->RequestSenseLength; currSCCB->Cdb[5] = 0x00; - currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength; + currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength; currSCCB->Sccb_ATC = 0x00; @@ -3737,7 +3714,7 @@ static void FPT_ssenss(struct sccb_card *pCurrCard) * *---------------------------------------------------------------------*/ -static void FPT_sxfrp(unsigned long p_port, unsigned char p_card) +static void FPT_sxfrp(u32 p_port, unsigned char p_card) { unsigned char curr_phz; @@ -3819,7 +3796,7 @@ static void FPT_sxfrp(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_schkdd(unsigned long port, unsigned char p_card) +static void FPT_schkdd(u32 port, unsigned char p_card) { unsigned short TimeOutLoop; unsigned char sPhase; @@ -3998,10 +3975,10 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card) +static void FPT_phaseDecode(u32 p_port, unsigned char p_card) { unsigned char phase_ref; - void (*phase) (unsigned long, unsigned char); + void (*phase) (u32, unsigned char); DISABLE_AUTO(p_port); @@ -4021,7 +3998,7 @@ static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDataOut(unsigned long port, unsigned char p_card) +static void FPT_phaseDataOut(u32 port, unsigned char p_card) { struct sccb *currSCCB; @@ -4062,7 +4039,7 @@ static void FPT_phaseDataOut(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseDataIn(unsigned long port, unsigned char p_card) +static void FPT_phaseDataIn(u32 port, unsigned char p_card) { struct sccb *currSCCB; @@ -4106,10 +4083,10 @@ static void FPT_phaseDataIn(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card) +static void FPT_phaseCommand(u32 p_port, unsigned char p_card) { struct sccb *currSCCB; - unsigned long cdb_reg; + u32 cdb_reg; unsigned char i; currSCCB = FPT_BL_Card[p_card].currentSCCB; @@ -4157,7 +4134,7 @@ static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseStatus(unsigned long port, unsigned char p_card) +static void FPT_phaseStatus(u32 port, unsigned char p_card) { /* Start-up the automation to finish off this command and let the isr handle the interrupt for command complete when it comes in. @@ -4178,7 +4155,7 @@ static void FPT_phaseStatus(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card) +static void FPT_phaseMsgOut(u32 port, unsigned char p_card) { unsigned char message, scsiID; struct sccb *currSCCB; @@ -4317,7 +4294,7 @@ static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card) +static void FPT_phaseMsgIn(u32 port, unsigned char p_card) { unsigned char message; struct sccb *currSCCB; @@ -4364,7 +4341,7 @@ static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseIllegal(unsigned long port, unsigned char p_card) +static void FPT_phaseIllegal(u32 port, unsigned char p_card) { struct sccb *currSCCB; @@ -4390,9 +4367,9 @@ static void FPT_phaseIllegal(unsigned long port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card) +static void FPT_phaseChkFifo(u32 port, unsigned char p_card) { - unsigned long xfercnt; + u32 xfercnt; struct sccb *currSCCB; currSCCB = FPT_BL_Card[p_card].currentSCCB; @@ -4461,7 +4438,7 @@ static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card) * because of command complete or from a disconnect. * *---------------------------------------------------------------------*/ -static void FPT_phaseBusFree(unsigned long port, unsigned char p_card) +static void FPT_phaseBusFree(u32 port, unsigned char p_card) { struct sccb *currSCCB; @@ -4557,9 +4534,9 @@ static void FPT_phaseBusFree(unsigned long port, unsigned char p_card) * Description: Load the Automation RAM with the defualt map values. * *---------------------------------------------------------------------*/ -static void FPT_autoLoadDefaultMap(unsigned long p_port) +static void FPT_autoLoadDefaultMap(u32 p_port) { - unsigned long map_addr; + u32 map_addr; ARAM_ACCESS(p_port); map_addr = p_port + hp_aramBase; @@ -4663,7 +4640,7 @@ static void FPT_autoLoadDefaultMap(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card) +static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card) { struct sccb *currSCCB; unsigned char status_byte; @@ -4936,8 +4913,7 @@ static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card) * *---------------------------------------------------------------------*/ -static void FPT_dataXferProcessor(unsigned long port, - struct sccb_card *pCurrCard) +static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard) { struct sccb *currSCCB; @@ -4970,22 +4946,18 @@ static void FPT_dataXferProcessor(unsigned long port, * Description: * *---------------------------------------------------------------------*/ -static void FPT_busMstrSGDataXferStart(unsigned long p_port, - struct sccb *pcurrSCCB) +static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB) { - unsigned long count, addr, tmpSGCnt; + u32 count, addr, tmpSGCnt; unsigned int sg_index; unsigned char sg_count, i; - unsigned long reg_offset; - - if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { + u32 reg_offset; + struct blogic_sg_seg *segp; - count = ((unsigned long)HOST_RD_CMD) << 24; - } - - else { - count = ((unsigned long)HOST_WRT_CMD) << 24; - } + if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) + count = ((u32)HOST_RD_CMD) << 24; + else + count = ((u32)HOST_WRT_CMD) << 24; sg_count = 0; tmpSGCnt = 0; @@ -4998,25 +4970,20 @@ static void FPT_busMstrSGDataXferStart(unsigned long p_port, WR_HARPOON(p_port + hp_page_ctrl, i); while ((sg_count < (unsigned char)SG_BUF_CNT) && - ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < - pcurrSCCB->DataLength)) { - - tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer) + - (sg_index * 2)); - - count |= *(((unsigned long *)pcurrSCCB->DataPointer) + - (sg_index * 2)); + ((sg_index * (unsigned int)SG_ELEMENT_SIZE) < + pcurrSCCB->DataLength)) { - addr = *(((unsigned long *)pcurrSCCB->DataPointer) + - ((sg_index * 2) + 1)); + segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) + + sg_index; + tmpSGCnt += segp->segbytes; + count |= segp->segbytes; + addr = segp->segdata; if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) { - addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset); count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset; - tmpSGCnt = count & 0x00FFFFFFL; } @@ -5072,17 +5039,15 @@ static void FPT_busMstrSGDataXferStart(unsigned long p_port, * Description: * *---------------------------------------------------------------------*/ -static void FPT_busMstrDataXferStart(unsigned long p_port, - struct sccb *pcurrSCCB) +static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB) { - unsigned long addr, count; + u32 addr, count; if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) { count = pcurrSCCB->Sccb_XferCnt; - addr = - (unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; + addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; } else { @@ -5127,7 +5092,7 @@ static void FPT_busMstrDataXferStart(unsigned long p_port, * command busy is also time out, it'll just give up. * *---------------------------------------------------------------------*/ -static unsigned char FPT_busMstrTimeOut(unsigned long p_port) +static unsigned char FPT_busMstrTimeOut(u32 p_port) { unsigned long timeout; @@ -5166,13 +5131,14 @@ static unsigned char FPT_busMstrTimeOut(unsigned long p_port) * Description: Abort any in progress transfer. * *---------------------------------------------------------------------*/ -static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, +static void FPT_hostDataXferAbort(u32 port, unsigned char p_card, struct sccb *pCurrSCCB) { unsigned long timeout; unsigned long remain_cnt; - unsigned int sg_ptr; + u32 sg_ptr; + struct blogic_sg_seg *segp; FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT; @@ -5236,9 +5202,8 @@ static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) { - sg_ptr = - (unsigned int)(pCurrSCCB->DataLength / - SG_ELEMENT_SIZE); + sg_ptr = (u32)(pCurrSCCB->DataLength / + SG_ELEMENT_SIZE); } remain_cnt = pCurrSCCB->Sccb_XferCnt; @@ -5246,23 +5211,13 @@ static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, while (remain_cnt < 0x01000000L) { sg_ptr--; - - if (remain_cnt > - (unsigned - long)(*(((unsigned long *)pCurrSCCB-> - DataPointer) + (sg_ptr * 2)))) { - + segp = (struct blogic_sg_seg *)(pCurrSCCB-> + DataPointer) + (sg_ptr * 2); + if (remain_cnt > (unsigned long)segp->segbytes) remain_cnt -= - (unsigned - long)(*(((unsigned long *) - pCurrSCCB->DataPointer) + - (sg_ptr * 2))); - } - - else { - + (unsigned long)segp->segbytes; + else break; - } } if (remain_cnt < 0x01000000L) { @@ -5418,23 +5373,18 @@ static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, pCurrSCCB->Sccb_SGoffset = 0x00; - if ((unsigned long)(pCurrSCCB->Sccb_sgseg * - SG_ELEMENT_SIZE) >= - pCurrSCCB->DataLength) { + if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >= + pCurrSCCB->DataLength) { pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; - pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE); - } } else { - if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE)) - pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; } } @@ -5454,21 +5404,22 @@ static void FPT_hostDataXferRestart(struct sccb *currSCCB) { unsigned long data_count; unsigned int sg_index; - unsigned long *sg_ptr; + struct blogic_sg_seg *segp; if (currSCCB->Sccb_XferState & F_SG_XFER) { currSCCB->Sccb_XferCnt = 0; sg_index = 0xffff; /*Index by long words into sg list. */ - data_count = 0; /*Running count of SG xfer counts. */ + data_count = 0; /*Running count of SG xfer counts. */ - sg_ptr = (unsigned long *)currSCCB->DataPointer; while (data_count < currSCCB->Sccb_ATC) { sg_index++; - data_count += *(sg_ptr + (sg_index * 2)); + segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) + + (sg_index * 2); + data_count += segp->segbytes; } if (data_count == currSCCB->Sccb_ATC) { @@ -5504,7 +5455,7 @@ static void FPT_scini(unsigned char p_card, unsigned char p_our_id, { unsigned char loser, assigned_id; - unsigned long p_port; + u32 p_port; unsigned char i, k, ScamFlg; struct sccb_card *currCard; @@ -5709,7 +5660,7 @@ static void FPT_scini(unsigned char p_card, unsigned char p_our_id, * *---------------------------------------------------------------------*/ -static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type) +static int FPT_scarb(u32 p_port, unsigned char p_sel_type) { if (p_sel_type == INIT_SELTD) { @@ -5771,7 +5722,7 @@ static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type) * *---------------------------------------------------------------------*/ -static void FPT_scbusf(unsigned long p_port) +static void FPT_scbusf(u32 p_port) { WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE)); @@ -5803,7 +5754,7 @@ static void FPT_scbusf(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_scasid(unsigned char p_card, unsigned long p_port) +static void FPT_scasid(unsigned char p_card, u32 p_port) { unsigned char temp_id_string[ID_STRING_LENGTH]; @@ -5880,7 +5831,7 @@ static void FPT_scasid(unsigned char p_card, unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_scsel(unsigned long p_port) +static void FPT_scsel(u32 p_port) { WR_HARPOON(p_port + hp_scsisig, SCSI_SEL); @@ -5914,7 +5865,7 @@ static void FPT_scsel(unsigned long p_port) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data) +static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data) { unsigned char curr_data, ret_data; @@ -5964,8 +5915,7 @@ static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scsendi(unsigned long p_port, - unsigned char p_id_string[]) +static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[]) { unsigned char ret_data, byte_cnt, bit_cnt, defer; @@ -6016,8 +5966,7 @@ static unsigned char FPT_scsendi(unsigned long p_port, * *---------------------------------------------------------------------*/ -static unsigned char FPT_sciso(unsigned long p_port, - unsigned char p_id_string[]) +static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[]) { unsigned char ret_data, the_data, byte_cnt, bit_cnt; @@ -6075,7 +6024,7 @@ static unsigned char FPT_sciso(unsigned long p_port, * *---------------------------------------------------------------------*/ -static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit) +static void FPT_scwirod(u32 p_port, unsigned char p_data_bit) { unsigned char i; @@ -6102,7 +6051,7 @@ static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit) * *---------------------------------------------------------------------*/ -static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit) +static void FPT_scwiros(u32 p_port, unsigned char p_data_bit) { unsigned char i; @@ -6154,7 +6103,7 @@ static unsigned char FPT_scvalq(unsigned char p_quintet) * *---------------------------------------------------------------------*/ -static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id) +static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id) { unsigned long i; @@ -6236,7 +6185,7 @@ static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id) * *---------------------------------------------------------------------*/ -static void FPT_scwtsel(unsigned long p_port) +static void FPT_scwtsel(u32 p_port) { while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) { } @@ -6250,8 +6199,7 @@ static void FPT_scwtsel(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_inisci(unsigned char p_card, unsigned long p_port, - unsigned char p_our_id) +static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id) { unsigned char i, k, max_id; unsigned short ee_data; @@ -6437,7 +6385,7 @@ static unsigned char FPT_scmachid(unsigned char p_card, * *---------------------------------------------------------------------*/ -static void FPT_scsavdi(unsigned char p_card, unsigned long p_port) +static void FPT_scsavdi(unsigned char p_card, u32 p_port) { unsigned char i, k, max_id; unsigned short ee_data, sum_data; @@ -6482,7 +6430,7 @@ static void FPT_scsavdi(unsigned char p_card, unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg) +static void FPT_XbowInit(u32 port, unsigned char ScamFlg) { unsigned char i; @@ -6531,7 +6479,7 @@ static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg) * *---------------------------------------------------------------------*/ -static void FPT_BusMasterInit(unsigned long p_port) +static void FPT_BusMasterInit(u32 p_port) { WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST); @@ -6558,7 +6506,7 @@ static void FPT_BusMasterInit(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_DiagEEPROM(unsigned long p_port) +static void FPT_DiagEEPROM(u32 p_port) { unsigned short index, temp, max_wd_cnt; @@ -7206,7 +7154,7 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB) { unsigned long partial_cnt; unsigned int sg_index; - unsigned long *sg_ptr; + struct blogic_sg_seg *segp; if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) { @@ -7219,7 +7167,6 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB) sg_index = p_SCCB->Sccb_sgseg; - sg_ptr = (unsigned long *)p_SCCB->DataPointer; if (p_SCCB->Sccb_SGoffset) { @@ -7229,8 +7176,9 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB) while (((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) { - - partial_cnt += *(sg_ptr + (sg_index * 2)); + segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) + + (sg_index * 2); + partial_cnt += segp->segbytes; sg_index++; } @@ -7251,7 +7199,7 @@ static void FPT_utilUpdateResidual(struct sccb *p_SCCB) * *---------------------------------------------------------------------*/ -static void FPT_Wait1Second(unsigned long p_port) +static void FPT_Wait1Second(u32 p_port) { unsigned char i; @@ -7275,7 +7223,7 @@ static void FPT_Wait1Second(unsigned long p_port) * *---------------------------------------------------------------------*/ -static void FPT_Wait(unsigned long p_port, unsigned char p_delay) +static void FPT_Wait(u32 p_port, unsigned char p_delay) { unsigned char old_timer; unsigned char green_flag; @@ -7321,7 +7269,7 @@ static void FPT_Wait(unsigned long p_port, unsigned char p_delay) * *---------------------------------------------------------------------*/ -static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode) +static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode) { unsigned char ee_value; @@ -7350,7 +7298,7 @@ static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode) * *---------------------------------------------------------------------*/ -static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, +static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data, unsigned short ee_addr) { @@ -7401,7 +7349,7 @@ static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, * *---------------------------------------------------------------------*/ -static unsigned short FPT_utilEERead(unsigned long p_port, +static unsigned short FPT_utilEERead(u32 p_port, unsigned short ee_addr) { unsigned short i, ee_data1, ee_data2; @@ -7431,8 +7379,7 @@ static unsigned short FPT_utilEERead(unsigned long p_port, * *---------------------------------------------------------------------*/ -static unsigned short FPT_utilEEReadOrg(unsigned long p_port, - unsigned short ee_addr) +static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr) { unsigned char ee_value; @@ -7479,7 +7426,7 @@ static unsigned short FPT_utilEEReadOrg(unsigned long p_port, * *---------------------------------------------------------------------*/ -static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, +static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd, unsigned short ee_addr) { unsigned char ee_value; @@ -7579,7 +7526,7 @@ FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo) FlashPointInfo); } -static inline unsigned int +static inline void * FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo) { return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) @@ -7587,33 +7534,31 @@ FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo) } static inline void -FlashPoint__ReleaseHostAdapter(unsigned int CardHandle) +FlashPoint__ReleaseHostAdapter(void *CardHandle) { FlashPoint_ReleaseHostAdapter(CardHandle); } static inline void -FlashPoint__StartCCB(unsigned int CardHandle, - struct blogic_ccb *CCB) +FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB) { FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB); } static inline void -FlashPoint__AbortCCB(unsigned int CardHandle, - struct blogic_ccb *CCB) +FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB) { FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); } static inline bool -FlashPoint__InterruptPending(unsigned int CardHandle) +FlashPoint__InterruptPending(void *CardHandle) { return FlashPoint_InterruptPending(CardHandle); } static inline int -FlashPoint__HandleInterrupt(unsigned int CardHandle) +FlashPoint__HandleInterrupt(void *CardHandle) { return FlashPoint_HandleInterrupt(CardHandle); } @@ -7633,11 +7578,11 @@ FlashPoint__HandleInterrupt(unsigned int CardHandle) */ extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *); -extern unsigned int FlashPoint_HardwareResetHostAdapter(struct fpoint_info *); -extern void FlashPoint_StartCCB(unsigned int, struct blogic_ccb *); -extern int FlashPoint_AbortCCB(unsigned int, struct blogic_ccb *); -extern bool FlashPoint_InterruptPending(unsigned int); -extern int FlashPoint_HandleInterrupt(unsigned int); -extern void FlashPoint_ReleaseHostAdapter(unsigned int); +extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *); +extern void FlashPoint_StartCCB(void *, struct blogic_ccb *); +extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *); +extern bool FlashPoint_InterruptPending(void *); +extern int FlashPoint_HandleInterrupt(void *); +extern void FlashPoint_ReleaseHostAdapter(void *); #endif /* CONFIG_SCSI_FLASHPOINT */ diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 86af29f..48b2918 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -633,7 +633,7 @@ config SCSI_BUSLOGIC config SCSI_FLASHPOINT bool "FlashPoint support" - depends on SCSI_BUSLOGIC && PCI && X86_32 + depends on SCSI_BUSLOGIC && PCI help This option allows you to add FlashPoint support to the BusLogic SCSI driver. The FlashPoint SCCB Manager code is -- cgit v1.1 From 1f34923c8a7d5512757318ff728fef24b1f50c9a Mon Sep 17 00:00:00 2001 From: Khalid Aziz Date: Tue, 25 Jun 2013 09:57:27 -0600 Subject: [SCSI] MAINTAINERS: Add myself as the maintainer for BusLogic SCSI driver I ported BusLogic driver to 64-bit. There is no current maintainer for this driver and since I made significant changes to the driver for 64-bit porting work, I will continue to maintain it. Signed-off-by: Khalid Aziz Signed-off-by: James Bottomley --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index fd3a495..9263589 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1858,6 +1858,13 @@ S: Odd fixes F: Documentation/video4linux/bttv/ F: drivers/media/pci/bt8xx/bttv* +BUSLOGIC SCSI DRIVER +M: Khalid Aziz +L: linux-scsi@vger.kernel.org +S: Maintained +F: drivers/scsi/BusLogic.* +F: drivers/scsi/FlashPoint.* + C-MEDIA CMI8788 DRIVER M: Clemens Ladisch L: alsa-devel@alsa-project.org (moderated for non-subscribers) -- cgit v1.1 From 893def38211980cf9581a74dfdc66be4d77a1db6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 4 Jun 2013 12:05:05 -0700 Subject: [SCSI] storvsc: Increase the value of scsi timeout for storvsc devices The standard scsi timeout is not appropriate in some of the environments where Hyper-V is deployed. Set this timeout appropriately for all devices managed by this driver. On cloud environments where storage latencies may be unbounded, having the scsi layer initiating recovery can be problematic since (a) the host is already implementing a variety of recovery strategies and (b) implementing a recovery strategy at the VM level may be more appropriate in cases where storage latencies exceed a certain threshold. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: James Bottomley --- drivers/scsi/storvsc_drv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 16a3a0c..ede8694 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -221,6 +221,11 @@ static int storvsc_ringbuffer_size = (20 * PAGE_SIZE); module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); +/* + * Timeout in seconds for all devices managed by this driver. + */ +static int storvsc_timeout = 180; + #define STORVSC_MAX_IO_REQUESTS 128 /* @@ -1204,6 +1209,8 @@ static int storvsc_device_configure(struct scsi_device *sdevice) blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY); + blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ)); + sdevice->no_write_same = 1; return 0; -- cgit v1.1 From 8b612fa23f13a51f5ee8eb318fe05eef63dc3de9 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 4 Jun 2013 12:05:06 -0700 Subject: [SCSI] storvsc: Update the storage protocol to win8 level Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: James Bottomley --- drivers/scsi/storvsc_drv.c | 203 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 168 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index ede8694..9451989 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -55,10 +55,15 @@ * V1 RC < 2008/1/31: 1.0 * V1 RC > 2008/1/31: 2.0 * Win7: 4.2 + * Win8: 5.1 */ -#define VMSTOR_CURRENT_MAJOR 4 -#define VMSTOR_CURRENT_MINOR 2 + +#define VMSTOR_WIN7_MAJOR 4 +#define VMSTOR_WIN7_MINOR 2 + +#define VMSTOR_WIN8_MAJOR 5 +#define VMSTOR_WIN8_MINOR 1 /* Packet structure describing virtual storage requests. */ @@ -74,18 +79,103 @@ enum vstor_packet_operation { VSTOR_OPERATION_QUERY_PROTOCOL_VERSION = 9, VSTOR_OPERATION_QUERY_PROPERTIES = 10, VSTOR_OPERATION_ENUMERATE_BUS = 11, - VSTOR_OPERATION_MAXIMUM = 11 + VSTOR_OPERATION_FCHBA_DATA = 12, + VSTOR_OPERATION_CREATE_SUB_CHANNELS = 13, + VSTOR_OPERATION_MAXIMUM = 13 +}; + +/* + * WWN packet for Fibre Channel HBA + */ + +struct hv_fc_wwn_packet { + bool primary_active; + u8 reserved1; + u8 reserved2; + u8 primary_port_wwn[8]; + u8 primary_node_wwn[8]; + u8 secondary_port_wwn[8]; + u8 secondary_node_wwn[8]; }; + + +/* + * SRB Flag Bits + */ + +#define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002 +#define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004 +#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008 +#define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010 +#define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020 +#define SRB_FLAGS_DATA_IN 0x00000040 +#define SRB_FLAGS_DATA_OUT 0x00000080 +#define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000 +#define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) +#define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100 +#define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200 +#define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400 + +/* + * This flag indicates the request is part of the workflow for processing a D3. + */ +#define SRB_FLAGS_D3_PROCESSING 0x00000800 +#define SRB_FLAGS_IS_ACTIVE 0x00010000 +#define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000 +#define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000 +#define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000 +#define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000 +#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE 0x00200000 +#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT 0x00400000 +#define SRB_FLAGS_DONT_START_NEXT_PACKET 0x00800000 +#define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000 +#define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000 + + /* * Platform neutral description of a scsi request - * this remains the same across the write regardless of 32/64 bit * note: it's patterned off the SCSI_PASS_THROUGH structure */ #define STORVSC_MAX_CMD_LEN 0x10 -#define STORVSC_SENSE_BUFFER_SIZE 0x12 + +#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE 0x14 +#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE 0x12 + +#define STORVSC_SENSE_BUFFER_SIZE 0x14 #define STORVSC_MAX_BUF_LEN_WITH_PADDING 0x14 +/* + * Sense buffer size changed in win8; have a run-time + * variable to track the size we should use. + */ +static int sense_buffer_size; + +/* + * The size of the vmscsi_request has changed in win8. The + * additional size is because of new elements added to the + * structure. These elements are valid only when we are talking + * to a win8 host. + * Track the correction to size we need to apply. + */ + +static int vmscsi_size_delta; +static int vmstor_current_major; +static int vmstor_current_minor; + +struct vmscsi_win8_extension { + /* + * The following were added in Windows 8 + */ + u16 reserve; + u8 queue_tag; + u8 queue_action; + u32 srb_flags; + u32 time_out_value; + u32 queue_sort_ey; +} __packed; + struct vmscsi_request { u16 length; u8 srb_status; @@ -108,6 +198,11 @@ struct vmscsi_request { u8 sense_data[STORVSC_SENSE_BUFFER_SIZE]; u8 reserved_array[STORVSC_MAX_BUF_LEN_WITH_PADDING]; }; + /* + * The following was added in win8. + */ + struct vmscsi_win8_extension win8_extension; + } __attribute((packed)); @@ -115,22 +210,18 @@ struct vmscsi_request { * This structure is sent during the intialization phase to get the different * properties of the channel. */ + +#define STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL 0x1 + struct vmstorage_channel_properties { - u16 protocol_version; - u8 path_id; - u8 target_id; + u32 reserved; + u16 max_channel_cnt; + u16 reserved1; - /* Note: port number is only really known on the client side */ - u32 port_number; - u32 flags; + u32 flags; u32 max_transfer_bytes; - /* - * This id is unique for each channel and will correspond with - * vendor specific data in the inquiry data. - */ - - u64 unique_id; + u64 reserved2; } __packed; /* This structure is sent during the storage protocol negotiations. */ @@ -175,6 +266,15 @@ struct vstor_packet { /* Used during version negotiations. */ struct vmstorage_protocol_version version; + + /* Fibre channel address packet */ + struct hv_fc_wwn_packet wwn_packet; + + /* Number of sub-channels to create */ + u16 sub_channel_count; + + /* This will be the maximum of the union members */ + u8 buffer[0x34]; }; } __packed; @@ -679,7 +779,8 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -703,7 +804,7 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->version.major_minor = - storvsc_get_version(VMSTOR_CURRENT_MAJOR, VMSTOR_CURRENT_MINOR); + storvsc_get_version(vmstor_current_major, vmstor_current_minor); /* * The revision number is only used in Windows; set it to 0. @@ -711,7 +812,8 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->version.revision = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -732,11 +834,10 @@ static int storvsc_channel_init(struct hv_device *device) memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - vstor_packet->storage_channel_properties.port_number = - stor_device->port_number; ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -754,16 +855,13 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->status != 0) goto cleanup; - stor_device->path_id = vstor_packet->storage_channel_properties.path_id; - stor_device->target_id - = vstor_packet->storage_channel_properties.target_id; - memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1017,7 +1115,8 @@ static void storvsc_on_channel_callback(void *context) do { ret = vmbus_recvpacket(device->channel, packet, - ALIGN(sizeof(struct vstor_packet), 8), + ALIGN((sizeof(struct vstor_packet) - + vmscsi_size_delta), 8), &bytes_recvd, &request_id); if (ret == 0 && bytes_recvd > 0) { @@ -1028,7 +1127,8 @@ static void storvsc_on_channel_callback(void *context) (request == &stor_device->reset_request)) { memcpy(&request->vstor_packet, packet, - sizeof(struct vstor_packet)); + (sizeof(struct vstor_packet) - + vmscsi_size_delta)); complete(&request->wait_event); } else { storvsc_on_receive(device, @@ -1121,10 +1221,11 @@ static int storvsc_do_io(struct hv_device *device, vstor_packet->flags |= REQUEST_COMPLETION_FLAG; - vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); + vstor_packet->vm_srb.length = (sizeof(struct vmscsi_request) - + vmscsi_size_delta); - vstor_packet->vm_srb.sense_info_length = STORVSC_SENSE_BUFFER_SIZE; + vstor_packet->vm_srb.sense_info_length = sense_buffer_size; vstor_packet->vm_srb.data_transfer_length = @@ -1136,11 +1237,13 @@ static int storvsc_do_io(struct hv_device *device, ret = vmbus_sendpacket_multipagebuffer(device->channel, &request->data_buffer, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request); } else { ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1264,7 +1367,8 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) vstor_packet->vm_srb.path_id = stor_device->path_id; ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), + (sizeof(struct vstor_packet) - + vmscsi_size_delta), (unsigned long)&stor_device->reset_request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1349,18 +1453,28 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) scmnd->host_scribble = (unsigned char *)cmd_request; vm_srb = &cmd_request->vstor_packet.vm_srb; + vm_srb->win8_extension.time_out_value = 60; /* Build the SRB */ switch (scmnd->sc_data_direction) { case DMA_TO_DEVICE: vm_srb->data_in = WRITE_TYPE; + vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT; + vm_srb->win8_extension.srb_flags |= + (SRB_FLAGS_QUEUE_ACTION_ENABLE | + SRB_FLAGS_DISABLE_SYNCH_TRANSFER); break; case DMA_FROM_DEVICE: vm_srb->data_in = READ_TYPE; + vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN; + vm_srb->win8_extension.srb_flags |= + (SRB_FLAGS_QUEUE_ACTION_ENABLE | + SRB_FLAGS_DISABLE_SYNCH_TRANSFER); break; default: vm_srb->data_in = UNKNOWN_TYPE; + vm_srb->win8_extension.srb_flags = 0; break; } @@ -1492,6 +1606,24 @@ static int storvsc_probe(struct hv_device *device, int target = 0; struct storvsc_device *stor_device; + /* + * Based on the windows host we are running on, + * set state to properly communicate with the host. + */ + + if (vmbus_proto_version == VERSION_WIN8) { + sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE; + vmscsi_size_delta = 0; + vmstor_current_major = VMSTOR_WIN8_MAJOR; + vmstor_current_minor = VMSTOR_WIN8_MINOR; + } else { + sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; + vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); + vmstor_current_major = VMSTOR_WIN7_MAJOR; + vmstor_current_minor = VMSTOR_WIN7_MINOR; + } + + host = scsi_host_alloc(&scsi_driver, sizeof(struct hv_host_device)); if (!host) @@ -1601,7 +1733,8 @@ static int __init storvsc_drv_init(void) max_outstanding_req_per_channel = ((storvsc_ringbuffer_size - PAGE_SIZE) / ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), + sizeof(struct vstor_packet) + sizeof(u64) - + vmscsi_size_delta, sizeof(u64))); if (max_outstanding_req_per_channel < -- cgit v1.1 From b873a27538dff59e77c15eaf23bdf7e6be7d36e9 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Wed, 26 Jun 2013 22:39:26 +0530 Subject: [SCSI] ufs: wrap the i/o access operations Simplify operations with hiding mmio_base. Signed-off-by: Seungwon Jeon Tested-by: Maya Erez Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 105 +++++++++++++++++++--------------------------- drivers/scsi/ufs/ufshcd.h | 7 +++- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c32a478..871c2f0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -71,7 +71,7 @@ enum { */ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) { - return readl(hba->mmio_base + REG_UFS_VERSION); + return ufshcd_readl(hba, REG_UFS_VERSION); } /** @@ -130,8 +130,7 @@ static inline int ufshcd_get_tm_free_slot(struct ufs_hba *hba) */ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) { - writel(~(1 << pos), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR)); + ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); } /** @@ -165,7 +164,7 @@ static inline int ufshcd_get_lists_status(u32 reg) */ static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba) { - return readl(hba->mmio_base + REG_UIC_COMMAND_ARG_2) & + return ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2) & MASK_UIC_COMMAND_RESULT; } @@ -243,18 +242,15 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option) { switch (option) { case INT_AGGR_RESET: - writel((INT_AGGR_ENABLE | - INT_AGGR_COUNTER_AND_TIMER_RESET), - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); + ufshcd_writel(hba, INT_AGGR_ENABLE | + INT_AGGR_COUNTER_AND_TIMER_RESET, + REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); break; case INT_AGGR_CONFIG: - writel((INT_AGGR_ENABLE | - INT_AGGR_PARAM_WRITE | - INT_AGGR_COUNTER_THRESHOLD_VALUE | - INT_AGGR_TIMEOUT_VALUE), - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); + ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE | + INT_AGGR_COUNTER_THRESHOLD_VALUE | + INT_AGGR_TIMEOUT_VALUE, + REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); break; } } @@ -267,12 +263,10 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option) */ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) { - writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT, - (hba->mmio_base + - REG_UTP_TASK_REQ_LIST_RUN_STOP)); - writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT, - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_LIST_RUN_STOP)); + ufshcd_writel(hba, UTP_TASK_REQ_LIST_RUN_STOP_BIT, + REG_UTP_TASK_REQ_LIST_RUN_STOP); + ufshcd_writel(hba, UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT, + REG_UTP_TRANSFER_REQ_LIST_RUN_STOP); } /** @@ -281,7 +275,7 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) */ static inline void ufshcd_hba_start(struct ufs_hba *hba) { - writel(CONTROLLER_ENABLE , (hba->mmio_base + REG_CONTROLLER_ENABLE)); + ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE); } /** @@ -292,7 +286,7 @@ static inline void ufshcd_hba_start(struct ufs_hba *hba) */ static inline int ufshcd_is_hba_active(struct ufs_hba *hba) { - return (readl(hba->mmio_base + REG_CONTROLLER_ENABLE) & 0x1) ? 0 : 1; + return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE) & 0x1) ? 0 : 1; } /** @@ -304,8 +298,7 @@ static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { __set_bit(task_tag, &hba->outstanding_reqs); - writel((1 << task_tag), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL)); + ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); } /** @@ -329,8 +322,7 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) */ static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) { - hba->capabilities = - readl(hba->mmio_base + REG_CONTROLLER_CAPABILITIES); + hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES); /* nutrs and nutmrs are 0 based values */ hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1; @@ -347,16 +339,13 @@ static inline void ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd) { /* Write Args */ - writel(uic_cmnd->argument1, - (hba->mmio_base + REG_UIC_COMMAND_ARG_1)); - writel(uic_cmnd->argument2, - (hba->mmio_base + REG_UIC_COMMAND_ARG_2)); - writel(uic_cmnd->argument3, - (hba->mmio_base + REG_UIC_COMMAND_ARG_3)); + ufshcd_writel(hba, uic_cmnd->argument1, REG_UIC_COMMAND_ARG_1); + ufshcd_writel(hba, uic_cmnd->argument2, REG_UIC_COMMAND_ARG_2); + ufshcd_writel(hba, uic_cmnd->argument3, REG_UIC_COMMAND_ARG_3); /* Write UIC Cmd */ - writel((uic_cmnd->command & COMMAND_OPCODE_MASK), - (hba->mmio_base + REG_UIC_COMMAND)); + ufshcd_writel(hba, uic_cmnd->command & COMMAND_OPCODE_MASK, + REG_UIC_COMMAND); } /** @@ -408,16 +397,15 @@ static void ufshcd_int_config(struct ufs_hba *hba, u32 option) { switch (option) { case UFSHCD_INT_ENABLE: - writel(hba->int_enable_mask, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); + ufshcd_writel(hba, hba->int_enable_mask, REG_INTERRUPT_ENABLE); break; case UFSHCD_INT_DISABLE: if (hba->ufs_version == UFSHCI_VERSION_10) - writel(INTERRUPT_DISABLE_MASK_10, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); + ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10, + REG_INTERRUPT_ENABLE); else - writel(INTERRUPT_DISABLE_MASK_11, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); + ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11, + REG_INTERRUPT_ENABLE); break; } } @@ -703,7 +691,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) unsigned long flags; /* check if controller is ready to accept UIC commands */ - if (((readl(hba->mmio_base + REG_CONTROLLER_STATUS)) & + if ((ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY) == 0x0) { dev_err(hba->dev, "Controller not ready" @@ -748,7 +736,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) u32 reg; /* check if device present */ - reg = readl((hba->mmio_base + REG_CONTROLLER_STATUS)); + reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS); if (!ufshcd_is_device_present(reg)) { dev_err(hba->dev, "cc: Device not present\n"); err = -ENXIO; @@ -870,14 +858,14 @@ static int ufshcd_initialize_hba(struct ufs_hba *hba) return -EIO; /* Configure UTRL and UTMRL base address registers */ - writel(lower_32_bits(hba->utrdl_dma_addr), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L)); - writel(upper_32_bits(hba->utrdl_dma_addr), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H)); - writel(lower_32_bits(hba->utmrdl_dma_addr), - (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L)); - writel(upper_32_bits(hba->utmrdl_dma_addr), - (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H)); + ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), + REG_UTP_TRANSFER_REQ_LIST_BASE_L); + ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), + REG_UTP_TRANSFER_REQ_LIST_BASE_H); + ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), + REG_UTP_TASK_REQ_LIST_BASE_L); + ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), + REG_UTP_TASK_REQ_LIST_BASE_H); /* Initialize unipro link startup procedure */ return ufshcd_dme_link_startup(hba); @@ -1169,8 +1157,7 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) int index; lrb = hba->lrb; - tr_doorbell = - readl(hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL); + tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = tr_doorbell ^ hba->outstanding_reqs; for (index = 0; index < hba->nutrs; index++) { @@ -1244,9 +1231,7 @@ static void ufshcd_err_handler(struct ufs_hba *hba) goto fatal_eh; if (hba->errors & UIC_ERROR) { - - reg = readl(hba->mmio_base + - REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) goto fatal_eh; } @@ -1264,7 +1249,7 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba) { u32 tm_doorbell; - tm_doorbell = readl(hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL); + tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks; wake_up_interruptible(&hba->ufshcd_tm_wait_queue); } @@ -1305,15 +1290,14 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) struct ufs_hba *hba = __hba; spin_lock(hba->host->host_lock); - intr_status = readl(hba->mmio_base + REG_INTERRUPT_STATUS); + intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); if (intr_status) { ufshcd_sl_intr(hba, intr_status); /* If UFSHCI 1.0 then clear interrupt status register */ if (hba->ufs_version == UFSHCI_VERSION_10) - writel(intr_status, - (hba->mmio_base + REG_INTERRUPT_STATUS)); + ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); retval = IRQ_HANDLED; } spin_unlock(hba->host->host_lock); @@ -1378,8 +1362,7 @@ ufshcd_issue_tm_cmd(struct ufs_hba *hba, /* send command to the controller */ __set_bit(free_slot, &hba->outstanding_tasks); - writel((1 << free_slot), - (hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL)); + ufshcd_writel(hba, 1 << free_slot, REG_UTP_TASK_REQ_DOOR_BELL); spin_unlock_irqrestore(host->host_lock, flags); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6b99a42..807dd2d 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -186,6 +186,11 @@ struct ufs_hba { u32 errors; }; +#define ufshcd_writel(hba, val, reg) \ + writel((val), (hba)->mmio_base + (reg)) +#define ufshcd_readl(hba, reg) \ + readl((hba)->mmio_base + (reg)) + int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * , unsigned int); void ufshcd_remove(struct ufs_hba *); @@ -196,7 +201,7 @@ void ufshcd_remove(struct ufs_hba *); */ static inline void ufshcd_hba_stop(struct ufs_hba *hba) { - writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE)); + ufshcd_writel(hba, CONTROLLER_DISABLE, REG_CONTROLLER_ENABLE); } #endif /* End of Header */ -- cgit v1.1 From 2fbd009b40967fc54b7eb3580372736862291a06 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Wed, 26 Jun 2013 22:39:27 +0530 Subject: [SCSI] ufs: amend interrupt configuration It makes interrupt setting more flexible especially for disabling. And wrong bit mask is fixed for ver 1.0. [17:16] is added for mask. Signed-off-by: Seungwon Jeon Tested-by: Maya Erez Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 84 +++++++++++++++++++++++++++++++++-------------- drivers/scsi/ufs/ufshcd.h | 4 +-- drivers/scsi/ufs/ufshci.h | 5 +-- 3 files changed, 64 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 871c2f0..1f1e085 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -35,6 +35,10 @@ #include "ufshcd.h" +#define UFSHCD_ENABLE_INTRS (UTP_TRANSFER_REQ_COMPL |\ + UTP_TASK_REQ_COMPL |\ + UFSHCD_ERROR_MASK) + enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, @@ -64,6 +68,20 @@ enum { }; /** + * ufshcd_get_intr_mask - Get the interrupt bit mask + * @hba - Pointer to adapter instance + * + * Returns interrupt bit mask per version + */ +static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) +{ + if (hba->ufs_version == UFSHCI_VERSION_10) + return INTERRUPT_MASK_ALL_VER_10; + else + return INTERRUPT_MASK_ALL_VER_11; +} + +/** * ufshcd_get_ufs_version - Get the UFS version supported by the HBA * @hba - Pointer to adapter instance * @@ -389,25 +407,45 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) } /** - * ufshcd_int_config - enable/disable interrupts + * ufshcd_enable_intr - enable interrupts * @hba: per adapter instance - * @option: interrupt option + * @intrs: interrupt bits */ -static void ufshcd_int_config(struct ufs_hba *hba, u32 option) +static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs) { - switch (option) { - case UFSHCD_INT_ENABLE: - ufshcd_writel(hba, hba->int_enable_mask, REG_INTERRUPT_ENABLE); - break; - case UFSHCD_INT_DISABLE: - if (hba->ufs_version == UFSHCI_VERSION_10) - ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10, - REG_INTERRUPT_ENABLE); - else - ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11, - REG_INTERRUPT_ENABLE); - break; + u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + + if (hba->ufs_version == UFSHCI_VERSION_10) { + u32 rw; + rw = set & INTERRUPT_MASK_RW_VER_10; + set = rw | ((set ^ intrs) & intrs); + } else { + set |= intrs; + } + + ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE); +} + +/** + * ufshcd_disable_intr - disable interrupts + * @hba: per adapter instance + * @intrs: interrupt bits + */ +static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) +{ + u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + + if (hba->ufs_version == UFSHCI_VERSION_10) { + u32 rw; + rw = (set & INTERRUPT_MASK_RW_VER_10) & + ~(intrs & INTERRUPT_MASK_RW_VER_10); + set = rw | ((set & intrs) & ~INTERRUPT_MASK_RW_VER_10); + + } else { + set &= ~intrs; } + + ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE); } /** @@ -709,8 +747,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) uic_cmd->argument3 = 0; /* enable UIC related interrupts */ - hba->int_enable_mask |= UIC_COMMAND_COMPL; - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); + ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); /* sending UIC commands to controller */ ufshcd_send_uic_command(hba, uic_cmd); @@ -757,13 +794,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) } /* Enable required interrupts */ - hba->int_enable_mask |= (UTP_TRANSFER_REQ_COMPL | - UIC_ERROR | - UTP_TASK_REQ_COMPL | - DEVICE_FATAL_ERROR | - CONTROLLER_FATAL_ERROR | - SYSTEM_BUS_FATAL_ERROR); - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); + ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); /* Configure interrupt aggregation */ ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); @@ -1570,7 +1601,7 @@ static void ufshcd_hba_free(struct ufs_hba *hba) void ufshcd_remove(struct ufs_hba *hba) { /* disable interrupts */ - ufshcd_int_config(hba, UFSHCD_INT_DISABLE); + ufshcd_disable_intr(hba, hba->intr_mask); ufshcd_hba_stop(hba); ufshcd_hba_free(hba); @@ -1628,6 +1659,9 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, /* Get UFS version supported by the controller */ hba->ufs_version = ufshcd_get_ufs_version(hba); + /* Get Interrupt bit mask per version */ + hba->intr_mask = ufshcd_get_intr_mask(hba); + /* Allocate memory for host memory space */ err = ufshcd_memory_alloc(hba); if (err) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 807dd2d..4213600 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -139,7 +139,7 @@ struct ufshcd_lrb { * @ufshcd_tm_wait_queue: wait queue for task management * @tm_condition: condition variable for task management * @ufshcd_state: UFSHCD states - * @int_enable_mask: Interrupt Mask Bits + * @intr_mask: Interrupt Mask Bits * @uic_workq: Work queue for UIC completion handling * @feh_workq: Work queue for fatal controller error handling * @errors: HBA errors @@ -176,7 +176,7 @@ struct ufs_hba { unsigned long tm_condition; u32 ufshcd_state; - u32 int_enable_mask; + u32 intr_mask; /* Work Queues */ struct work_struct uic_workq; diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 0c16484..d5c5f14 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -232,10 +232,11 @@ enum { /* Interrupt disable masks */ enum { /* Interrupt disable mask for UFSHCI v1.0 */ - INTERRUPT_DISABLE_MASK_10 = 0xFFFF, + INTERRUPT_MASK_ALL_VER_10 = 0x30FFF, + INTERRUPT_MASK_RW_VER_10 = 0x30000, /* Interrupt disable mask for UFSHCI v1.1 */ - INTERRUPT_DISABLE_MASK_11 = 0x0, + INTERRUPT_MASK_ALL_VER_11 = 0x31FFF, }; /* -- cgit v1.1 From 261ea452037471b7cab6a3913d308acba54f7933 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Wed, 26 Jun 2013 22:39:28 +0530 Subject: [SCSI] ufs: remove version check before IS reg clear There is no need to check the version to clear the interrupt status. And the order is changed prior to actual handling. Signed-off-by: Seungwon Jeon Tested-by: Maya Erez Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 1f1e085..2e02483 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1324,11 +1324,8 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); if (intr_status) { + ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); ufshcd_sl_intr(hba, intr_status); - - /* If UFSHCI 1.0 then clear interrupt status register */ - if (hba->ufs_version == UFSHCI_VERSION_10) - ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); retval = IRQ_HANDLED; } spin_unlock(hba->host->host_lock); -- cgit v1.1 From 6ccf44fe4cd7c45a33f571788890a299d8bca448 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Wed, 26 Jun 2013 22:39:29 +0530 Subject: [SCSI] ufs: rework link start-up process Link start-up requires long time with multiphase handshakes between UFS host and device. This affects driver's probe time. This patch let link start-up run asynchronously. Link start-up will be executed at the end of prove separately. Along with this change, the following is worked. Defined completion time of uic command to avoid a permanent wait. Added mutex to guarantee of uic command at a time. Adapted some sequence of controller initialization after link statup according to HCI standard. Signed-off-by: Seungwon Jeon Signed-off-by: Sujit Reddy Thumma Tested-by: Maya Erez Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 295 +++++++++++++++++++++++++++++++--------------- drivers/scsi/ufs/ufshcd.h | 10 +- 2 files changed, 208 insertions(+), 97 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2e02483..48a7645 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -33,11 +33,15 @@ * this program. */ +#include + #include "ufshcd.h" #define UFSHCD_ENABLE_INTRS (UTP_TRANSFER_REQ_COMPL |\ UTP_TASK_REQ_COMPL |\ UFSHCD_ERROR_MASK) +/* UIC command timeout, unit: ms */ +#define UIC_CMD_TIMEOUT 500 enum { UFSHCD_MAX_CHANNEL = 0, @@ -349,24 +353,122 @@ static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) } /** - * ufshcd_send_uic_command - Send UIC commands to unipro layers + * ufshcd_ready_for_uic_cmd - Check if controller is ready + * to accept UIC commands * @hba: per adapter instance - * @uic_command: UIC command + * Return true on success, else false + */ +static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) +{ + if (ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY) + return true; + else + return false; +} + +/** + * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Mutex must be held. */ static inline void -ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd) +ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) { + WARN_ON(hba->active_uic_cmd); + + hba->active_uic_cmd = uic_cmd; + /* Write Args */ - ufshcd_writel(hba, uic_cmnd->argument1, REG_UIC_COMMAND_ARG_1); - ufshcd_writel(hba, uic_cmnd->argument2, REG_UIC_COMMAND_ARG_2); - ufshcd_writel(hba, uic_cmnd->argument3, REG_UIC_COMMAND_ARG_3); + ufshcd_writel(hba, uic_cmd->argument1, REG_UIC_COMMAND_ARG_1); + ufshcd_writel(hba, uic_cmd->argument2, REG_UIC_COMMAND_ARG_2); + ufshcd_writel(hba, uic_cmd->argument3, REG_UIC_COMMAND_ARG_3); /* Write UIC Cmd */ - ufshcd_writel(hba, uic_cmnd->command & COMMAND_OPCODE_MASK, + ufshcd_writel(hba, uic_cmd->command & COMMAND_OPCODE_MASK, REG_UIC_COMMAND); } /** + * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command + * @hba: per adapter instance + * @uic_command: UIC command + * + * Must be called with mutex held. + * Returns 0 only if success. + */ +static int +ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + unsigned long flags; + + if (wait_for_completion_timeout(&uic_cmd->done, + msecs_to_jiffies(UIC_CMD_TIMEOUT))) + ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; + else + ret = -ETIMEDOUT; + + spin_lock_irqsave(hba->host->host_lock, flags); + hba->active_uic_cmd = NULL; + spin_unlock_irqrestore(hba->host->host_lock, flags); + + return ret; +} + +/** + * __ufshcd_send_uic_cmd - Send UIC commands and retrieve the result + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called + * with mutex held. + * Returns 0 only if success. + */ +static int +__ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + unsigned long flags; + + if (!ufshcd_ready_for_uic_cmd(hba)) { + dev_err(hba->dev, + "Controller not ready to accept UIC commands\n"); + return -EIO; + } + + init_completion(&uic_cmd->done); + + spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_dispatch_uic_cmd(hba, uic_cmd); + spin_unlock_irqrestore(hba->host->host_lock, flags); + + ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); + + return ret; +} + +/** + * ufshcd_send_uic_cmd - Send UIC commands and retrieve the result + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Returns 0 only if success. + */ +static int +ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + + mutex_lock(&hba->uic_cmd_mutex); + ret = __ufshcd_send_uic_cmd(hba, uic_cmd); + mutex_unlock(&hba->uic_cmd_mutex); + + return ret; +} + +/** * ufshcd_map_sg - Map scatter-gather list to prdt * @lrbp - pointer to local reference block * @@ -725,34 +827,16 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) */ static int ufshcd_dme_link_startup(struct ufs_hba *hba) { - struct uic_command *uic_cmd; - unsigned long flags; + struct uic_command uic_cmd = {0}; + int ret; - /* check if controller is ready to accept UIC commands */ - if ((ufshcd_readl(hba, REG_CONTROLLER_STATUS) & - UIC_COMMAND_READY) == 0x0) { - dev_err(hba->dev, - "Controller not ready" - " to accept UIC commands\n"); - return -EIO; - } + uic_cmd.command = UIC_CMD_DME_LINK_STARTUP; - spin_lock_irqsave(hba->host->host_lock, flags); - - /* form UIC command */ - uic_cmd = &hba->active_uic_cmd; - uic_cmd->command = UIC_CMD_DME_LINK_STARTUP; - uic_cmd->argument1 = 0; - uic_cmd->argument2 = 0; - uic_cmd->argument3 = 0; - - /* enable UIC related interrupts */ - ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); - - /* sending UIC commands to controller */ - ufshcd_send_uic_command(hba, uic_cmd); - spin_unlock_irqrestore(hba->host->host_lock, flags); - return 0; + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, + "dme-link-startup: error code %d\n", ret); + return ret; } /** @@ -761,9 +845,10 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) * * To bring UFS host controller to operational state, * 1. Check if device is present - * 2. Configure run-stop-registers - * 3. Enable required interrupts - * 4. Configure interrupt aggregation + * 2. Enable required interrupts + * 3. Configure interrupt aggregation + * 4. Program UTRL and UTMRL base addres + * 5. Configure run-stop-registers * * Returns 0 on success, non-zero value on failure */ @@ -780,6 +865,22 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) goto out; } + /* Enable required interrupts */ + ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); + + /* Configure interrupt aggregation */ + ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); + + /* Configure UTRL and UTMRL base address registers */ + ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), + REG_UTP_TRANSFER_REQ_LIST_BASE_L); + ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), + REG_UTP_TRANSFER_REQ_LIST_BASE_H); + ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), + REG_UTP_TASK_REQ_LIST_BASE_L); + ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), + REG_UTP_TASK_REQ_LIST_BASE_H); + /* * UCRDY, UTMRLDY and UTRLRDY bits must be 1 * DEI, HEI bits must be 0 @@ -793,17 +894,11 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) goto out; } - /* Enable required interrupts */ - ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); - - /* Configure interrupt aggregation */ - ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); - if (hba->ufshcd_state == UFSHCD_STATE_RESET) scsi_unblock_requests(hba->host); hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; - scsi_scan_host(hba->host); + out: return err; } @@ -872,34 +967,28 @@ static int ufshcd_hba_enable(struct ufs_hba *hba) } /** - * ufshcd_initialize_hba - start the initialization process + * ufshcd_link_startup - Initialize unipro link startup * @hba: per adapter instance * - * 1. Enable the controller via ufshcd_hba_enable. - * 2. Program the Transfer Request List Address with the starting address of - * UTRDL. - * 3. Program the Task Management Request List Address with starting address - * of UTMRDL. - * - * Returns 0 on success, non-zero value on failure. + * Returns 0 for success, non-zero in case of failure */ -static int ufshcd_initialize_hba(struct ufs_hba *hba) +static int ufshcd_link_startup(struct ufs_hba *hba) { - if (ufshcd_hba_enable(hba)) - return -EIO; + int ret; - /* Configure UTRL and UTMRL base address registers */ - ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), - REG_UTP_TRANSFER_REQ_LIST_BASE_L); - ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), - REG_UTP_TRANSFER_REQ_LIST_BASE_H); - ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), - REG_UTP_TASK_REQ_LIST_BASE_L); - ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), - REG_UTP_TASK_REQ_LIST_BASE_H); + /* enable UIC related interrupts */ + ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); + + ret = ufshcd_dme_link_startup(hba); + if (ret) + goto out; + + ret = ufshcd_make_hba_operational(hba); - /* Initialize unipro link startup procedure */ - return ufshcd_dme_link_startup(hba); +out: + if (ret) + dev_err(hba->dev, "link startup failed %d\n", ret); + return ret; } /** @@ -939,12 +1028,19 @@ static int ufshcd_do_reset(struct ufs_hba *hba) hba->outstanding_reqs = 0; hba->outstanding_tasks = 0; - /* start the initialization process */ - if (ufshcd_initialize_hba(hba)) { + /* Host controller enable */ + if (ufshcd_hba_enable(hba)) { dev_err(hba->dev, "Reset: Controller initialization failed\n"); return FAILED; } + + if (ufshcd_link_startup(hba)) { + dev_err(hba->dev, + "Reset: Link start-up failed\n"); + return FAILED; + } + return SUCCESS; } @@ -1176,6 +1272,19 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } /** + * ufshcd_uic_cmd_compl - handle completion of uic command + * @hba: per adapter instance + */ +static void ufshcd_uic_cmd_compl(struct ufs_hba *hba) +{ + if (hba->active_uic_cmd) { + hba->active_uic_cmd->argument2 |= + ufshcd_get_uic_cmd_result(hba); + complete(&hba->active_uic_cmd->done); + } +} + +/** * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance */ @@ -1215,28 +1324,6 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) } /** - * ufshcd_uic_cc_handler - handle UIC command completion - * @work: pointer to a work queue structure - * - * Returns 0 on success, non-zero value on failure - */ -static void ufshcd_uic_cc_handler (struct work_struct *work) -{ - struct ufs_hba *hba; - - hba = container_of(work, struct ufs_hba, uic_workq); - - if ((hba->active_uic_cmd.command == UIC_CMD_DME_LINK_STARTUP) && - !(ufshcd_get_uic_cmd_result(hba))) { - - if (ufshcd_make_hba_operational(hba)) - dev_err(hba->dev, - "cc: hba not operational state\n"); - return; - } -} - -/** * ufshcd_fatal_err_handler - handle fatal errors * @hba: per adapter instance */ @@ -1297,7 +1384,7 @@ static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) ufshcd_err_handler(hba); if (intr_status & UIC_COMMAND_COMPL) - schedule_work(&hba->uic_workq); + ufshcd_uic_cmd_compl(hba); if (intr_status & UTP_TASK_REQ_COMPL) ufshcd_tmc_handler(hba); @@ -1520,6 +1607,21 @@ out: return err; } +/** + * ufshcd_async_scan - asynchronous execution for link startup + * @data: data pointer to pass to this function + * @cookie: cookie data + */ +static void ufshcd_async_scan(void *data, async_cookie_t cookie) +{ + struct ufs_hba *hba = (struct ufs_hba *)data; + int ret; + + ret = ufshcd_link_startup(hba); + if (!ret) + scsi_scan_host(hba->host); +} + static struct scsi_host_template ufshcd_driver_template = { .module = THIS_MODULE, .name = UFSHCD, @@ -1681,9 +1783,11 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, init_waitqueue_head(&hba->ufshcd_tm_wait_queue); /* Initialize work queues */ - INIT_WORK(&hba->uic_workq, ufshcd_uic_cc_handler); INIT_WORK(&hba->feh_workq, ufshcd_fatal_err_handler); + /* Initialize UIC command mutex */ + mutex_init(&hba->uic_cmd_mutex); + /* IRQ registration */ err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); if (err) { @@ -1704,14 +1808,17 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, goto out_free_irq; } - /* Initialization routine */ - err = ufshcd_initialize_hba(hba); + /* Host controller enable */ + err = ufshcd_hba_enable(hba); if (err) { - dev_err(hba->dev, "Initialization failed\n"); + dev_err(hba->dev, "Host controller enable failed\n"); goto out_remove_scsi_host; } + *hba_handle = hba; + async_schedule(ufshcd_async_scan, hba); + return 0; out_remove_scsi_host: diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 4213600..49590ee 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ * @argument3: UIC command argument 3 * @cmd_active: Indicate if UIC command is outstanding * @result: UIC command result + * @done: UIC command completion */ struct uic_command { u32 command; @@ -83,6 +85,7 @@ struct uic_command { u32 argument3; int cmd_active; int result; + struct completion done; }; /** @@ -136,11 +139,11 @@ struct ufshcd_lrb { * @ufs_version: UFS Version to which controller complies * @irq: Irq number of the controller * @active_uic_cmd: handle of active UIC command + * @uic_cmd_mutex: mutex for uic command * @ufshcd_tm_wait_queue: wait queue for task management * @tm_condition: condition variable for task management * @ufshcd_state: UFSHCD states * @intr_mask: Interrupt Mask Bits - * @uic_workq: Work queue for UIC completion handling * @feh_workq: Work queue for fatal controller error handling * @errors: HBA errors */ @@ -171,7 +174,9 @@ struct ufs_hba { u32 ufs_version; unsigned int irq; - struct uic_command active_uic_cmd; + struct uic_command *active_uic_cmd; + struct mutex uic_cmd_mutex; + wait_queue_head_t ufshcd_tm_wait_queue; unsigned long tm_condition; @@ -179,7 +184,6 @@ struct ufs_hba { u32 intr_mask; /* Work Queues */ - struct work_struct uic_workq; struct work_struct feh_workq; /* HBA Errors */ -- cgit v1.1 From 3ca316c582ddf11944806a27e460e7bd8f61a968 Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Wed, 26 Jun 2013 22:39:30 +0530 Subject: [SCSI] ufs: Fix the response UPIU length setting The response UPIU length should be in DWORD and not in bytes. Signed-off-by: Maya Erez Signed-off-by: Sujit Reddy Thumma Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 48a7645..2230f14 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -802,7 +802,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) utrdlp[i].prd_table_offset = cpu_to_le16((prdt_offset >> 2)); utrdlp[i].response_upiu_length = - cpu_to_le16(ALIGNED_UPIU_SIZE); + cpu_to_le16(ALIGNED_UPIU_SIZE >> 2); hba->lrb[i].utr_descriptor_ptr = (utrdlp + i); hba->lrb[i].ucd_cmd_ptr = -- cgit v1.1 From 2953f850c3b80bdca004967c83733365d8aa0aa2 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Thu, 27 Jun 2013 13:31:54 +0900 Subject: [SCSI] ufs: use devres functions for ufshcd This patch replaces normal calls for resource allocation with devm_*() derivative functions. It makes resource freeing simpler. Signed-off-by: Seungwon Jeon Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd-pci.c | 1 - drivers/scsi/ufs/ufshcd-pltfrm.c | 72 ++++++++++----------------------- drivers/scsi/ufs/ufshcd.c | 86 +++++++++------------------------------- 3 files changed, 39 insertions(+), 120 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index 5cb1d75..48be39a 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -92,7 +92,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev) struct ufs_hba *hba = pci_get_drvdata(pdev); disable_irq(pdev->irq); - free_irq(pdev->irq, hba); ufshcd_remove(hba); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 3db2ee1..0e48827 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -33,9 +33,10 @@ * this program. */ -#include "ufshcd.h" #include +#include "ufshcd.h" + #ifdef CONFIG_PM /** * ufshcd_pltfrm_suspend - suspend power management function @@ -97,62 +98,45 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) struct ufs_hba *hba; void __iomem *mmio_base; struct resource *mem_res; - struct resource *irq_res; - resource_size_t mem_size; - int err; + int irq, err; struct device *dev = &pdev->dev; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { - dev_err(&pdev->dev, - "Memory resource not available\n"); + dev_err(dev, "Memory resource not available\n"); err = -ENODEV; - goto out_error; + goto out; } - mem_size = resource_size(mem_res); - if (!request_mem_region(mem_res->start, mem_size, "ufshcd")) { - dev_err(&pdev->dev, - "Cannot reserve the memory resource\n"); - err = -EBUSY; - goto out_error; + mmio_base = devm_ioremap_resource(dev, mem_res); + if (IS_ERR(mmio_base)) { + dev_err(dev, "memory map failed\n"); + err = PTR_ERR(mmio_base); + goto out; } - mmio_base = ioremap_nocache(mem_res->start, mem_size); - if (!mmio_base) { - dev_err(&pdev->dev, "memory map failed\n"); - err = -ENOMEM; - goto out_release_regions; - } - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) { - dev_err(&pdev->dev, "IRQ resource not available\n"); + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "IRQ resource not available\n"); err = -ENODEV; - goto out_iounmap; + goto out; } err = dma_set_coherent_mask(dev, dev->coherent_dma_mask); if (err) { - dev_err(&pdev->dev, "set dma mask failed\n"); - goto out_iounmap; + dev_err(dev, "set dma mask failed\n"); + goto out; } - err = ufshcd_init(&pdev->dev, &hba, mmio_base, irq_res->start); + err = ufshcd_init(dev, &hba, mmio_base, irq); if (err) { - dev_err(&pdev->dev, "Intialization failed\n"); - goto out_iounmap; + dev_err(dev, "Intialization failed\n"); + goto out; } platform_set_drvdata(pdev, hba); - return 0; - -out_iounmap: - iounmap(mmio_base); -out_release_regions: - release_mem_region(mem_res->start, mem_size); -out_error: +out: return err; } @@ -164,26 +148,10 @@ out_error: */ static int ufshcd_pltfrm_remove(struct platform_device *pdev) { - struct resource *mem_res; - resource_size_t mem_size; struct ufs_hba *hba = platform_get_drvdata(pdev); disable_irq(hba->irq); - - /* Some buggy controllers raise interrupt after - * the resources are removed. So first we unregister the - * irq handler and then the resources used by driver - */ - - free_irq(hba->irq, hba); ufshcd_remove(hba); - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) - dev_err(&pdev->dev, "ufshcd: Memory resource not available\n"); - else { - mem_size = resource_size(mem_res); - release_mem_region(mem_res->start, mem_size); - } return 0; } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2230f14..aba461f0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -191,38 +191,6 @@ static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba) } /** - * ufshcd_free_hba_memory - Free allocated memory for LRB, request - * and task lists - * @hba: Pointer to adapter instance - */ -static inline void ufshcd_free_hba_memory(struct ufs_hba *hba) -{ - size_t utmrdl_size, utrdl_size, ucdl_size; - - kfree(hba->lrb); - - if (hba->utmrdl_base_addr) { - utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs; - dma_free_coherent(hba->dev, utmrdl_size, - hba->utmrdl_base_addr, hba->utmrdl_dma_addr); - } - - if (hba->utrdl_base_addr) { - utrdl_size = - (sizeof(struct utp_transfer_req_desc) * hba->nutrs); - dma_free_coherent(hba->dev, utrdl_size, - hba->utrdl_base_addr, hba->utrdl_dma_addr); - } - - if (hba->ucdl_base_addr) { - ucdl_size = - (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); - dma_free_coherent(hba->dev, ucdl_size, - hba->ucdl_base_addr, hba->ucdl_dma_addr); - } -} - -/** * ufshcd_is_valid_req_rsp - checks if controller TR response is valid * @ucd_rsp_ptr: pointer to response UPIU * @@ -690,10 +658,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) /* Allocate memory for UTP command descriptors */ ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); - hba->ucdl_base_addr = dma_alloc_coherent(hba->dev, - ucdl_size, - &hba->ucdl_dma_addr, - GFP_KERNEL); + hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev, + ucdl_size, + &hba->ucdl_dma_addr, + GFP_KERNEL); /* * UFSHCI requires UTP command descriptor to be 128 byte aligned. @@ -713,10 +681,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) * UFSHCI requires 1024 byte alignment of UTRD */ utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs); - hba->utrdl_base_addr = dma_alloc_coherent(hba->dev, - utrdl_size, - &hba->utrdl_dma_addr, - GFP_KERNEL); + hba->utrdl_base_addr = dmam_alloc_coherent(hba->dev, + utrdl_size, + &hba->utrdl_dma_addr, + GFP_KERNEL); if (!hba->utrdl_base_addr || WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) { dev_err(hba->dev, @@ -729,10 +697,10 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) * UFSHCI requires 1024 byte alignment of UTMRD */ utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs; - hba->utmrdl_base_addr = dma_alloc_coherent(hba->dev, - utmrdl_size, - &hba->utmrdl_dma_addr, - GFP_KERNEL); + hba->utmrdl_base_addr = dmam_alloc_coherent(hba->dev, + utmrdl_size, + &hba->utmrdl_dma_addr, + GFP_KERNEL); if (!hba->utmrdl_base_addr || WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) { dev_err(hba->dev, @@ -741,14 +709,15 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba) } /* Allocate memory for local reference block */ - hba->lrb = kcalloc(hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL); + hba->lrb = devm_kzalloc(hba->dev, + hba->nutrs * sizeof(struct ufshcd_lrb), + GFP_KERNEL); if (!hba->lrb) { dev_err(hba->dev, "LRB Memory allocation failed\n"); goto out; } return 0; out: - ufshcd_free_hba_memory(hba); return -ENOMEM; } @@ -1682,17 +1651,6 @@ int ufshcd_resume(struct ufs_hba *hba) EXPORT_SYMBOL_GPL(ufshcd_resume); /** - * ufshcd_hba_free - free allocated memory for - * host memory space data structures - * @hba: per adapter instance - */ -static void ufshcd_hba_free(struct ufs_hba *hba) -{ - iounmap(hba->mmio_base); - ufshcd_free_hba_memory(hba); -} - -/** * ufshcd_remove - de-allocate SCSI host and host memory space * data structure memory * @hba - per adapter instance @@ -1701,9 +1659,7 @@ void ufshcd_remove(struct ufs_hba *hba) { /* disable interrupts */ ufshcd_disable_intr(hba, hba->intr_mask); - ufshcd_hba_stop(hba); - ufshcd_hba_free(hba); scsi_remove_host(hba->host); scsi_host_put(hba->host); @@ -1789,23 +1745,23 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, mutex_init(&hba->uic_cmd_mutex); /* IRQ registration */ - err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); + err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); if (err) { dev_err(hba->dev, "request irq failed\n"); - goto out_lrb_free; + goto out_disable; } /* Enable SCSI tag mapping */ err = scsi_init_shared_tag_map(host, host->can_queue); if (err) { dev_err(hba->dev, "init shared queue failed\n"); - goto out_free_irq; + goto out_disable; } err = scsi_add_host(host, hba->dev); if (err) { dev_err(hba->dev, "scsi_add_host failed\n"); - goto out_free_irq; + goto out_disable; } /* Host controller enable */ @@ -1823,10 +1779,6 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, out_remove_scsi_host: scsi_remove_host(hba->host); -out_free_irq: - free_irq(irq, hba); -out_lrb_free: - ufshcd_free_hba_memory(hba); out_disable: scsi_host_put(host); out_error: -- cgit v1.1 From 2e2930a3449f1fe3806e26c4391a71097cae43f3 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 Jun 2013 22:39:32 +0530 Subject: [SCSI] ufshcd-pltfrm: add missing empty slot in ufs_of_match[] of_match_table member in struct device_driver must be terminated by empty slot as a sentinel. Signed-off-by: Akinobu Mita Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd-pltfrm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 0e48827..6829a16 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -157,6 +157,7 @@ static int ufshcd_pltfrm_remove(struct platform_device *pdev) static const struct of_device_id ufs_of_match[] = { { .compatible = "jedec,ufs-1.1"}, + {}, }; static const struct dev_pm_ops ufshcd_dev_pm_ops = { -- cgit v1.1 From cf9f4b59c52bd12c850c20435eef9f196976f541 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 Jun 2013 22:39:33 +0530 Subject: [SCSI] ufs: fix register address in UIC error interrupt handling In UIC error interrupt handling, it checks if UIC data link layer error code indicates PA_INIT_ERROR in order to determine whether a fatal error handling is needed or not. But the code tries to read UIC data link layer error code from wrong REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER, it should be REG_UIC_ERROR_CODE_DATA_LINK_LAYER. Signed-off-by: Akinobu Mita Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index aba461f0..b743bd6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1318,7 +1318,7 @@ static void ufshcd_err_handler(struct ufs_hba *hba) goto fatal_eh; if (hba->errors & UIC_ERROR) { - reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); + reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER); if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) goto fatal_eh; } -- cgit v1.1 From aca898f5d7ddcd0e7cc358a613338b009a88af80 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 Jun 2013 22:39:34 +0530 Subject: [SCSI] ufshcd-pltfrm: remove unnecessary dma_set_coherent_mask() call Changing the device coherent dma mask to the value that currently set has no effect. Signed-off-by: Akinobu Mita Signed-off-by: Santosh Y Signed-off-by: James Bottomley --- drivers/scsi/ufs/ufshcd-pltfrm.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 6829a16..c42db40 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -122,12 +122,6 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) goto out; } - err = dma_set_coherent_mask(dev, dev->coherent_dma_mask); - if (err) { - dev_err(dev, "set dma mask failed\n"); - goto out; - } - err = ufshcd_init(dev, &hba, mmio_base, irq); if (err) { dev_err(dev, "Intialization failed\n"); -- cgit v1.1 From a3fda7dd5179989dd0ead820dcebd13f956ddec1 Mon Sep 17 00:00:00 2001 From: James Georgas Date: Wed, 26 Jun 2013 12:03:19 -0600 Subject: [SCSI] megaraid: minor cut and paste error fixed. This looks like a cut and paste typo to me. Both of the megasas_read_fw_status_reg_* functions involved are identical though, so there was no bad behaviour. I changed it for consistency and clarity. Signed-off-by: James Georgas Acked-by: Sumit Saxena Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 4c4abe1..6002d36 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -596,7 +596,7 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) /* * Check if it is our interrupt */ - if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == + if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) == MFI_STATE_FAULT) { mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; } else -- cgit v1.1