From 09345f65058bb927f3b3f4c33421f83ba8eeb5f8 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 27 Jun 2007 16:32:39 +0900 Subject: [SCSI] add srp transport class This adds srp transport class that works with ib_srp and ibmvscsi. It creates only /sys/class/{srp_host,srp_remote_ports} and srp_remote_ports has only "port_id" attribute. viola:/sys/class/srp_remote_ports/port-0:1# ls device port_id subsystem uevent viola:/sys/class/srp_remote_ports/port-0:1# cat port_id 4c:49:4e:55:58:20:56:49:4f:00:00:00:00:00:00:00 Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 7 + drivers/scsi/Makefile | 1 + drivers/scsi/scsi_transport_srp.c | 320 ++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_transport_srp.h | 32 ++++ 4 files changed, 360 insertions(+) create mode 100644 drivers/scsi/scsi_transport_srp.c create mode 100644 include/scsi/scsi_transport_srp.h diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d2b3898..50d3062 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -289,6 +289,13 @@ config SCSI_SAS_ATTRS source "drivers/scsi/libsas/Kconfig" +config SCSI_SRP_ATTRS + tristate "SRP Transport Attributes" + depends on SCSI + help + If you wish to export transport-specific information about + each attached SRP device to sysfs, say Y. + endmenu menuconfig SCSI_LOWLEVEL diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 86a7ba7..6141389 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/ +obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c new file mode 100644 index 0000000..dcb3d2a --- /dev/null +++ b/drivers/scsi/scsi_transport_srp.c @@ -0,0 +1,320 @@ +/* + * SCSI RDMA (SRP) transport class + * + * Copyright (C) 2007 FUJITA Tomonori + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct srp_host_attrs { + atomic_t next_port_id; +}; +#define to_srp_host_attrs(host) ((struct srp_host_attrs *)(host)->shost_data) + +#define SRP_HOST_ATTRS 0 +#define SRP_RPORT_ATTRS 3 + +struct srp_internal { + struct scsi_transport_template t; + struct srp_function_template *f; + + struct class_device_attribute *host_attrs[SRP_HOST_ATTRS + 1]; + + struct class_device_attribute *rport_attrs[SRP_RPORT_ATTRS + 1]; + struct class_device_attribute private_rport_attrs[SRP_RPORT_ATTRS]; + struct transport_container rport_attr_cont; +}; + +#define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t) + +#define dev_to_rport(d) container_of(d, struct srp_rport, dev) +#define transport_class_to_srp_rport(cdev) dev_to_rport((cdev)->dev) + +static int srp_host_setup(struct transport_container *tc, struct device *dev, + struct class_device *cdev) +{ + struct Scsi_Host *shost = dev_to_shost(dev); + struct srp_host_attrs *srp_host = to_srp_host_attrs(shost); + + atomic_set(&srp_host->next_port_id, 0); + return 0; +} + +static DECLARE_TRANSPORT_CLASS(srp_host_class, "srp_host", srp_host_setup, + NULL, NULL); + +static DECLARE_TRANSPORT_CLASS(srp_rport_class, "srp_remote_ports", + NULL, NULL, NULL); + +#define SETUP_TEMPLATE(attrb, field, perm, test, ro_test, ro_perm) \ + i->private_##attrb[count] = class_device_attr_##field; \ + i->private_##attrb[count].attr.mode = perm; \ + if (ro_test) { \ + i->private_##attrb[count].attr.mode = ro_perm; \ + i->private_##attrb[count].store = NULL; \ + } \ + i->attrb[count] = &i->private_##attrb[count]; \ + if (test) \ + count++ + +#define SETUP_RPORT_ATTRIBUTE_RD(field) \ + SETUP_TEMPLATE(rport_attrs, field, S_IRUGO, 1, 0, 0) + +#define SETUP_RPORT_ATTRIBUTE_RW(field) \ + SETUP_TEMPLATE(rport_attrs, field, S_IRUGO | S_IWUSR, \ + 1, 1, S_IRUGO) + +#define SRP_PID(p) \ + (p)->port_id[0], (p)->port_id[1], (p)->port_id[2], (p)->port_id[3], \ + (p)->port_id[4], (p)->port_id[5], (p)->port_id[6], (p)->port_id[7], \ + (p)->port_id[8], (p)->port_id[9], (p)->port_id[10], (p)->port_id[11], \ + (p)->port_id[12], (p)->port_id[13], (p)->port_id[14], (p)->port_id[15] + +#define SRP_PID_FMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" + +static ssize_t +show_srp_rport_id(struct class_device *cdev, char *buf) +{ + struct srp_rport *rport = transport_class_to_srp_rport(cdev); + return sprintf(buf, SRP_PID_FMT "\n", SRP_PID(rport)); +} + +static CLASS_DEVICE_ATTR(port_id, S_IRUGO, show_srp_rport_id, NULL); + +static void srp_rport_release(struct device *dev) +{ + struct srp_rport *rport = dev_to_rport(dev); + + put_device(dev->parent); + kfree(rport); +} + +static int scsi_is_srp_rport(const struct device *dev) +{ + return dev->release == srp_rport_release; +} + +static int srp_rport_match(struct attribute_container *cont, + struct device *dev) +{ + struct Scsi_Host *shost; + struct srp_internal *i; + + if (!scsi_is_srp_rport(dev)) + return 0; + + shost = dev_to_shost(dev->parent); + if (!shost->transportt) + return 0; + if (shost->transportt->host_attrs.ac.class != &srp_host_class.class) + return 0; + + i = to_srp_internal(shost->transportt); + return &i->rport_attr_cont.ac == cont; +} + +static int srp_host_match(struct attribute_container *cont, struct device *dev) +{ + struct Scsi_Host *shost; + struct srp_internal *i; + + if (!scsi_is_host_device(dev)) + return 0; + + shost = dev_to_shost(dev); + if (!shost->transportt) + return 0; + if (shost->transportt->host_attrs.ac.class != &srp_host_class.class) + return 0; + + i = to_srp_internal(shost->transportt); + return &i->t.host_attrs.ac == cont; +} + +/** + * srp_rport_add - add a SRP remote port to the device hierarchy + * + * @shost: scsi host the remote port is connected to. + * @ids: The port id for the remote port. + * + * publishes a port to the rest of the system + */ +struct srp_rport *srp_rport_add(struct Scsi_Host *shost, + struct srp_rport_identifiers *ids) +{ + struct srp_rport *rport; + struct device *parent = &shost->shost_gendev; + int id, ret; + + rport = kzalloc(sizeof(*rport), GFP_KERNEL); + if (!rport) + return ERR_PTR(-ENOMEM); + + device_initialize(&rport->dev); + + rport->dev.parent = get_device(parent); + rport->dev.release = srp_rport_release; + + memcpy(rport->port_id, ids->port_id, sizeof(rport->port_id)); + + id = atomic_inc_return(&to_srp_host_attrs(shost)->next_port_id); + sprintf(rport->dev.bus_id, "port-%d:%d", shost->host_no, id); + + transport_setup_device(&rport->dev); + + ret = device_add(&rport->dev); + if (ret) { + transport_destroy_device(&rport->dev); + put_device(&rport->dev); + return ERR_PTR(ret); + } + + transport_add_device(&rport->dev); + transport_configure_device(&rport->dev); + + return rport; +} +EXPORT_SYMBOL_GPL(srp_rport_add); + +/** + * srp_rport_del -- remove a SRP remote port + * @port: SRP remote port to remove + * + * Removes the specified SRP remote port. + */ +void srp_rport_del(struct srp_rport *rport) +{ + struct device *dev = &rport->dev; + + transport_remove_device(dev); + device_del(dev); + transport_destroy_device(dev); + put_device(dev); +} +EXPORT_SYMBOL_GPL(srp_rport_del); + +static int do_srp_rport_del(struct device *dev, void *data) +{ + srp_rport_del(dev_to_rport(dev)); + return 0; +} + +/** + * srp_remove_host -- tear down a Scsi_Host's SRP data structures + * @shost: Scsi Host that is torn down + * + * Removes all SRP remote ports for a given Scsi_Host. + * Must be called just before scsi_remove_host for SRP HBAs. + */ +void srp_remove_host(struct Scsi_Host *shost) +{ + device_for_each_child(&shost->shost_gendev, NULL, do_srp_rport_del); +} +EXPORT_SYMBOL_GPL(srp_remove_host); + +/** + * srp_attach_transport -- instantiate SRP transport template + * @ft: SRP transport class function template + */ +struct scsi_transport_template * +srp_attach_transport(struct srp_function_template *ft) +{ + int count; + struct srp_internal *i; + + i = kzalloc(sizeof(*i), GFP_KERNEL); + if (!i) + return NULL; + + i->t.host_size = sizeof(struct srp_host_attrs); + i->t.host_attrs.ac.attrs = &i->host_attrs[0]; + i->t.host_attrs.ac.class = &srp_host_class.class; + i->t.host_attrs.ac.match = srp_host_match; + i->host_attrs[0] = NULL; + transport_container_register(&i->t.host_attrs); + + i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; + i->rport_attr_cont.ac.class = &srp_rport_class.class; + i->rport_attr_cont.ac.match = srp_rport_match; + transport_container_register(&i->rport_attr_cont); + + count = 0; + SETUP_RPORT_ATTRIBUTE_RD(port_id); + i->rport_attrs[count] = NULL; + + i->f = ft; + + return &i->t; +} +EXPORT_SYMBOL_GPL(srp_attach_transport); + +/** + * srp_release_transport -- release SRP transport template instance + * @t: transport template instance + */ +void srp_release_transport(struct scsi_transport_template *t) +{ + struct srp_internal *i = to_srp_internal(t); + + transport_container_unregister(&i->t.host_attrs); + transport_container_unregister(&i->rport_attr_cont); + + kfree(i); +} +EXPORT_SYMBOL_GPL(srp_release_transport); + +static __init int srp_transport_init(void) +{ + int ret; + + ret = transport_class_register(&srp_host_class); + if (ret) + return ret; + ret = transport_class_register(&srp_rport_class); + if (ret) + goto unregister_host_class; + + return 0; +unregister_host_class: + transport_class_unregister(&srp_host_class); + return ret; +} + +static void __exit srp_transport_exit(void) +{ + transport_class_unregister(&srp_host_class); + transport_class_unregister(&srp_rport_class); +} + +MODULE_AUTHOR("FUJITA Tomonori"); +MODULE_DESCRIPTION("SRP Transport Attributes"); +MODULE_LICENSE("GPL"); + +module_init(srp_transport_init); +module_exit(srp_transport_exit); diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h new file mode 100644 index 0000000..adbfca4 --- /dev/null +++ b/include/scsi/scsi_transport_srp.h @@ -0,0 +1,32 @@ +#ifndef SCSI_TRANSPORT_SRP_H +#define SCSI_TRANSPORT_SRP_H + +#include +#include +#include + +struct srp_rport_identifiers { + u8 port_id[16]; +}; + +struct srp_rport { + struct device dev; + + u8 port_id[16]; +}; + +struct srp_function_template { + /* later */ +}; + +extern struct scsi_transport_template * +srp_attach_transport(struct srp_function_template *); +extern void srp_release_transport(struct scsi_transport_template *); + +extern struct srp_rport *srp_rport_add(struct Scsi_Host *, + struct srp_rport_identifiers *); +extern void srp_rport_del(struct srp_rport *); + +extern void srp_remove_host(struct Scsi_Host *); + +#endif -- cgit v1.1 From 4d68041907b150b07640b607c6c626391cf3fe8b Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 27 Jun 2007 16:32:50 +0900 Subject: [SCSI] ibmvscsi: convert to use the srp transport class This converts ibmvscsi to use the srp transport class. Signed-off-by: FUJITA Tomonori Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 1 + drivers/scsi/ibmvscsi/ibmvscsi.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 50d3062..778dc0f 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -839,6 +839,7 @@ config SCSI_IPS config SCSI_IBMVSCSI tristate "IBM Virtual SCSI support" depends on PPC_PSERIES || PPC_ISERIES + select SCSI_SRP_ATTRS help This is the IBM POWER Virtual SCSI Client diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5ecc63d..e6f937e 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -75,6 +75,7 @@ #include #include #include +#include #include "ibmvscsi.h" /* The values below are somewhat arbitrary default values, but @@ -87,6 +88,8 @@ static int max_channel = 3; static int init_timeout = 5; static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; +static struct scsi_transport_template *ibmvscsi_transport_template; + #define IBMVSCSI_VERSION "1.5.8" MODULE_DESCRIPTION("IBM Virtual SCSI"); @@ -1553,6 +1556,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct ibmvscsi_host_data *hostdata; struct Scsi_Host *host; struct device *dev = &vdev->dev; + struct srp_rport_identifiers ids; + struct srp_rport *rport; unsigned long wait_switch = 0; int rc; @@ -1565,6 +1570,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto scsi_host_alloc_failed; } + host->transportt = ibmvscsi_transport_template; hostdata = shost_priv(host); memset(hostdata, 0x00, sizeof(*hostdata)); INIT_LIST_HEAD(&hostdata->sent); @@ -1590,6 +1596,13 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) if (scsi_add_host(hostdata->host, hostdata->dev)) goto add_host_failed; + /* we don't have a proper target_port_id so let's use the fake one */ + memcpy(ids.port_id, hostdata->madapter_info.partition_name, + sizeof(ids.port_id)); + rport = srp_rport_add(host, &ids); + if (IS_ERR(rport)) + goto add_srp_port_failed; + /* Try to send an initialization message. Note that this is allowed * to fail if the other end is not acive. In that case we don't * want to scan @@ -1617,6 +1630,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) vdev->dev.driver_data = hostdata; return 0; + add_srp_port_failed: + scsi_remove_host(hostdata->host); add_host_failed: release_event_pool(&hostdata->pool, hostdata); init_pool_failed: @@ -1633,7 +1648,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev) release_event_pool(&hostdata->pool, hostdata); ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); - + + srp_remove_host(hostdata->host); scsi_remove_host(hostdata->host); scsi_host_put(hostdata->host); @@ -1660,14 +1676,28 @@ static struct vio_driver ibmvscsi_driver = { } }; +static struct srp_function_template ibmvscsi_transport_functions = { +}; + int __init ibmvscsi_module_init(void) { - return vio_register_driver(&ibmvscsi_driver); + int ret; + + ibmvscsi_transport_template = + srp_attach_transport(&ibmvscsi_transport_functions); + if (!ibmvscsi_transport_template) + return -ENOMEM; + + ret = vio_register_driver(&ibmvscsi_driver); + if (ret) + srp_release_transport(ibmvscsi_transport_template); + return ret; } void __exit ibmvscsi_module_exit(void) { vio_unregister_driver(&ibmvscsi_driver); + srp_release_transport(ibmvscsi_transport_template); } module_init(ibmvscsi_module_init); -- cgit v1.1 From 3236822b1c9b67ad10745d965515b528818f1120 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 27 Jun 2007 16:33:12 +0900 Subject: [SCSI] ib_srp: convert to use the srp transport class This converts ib_srp to use the srp transport class. I don't have ib hardware so I've not tested this patch. Signed-off-by: FUJITA Tomonori Cc: Roland Dreier Signed-off-by: James Bottomley --- drivers/infiniband/ulp/srp/Kconfig | 1 + drivers/infiniband/ulp/srp/ib_srp.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/infiniband/ulp/srp/Kconfig b/drivers/infiniband/ulp/srp/Kconfig index 3432dce..c74ee96 100644 --- a/drivers/infiniband/ulp/srp/Kconfig +++ b/drivers/infiniband/ulp/srp/Kconfig @@ -1,6 +1,7 @@ config INFINIBAND_SRP tristate "InfiniBand SCSI RDMA Protocol" depends on SCSI + select SCSI_SRP_ATTRS ---help--- Support for the SCSI RDMA Protocol over InfiniBand. This allows you to access storage devices that speak SRP over diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f01ca18..d8d056e 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -90,6 +91,8 @@ static void srp_remove_one(struct ib_device *device); static void srp_completion(struct ib_cq *cq, void *target_ptr); static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); +static struct scsi_transport_template *ib_srp_transport_template; + static struct ib_client srp_client = { .name = "srp", .add = srp_add_one, @@ -405,6 +408,7 @@ static void srp_remove_work(struct work_struct *work) list_del(&target->list); spin_unlock(&target->srp_host->target_lock); + srp_remove_host(target->scsi_host); scsi_remove_host(target->scsi_host); ib_destroy_cm_id(target->cm_id); srp_free_target_ib(target); @@ -1530,12 +1534,23 @@ static struct scsi_host_template srp_template = { static int srp_add_target(struct srp_host *host, struct srp_target_port *target) { + struct srp_rport_identifiers ids; + struct srp_rport *rport; + sprintf(target->target_name, "SRP.T10:%016llX", (unsigned long long) be64_to_cpu(target->id_ext)); if (scsi_add_host(target->scsi_host, host->dev->dev->dma_device)) return -ENODEV; + memcpy(ids.port_id, &target->id_ext, 8); + memcpy(ids.port_id + 8, &target->ioc_guid, 8); + rport = srp_rport_add(target->scsi_host, &ids); + if (IS_ERR(rport)) { + scsi_remove_host(target->scsi_host); + return PTR_ERR(rport); + } + spin_lock(&host->target_lock); list_add_tail(&target->list, &host->target_list); spin_unlock(&host->target_lock); @@ -1760,6 +1775,7 @@ static ssize_t srp_create_target(struct class_device *class_dev, if (!target_host) return -ENOMEM; + target_host->transportt = ib_srp_transport_template; target_host->max_lun = SRP_MAX_LUN; target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; @@ -2039,10 +2055,18 @@ static void srp_remove_one(struct ib_device *device) kfree(srp_dev); } +static struct srp_function_template ib_srp_transport_functions = { +}; + static int __init srp_init_module(void) { int ret; + ib_srp_transport_template = + srp_attach_transport(&ib_srp_transport_functions); + if (!ib_srp_transport_template) + return -ENOMEM; + srp_template.sg_tablesize = srp_sg_tablesize; srp_max_iu_len = (sizeof (struct srp_cmd) + sizeof (struct srp_indirect_buf) + @@ -2051,6 +2075,7 @@ static int __init srp_init_module(void) ret = class_register(&srp_class); if (ret) { printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); + srp_release_transport(ib_srp_transport_template); return ret; } @@ -2059,6 +2084,7 @@ static int __init srp_init_module(void) ret = ib_register_client(&srp_client); if (ret) { printk(KERN_ERR PFX "couldn't register IB client\n"); + srp_release_transport(ib_srp_transport_template); ib_sa_unregister_client(&srp_sa_client); class_unregister(&srp_class); return ret; @@ -2072,6 +2098,7 @@ static void __exit srp_cleanup_module(void) ib_unregister_client(&srp_client); ib_sa_unregister_client(&srp_sa_client); class_unregister(&srp_class); + srp_release_transport(ib_srp_transport_template); } module_init(srp_init_module); -- cgit v1.1 From aebd5e476ecc8ceb53577b20f2a352ff4ceffd8d Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:15 +0900 Subject: [SCSI] transport_srp: add rport roles attribute This adds a 'roles' attribute to rport like transport_fc. The role can be initiator or target. That is, the initiator driver creates target remote ports and the target driver creates initiator remote ports. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/infiniband/ulp/srp/ib_srp.c | 1 + drivers/scsi/ibmvscsi/ibmvscsi.c | 1 + drivers/scsi/scsi_transport_srp.c | 29 ++++++++++++++++++++++++++++- include/scsi/scsi_transport_srp.h | 5 +++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index d8d056e..e616c4f 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1545,6 +1545,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) memcpy(ids.port_id, &target->id_ext, 8); memcpy(ids.port_id + 8, &target->ioc_guid, 8); + ids.roles = SRP_RPORT_ROLE_TARGET; rport = srp_rport_add(target->scsi_host, &ids); if (IS_ERR(rport)) { scsi_remove_host(target->scsi_host); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e6f937e..93bd01b 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1599,6 +1599,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) /* we don't have a proper target_port_id so let's use the fake one */ memcpy(ids.port_id, hostdata->madapter_info.partition_name, sizeof(ids.port_id)); + ids.roles = SRP_RPORT_ROLE_TARGET; rport = srp_rport_add(host, &ids); if (IS_ERR(rport)) goto add_srp_port_failed; diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index dcb3d2a..608abd8 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -37,7 +37,7 @@ struct srp_host_attrs { #define to_srp_host_attrs(host) ((struct srp_host_attrs *)(host)->shost_data) #define SRP_HOST_ATTRS 0 -#define SRP_RPORT_ATTRS 3 +#define SRP_RPORT_ATTRS 2 struct srp_internal { struct scsi_transport_template t; @@ -107,6 +107,31 @@ show_srp_rport_id(struct class_device *cdev, char *buf) static CLASS_DEVICE_ATTR(port_id, S_IRUGO, show_srp_rport_id, NULL); +static const struct { + u32 value; + char *name; +} srp_rport_role_names[] = { + {SRP_RPORT_ROLE_INITIATOR, "SRP Initiator"}, + {SRP_RPORT_ROLE_TARGET, "SRP Target"}, +}; + +static ssize_t +show_srp_rport_roles(struct class_device *cdev, char *buf) +{ + struct srp_rport *rport = transport_class_to_srp_rport(cdev); + int i; + char *name = NULL; + + for (i = 0; i < ARRAY_SIZE(srp_rport_role_names); i++) + if (srp_rport_role_names[i].value == rport->roles) { + name = srp_rport_role_names[i].name; + break; + } + return sprintf(buf, "%s\n", name ? : "unknown"); +} + +static CLASS_DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL); + static void srp_rport_release(struct device *dev) { struct srp_rport *rport = dev_to_rport(dev); @@ -182,6 +207,7 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, rport->dev.release = srp_rport_release; memcpy(rport->port_id, ids->port_id, sizeof(rport->port_id)); + rport->roles = ids->roles; id = atomic_inc_return(&to_srp_host_attrs(shost)->next_port_id); sprintf(rport->dev.bus_id, "port-%d:%d", shost->host_no, id); @@ -266,6 +292,7 @@ srp_attach_transport(struct srp_function_template *ft) count = 0; SETUP_RPORT_ATTRIBUTE_RD(port_id); + SETUP_RPORT_ATTRIBUTE_RD(roles); i->rport_attrs[count] = NULL; i->f = ft; diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index adbfca4..08b4a28 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -5,14 +5,19 @@ #include #include +#define SRP_RPORT_ROLE_INITIATOR 0 +#define SRP_RPORT_ROLE_TARGET 1 + struct srp_rport_identifiers { u8 port_id[16]; + u8 roles; }; struct srp_rport { struct device dev; u8 port_id[16]; + u8 roles; }; struct srp_function_template { -- cgit v1.1 From 2c47f9efbedbe5749b6bb16e59bc11d6e460855f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:17 +0900 Subject: [SCSI] tgt: add I_T nexus support tgt uses scsi_host as I_T nexus. This works for ibmvstgt because it creates one scsi_host for one initiator. However, other target drivers don't work like that. This adds I_T nexus support, which enable one scsi_host to handle multiple initiators. New scsi_tgt_it_nexus_create/destroy functions are expected be called transport classes. For example, ibmvstgt creates an initiator remote port, then the srp transport calls tgt_it_nexus_create. tgt doesn't manages I_T nexus, instead it tells tgtd, user-space daemon, to create a new I_T nexus. On the receiving the response from tgtd, tgt calls shost->transportt->it_nexus_response. transports should notify a lld. The srp transport uses it_nexus_response callback in srp_function_template to do that. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_tgt_if.c | 42 +++++++++++++++++++--- drivers/scsi/scsi_tgt_lib.c | 83 ++++++++++++++++++++++++++++++++++++------- drivers/scsi/scsi_tgt_priv.h | 22 +++++++----- include/scsi/scsi_host.h | 2 +- include/scsi/scsi_tgt.h | 8 +++-- include/scsi/scsi_tgt_if.h | 35 +++++++++++++----- include/scsi/scsi_transport.h | 6 ++++ 7 files changed, 161 insertions(+), 37 deletions(-) diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c index ca22ddf..9815a1a 100644 --- a/drivers/scsi/scsi_tgt_if.c +++ b/drivers/scsi/scsi_tgt_if.c @@ -102,7 +102,8 @@ static int tgt_uspace_send_event(u32 type, struct tgt_event *p) return 0; } -int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag) +int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 itn_id, + struct scsi_lun *lun, u64 tag) { struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); struct tgt_event ev; @@ -110,6 +111,7 @@ int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 ta memset(&ev, 0, sizeof(ev)); ev.p.cmd_req.host_no = shost->host_no; + ev.p.cmd_req.itn_id = itn_id; ev.p.cmd_req.data_len = cmd->request_bufflen; memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb)); memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun)); @@ -127,7 +129,7 @@ int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 ta return err; } -int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) +int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 itn_id, u64 tag) { struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); struct tgt_event ev; @@ -135,6 +137,7 @@ int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) memset(&ev, 0, sizeof(ev)); ev.p.cmd_done.host_no = shost->host_no; + ev.p.cmd_done.itn_id = itn_id; ev.p.cmd_done.tag = tag; ev.p.cmd_done.result = cmd->result; @@ -149,14 +152,15 @@ int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) return err; } -int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, - struct scsi_lun *scsilun, void *data) +int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 itn_id, int function, + u64 tag, struct scsi_lun *scsilun, void *data) { struct tgt_event ev; int err; memset(&ev, 0, sizeof(ev)); ev.p.tsk_mgmt_req.host_no = host_no; + ev.p.tsk_mgmt_req.itn_id = itn_id; ev.p.tsk_mgmt_req.function = function; ev.p.tsk_mgmt_req.tag = tag; memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun)); @@ -172,6 +176,29 @@ int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, return err; } +int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 itn_id, + int function, char *initiator_id) +{ + struct tgt_event ev; + int err; + + memset(&ev, 0, sizeof(ev)); + ev.p.it_nexus_req.host_no = host_no; + ev.p.it_nexus_req.function = function; + ev.p.it_nexus_req.itn_id = itn_id; + if (initiator_id) + strncpy(ev.p.it_nexus_req.initiator_id, initiator_id, + sizeof(ev.p.it_nexus_req.initiator_id)); + + dprintk("%d %x %llx\n", host_no, function, (unsigned long long)itn_id); + + err = tgt_uspace_send_event(TGT_KEVENT_IT_NEXUS_REQ, &ev); + if (err) + eprintk("tx buf is full, could not send\n"); + + return err; +} + static int event_recv_msg(struct tgt_event *ev) { int err = 0; @@ -179,6 +206,7 @@ static int event_recv_msg(struct tgt_event *ev) switch (ev->hdr.type) { case TGT_UEVENT_CMD_RSP: err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, + ev->p.cmd_rsp.itn_id, ev->p.cmd_rsp.result, ev->p.cmd_rsp.tag, ev->p.cmd_rsp.uaddr, @@ -189,9 +217,15 @@ static int event_recv_msg(struct tgt_event *ev) break; case TGT_UEVENT_TSK_MGMT_RSP: err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no, + ev->p.tsk_mgmt_rsp.itn_id, ev->p.tsk_mgmt_rsp.mid, ev->p.tsk_mgmt_rsp.result); break; + case TGT_UEVENT_IT_NEXUS_RSP: + err = scsi_tgt_kspace_it_nexus_rsp(ev->p.it_nexus_rsp.host_no, + ev->p.it_nexus_rsp.itn_id, + ev->p.it_nexus_rsp.result); + break; default: eprintk("unknown type %d\n", ev->hdr.type); err = -EINVAL; diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 371b69c..fa79e54 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "scsi_tgt_priv.h" @@ -46,6 +47,7 @@ struct scsi_tgt_cmd { struct list_head hash_list; struct request *rq; + u64 itn_id; u64 tag; }; @@ -185,12 +187,13 @@ static void scsi_tgt_cmd_destroy(struct work_struct *work) } static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, - u64 tag) + u64 itn_id, u64 tag) { struct scsi_tgt_queuedata *qdata = rq->q->queuedata; unsigned long flags; struct list_head *head; + tcmd->itn_id = itn_id; tcmd->tag = tag; tcmd->bio = NULL; INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); @@ -301,14 +304,14 @@ EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); * @scsilun: scsi lun * @tag: unique value to identify this command for tmf */ -int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, - u64 tag) +int scsi_tgt_queue_command(struct scsi_cmnd *cmd, u64 itn_id, + struct scsi_lun *scsilun, u64 tag) { struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; int err; - init_scsi_tgt_cmd(cmd->request, tcmd, tag); - err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); + init_scsi_tgt_cmd(cmd->request, tcmd, itn_id, tag); + err = scsi_tgt_uspace_send_cmd(cmd, itn_id, scsilun, tag); if (err) cmd_hashlist_del(cmd); @@ -326,7 +329,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); - scsi_tgt_uspace_send_status(cmd, tcmd->tag); + scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag); if (cmd->request_buffer) scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); @@ -459,7 +462,7 @@ static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) return rq; } -int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, +int scsi_tgt_kspace_exec(int host_no, u64 itn_id, int result, u64 tag, unsigned long uaddr, u32 len, unsigned long sense_uaddr, u32 sense_len, u8 rw) { @@ -541,21 +544,22 @@ done: return err; } -int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, - struct scsi_lun *scsilun, void *data) +int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, u64 itn_id, + int function, u64 tag, struct scsi_lun *scsilun, + void *data) { int err; /* TODO: need to retry if this fails. */ - err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, - tag, scsilun, data); + err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, itn_id, + function, tag, scsilun, data); if (err < 0) eprintk("The task management request lost!\n"); return err; } EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); -int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) +int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result) { struct Scsi_Host *shost; int err = -EINVAL; @@ -573,7 +577,60 @@ int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) goto done; } - err = shost->hostt->tsk_mgmt_response(mid, result); + err = shost->hostt->tsk_mgmt_response(shost, itn_id, mid, result); +done: + scsi_host_put(shost); + return err; +} + +int scsi_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + int err; + + /* TODO: need to retry if this fails. */ + err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, itn_id, 0, + initiator); + if (err < 0) + eprintk("The i_t_neuxs request lost, %d %llx!\n", + shost->host_no, (unsigned long long)itn_id); + return err; +} +EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_create); + +int scsi_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + int err; + + /* TODO: need to retry if this fails. */ + err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, + itn_id, 1, NULL); + if (err < 0) + eprintk("The i_t_neuxs request lost, %d %llx!\n", + shost->host_no, (unsigned long long)itn_id); + return err; +} +EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_destroy); + +int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 itn_id, int result) +{ + struct Scsi_Host *shost; + int err = -EINVAL; + + dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid); + + shost = scsi_host_lookup(host_no); + if (IS_ERR(shost)) { + printk(KERN_ERR "Could not find host no %d\n", host_no); + return err; + } + + if (!shost->uspace_req_q) { + printk(KERN_ERR "Not target scsi host %d\n", host_no); + goto done; + } + + err = shost->transportt->it_nexus_response(shost, itn_id, result); done: scsi_host_put(shost); return err; diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h index e9e6db1..cb92888 100644 --- a/drivers/scsi/scsi_tgt_priv.h +++ b/drivers/scsi/scsi_tgt_priv.h @@ -15,12 +15,18 @@ do { \ extern void scsi_tgt_if_exit(void); extern int scsi_tgt_if_init(void); -extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, - u64 tag); -extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); -extern int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, - unsigned long uaddr, u32 len, unsigned long sense_uaddr, - u32 sense_len, u8 rw); -extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, +extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 it_nexus_id, + struct scsi_lun *lun, u64 tag); +extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 it_nexus_id, + u64 tag); +extern int scsi_tgt_kspace_exec(int host_no, u64 it_nexus_id, int result, u64 tag, + unsigned long uaddr, u32 len, + unsigned long sense_uaddr, u32 sense_len, u8 rw); +extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 it_nexus_id, + int function, u64 tag, struct scsi_lun *scsilun, void *data); -extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); +extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 it_nexus_id, + u64 mid, int result); +extern int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 it_nexus_id, + int function, char *initiator); +extern int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 it_nexus_id, int result); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 3b8a6a8..89c40c4 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -146,7 +146,7 @@ struct scsi_host_template { void (*done)(struct scsi_cmnd *)); /* Used as callback for the completion of task management request. */ - int (* tsk_mgmt_response)(u64 mid, int result); + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64 mid, int result); /* * This is an error handling strategy routine. You don't need to diff --git a/include/scsi/scsi_tgt.h b/include/scsi/scsi_tgt.h index 4f44279..d0fefb9 100644 --- a/include/scsi/scsi_tgt.h +++ b/include/scsi/scsi_tgt.h @@ -11,9 +11,11 @@ struct scsi_lun; extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *); extern int scsi_tgt_alloc_queue(struct Scsi_Host *); extern void scsi_tgt_free_queue(struct Scsi_Host *); -extern int scsi_tgt_queue_command(struct scsi_cmnd *, struct scsi_lun *, u64); -extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, int, u64, struct scsi_lun *, - void *); +extern int scsi_tgt_queue_command(struct scsi_cmnd *, u64, struct scsi_lun *, u64); +extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, u64, int, u64, + struct scsi_lun *, void *); extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *, enum dma_data_direction, gfp_t); extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *); +extern int scsi_tgt_it_nexus_create(struct Scsi_Host *, u64, char *); +extern int scsi_tgt_it_nexus_destroy(struct Scsi_Host *, u64); diff --git a/include/scsi/scsi_tgt_if.h b/include/scsi/scsi_tgt_if.h index 4cf9dff..f2ee7c2 100644 --- a/include/scsi/scsi_tgt_if.h +++ b/include/scsi/scsi_tgt_if.h @@ -23,13 +23,15 @@ #define __SCSI_TARGET_IF_H /* user -> kernel */ -#define TGT_UEVENT_CMD_RSP 0x0001 -#define TGT_UEVENT_TSK_MGMT_RSP 0x0002 +#define TGT_UEVENT_CMD_RSP 0x0001 +#define TGT_UEVENT_IT_NEXUS_RSP 0x0002 +#define TGT_UEVENT_TSK_MGMT_RSP 0x0003 /* kernel -> user */ -#define TGT_KEVENT_CMD_REQ 0x1001 -#define TGT_KEVENT_CMD_DONE 0x1002 -#define TGT_KEVENT_TSK_MGMT_REQ 0x1003 +#define TGT_KEVENT_CMD_REQ 0x1001 +#define TGT_KEVENT_CMD_DONE 0x1002 +#define TGT_KEVENT_IT_NEXUS_REQ 0x1003 +#define TGT_KEVENT_TSK_MGMT_REQ 0x1004 struct tgt_event_hdr { uint16_t version; @@ -46,6 +48,7 @@ struct tgt_event { struct { int host_no; int result; + aligned_u64 itn_id; aligned_u64 tag; aligned_u64 uaddr; aligned_u64 sense_uaddr; @@ -55,15 +58,22 @@ struct tgt_event { } cmd_rsp; struct { int host_no; - aligned_u64 mid; int result; + aligned_u64 itn_id; + aligned_u64 mid; } tsk_mgmt_rsp; - + struct { + __s32 host_no; + __s32 result; + aligned_u64 itn_id; + __u32 function; + } it_nexus_rsp; /* kernel -> user */ struct { int host_no; uint32_t data_len; + aligned_u64 itn_id; uint8_t scb[16]; uint8_t lun[8]; int attribute; @@ -71,16 +81,25 @@ struct tgt_event { } cmd_req; struct { int host_no; - aligned_u64 tag; int result; + aligned_u64 itn_id; + aligned_u64 tag; } cmd_done; struct { int host_no; int function; + aligned_u64 itn_id; aligned_u64 tag; uint8_t lun[8]; aligned_u64 mid; } tsk_mgmt_req; + struct { + __s32 host_no; + __u32 function; + aligned_u64 itn_id; + __u32 max_cmds; + __u8 initiator_id[16]; + } it_nexus_req; } p; } __attribute__ ((aligned (sizeof(uint64_t)))); diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index 3c18baa..af5b3e1 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h @@ -65,6 +65,12 @@ struct scsi_transport_template { * EH_NOT_HANDLED Begin normal error recovery */ enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); + + /* + * Used as callback for the completion of i_t_nexus request + * for target drivers. + */ + int (* it_nexus_response)(struct Scsi_Host *, u64, int); }; #define transport_class_to_shost(tc) \ -- cgit v1.1 From 62fe88261b9d865264d857777cf58a0335513151 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:19 +0900 Subject: [SCSI] srp_transport: add target driver support This adds minimum target driver support: - srp_rport_{add,del} calls scsi_tgt_it_nexus_{create,destroy} for target drivers. - add a callback to notify target drivers of the nexus operation results to srp_function_template. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 2 +- drivers/scsi/scsi_transport_srp.c | 24 ++++++++++++++++++++++++ include/scsi/scsi_transport_srp.h | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 778dc0f..8d4057e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -291,7 +291,7 @@ source "drivers/scsi/libsas/Kconfig" config SCSI_SRP_ATTRS tristate "SRP Transport Attributes" - depends on SCSI + depends on SCSI && SCSI_TGT help If you wish to export transport-specific information about each attached SRP device to sysfs, say Y. diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 608abd8..8e5b41c 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -30,6 +30,7 @@ #include #include #include +#include struct srp_host_attrs { atomic_t next_port_id; @@ -221,6 +222,17 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, return ERR_PTR(ret); } + if (ids->roles == SRP_RPORT_ROLE_INITIATOR) { + ret = scsi_tgt_it_nexus_create(shost, (unsigned long)rport, + rport->port_id); + if (ret) { + device_del(&rport->dev); + transport_destroy_device(&rport->dev); + put_device(&rport->dev); + return ERR_PTR(ret); + } + } + transport_add_device(&rport->dev); transport_configure_device(&rport->dev); @@ -238,6 +250,10 @@ void srp_rport_del(struct srp_rport *rport) { struct device *dev = &rport->dev; + if (rport->roles == SRP_RPORT_ROLE_INITIATOR) + scsi_tgt_it_nexus_destroy(dev_to_shost(dev->parent), + (unsigned long)rport); + transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); @@ -264,6 +280,12 @@ void srp_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL_GPL(srp_remove_host); +static int srp_it_nexus_response(struct Scsi_Host *shost, u64 id, int result) +{ + struct srp_internal *i = to_srp_internal(shost->transportt); + return i->f->it_nexus_response(shost, id, result); +} + /** * srp_attach_transport -- instantiate SRP transport template * @ft: SRP transport class function template @@ -278,6 +300,8 @@ srp_attach_transport(struct srp_function_template *ft) if (!i) return NULL; + i->t.it_nexus_response = srp_it_nexus_response; + i->t.host_size = sizeof(struct srp_host_attrs); i->t.host_attrs.ac.attrs = &i->host_attrs[0]; i->t.host_attrs.ac.class = &srp_host_class.class; diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index 08b4a28..a705dbc 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -21,7 +21,8 @@ struct srp_rport { }; struct srp_function_template { - /* later */ + /* for target drivers */ + int (* it_nexus_response)(struct Scsi_Host *, u64, int); }; extern struct scsi_transport_template * -- cgit v1.1 From 17b0bcfad795913b1f2a3926cd238fa2ad5522a2 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:21 +0900 Subject: [SCSI] tgt: convert libsrp and ibmvstgt to use srp_transport This converts libsrp and ibmvstgt to use srp transport. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 2 +- drivers/scsi/ibmvscsi/ibmvstgt.c | 58 +++++++++++++++++++++++++++++++++++----- drivers/scsi/libsrp.c | 5 ++-- include/scsi/libsrp.h | 2 +- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8d4057e..4562273 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -848,7 +848,7 @@ config SCSI_IBMVSCSI config SCSI_IBMVSCSIS tristate "IBM Virtual SCSI Server support" - depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP + depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP && SCSI_SRP_ATTRS help This is the SRP target driver for IBM pSeries virtual environments. diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd0..4ee6e41 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -68,9 +69,12 @@ struct vio_port { unsigned long liobn; unsigned long riobn; struct srp_target *target; + + struct srp_rport *rport; }; static struct workqueue_struct *vtgtd; +static struct scsi_transport_template *ibmvstgt_transport_template; /* * These are fixed for the system and come from the Open Firmware device tree. @@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, static void handle_cmd_queue(struct srp_target *target) { struct Scsi_Host *shost = target->shost; + struct srp_rport *rport = target_to_port(target)->rport; struct iu_entry *iue; struct srp_cmd *cmd; unsigned long flags; @@ -200,7 +205,8 @@ retry: if (!test_and_set_bit(V_FLYING, &iue->flags)) { spin_unlock_irqrestore(&target->lock, flags); cmd = iue->sbuf->buf; - err = srp_cmd_queue(shost, cmd, iue, 0); + err = srp_cmd_queue(shost, cmd, iue, + (unsigned long)rport, 0); if (err) { eprintk("cannot queue cmd %p %d\n", cmd, err); srp_iu_put(iue); @@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue) union viosrp_iu *iu = vio_iu(iue); struct srp_login_rsp *rsp = &iu->srp.login_rsp; uint64_t tag = iu->srp.rsp.tag; + struct Scsi_Host *shost = iue->target->shost; + struct srp_target *target = host_to_srp_target(shost); + struct vio_port *vport = target_to_port(target); + struct srp_rport_identifiers ids; + + memset(&ids, 0, sizeof(ids)); + sprintf(ids.port_id, "%x", vport->dma_dev->unit_address); + ids.roles = SRP_RPORT_ROLE_INITIATOR; + if (!vport->rport) + vport->rport = srp_rport_add(shost, &ids); /* TODO handle case that requested size is wrong and * buffer format is wrong @@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue) fn = 0; } if (fn) - scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, + scsi_tgt_tsk_mgmt_request(iue->target->shost, + (unsigned long)iue->target->shost, + fn, iu->srp.tsk_mgmt.task_tag, (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, iue); @@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) return 0; } -static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) +static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost, + u64 itn_id, u64 mid, int result) { struct iu_entry *iue = (struct iu_entry *) ((void *) mid); union viosrp_iu *iu = vio_iu(iue); @@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) return 0; } +static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id, + int result) +{ + struct srp_target *target = host_to_srp_target(shost); + struct vio_port *vport = target_to_port(target); + + if (result) { + eprintk("%p %d\n", shost, result); + srp_rport_del(vport->rport); + vport->rport = NULL; + } + return 0; +} + static ssize_t system_id_show(struct class_device *cdev, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", system_id); @@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); if (!shost) goto free_vport; + shost->transportt = ibmvstgt_transport_template; err = scsi_tgt_alloc_queue(shost); if (err) goto put_host; @@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) err = scsi_add_host(shost, target->dev); if (err) goto destroy_queue; - return 0; + return 0; destroy_queue: crq_queue_destroy(target); free_srp_target: @@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev) struct vio_port *vport = target->ldata; crq_queue_destroy(target); + srp_remove_host(shost); scsi_remove_host(shost); scsi_tgt_free_queue(shost); srp_target_free(target); @@ -909,15 +944,24 @@ static int get_system_info(void) return 0; } +static struct srp_function_template ibmvstgt_transport_functions = { + .it_nexus_response = ibmvstgt_it_nexus_response, +}; + static int ibmvstgt_init(void) { int err = -ENOMEM; printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); + ibmvstgt_transport_template = + srp_attach_transport(&ibmvstgt_transport_functions); + if (!ibmvstgt_transport_template) + return err; + vtgtd = create_workqueue("ibmvtgtd"); if (!vtgtd) - return err; + goto release_transport; err = get_system_info(); if (err) @@ -928,9 +972,10 @@ static int ibmvstgt_init(void) goto destroy_wq; return 0; - destroy_wq: destroy_workqueue(vtgtd); +release_transport: + srp_release_transport(ibmvstgt_transport_template); return err; } @@ -940,6 +985,7 @@ static void ibmvstgt_exit(void) destroy_workqueue(vtgtd); vio_unregister_driver(&ibmvstgt_driver); + srp_release_transport(ibmvstgt_transport_template); } MODULE_DESCRIPTION("IBM Virtual SCSI Target"); diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 732446e..2ad0a27 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -392,7 +392,7 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) } int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, - u64 addr) + u64 itn_id, u64 addr) { enum dma_data_direction dir; struct scsi_cmnd *sc; @@ -428,7 +428,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, sc->request_bufflen = len; sc->request_buffer = (void *) (unsigned long) addr; sc->tag = tag; - err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); + err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun, + cmd->tag); if (err) scsi_host_put_command(shost, sc); diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index d143171..ba615e4 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h @@ -59,7 +59,7 @@ extern void srp_target_free(struct srp_target *); extern struct iu_entry *srp_iu_get(struct srp_target *); extern void srp_iu_put(struct iu_entry *); -extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64); +extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64, u64); extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, srp_rdma_t, int, int); -- cgit v1.1 From bfb743740e1598d3030c4972a8808f2bb5b95b6b Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:22 +0900 Subject: [SCSI] tgt: move tsk_mgmt_response callback to transport class This moves tsk_mgmt_response callback in struct scsi_host_template to struct scsi_transport_template since struct scsi_transport_template is more suitable for the task management stuff. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_tgt_lib.c | 2 +- drivers/scsi/scsi_transport_srp.c | 12 ++++++++++-- include/scsi/scsi_host.h | 3 --- include/scsi/scsi_transport.h | 6 ++++++ include/scsi/scsi_transport_srp.h | 1 + 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index fa79e54..5851c8e 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -577,7 +577,7 @@ int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result) goto done; } - err = shost->hostt->tsk_mgmt_response(shost, itn_id, mid, result); + err = shost->transportt->tsk_mgmt_response(shost, itn_id, mid, result); done: scsi_host_put(shost); return err; diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 8e5b41c..cdd001a 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -280,10 +280,17 @@ void srp_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL_GPL(srp_remove_host); -static int srp_it_nexus_response(struct Scsi_Host *shost, u64 id, int result) +static int srp_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, + int result) { struct srp_internal *i = to_srp_internal(shost->transportt); - return i->f->it_nexus_response(shost, id, result); + return i->f->tsk_mgmt_response(shost, nexus, tm_id, result); +} + +static int srp_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) +{ + struct srp_internal *i = to_srp_internal(shost->transportt); + return i->f->it_nexus_response(shost, nexus, result); } /** @@ -300,6 +307,7 @@ srp_attach_transport(struct srp_function_template *ft) if (!i) return NULL; + i->t.tsk_mgmt_response = srp_tsk_mgmt_response; i->t.it_nexus_response = srp_it_nexus_response; i->t.host_size = sizeof(struct srp_host_attrs); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 89c40c4..88f6871 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -145,9 +145,6 @@ struct scsi_host_template { int (* transfer_response)(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); - /* Used as callback for the completion of task management request. */ - int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64 mid, int result); - /* * This is an error handling strategy routine. You don't need to * define one of these if you don't want to - there is a default diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index af5b3e1..0dfef75 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h @@ -71,6 +71,12 @@ struct scsi_transport_template { * for target drivers. */ int (* it_nexus_response)(struct Scsi_Host *, u64, int); + + /* + * Used as callback for the completion of task management + * request for target drivers. + */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); }; #define transport_class_to_shost(tc) \ diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index a705dbc..9c60ca1 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -22,6 +22,7 @@ struct srp_rport { struct srp_function_template { /* for target drivers */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); int (* it_nexus_response)(struct Scsi_Host *, u64, int); }; -- cgit v1.1 From e9906fe8c6e8d004635753b7c4189692df281b70 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 11 Jul 2007 15:08:24 +0900 Subject: [SCSI] tgt: convert ibmvstgt to use transport tsk_mgmt_response callback This converts ibmvstgt to use transport tsk_mgmt_response callback. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvstgt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 4ee6e41..3db03dd 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -818,7 +818,6 @@ static struct scsi_host_template ibmvstgt_sht = { .max_sectors = DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, .eh_abort_handler = ibmvstgt_eh_abort_handler, - .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs = ibmvstgt_attrs, .proc_name = TGT_NAME, }; @@ -945,6 +944,7 @@ static int get_system_info(void) } static struct srp_function_template ibmvstgt_transport_functions = { + .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .it_nexus_response = ibmvstgt_it_nexus_response, }; -- cgit v1.1 From 0012fdf986c9b9c7fe8d0842a0ad8dd981a06c06 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 2 Aug 2007 00:20:34 +0900 Subject: [SCSI] scsi_transport_srp: remove tgt dependencies it's better to remove tgt dependencies in srp transport class since most people want only initiator support. Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 11 +++++++++-- drivers/scsi/scsi_transport_srp.c | 10 +++++----- drivers/scsi/scsi_transport_srp_internal.h | 25 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 drivers/scsi/scsi_transport_srp_internal.h diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 4562273..7877dfd 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -291,11 +291,18 @@ source "drivers/scsi/libsas/Kconfig" config SCSI_SRP_ATTRS tristate "SRP Transport Attributes" - depends on SCSI && SCSI_TGT + depends on SCSI help If you wish to export transport-specific information about each attached SRP device to sysfs, say Y. +config SCSI_SRP_TGT_ATTRS + bool "SCSI target support for SRP Transport Attributes" + depends on SCSI_SRP_ATTRS + depends on SCSI_TGT = y || SCSI_TGT = SCSI_SRP_ATTRS + help + If you want to use SCSI target mode drivers enable this option. + endmenu menuconfig SCSI_LOWLEVEL @@ -848,7 +855,7 @@ config SCSI_IBMVSCSI config SCSI_IBMVSCSIS tristate "IBM Virtual SCSI Server support" - depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP && SCSI_SRP_ATTRS + depends on PPC_PSERIES && SCSI_SRP && SCSI_SRP_TGT_ATTRS help This is the SRP target driver for IBM pSeries virtual environments. diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index cdd001a..430501e 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include "scsi_transport_srp_internal.h" struct srp_host_attrs { atomic_t next_port_id; @@ -223,8 +223,8 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, } if (ids->roles == SRP_RPORT_ROLE_INITIATOR) { - ret = scsi_tgt_it_nexus_create(shost, (unsigned long)rport, - rport->port_id); + ret = srp_tgt_it_nexus_create(shost, (unsigned long)rport, + rport->port_id); if (ret) { device_del(&rport->dev); transport_destroy_device(&rport->dev); @@ -251,8 +251,8 @@ void srp_rport_del(struct srp_rport *rport) struct device *dev = &rport->dev; if (rport->roles == SRP_RPORT_ROLE_INITIATOR) - scsi_tgt_it_nexus_destroy(dev_to_shost(dev->parent), - (unsigned long)rport); + srp_tgt_it_nexus_destroy(dev_to_shost(dev->parent), + (unsigned long)rport); transport_remove_device(dev); device_del(dev); diff --git a/drivers/scsi/scsi_transport_srp_internal.h b/drivers/scsi/scsi_transport_srp_internal.h new file mode 100644 index 0000000..8a79747 --- /dev/null +++ b/drivers/scsi/scsi_transport_srp_internal.h @@ -0,0 +1,25 @@ +#include + +#ifdef CONFIG_SCSI_SRP_TGT_ATTRS +static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + return scsi_tgt_it_nexus_create(shost, itn_id, initiator); +} + +static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + return scsi_tgt_it_nexus_destroy(shost, itn_id); +} + +#else +static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + return 0; +} +static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + return 0; +} +#endif -- cgit v1.1 From 358147403d1506ee43335c152fa3864d90f5ef6e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 23 Jul 2007 09:42:32 +0900 Subject: [SCSI] ps3rom: convert to use the data buffer accessors This converts ps3rom driver to use the new accessors for the sg lists and the parameters. Signed-off-by: FUJITA Tomonori Acked-by: Geert Uytterhoeven Signed-off-by: James Bottomley --- drivers/scsi/ps3rom.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index b50f1e1..0f43d1d 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -100,16 +100,16 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) struct scatterlist *sgpnt; unsigned int buflen; - buflen = cmd->request_bufflen; + buflen = scsi_bufflen(cmd); if (!buflen) return 0; - if (!cmd->request_buffer) + if (!scsi_sglist(cmd)) return -1; - sgpnt = cmd->request_buffer; active = 1; - for (k = 0, req_len = 0, act_len = 0; k < cmd->use_sg; ++k, ++sgpnt) { + req_len = act_len = 0; + scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { if (active) { kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); len = sgpnt->length; @@ -124,7 +124,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) } req_len += sgpnt->length; } - cmd->resid = req_len - act_len; + scsi_set_resid(cmd, req_len - act_len); return 0; } @@ -138,15 +138,15 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf) struct scatterlist *sgpnt; unsigned int buflen; - buflen = cmd->request_bufflen; + buflen = scsi_bufflen(cmd); if (!buflen) return 0; - if (!cmd->request_buffer) + if (!scsi_sglist(cmd)) return -1; - sgpnt = cmd->request_buffer; - for (k = 0, req_len = 0, fin = 0; k < cmd->use_sg; ++k, ++sgpnt) { + req_len = fin = 0; + scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); len = sgpnt->length; if ((req_len + len) > buflen) { @@ -177,12 +177,12 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12); atapi_cmnd.pktlen = 12; atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */ - atapi_cmnd.blocks = atapi_cmnd.arglen = cmd->request_bufflen; + atapi_cmnd.blocks = atapi_cmnd.arglen = scsi_bufflen(cmd); atapi_cmnd.buffer = dev->bounce_lpar; switch (cmd->sc_data_direction) { case DMA_FROM_DEVICE: - if (cmd->request_bufflen >= CD_FRAMESIZE) + if (scsi_bufflen(cmd) >= CD_FRAMESIZE) atapi_cmnd.proto = DMA_PROTO; else atapi_cmnd.proto = PIO_DATA_IN_PROTO; @@ -190,7 +190,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, break; case DMA_TO_DEVICE: - if (cmd->request_bufflen >= CD_FRAMESIZE) + if (scsi_bufflen(cmd) >= CD_FRAMESIZE) atapi_cmnd.proto = DMA_PROTO; else atapi_cmnd.proto = PIO_DATA_OUT_PROTO; -- cgit v1.1 From bd441deaf341c524b28fd72831ebf6fef88f1c41 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 13 Mar 2007 12:52:29 -0500 Subject: [SCSI] fix write buffer length in scsi_req_map_sg() sg's may have setup a the buffer with a different length than the transfer length so we should be using the bufflen passed in as the request's data len. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a417a6f..277f1b6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -301,7 +301,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, { struct request_queue *q = rq->q; int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - unsigned int data_len = 0, len, bytes, off; + unsigned int data_len = bufflen, len, bytes, off; struct page *page; struct bio *bio = NULL; int i, err, nr_vecs = 0; @@ -310,10 +310,15 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, page = sgl[i].page; off = sgl[i].offset; len = sgl[i].length; - data_len += len; - while (len > 0) { + while (len > 0 && data_len > 0) { + /* + * sg sends a scatterlist that is larger than + * the data_len it wants transferred for certain + * IO sizes + */ bytes = min_t(unsigned int, len, PAGE_SIZE - off); + bytes = min(bytes, data_len); if (!bio) { nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages); @@ -345,12 +350,13 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, page++; len -= bytes; + data_len -=bytes; off = 0; } } rq->buffer = rq->data = NULL; - rq->data_len = data_len; + rq->data_len = bufflen; return 0; free_bios: -- cgit v1.1 From afd9a033ca1354e95c95201f5d21a097da9f7fb2 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 12 Jul 2007 16:11:24 +0300 Subject: [SCSI] microtek: use data accessors and !use_sg cleanup - use scsi_cmnd data accessors - Clean the !use_sg code paths Signed-off-by: Boaz Harrosh Acked-by: Greg Kroah-Hartman [jejb: merge conflict fix] Signed-off-by: James Bottomley --- drivers/usb/image/microtek.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 768b2c1..e7d982a 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -446,7 +446,8 @@ static void mts_data_done( struct urb* transfer ) MTS_INT_INIT(); if ( context->data_length != transfer->actual_length ) { - context->srb->resid = context->data_length - transfer->actual_length; + scsi_set_resid(context->srb, context->data_length - + transfer->actual_length); } else if ( unlikely(status) ) { context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; } @@ -490,7 +491,8 @@ static void mts_command_done( struct urb *transfer ) context->data_pipe, context->data, context->data_length, - context->srb->use_sg > 1 ? mts_do_sg : mts_data_done); + scsi_sg_count(context->srb) > 1 ? + mts_do_sg : mts_data_done); } else { mts_get_status(transfer); } @@ -505,21 +507,23 @@ static void mts_do_sg (struct urb* transfer) int status = transfer->status; MTS_INT_INIT(); - MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); + MTS_DEBUG("Processing fragment %d of %d\n", context->fragment, + scsi_sg_count(context->srb)); if (unlikely(status)) { context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; mts_transfer_cleanup(transfer); } - sg = context->srb->request_buffer; + sg = scsi_sglist(context->srb); context->fragment++; mts_int_submit_urb(transfer, context->data_pipe, page_address(sg[context->fragment].page) + sg[context->fragment].offset, sg[context->fragment].length, - context->fragment + 1 == context->srb->use_sg ? mts_data_done : mts_do_sg); + context->fragment + 1 == scsi_sg_count(context->srb) ? + mts_data_done : mts_do_sg); return; } @@ -547,20 +551,12 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) desc->context.srb = srb; desc->context.fragment = 0; - if (!srb->use_sg) { - if ( !srb->request_bufflen ){ - desc->context.data = NULL; - desc->context.data_length = 0; - return; - } else { - desc->context.data = srb->request_buffer; - desc->context.data_length = srb->request_bufflen; - MTS_DEBUG("length = %d or %d\n", - srb->request_bufflen, srb->bufflen); - } + if (!scsi_bufflen(srb)) { + desc->context.data = NULL; + desc->context.data_length = 0; + return; } else { - MTS_DEBUG("Using scatter/gather\n"); - sg = srb->request_buffer; + sg = scsi_sglist(srb); desc->context.data = page_address(sg[0].page) + sg[0].offset; desc->context.data_length = sg[0].length; } -- cgit v1.1 From 6b7f123f378743d739377871c0cbfbaf28c7d25a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 26 Jun 2007 15:18:51 -0600 Subject: [SCSI] Fix async scanning double-add problems Stress-testing and some thought has revealed some places where asynchronous scanning needs some more attention to locking. - Since async_scan is a bit, we need to hold the host_lock while modifying it to prevent races against other CPUs modifying the word that bit is in. This is probably a theoretical race for the moment, but other patches may change that. - The async_scan bit means not only that this host is being scanned asynchronously, but that all the devices attached to this host are not yet added to sysfs. So we must ensure that this bit is always in sync. I've chosen to do this with the scan_mutex since it's already acquired in most of the right places. - If the host changes state to deleted while we're in the middle of a scan, we'll end up with some devices on the host's list which must be deleted. Add a check to scsi_sysfs_add_devices() to ensure the host is still running. - To avoid the async_scan bit being protected by three locks, the async_scan_lock now only protects the scanning_list. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a86e62f..309b224 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -121,6 +121,7 @@ MODULE_PARM_DESC(inq_timeout, "Timeout (in seconds) waiting for devices to answer INQUIRY." " Default is 5. Some non-compliant devices need more."); +/* This lock protects only this list */ static DEFINE_SPINLOCK(async_scan_lock); static LIST_HEAD(scanning_hosts); @@ -1466,14 +1467,14 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, if (strncmp(scsi_scan_type, "none", 4) == 0) return ERR_PTR(-ENODEV); - if (!shost->async_scan) - scsi_complete_async_scans(); - starget = scsi_alloc_target(parent, channel, id); if (!starget) return ERR_PTR(-ENOMEM); mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) + scsi_complete_async_scans(); + if (scsi_host_scan_allowed(shost)) scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); mutex_unlock(&shost->scan_mutex); @@ -1586,10 +1587,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel, if (strncmp(scsi_scan_type, "none", 4) == 0) return; + mutex_lock(&shost->scan_mutex); if (!shost->async_scan) scsi_complete_async_scans(); - mutex_lock(&shost->scan_mutex); if (scsi_host_scan_allowed(shost)) __scsi_scan_target(parent, channel, id, lun, rescan); mutex_unlock(&shost->scan_mutex); @@ -1634,15 +1635,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, "%s: <%u:%u:%u>\n", __FUNCTION__, channel, id, lun)); - if (!shost->async_scan) - scsi_complete_async_scans(); - if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) return -EINVAL; mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) + scsi_complete_async_scans(); + if (scsi_host_scan_allowed(shost)) { if (channel == SCAN_WILD_CARD) for (channel = 0; channel <= shost->max_channel; @@ -1661,7 +1662,8 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) { struct scsi_device *sdev; shost_for_each_device(sdev, shost) { - if (scsi_sysfs_add_sdev(sdev) != 0) + if (!scsi_host_scan_allowed(shost) || + scsi_sysfs_add_sdev(sdev) != 0) scsi_destroy_sdev(sdev); } } @@ -1679,6 +1681,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) { struct async_scan_data *data; + unsigned long flags; if (strncmp(scsi_scan_type, "sync", 4) == 0) return NULL; @@ -1698,8 +1701,13 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) goto err; init_completion(&data->prev_finished); - spin_lock(&async_scan_lock); + mutex_lock(&shost->scan_mutex); + spin_lock_irqsave(shost->host_lock, flags); shost->async_scan = 1; + spin_unlock_irqrestore(shost->host_lock, flags); + mutex_unlock(&shost->scan_mutex); + + spin_lock(&async_scan_lock); if (list_empty(&scanning_hosts)) complete(&data->prev_finished); list_add_tail(&data->list, &scanning_hosts); @@ -1723,11 +1731,15 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) static void scsi_finish_async_scan(struct async_scan_data *data) { struct Scsi_Host *shost; + unsigned long flags; if (!data) return; shost = data->shost; + + mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) { printk("%s called twice for host %d", __FUNCTION__, shost->host_no); @@ -1739,8 +1751,13 @@ static void scsi_finish_async_scan(struct async_scan_data *data) scsi_sysfs_add_devices(shost); - spin_lock(&async_scan_lock); + spin_lock_irqsave(shost->host_lock, flags); shost->async_scan = 0; + spin_unlock_irqrestore(shost->host_lock, flags); + + mutex_unlock(&shost->scan_mutex); + + spin_lock(&async_scan_lock); list_del(&data->list); if (!list_empty(&scanning_hosts)) { struct async_scan_data *next = list_entry(scanning_hosts.next, -- cgit v1.1 From ea312552e94883efc42cfa4651bcf964f3110564 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 6 Aug 2007 00:31:24 +0900 Subject: [SCSI] sg: increase sglist_len of the sg_scatter_hold structure unsigned short is too small for sizeof(struct scatterlist) * min(q->max_hw_segments, q->max_phys_segments). This fixes memory leak with 4096 segments since 16 (likely sg size with x86) * 4096 sets sglist_len to zero. This might not happen without sg chaining support. Signed-off-by: FUJITA Tomonori Acked-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 85d3894..fdc6618 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -114,7 +114,7 @@ static struct class_interface sg_interface = { typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */ - unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */ + unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */ unsigned bufflen; /* Size of (aggregate) data buffer */ unsigned b_malloc_len; /* actual len malloc'ed in buffer */ struct scatterlist *buffer;/* scatter list */ -- cgit v1.1 From 8c6af9e174abdf40c30a4a229bbd11b458869f97 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:03:19 -0400 Subject: [SCSI] advansys: undate version, copyright, etc Update the version to 3.4 Add my copyright Add myself to MAINTAINERS Exercise my right to change the license from dual BSD/GPL to GPL Don't force the definition of CONFIG_ISA on x86 Always include pci.h Stop including stat.h Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- MAINTAINERS | 6 ++++++ drivers/scsi/advansys.c | 43 +++++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e4dde7f..fa35397 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -288,6 +288,12 @@ P: Colin Leroy M: colin@colino.net S: Maintained +ADVANSYS SCSI DRIVER +P: Matthew Wilcox +M: matthew@wil.cx +L: linux-scsi@vger.kernel.org +S: Maintained + AEDSP16 DRIVER P: Riccardo Facchetti M: fizban@tin.it diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 79c0b6e..8ace30e 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1,20 +1,23 @@ -#define ASC_VERSION "3.3K" /* AdvanSys Driver Version */ +#define ASC_VERSION "3.4" /* AdvanSys Driver Version */ /* * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters * * Copyright (c) 1995-2000 Advanced System Products, Inc. * Copyright (c) 2000-2001 ConnectCom Solutions, Inc. + * Copyright (c) 2007 Matthew Wilcox * All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. - * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys) * changed its name to ConnectCom Solutions, Inc. - * + * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets */ /* @@ -755,11 +758,6 @@ */ #include - -#if defined(CONFIG_X86) && !defined(CONFIG_ISA) -#define CONFIG_ISA -#endif /* CONFIG_X86 && !CONFIG_ISA */ - #include #include #include @@ -771,7 +769,7 @@ #include #include #include -#include +#include #include #include @@ -779,6 +777,12 @@ #include #include +#include +#include +#include +#include +#include + /* FIXME: (by jejb@steeleye.com) This warning is present for two * reasons: * @@ -793,15 +797,6 @@ */ #warning this driver is still not properly converted to the DMA API -#include -#include -#include -#include -#include -#ifdef CONFIG_PCI -#include -#endif /* CONFIG_PCI */ - /* * --- Driver Options */ @@ -17772,8 +17767,6 @@ static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) } } -MODULE_LICENSE("Dual BSD/GPL"); - static struct Scsi_Host *__devinit advansys_board_found(int iop, struct device *dev, int bus_type) { @@ -19029,3 +19022,5 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); #endif /* CONFIG_PCI */ + +MODULE_LICENSE("GPL"); -- cgit v1.1 From 2a437959e963d98e04dbbcd26b69bfb1985567ce Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:00:51 -0400 Subject: [SCSI] advansys: Clean up proc_info implementation Just use the Scsi_Host passed in, rather than looking through the driver's own array of boards for one that matches it. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 8ace30e..6d11076 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -4031,9 +4031,7 @@ static int advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout) { - struct Scsi_Host *shp; asc_board_t *boardp; - int i; char *cp; int cplen; int cnt; @@ -4058,18 +4056,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, * User read of /proc/scsi/advansys/[0...] file. */ - /* Find the specified board. */ - for (i = 0; i < asc_board_count; i++) { - if (asc_host[i]->host_no == shost->host_no) { - break; - } - } - if (i == asc_board_count) { - return (-ENOENT); - } - - shp = asc_host[i]; - boardp = ASC_BOARDP(shp); + boardp = ASC_BOARDP(shost); /* Copy read data starting at the beginning of the buffer. */ *start = buffer; @@ -4083,7 +4070,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, * * advansys_info() returns the board string from its own static buffer. */ - cp = (char *)advansys_info(shp); + cp = (char *)advansys_info(shost); strcat(cp, "\n"); cplen = strlen(cp); /* Copy board information. */ @@ -4102,7 +4089,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ if (ASC_WIDE_BOARD(boardp)) { cp = boardp->prtbuf; - cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, @@ -4121,7 +4108,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, * Display driver information for each device attached to the board. */ cp = boardp->prtbuf; - cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; @@ -4138,9 +4125,9 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ cp = boardp->prtbuf; if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); } else { - cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); } ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); @@ -4157,7 +4144,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, * Display driver configuration and information for the board. */ cp = boardp->prtbuf; - cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; @@ -4174,7 +4161,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, * Display driver statistics for the board. */ cp = boardp->prtbuf; - cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; @@ -4191,7 +4178,8 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) { cp = boardp->prtbuf; - cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_target_stats(shost, tgt_id, cp, + ASC_PRTBUF_SIZE); ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, @@ -4213,9 +4201,9 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ cp = boardp->prtbuf; if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE); } else { - cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE); + cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); } ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); -- cgit v1.1 From 074c8fe4c0c0c7918d99bca34ea8e02a86997530 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 28 Jul 2007 23:11:05 -0600 Subject: [SCSI] advansys: Improve interrupt handler Pass the Scsi_Host to the interrupt handler, rather than polling all hosts for each interrupt. Return IRQ_NONE if we didn't handle this interrupt Don't set the IRQF_DISABLED flag; this is not a fast-executing interrupt handler. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 172 ++++++++++++++++++++---------------------------- 1 file changed, 72 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 6d11076..a407ff3 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3951,7 +3951,6 @@ static PortAddr _asc_def_iop_base[]; * advansys.h contains function prototypes for functions global to Linux. */ -static irqreturn_t advansys_interrupt(int, void *); static int advansys_slave_configure(struct scsi_device *); static void asc_scsi_done_list(struct scsi_cmnd *); static int asc_execute_scsi_cmnd(struct scsi_cmnd *); @@ -4684,89 +4683,76 @@ static struct scsi_host_template driver_template = { */ static irqreturn_t advansys_interrupt(int irq, void *dev_id) { - ulong flags; - int i; - asc_board_t *boardp; + unsigned long flags; struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; struct scsi_cmnd *new_last_scp; - struct Scsi_Host *shost; + struct Scsi_Host *shost = dev_id; + asc_board_t *boardp = ASC_BOARDP(shost); + irqreturn_t result = IRQ_NONE; - ASC_DBG(1, "advansys_interrupt: begin\n"); + ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); + spin_lock_irqsave(&boardp->lock, flags); + if (ASC_NARROW_BOARD(boardp)) { + /* + * Narrow Board + */ + if (AscIsIntPending(shost->io_port)) { + result = IRQ_HANDLED; + ASC_STATS(shost, interrupt); + ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); + AscISR(&boardp->dvc_var.asc_dvc_var); + } + } else { + /* + * Wide Board + */ + ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); + if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { + result = IRQ_HANDLED; + ASC_STATS(shost, interrupt); + } + } /* - * Check for interrupts on all boards. - * AscISR() will call asc_isr_callback(). - */ - for (i = 0; i < asc_board_count; i++) { - shost = asc_host[i]; - boardp = ASC_BOARDP(shost); - ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n", - i, (ulong)boardp); - spin_lock_irqsave(&boardp->lock, flags); - if (ASC_NARROW_BOARD(boardp)) { - /* - * Narrow Board - */ - if (AscIsIntPending(shost->io_port)) { - ASC_STATS(shost, interrupt); - ASC_DBG(1, - "advansys_interrupt: before AscISR()\n"); - AscISR(&boardp->dvc_var.asc_dvc_var); - } - } else { - /* - * Wide Board - */ - ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); - if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { - ASC_STATS(shost, interrupt); - } + * Start waiting requests and create a list of completed requests. + * + * If a reset request is being performed for the board, the reset + * handler will complete pending requests after it has completed. + */ + if ((boardp->flags & ASC_HOST_IN_RESET) == 0) { + ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, " + "last_scp 0x%p\n", done_scp, last_scp); + + /* Start any waiting commands for the board. */ + if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { + ASC_DBG(1, "advansys_interrupt: before " + "asc_execute_queue()\n"); + asc_execute_queue(&boardp->waiting); } /* - * Start waiting requests and create a list of completed requests. + * Add to the list of requests that must be completed. * - * If a reset request is being performed for the board, the reset - * handler will complete pending requests after it has completed. + * 'done_scp' will always be NULL on the first iteration of + * this loop. 'last_scp' is set at the same time as 'done_scp'. */ - if ((boardp->flags & ASC_HOST_IN_RESET) == 0) { - ASC_DBG2(1, - "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n", - (ulong)done_scp, (ulong)last_scp); - - /* Start any waiting commands for the board. */ - if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { - ASC_DBG(1, - "advansys_interrupt: before asc_execute_queue()\n"); - asc_execute_queue(&boardp->waiting); - } - - /* - * Add to the list of requests that must be completed. - * - * 'done_scp' will always be NULL on the first iteration - * of this loop. 'last_scp' is set at the same time as - * 'done_scp'. - */ - if (done_scp == NULL) { - done_scp = - asc_dequeue_list(&boardp->done, &last_scp, - ASC_TID_ALL); - } else { - ASC_ASSERT(last_scp != NULL); - last_scp->host_scribble = - (unsigned char *)asc_dequeue_list(&boardp-> - done, - &new_last_scp, - ASC_TID_ALL); - if (new_last_scp != NULL) { - ASC_ASSERT(REQPNEXT(last_scp) != NULL); - last_scp = new_last_scp; - } + if (done_scp == NULL) { + done_scp = asc_dequeue_list(&boardp->done, + &last_scp, ASC_TID_ALL); + } else { + ASC_ASSERT(last_scp != NULL); + last_scp->host_scribble = + (unsigned char *)asc_dequeue_list(&boardp-> + done, + &new_last_scp, + ASC_TID_ALL); + if (new_last_scp != NULL) { + ASC_ASSERT(REQPNEXT(last_scp) != NULL); + last_scp = new_last_scp; } } - spin_unlock_irqrestore(&boardp->lock, flags); } + spin_unlock_irqrestore(&boardp->lock, flags); /* * If interrupts were enabled on entry, then they @@ -4778,7 +4764,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) asc_scsi_done_list(done_scp); ASC_DBG(1, "advansys_interrupt: end\n"); - return IRQ_HANDLED; + return result; } /* @@ -17764,7 +17750,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_DVC_VAR *asc_dvc_varp = NULL; ADV_DVC_VAR *adv_dvc_varp = NULL; adv_sgblk_t *sgp = NULL; - int share_irq = FALSE; + int share_irq; int iolen = 0; ADV_PADDR pci_memory_address; int warn_code, err_code; @@ -17918,15 +17904,15 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #ifdef CONFIG_ISA case ASC_IS_ISA: shost->unchecked_isa_dma = TRUE; - share_irq = FALSE; + share_irq = 0; break; case ASC_IS_VL: shost->unchecked_isa_dma = FALSE; - share_irq = FALSE; + share_irq = 0; break; case ASC_IS_EISA: shost->unchecked_isa_dma = FALSE; - share_irq = TRUE; + share_irq = IRQF_SHARED; break; #endif /* CONFIG_ISA */ #ifdef CONFIG_PCI @@ -17937,7 +17923,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); shost->unchecked_isa_dma = FALSE; - share_irq = TRUE; + share_irq = IRQF_SHARED; break; #endif /* CONFIG_PCI */ default: @@ -17945,7 +17931,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ("advansys_board_found: board %d: unknown adapter type: %d\n", boardp->id, asc_dvc_varp->bus_type); shost->unchecked_isa_dma = TRUE; - share_irq = FALSE; + share_irq = 0; break; } } else { @@ -17961,7 +17947,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); shost->unchecked_isa_dma = FALSE; - share_irq = TRUE; + share_irq = IRQF_SHARED; #endif /* CONFIG_PCI */ } @@ -18425,25 +18411,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type) /* Register IRQ Number. */ ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq); - /* - * If request_irq() fails with the IRQF_DISABLED flag set, - * then try again without the IRQF_DISABLED flag set. This - * allows IRQ sharing to work even with other drivers that - * do not set the IRQF_DISABLED flag. - * - * If IRQF_DISABLED is not set, then interrupts are enabled - * before the driver interrupt function is called. - */ - if (((ret = request_irq(shost->irq, advansys_interrupt, - IRQF_DISABLED | (share_irq == - TRUE ? - IRQF_SHARED : - 0), "advansys", boardp)) != 0) - && - ((ret = - request_irq(shost->irq, advansys_interrupt, - (share_irq == TRUE ? IRQF_SHARED : 0), - "advansys", boardp)) != 0)) { + + ret = request_irq(shost->irq, advansys_interrupt, share_irq, + "advansys", shost); + + if (ret) { if (ret == -EBUSY) { ASC_PRINT2 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", @@ -18644,7 +18616,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #ifdef CONFIG_PROC_FS kfree(boardp->prtbuf); #endif /* CONFIG_PROC_FS */ - free_irq(shost->irq, boardp); + free_irq(shost->irq, shost); scsi_unregister(shost); asc_board_count--; return NULL; @@ -18960,7 +18932,7 @@ static int advansys_release(struct Scsi_Host *shost) ASC_DBG(1, "advansys_release: begin\n"); boardp = ASC_BOARDP(shost); - free_irq(shost->irq, boardp); + free_irq(shost->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { ASC_DBG(1, "advansys_release: free_dma()\n"); free_dma(shost->dma_channel); -- cgit v1.1 From 605fe5987f728e92e75ba12f7be01ffc3b132ad0 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 29 Jul 2007 17:27:20 -0600 Subject: [SCSI] advansys: Stop checking the scsi_cmnd belongs to our Scsi_Host The interrupt routines used to walk the list of Scsi_Hosts belonging to this driver to make sure that the scsi_cmnd belonged to one of them. This is a waste of time and gets in the way of later cleanups, so delete it. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index a407ff3..7a964bb 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -5506,7 +5506,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) asc_board_t *boardp; struct scsi_cmnd *scp; struct Scsi_Host *shost; - int i; ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", (ulong)asc_dvc_varp, (ulong)qdonep); @@ -5525,23 +5524,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) } ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); - /* - * If the request's host pointer is not valid, display a - * message and return. - */ shost = scp->device->host; - for (i = 0; i < asc_board_count; i++) { - if (asc_host[i] == shost) { - break; - } - } - if (i == asc_board_count) { - ASC_PRINT2 - ("asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", - (ulong)scp, (ulong)shost); - return; - } - ASC_STATS(shost, callback); ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); @@ -5680,7 +5663,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) adv_sgblk_t *sgblkp; struct scsi_cmnd *scp; struct Scsi_Host *shost; - int i; ADV_DCNT resid_cnt; ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", @@ -5716,27 +5698,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) } ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); - /* - * If the request's host pointer is not valid, display a message - * and return. - */ shost = scp->device->host; - for (i = 0; i < asc_board_count; i++) { - if (asc_host[i] == shost) { - break; - } - } - /* - * Note: If the host structure is not found, the adv_req_t request - * structure and adv_sgblk_t structure, if any, is dropped. - */ - if (i == asc_board_count) { - ASC_PRINT2 - ("adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", - (ulong)scp, (ulong)shost); - return; - } - ASC_STATS(shost, callback); ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); -- cgit v1.1 From b2c16f586ee529e97ac63183e70e2bfd586a2f47 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 29 Jul 2007 17:30:28 -0600 Subject: [SCSI] advansys: Make advansys_board_found a little more readable - Put all the error cleanup at the end of the function and goto the appropriate label - Split advansys_wide_init_chip out of advansys_board_found - Split advansys_wide_free_mem out of advansys_board_found. Use it from advansys_release - Use GFP_KERNEL, not GFP_ATOMIC, when allocating memory during initialisation - Eliminate lots of PROC_FS ifdefs by removing the ifdefs around the prtbuf struct member Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 394 +++++++++++++++++++----------------------------- 1 file changed, 158 insertions(+), 236 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 7a964bb..303dc98 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3825,10 +3825,8 @@ typedef struct asc_board { } eep_config; ulong last_reset; /* Saved last reset time */ spinlock_t lock; /* Board spinlock */ -#ifdef CONFIG_PROC_FS /* /proc/scsi/advansys/[0...] */ char *prtbuf; /* /proc print buffer */ -#endif /* CONFIG_PROC_FS */ #ifdef ADVANSYS_STATS struct asc_stats asc_stats; /* Board statistics */ #endif /* ADVANSYS_STATS */ @@ -3845,7 +3843,7 @@ typedef struct asc_board { */ void __iomem *ioremap_addr; /* I/O Memory remap address. */ ushort ioport; /* I/O Port address. */ - ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */ + ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */ adv_req_t *orig_reqp; /* adv_req_t memory block. */ adv_req_t *adv_reqp; /* Request structures. */ adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ @@ -17703,6 +17701,124 @@ static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) } } +static int __devinit +advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) +{ + int req_cnt = 0; + adv_req_t *reqp = NULL; + int sg_cnt = 0; + adv_sgblk_t *sgp; + int warn_code, err_code; + + /* + * Allocate buffer carrier structures. The total size + * is about 4 KB, so allocate all at once. + */ + boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); + ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp); + + if (!boardp->carrp) + goto kmalloc_failed; + + /* + * Allocate up to 'max_host_qng' request structures for the Wide + * board. The total size is about 16 KB, so allocate all at once. + * If the allocation fails decrement and try again. + */ + for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) { + reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); + + ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, " + "bytes %lu\n", reqp, req_cnt, + (ulong)sizeof(adv_req_t) * req_cnt); + + if (reqp) + break; + } + + if (!reqp) + goto kmalloc_failed; + + boardp->orig_reqp = reqp; + + /* + * Allocate up to ADV_TOT_SG_BLOCK request structures for + * the Wide board. Each structure is about 136 bytes. + */ + boardp->adv_sgblkp = NULL; + for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { + sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL); + + if (!sgp) + break; + + sgp->next_sgblkp = boardp->adv_sgblkp; + boardp->adv_sgblkp = sgp; + + } + + ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n", + sg_cnt, sizeof(adv_sgblk_t), + (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); + + if (!boardp->adv_sgblkp) + goto kmalloc_failed; + + adv_dvc_varp->carrier_buf = boardp->carrp; + + /* + * Point 'adv_reqp' to the request structures and + * link them together. + */ + req_cnt--; + reqp[req_cnt].next_reqp = NULL; + for (; req_cnt > 0; req_cnt--) { + reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; + } + boardp->adv_reqp = &reqp[0]; + + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n"); + warn_code = AdvInitAsc3550Driver(adv_dvc_varp); + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()" + "\n"); + warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); + } else { + ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()" + "\n"); + warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); + } + err_code = adv_dvc_varp->err_code; + + if (warn_code || err_code) { + ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x," + " error 0x%x\n", boardp->id, warn_code, err_code); + } + + goto exit; + + kmalloc_failed: + ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() " + "failed\n", boardp->id); + err_code = ADV_ERROR; + exit: + return err_code; +} + +static void advansys_wide_free_mem(asc_board_t *boardp) +{ + kfree(boardp->carrp); + boardp->carrp = NULL; + kfree(boardp->orig_reqp); + boardp->orig_reqp = boardp->adv_reqp = NULL; + while (boardp->adv_sgblkp) { + adv_sgblk_t *sgp = boardp->adv_sgblkp; + boardp->adv_sgblkp = sgp->next_sgblkp; + kfree(sgp); + } +} + static struct Scsi_Host *__devinit advansys_board_found(int iop, struct device *dev, int bus_type) { @@ -17711,7 +17827,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) asc_board_t *boardp; ASC_DVC_VAR *asc_dvc_varp = NULL; ADV_DVC_VAR *adv_dvc_varp = NULL; - adv_sgblk_t *sgp = NULL; int share_irq; int iolen = 0; ADV_PADDR pci_memory_address; @@ -17814,9 +17929,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_PRINT3 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", boardp->id, pci_memory_address, iolen); - scsi_unregister(shost); - asc_board_count--; - return NULL; + goto err_shost; } ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n", @@ -17846,13 +17959,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Allocate buffer for printing information from * /proc/scsi/advansys/[0...]. */ - if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) { - ASC_PRINT3 - ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n", - boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC); - scsi_unregister(shost); - asc_board_count--; - return NULL; + boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); + if (!boardp->prtbuf) { + ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " + "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); + goto err_unmap; } #endif /* CONFIG_PROC_FS */ @@ -17978,14 +18089,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) } } - if (err_code != 0) { -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - scsi_unregister(shost); - asc_board_count--; - return NULL; - } + if (err_code != 0) + goto err_free_proc; /* * Save the EEPROM configuration so that it can be displayed @@ -18067,12 +18172,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", boardp->id, asc_dvc_varp->init_state, asc_dvc_varp->err_code); -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - scsi_unregister(shost); - asc_board_count--; - return NULL; + goto err_free_proc; } /* @@ -18276,10 +18376,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) /* BIOS start address. */ if (ASC_NARROW_BOARD(boardp)) { - shost->base = ((ulong) - AscGetChipBiosAddress(asc_dvc_varp-> - iop_base, - asc_dvc_varp->bus_type)); + shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base, + asc_dvc_varp->bus_type); } else { /* * Fill-in BIOS board variables. The Wide BIOS saves @@ -18337,12 +18435,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_PRINT3 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n", boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port); -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - scsi_unregister(shost); - asc_board_count--; - return NULL; + goto err_free_proc; } /* Register DMA Channel for Narrow boards. */ @@ -18352,19 +18445,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) /* Register DMA channel for ISA bus. */ if (asc_dvc_varp->bus_type & ASC_IS_ISA) { shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; - if ((ret = - request_dma(shost->dma_channel, "advansys")) != 0) { + ret = request_dma(shost->dma_channel, "advansys"); + if (ret) { ASC_PRINT3 ("advansys_board_found: board %d: request_dma() %d failed %d\n", boardp->id, shost->dma_channel, ret); - release_region(shost->io_port, - boardp->asc_n_io_port); -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - scsi_unregister(shost); - asc_board_count--; - return NULL; + goto err_free_region; } AscEnableIsaDma(shost->dma_channel); } @@ -18391,17 +18477,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", boardp->id, shost->irq, ret); } - release_region(shost->io_port, boardp->asc_n_io_port); - iounmap(boardp->ioremap_addr); - if (shost->dma_channel != NO_ISA_DMA) { - free_dma(shost->dma_channel); - } -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - scsi_unregister(shost); - asc_board_count--; - return NULL; + goto err_free_dma; } /* @@ -18419,173 +18495,33 @@ advansys_board_found(int iop, struct device *dev, int bus_type) asc_dvc_varp->init_state, warn_code, err_code); } } else { - ADV_CARR_T *carrp; - int req_cnt = 0; - adv_req_t *reqp = NULL; - int sg_cnt = 0; - - /* - * Allocate buffer carrier structures. The total size - * is about 4 KB, so allocate all at once. - */ - carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC); - ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp); - - if (carrp == NULL) { - goto kmalloc_error; - } - - /* - * Allocate up to 'max_host_qng' request structures for - * the Wide board. The total size is about 16 KB, so - * allocate all at once. If the allocation fails decrement - * and try again. - */ - for (req_cnt = adv_dvc_varp->max_host_qng; - req_cnt > 0; req_cnt--) { - - reqp = (adv_req_t *) - kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC); - - ASC_DBG3(1, - "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n", - (ulong)reqp, req_cnt, - (ulong)sizeof(adv_req_t) * req_cnt); - - if (reqp != NULL) { - break; - } - } - if (reqp == NULL) { - goto kmalloc_error; - } - - /* - * Allocate up to ADV_TOT_SG_BLOCK request structures for - * the Wide board. Each structure is about 136 bytes. - */ - boardp->adv_sgblkp = NULL; - for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { - - sgp = (adv_sgblk_t *) - kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC); - - if (sgp == NULL) { - break; - } - - sgp->next_sgblkp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgp; - - } - ASC_DBG3(1, - "advansys_board_found: sg_cnt %d * %u = %u bytes\n", - sg_cnt, sizeof(adv_sgblk_t), - (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); - - /* - * If no request structures or scatter-gather structures could - * be allocated, then return an error. Otherwise continue with - * initialization. - */ - kmalloc_error: - if (carrp == NULL) { - ASC_PRINT1 - ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n", - boardp->id); - err_code = ADV_ERROR; - } else if (reqp == NULL) { - kfree(carrp); - ASC_PRINT1 - ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n", - boardp->id); - err_code = ADV_ERROR; - } else if (boardp->adv_sgblkp == NULL) { - kfree(carrp); - kfree(reqp); - ASC_PRINT1 - ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n", - boardp->id); - err_code = ADV_ERROR; - } else { - - /* Save carrier buffer pointer. */ - boardp->orig_carrp = carrp; - - /* - * Save original pointer for kfree() in case the - * driver is built as a module and can be unloaded. - */ - boardp->orig_reqp = reqp; - - adv_dvc_varp->carrier_buf = carrp; - - /* - * Point 'adv_reqp' to the request structures and - * link them together. - */ - req_cnt--; - reqp[req_cnt].next_reqp = NULL; - for (; req_cnt > 0; req_cnt--) { - reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; - } - boardp->adv_reqp = &reqp[0]; - - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - ASC_DBG(2, - "advansys_board_found: AdvInitAsc3550Driver()\n"); - warn_code = AdvInitAsc3550Driver(adv_dvc_varp); - } else if (adv_dvc_varp->chip_type == - ADV_CHIP_ASC38C0800) { - ASC_DBG(2, - "advansys_board_found: AdvInitAsc38C0800Driver()\n"); - warn_code = - AdvInitAsc38C0800Driver(adv_dvc_varp); - } else { - ASC_DBG(2, - "advansys_board_found: AdvInitAsc38C1600Driver()\n"); - warn_code = - AdvInitAsc38C1600Driver(adv_dvc_varp); - } - err_code = adv_dvc_varp->err_code; - - if (warn_code || err_code) { - ASC_PRINT3 - ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n", - boardp->id, warn_code, err_code); - } - } + err_code = advansys_wide_init_chip(boardp, adv_dvc_varp); } - if (err_code != 0) { - release_region(shost->io_port, boardp->asc_n_io_port); - if (ASC_WIDE_BOARD(boardp)) { - iounmap(boardp->ioremap_addr); - kfree(boardp->orig_carrp); - boardp->orig_carrp = NULL; - if (boardp->orig_reqp) { - kfree(boardp->orig_reqp); - boardp->orig_reqp = boardp->adv_reqp = NULL; - } - while ((sgp = boardp->adv_sgblkp) != NULL) { - boardp->adv_sgblkp = sgp->next_sgblkp; - kfree(sgp); - } - } - if (shost->dma_channel != NO_ISA_DMA) { - free_dma(shost->dma_channel); - } -#ifdef CONFIG_PROC_FS - kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ - free_irq(shost->irq, shost); - scsi_unregister(shost); - asc_board_count--; - return NULL; - } + if (err_code != 0) + goto err_free_wide_mem; + ASC_DBG_PRT_SCSI_HOST(2, shost); return shost; + + err_free_wide_mem: + advansys_wide_free_mem(boardp); + free_irq(shost->irq, shost); + err_free_dma: + if (shost->dma_channel != NO_ISA_DMA) + free_dma(shost->dma_channel); + err_free_region: + release_region(shost->io_port, boardp->asc_n_io_port); + err_free_proc: + kfree(boardp->prtbuf); + err_unmap: + if (boardp->ioremap_addr) + iounmap(boardp->ioremap_addr); + err_shost: + scsi_unregister(shost); + asc_board_count--; + return NULL; } /* @@ -18901,24 +18837,10 @@ static int advansys_release(struct Scsi_Host *shost) } release_region(shost->io_port, boardp->asc_n_io_port); if (ASC_WIDE_BOARD(boardp)) { - adv_sgblk_t *sgp = NULL; - iounmap(boardp->ioremap_addr); - kfree(boardp->orig_carrp); - boardp->orig_carrp = NULL; - if (boardp->orig_reqp) { - kfree(boardp->orig_reqp); - boardp->orig_reqp = boardp->adv_reqp = NULL; - } - while ((sgp = boardp->adv_sgblkp) != NULL) { - boardp->adv_sgblkp = sgp->next_sgblkp; - kfree(sgp); - } + advansys_wide_free_mem(boardp); } -#ifdef CONFIG_PROC_FS - ASC_ASSERT(boardp->prtbuf != NULL); kfree(boardp->prtbuf); -#endif /* CONFIG_PROC_FS */ scsi_unregister(shost); ASC_DBG(1, "advansys_release: end\n"); return 0; -- cgit v1.1 From 8dfb537933a87588e83196d14cd9ec245eb065b8 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 09:08:34 -0600 Subject: [SCSI] advansys: Move to scsi hotplug initialisation model - Switch from scsi_register/scsi_unregister to scsi_host_alloc, scsi_add_host, scsi_scan_host and scsi_host_put. - Rename the scsi_host_template to advansys_template - Use module_init and module_exit instead of scsi_module.c - Remove protection against advansys_detect being called twice Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 61 +++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 303dc98..8353680 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3793,7 +3793,7 @@ typedef struct adv_req { /* * Structure allocated for each board. * - * This structure is allocated by scsi_register() at the end + * This structure is allocated by scsi_host_alloc() at the end * of the 'Scsi_Host' structure starting at the 'hostdata' * field. It is guaranteed to be allocated from DMA-able memory. */ @@ -4632,17 +4632,12 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, return 0; } -static int __init advansys_detect(struct scsi_host_template *tpnt); -static int advansys_release(struct Scsi_Host *shp); - -static struct scsi_host_template driver_template = { +static struct scsi_host_template advansys_template = { .proc_name = "advansys", #ifdef CONFIG_PROC_FS .proc_info = advansys_proc_info, #endif .name = "advansys", - .detect = advansys_detect, - .release = advansys_release, .info = advansys_info, .queuecommand = advansys_queuecommand, .eh_bus_reset_handler = advansys_reset, @@ -4650,8 +4645,8 @@ static struct scsi_host_template driver_template = { .slave_configure = advansys_slave_configure, /* * Because the driver may control an ISA adapter 'unchecked_isa_dma' - * must be set. The flag will be cleared in advansys_detect for non-ISA - * adapters. Refer to the comment in scsi_module.c for more information. + * must be set. The flag will be cleared in advansys_board_found + * for non-ISA adapters. */ .unchecked_isa_dma = 1, /* @@ -4664,8 +4659,6 @@ static struct scsi_host_template driver_template = { .use_clustering = ENABLE_CLUSTERING, }; -#include "scsi_module.c" - /* * --- Miscellaneous Driver Functions */ @@ -17839,8 +17832,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Register the adapter, get its configuration, and * initialize it. */ - ASC_DBG(2, "advansys_board_found: scsi_register()\n"); - shost = scsi_register(&driver_template, sizeof(asc_board_t)); + ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n"); + shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t)); if (!shost) return NULL; @@ -18503,6 +18496,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_DBG_PRT_SCSI_HOST(2, shost); + ret = scsi_add_host(shost, dev); + if (ret) + goto err_free_wide_mem; + + scsi_scan_host(shost); return shost; err_free_wide_mem: @@ -18519,7 +18517,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (boardp->ioremap_addr) iounmap(boardp->ioremap_addr); err_shost: - scsi_unregister(shost); + scsi_host_put(shost); asc_board_count--; return NULL; } @@ -18537,9 +18535,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * it must not call SCSI mid-level functions including scsi_malloc() * and scsi_free(). */ -static int __init advansys_detect(struct scsi_host_template *tpnt) +static int __init advansys_detect(void) { - static int detect_called = ASC_FALSE; int iop; int bus; int ioport = 0; @@ -18561,14 +18558,6 @@ static int __init advansys_detect(struct scsi_host_template *tpnt) }; #endif /* CONFIG_PCI */ - if (detect_called == ASC_FALSE) { - detect_called = ASC_TRUE; - } else { - printk - ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n"); - return 0; - } - ASC_DBG(1, "advansys_detect: begin\n"); asc_board_count = 0; @@ -18829,6 +18818,7 @@ static int advansys_release(struct Scsi_Host *shost) asc_board_t *boardp; ASC_DBG(1, "advansys_release: begin\n"); + scsi_remove_host(shost); boardp = ASC_BOARDP(shost); free_irq(shost->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { @@ -18841,7 +18831,7 @@ static int advansys_release(struct Scsi_Host *shost) advansys_wide_free_mem(boardp); } kfree(boardp->prtbuf); - scsi_unregister(shost); + scsi_host_put(shost); ASC_DBG(1, "advansys_release: end\n"); return 0; } @@ -18867,4 +18857,25 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); #endif /* CONFIG_PCI */ +static int __init advansys_init(void) +{ + int count; + count = advansys_detect(); + if (count == 0) + return -ENODEV; + + return 0; +} + +static void __exit advansys_exit(void) +{ + int i; + + for (i = 0; i < asc_board_count; i++) + advansys_release(asc_host[i]); +} + +module_init(advansys_init); +module_exit(advansys_exit); + MODULE_LICENSE("GPL"); -- cgit v1.1 From 78e77d8b50633241d34cd9e64626d39d0a8cd2c0 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 29 Jul 2007 21:46:15 -0600 Subject: [SCSI] advansys: Convert to PCI driver model - Add a pci_driver interface for the PCI advansys devices (for ISA/EISA/VLB devices, we still call advansys_detect). - Many functions are converted from __init to __devinit to allow hotplug PCI to work. - Only keep devices found by advansys_detect in the asc_host list. - Rename asc_board_count to asc_legacy_count. New asc_board_count is only used to generate a unique name for each device. - Remove some now-unused macros and struct definitions Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 378 +++++++++++++++++------------------------------- 1 file changed, 129 insertions(+), 249 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 8353680..3ba7032 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -865,12 +865,8 @@ typedef unsigned char uchar; #define AscPCIConfigLatencyTimer 0x000D #define AscPCIIOBaseRegister 0x0010 #define AscPCICmdRegBits_IOMemBusMaster 0x0007 -#define ASC_PCI_ID2BUS(id) ((id) & 0xFF) -#define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F) #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) -#define ASC_PCI_REVISION_3150 0x02 -#define ASC_PCI_REVISION_3050 0x03 #define ASC_DVCLIB_CALL_DONE (1) #define ASC_DVCLIB_CALL_FAILED (0) @@ -3422,7 +3418,7 @@ typedef struct { #define ASC_NUM_BOARD_SUPPORTED 16 #define ASC_NUM_IOPORT_PROBE 4 -#define ASC_NUM_BUS 4 +#define ASC_NUM_BUS 3 /* Reference Scsi_Host hostdata */ #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) @@ -3526,11 +3522,6 @@ typedef struct scsi_cmnd REQ, *REQP; /* Return non-zero, if the queue is empty. */ #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) -#define PCI_MAX_SLOT 0x1F -#define PCI_MAX_BUS 0xFF -#define PCI_IOADDRESS_MASK 0xFFFE -#define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */ - #ifndef ADVANSYS_STATS #define ASC_STATS(shost, counter) #define ASC_STATS_ADD(shost, counter, count) @@ -3853,60 +3844,11 @@ typedef struct asc_board { ushort bios_codelen; /* BIOS Code Segment Length. */ } asc_board_t; -/* - * PCI configuration structures - */ -typedef struct _PCI_DATA_ { - uchar type; - uchar bus; - uchar slot; - uchar func; - uchar offset; -} PCI_DATA; - -typedef struct _PCI_DEVICE_ { - ushort vendorID; - ushort deviceID; - ushort slotNumber; - ushort slotFound; - uchar busNumber; - uchar maxBusNumber; - uchar devFunc; - ushort startSlot; - ushort endSlot; - uchar bridge; - uchar type; -} PCI_DEVICE; - -typedef struct _PCI_CONFIG_SPACE_ { - ushort vendorID; - ushort deviceID; - ushort command; - ushort status; - uchar revision; - uchar classCode[3]; - uchar cacheSize; - uchar latencyTimer; - uchar headerType; - uchar bist; - ADV_PADDR baseAddress[6]; - ushort reserved[4]; - ADV_PADDR optionRomAddr; - ushort reserved2[4]; - uchar irqLine; - uchar irqPin; - uchar minGnt; - uchar maxLatency; -} PCI_CONFIG_SPACE; - -/* - * --- Driver Data - */ - -/* Note: All driver global data should be initialized. */ - /* Number of boards detected in system. */ -static int asc_board_count = 0; +static int asc_board_count; + +/* Number of boards detected by advansys_detect */ +static int asc_legacy_count; static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL }; /* Overrun buffer used by all narrow boards. */ @@ -3918,12 +3860,11 @@ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; static ASC_SCSI_Q asc_scsi_q = { {0} }; static ASC_SG_HEAD asc_sg_head = { 0 }; -/* List of supported bus types. */ +/* List of bus types probed in advansys_detect. */ static ushort asc_bus[ASC_NUM_BUS] __initdata = { ASC_IS_ISA, ASC_IS_VL, ASC_IS_EISA, - ASC_IS_PCI, }; static int asc_iopflag = ASC_FALSE; @@ -3934,7 +3875,6 @@ static char *asc_bus_name[ASC_NUM_BUS] = { "ASC_IS_ISA", "ASC_IS_VL", "ASC_IS_EISA", - "ASC_IS_PCI", }; static int asc_dbglvl = 3; @@ -7441,7 +7381,7 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) /* * Read a PCI configuration byte. */ -static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset) +static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset) { #ifdef CONFIG_PCI uchar byte_data; @@ -7455,7 +7395,7 @@ static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset) /* * Write a PCI configuration byte. */ -static void __init +static void __devinit DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) { #ifdef CONFIG_PCI @@ -7467,7 +7407,7 @@ DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ -static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type) +static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type) { ushort cfg_lsw; ushort bios_addr; @@ -7538,7 +7478,7 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, /* * Read a PCI configuration byte. */ -static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset) +static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset) { #ifdef CONFIG_PCI uchar byte_data; @@ -7552,7 +7492,7 @@ static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset) /* * Write a PCI configuration byte. */ -static void __init +static void __devinit DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) { #ifdef CONFIG_PCI @@ -8148,7 +8088,7 @@ static void asc_prt_hex(char *f, uchar *s, int l) * --- Asc Library Functions */ -static ushort __init AscGetEisaChipCfg(PortAddr iop_base) +static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base) { PortAddr eisa_cfg_iop; @@ -8157,7 +8097,7 @@ static ushort __init AscGetEisaChipCfg(PortAddr iop_base) return (inpw(eisa_cfg_iop)); } -static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) +static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) { ushort cfg_lsw; @@ -8171,7 +8111,7 @@ static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) return (AscGetChipScsiID(iop_base)); } -static uchar __init AscGetChipScsiCtrl(PortAddr iop_base) +static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base) { uchar sc; @@ -8181,7 +8121,7 @@ static uchar __init AscGetChipScsiCtrl(PortAddr iop_base) return (sc); } -static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type) +static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type) { if ((bus_type & ASC_IS_EISA) != 0) { PortAddr eisa_iop; @@ -8194,7 +8134,7 @@ static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type) return (AscGetChipVerNo(iop_base)); } -static ushort __init AscGetChipBusType(PortAddr iop_base) +static ushort __devinit AscGetChipBusType(PortAddr iop_base) { ushort chip_ver; @@ -8346,14 +8286,14 @@ static void __init AscSetISAPNPWaitForKey(void) } #endif /* CONFIG_ISA */ -static void __init AscToggleIRQAct(PortAddr iop_base) +static void __devinit AscToggleIRQAct(PortAddr iop_base) { AscSetChipStatus(iop_base, CIW_IRQ_ACT); AscSetChipStatus(iop_base, 0); return; } -static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type) +static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type) { ushort cfg_lsw; uchar chip_irq; @@ -8381,7 +8321,7 @@ static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type) return ((uchar)(chip_irq + ASC_MIN_IRQ_NO)); } -static uchar __init +static uchar __devinit AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) { ushort cfg_lsw; @@ -8418,7 +8358,7 @@ AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) } #ifdef CONFIG_ISA -static void __init AscEnableIsaDma(uchar dma_channel) +static void __devinit AscEnableIsaDma(uchar dma_channel) { if (dma_channel < 4) { outp(0x000B, (ushort)(0xC0 | dma_channel)); @@ -10500,7 +10440,7 @@ static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) return (AscIsChipHalted(iop_base)); } -static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type) +static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type) { if (bus_type & ASC_IS_ISA) return (ASC_MAX_ISA_DMA_COUNT); @@ -10510,7 +10450,7 @@ static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type) } #ifdef CONFIG_ISA -static ushort __init AscGetIsaDmaChannel(PortAddr iop_base) +static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base) { ushort channel; @@ -10522,7 +10462,7 @@ static ushort __init AscGetIsaDmaChannel(PortAddr iop_base) return (channel + 4); } -static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) +static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) { ushort cfg_lsw; uchar value; @@ -10540,7 +10480,7 @@ static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) return (0); } -static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) +static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) { speed_value &= 0x07; AscSetBank(iop_base, 1); @@ -10549,7 +10489,7 @@ static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) return (AscGetIsaDmaSpeed(iop_base)); } -static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base) +static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) { uchar speed_value; @@ -10561,7 +10501,7 @@ static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base) } #endif /* CONFIG_ISA */ -static ushort __init +static ushort __devinit AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset) { uchar lsb, msb; @@ -10571,7 +10511,7 @@ AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset) return ((ushort)((msb << 8) | lsb)); } -static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc) +static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) { ushort warn_code; PortAddr iop_base; @@ -10656,7 +10596,7 @@ static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc) +static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc) { ushort warn_code = 0; @@ -10672,7 +10612,7 @@ static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) +static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) { PortAddr iop_base; ushort cfg_msw; @@ -10773,7 +10713,7 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) +static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) { int i; PortAddr iop_base; @@ -10885,7 +10825,7 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc) +static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) { ASCEEP_CONFIG eep_config_buf; ASCEEP_CONFIG *eep_config; @@ -11106,7 +11046,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc) +static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) { PortAddr iop_base; ushort q_addr; @@ -11128,7 +11068,7 @@ static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc) return (sta); } -static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) +static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) { uchar read_back; int retry; @@ -11147,7 +11087,7 @@ static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) } } -static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) +static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) { ushort read_back; int retry; @@ -11166,19 +11106,19 @@ static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) } } -static void __init AscWaitEEPRead(void) +static void __devinit AscWaitEEPRead(void) { DvcSleepMilliSecond(1); return; } -static void __init AscWaitEEPWrite(void) +static void __devinit AscWaitEEPWrite(void) { DvcSleepMilliSecond(20); return; } -static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr) +static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr) { ushort read_wval; uchar cmd_reg; @@ -11193,7 +11133,7 @@ static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr) return (read_wval); } -static ushort __init +static ushort __devinit AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) { ushort read_wval; @@ -11214,7 +11154,7 @@ AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) return (read_wval); } -static ushort __init +static ushort __devinit AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) { ushort wval; @@ -11261,7 +11201,7 @@ AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) return (sum); } -static int __init +static int __devinit AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) { int n_error; @@ -11357,7 +11297,7 @@ AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) return (n_error); } -static int __init +static int __devinit AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) { int retry; @@ -13769,7 +13709,7 @@ static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian * on big-endian platforms so char fields read as words are actually being * unswapped on big-endian platforms. */ -static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = { +static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = { ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ 0x0000, /* cfg_msw */ 0xFFFF, /* disc_enable */ @@ -13807,7 +13747,7 @@ static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = { 0 /* num_of_err */ }; -static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = { +static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = { 0, /* cfg_lsw */ 0, /* cfg_msw */ 0, /* -disc_enable */ @@ -13845,7 +13785,7 @@ static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = { 0 /* num_of_err */ }; -static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = { +static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = { ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ 0x0000, /* 01 cfg_msw */ 0xFFFF, /* 02 disc_enable */ @@ -13910,7 +13850,7 @@ static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = { 0 /* 63 reserved */ }; -static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = { +static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = { 0, /* 00 cfg_lsw */ 0, /* 01 cfg_msw */ 0, /* 02 disc_enable */ @@ -13975,7 +13915,7 @@ static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = { 0 /* 63 reserved */ }; -static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = { +static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = { ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ 0x0000, /* 01 cfg_msw */ 0xFFFF, /* 02 disc_enable */ @@ -14040,7 +13980,7 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = { 0 /* 63 reserved */ }; -static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = { +static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = { 0, /* 00 cfg_lsw */ 0, /* 01 cfg_msw */ 0, /* 02 disc_enable */ @@ -14113,7 +14053,7 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = { * For a non-fatal error return a warning code. If there are no warnings * then 0 is returned. */ -static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) { ushort warn_code; AdvPortAddr iop_base; @@ -16057,7 +15997,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) * * Note: Chip is stopped on entry. */ -static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; @@ -16211,7 +16151,7 @@ static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) * * Note: Chip is stopped on entry. */ -static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; @@ -16414,7 +16354,7 @@ static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) * * Note: Chip is stopped on entry. */ -static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; @@ -16655,7 +16595,7 @@ static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) * * Return a checksum based on the EEPROM configuration read. */ -static ushort __init +static ushort __devinit AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { ushort wval, chksum; @@ -16698,7 +16638,7 @@ AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) * * Return a checksum based on the EEPROM configuration read. */ -static ushort __init +static ushort __devinit AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) { ushort wval, chksum; @@ -16741,7 +16681,7 @@ AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) * * Return a checksum based on the EEPROM configuration read. */ -static ushort __init +static ushort __devinit AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { ushort wval, chksum; @@ -16782,7 +16722,7 @@ AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) /* * Read the EEPROM from specified location */ -static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) +static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) { AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_READ | eep_word_addr); @@ -16793,7 +16733,7 @@ static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) /* * Wait for EEPROM command to complete */ -static void __init AdvWaitEEPCmd(AdvPortAddr iop_base) +static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base) { int eep_delay_ms; @@ -16814,7 +16754,7 @@ static void __init AdvWaitEEPCmd(AdvPortAddr iop_base) /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void __devinit AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { ushort *wbuf; @@ -16882,7 +16822,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void __devinit AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) { ushort *wbuf; @@ -16950,7 +16890,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void __devinit AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { ushort *wbuf; @@ -17838,13 +17778,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (!shost) return NULL; - /* Save a pointer to the Scsi_Host of each board found. */ - asc_host[asc_board_count++] = shost; - /* Initialize private per board data */ boardp = ASC_BOARDP(shost); memset(boardp, 0, sizeof(asc_board_t)); - boardp->id = asc_board_count - 1; + boardp->id = asc_board_count++; /* Initialize spinlock. */ spin_lock_init(&boardp->lock); @@ -18518,7 +18455,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) iounmap(boardp->ioremap_addr); err_shost: scsi_host_put(shost); - asc_board_count--; return NULL; } @@ -18540,27 +18476,11 @@ static int __init advansys_detect(void) int iop; int bus; int ioport = 0; - struct device *dev = NULL; -#ifdef CONFIG_PCI - int pci_init_search = 0; - struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED]; - int pci_card_cnt_max = 0; - int pci_card_cnt = 0; - struct pci_dev *pdev = NULL; - int pci_device_id_cnt = 0; - unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = { - PCI_DEVICE_ID_ASP_1200A, - PCI_DEVICE_ID_ASP_ABP940, - PCI_DEVICE_ID_ASP_ABP940U, - PCI_DEVICE_ID_ASP_ABP940UW, - PCI_DEVICE_ID_38C0800_REV1, - PCI_DEVICE_ID_38C1600_REV1 - }; -#endif /* CONFIG_PCI */ + struct Scsi_Host *shost; ASC_DBG(1, "advansys_detect: begin\n"); - asc_board_count = 0; + asc_legacy_count = 0; /* * If I/O port probing has been modified, then verify and @@ -18595,10 +18515,10 @@ static int __init advansys_detect(void) bus, asc_bus_name[bus]); iop = 0; - while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) { + while (asc_legacy_count < ASC_NUM_BOARD_SUPPORTED) { - ASC_DBG1(2, "advansys_detect: asc_board_count %d\n", - asc_board_count); + ASC_DBG1(2, "advansys_detect: asc_legacy_count %d\n", + asc_legacy_count); switch (asc_bus[bus]) { case ASC_IS_ISA: @@ -18693,97 +18613,6 @@ static int __init advansys_detect(void) #endif /* CONFIG_ISA */ break; - case ASC_IS_PCI: -#ifdef CONFIG_PCI - if (pci_init_search == 0) { - int i, j; - - pci_init_search = 1; - - /* Find all PCI cards. */ - while (pci_device_id_cnt < - ASC_PCI_DEVICE_ID_CNT) { - if ((pdev = - pci_find_device - (PCI_VENDOR_ID_ASP, - pci_device_id - [pci_device_id_cnt], - pdev)) == NULL) { - pci_device_id_cnt++; - } else { - if (pci_enable_device - (pdev) == 0) { - pci_devicep - [pci_card_cnt_max++] - = pdev; - } - } - } - - /* - * Sort PCI cards in ascending order by PCI Bus, Slot, - * and Device Number. - */ - for (i = 0; i < pci_card_cnt_max - 1; - i++) { - for (j = i + 1; - j < pci_card_cnt_max; - j++) { - if ((pci_devicep[j]-> - bus->number < - pci_devicep[i]-> - bus->number) - || - ((pci_devicep[j]-> - bus->number == - pci_devicep[i]-> - bus->number) - && - (pci_devicep[j]-> - devfn < - pci_devicep[i]-> - devfn))) { - pdev = - pci_devicep - [i]; - pci_devicep[i] = - pci_devicep - [j]; - pci_devicep[j] = - pdev; - } - } - } - - pci_card_cnt = 0; - } else { - pci_card_cnt++; - } - - if (pci_card_cnt == pci_card_cnt_max) { - iop = 0; - } else { - pdev = pci_devicep[pci_card_cnt]; - - ASC_DBG2(2, - "advansys_detect: devfn %d, bus number %d\n", - pdev->devfn, - pdev->bus->number); - iop = pci_resource_start(pdev, 0); - ASC_DBG2(1, - "advansys_detect: vendorID %X, deviceID %X\n", - pdev->vendor, - pdev->device); - ASC_DBG2(2, - "advansys_detect: iop %X, irqLine %d\n", - iop, pdev->irq); - } - if (pdev) - dev = &pdev->dev; - -#endif /* CONFIG_PCI */ - break; - default: ASC_PRINT1 ("advansys_detect: unknown bus type: %d\n", @@ -18795,17 +18624,19 @@ static int __init advansys_detect(void) /* * Adapter not found, try next bus type. */ - if (iop == 0) { + if (iop == 0) break; - } - advansys_board_found(iop, dev, asc_bus[bus]); + shost = advansys_board_found(iop, NULL, asc_bus[bus]); + if (shost) { + asc_host[asc_legacy_count++] = shost; + } } } - ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", - asc_board_count); - return asc_board_count; + ASC_DBG1(1, "advansys_detect: done: asc_legacy_count %d\n", + asc_legacy_count); + return asc_legacy_count; } /* @@ -18836,7 +18667,6 @@ static int advansys_release(struct Scsi_Host *shost) return 0; } -#ifdef CONFIG_PCI /* PCI Devices supported by this driver */ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A, @@ -18855,23 +18685,73 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); -#endif /* CONFIG_PCI */ + +static int __devinit +advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err, ioport; + struct Scsi_Host *shost; + + err = pci_enable_device(pdev); + if (err) + goto fail; + + if (pci_resource_len(pdev, 0) == 0) + goto nodev; + + ioport = pci_resource_start(pdev, 0); + shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI); + + if (!shost) + goto nodev; + + pci_set_drvdata(pdev, shost); + return 0; + + nodev: + err = -ENODEV; + pci_disable_device(pdev); + fail: + return err; +} + +static void __devexit advansys_pci_remove(struct pci_dev *pdev) +{ + advansys_release(pci_get_drvdata(pdev)); + pci_disable_device(pdev); +} + +static struct pci_driver advansys_pci_driver = { + .name = "advansys", + .id_table = advansys_pci_tbl, + .probe = advansys_pci_probe, + .remove = __devexit_p(advansys_pci_remove), +}; static int __init advansys_init(void) { - int count; - count = advansys_detect(); - if (count == 0) - return -ENODEV; + int i, error; + advansys_detect(); + error = pci_register_driver(&advansys_pci_driver); + if (error) + goto fail; return 0; + + fail: + for (i = 0; i < asc_legacy_count; i++) + advansys_release(asc_host[i]); + + return error; } static void __exit advansys_exit(void) { int i; - for (i = 0; i < asc_board_count; i++) + pci_unregister_driver(&advansys_pci_driver); + + for (i = 0; i < asc_legacy_count; i++) advansys_release(asc_host[i]); } -- cgit v1.1 From b09e05a73e8308397371edc15b7d45082971fa95 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 09:14:52 -0600 Subject: [SCSI] advansys: Convert to EISA driver model - Switch EISA probing to the driver model - Remove some now-unused macros and functions - Update the FIXME now that we use the correct driver model probing API Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 175 ++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 81 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 3ba7032..e096f19 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -769,6 +769,7 @@ #include #include #include +#include #include #include #include @@ -783,13 +784,9 @@ #include #include -/* FIXME: (by jejb@steeleye.com) This warning is present for two - * reasons: +/* FIXME: (by jejb@steeleye.com) * - * 1) This driver badly needs converting to the correct driver model - * probing API - * - * 2) Although all of the necessary command mapping places have the + * Although all of the necessary command mapping places have the * appropriate dma_map.. APIs, the driver still processes its internal * queue using bus_to_virt() and virt_to_bus() which are illegal under * the API. The entire queue processing structure will need to be @@ -1787,16 +1784,10 @@ typedef struct asceep_config { #define ASC_1000_ID0W 0x04C1 #define ASC_1000_ID0W_FIX 0x00C1 #define ASC_1000_ID1B 0x25 -#define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50) -#define ASC_EISA_SMALL_IOP_GAP (0x0020) -#define ASC_EISA_MIN_IOP_ADDR (0x0C30) -#define ASC_EISA_MAX_IOP_ADDR (0xFC50) #define ASC_EISA_REV_IOP_MASK (0x0C83) #define ASC_EISA_PID_IOP_MASK (0x0C80) #define ASC_EISA_CFG_IOP_MASK (0x0C86) #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) -#define ASC_EISA_ID_740 0x01745004UL -#define ASC_EISA_ID_750 0x01755004UL #define INS_HALTINT (ushort)0x6281 #define INS_HALT (ushort)0x6280 #define INS_SINT (ushort)0x6200 @@ -1943,8 +1934,6 @@ static int AscIsrQDone(ASC_DVC_VAR *); static int AscCompareString(uchar *, uchar *, int); #ifdef CONFIG_ISA static ushort AscGetEisaChipCfg(PortAddr); -static ASC_DCNT AscGetEisaProductID(PortAddr); -static PortAddr AscSearchIOPortAddrEISA(PortAddr); static PortAddr AscSearchIOPortAddr11(PortAddr); static PortAddr AscSearchIOPortAddr(PortAddr, ushort); static void AscSetISAPNPWaitForKey(void); @@ -3418,7 +3407,7 @@ typedef struct { #define ASC_NUM_BOARD_SUPPORTED 16 #define ASC_NUM_IOPORT_PROBE 4 -#define ASC_NUM_BUS 3 +#define ASC_NUM_BUS 2 /* Reference Scsi_Host hostdata */ #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) @@ -3864,7 +3853,6 @@ static ASC_SG_HEAD asc_sg_head = { 0 }; static ushort asc_bus[ASC_NUM_BUS] __initdata = { ASC_IS_ISA, ASC_IS_VL, - ASC_IS_EISA, }; static int asc_iopflag = ASC_FALSE; @@ -3874,7 +3862,6 @@ static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 }; static char *asc_bus_name[ASC_NUM_BUS] = { "ASC_IS_ISA", "ASC_IS_VL", - "ASC_IS_EISA", }; static int asc_dbglvl = 3; @@ -8241,12 +8228,6 @@ static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type) } return (0); } - if (bus_type & ASC_IS_EISA) { - if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) { - return (iop_beg); - } - return (0); - } return (0); } @@ -10256,57 +10237,6 @@ static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec) udelay((nano_sec + 999) / 1000); } -#ifdef CONFIG_ISA -static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base) -{ - PortAddr eisa_iop; - ushort product_id_high, product_id_low; - ASC_DCNT product_id; - - eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK; - product_id_low = inpw(eisa_iop); - product_id_high = inpw(eisa_iop + 2); - product_id = ((ASC_DCNT) product_id_high << 16) | - (ASC_DCNT) product_id_low; - return (product_id); -} - -static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base) -{ - ASC_DCNT eisa_product_id; - - if (iop_base == 0) { - iop_base = ASC_EISA_MIN_IOP_ADDR; - } else { - if (iop_base == ASC_EISA_MAX_IOP_ADDR) - return (0); - if ((iop_base & 0x0050) == 0x0050) { - iop_base += ASC_EISA_BIG_IOP_GAP; - } else { - iop_base += ASC_EISA_SMALL_IOP_GAP; - } - } - while (iop_base <= ASC_EISA_MAX_IOP_ADDR) { - eisa_product_id = AscGetEisaProductID(iop_base); - if ((eisa_product_id == ASC_EISA_ID_740) || - (eisa_product_id == ASC_EISA_ID_750)) { - if (AscFindSignature(iop_base)) { - inpw(iop_base + 4); - return (iop_base); - } - } - if (iop_base == ASC_EISA_MAX_IOP_ADDR) - return (0); - if ((iop_base & 0x0050) == 0x0050) { - iop_base += ASC_EISA_BIG_IOP_GAP; - } else { - iop_base += ASC_EISA_SMALL_IOP_GAP; - } - } - return (0); -} -#endif /* CONFIG_ISA */ - static int AscStartChip(PortAddr iop_base) { AscSetChipControl(iop_base, 0); @@ -18607,12 +18537,6 @@ static int __init advansys_detect(void) #endif /* CONFIG_ISA */ break; - case ASC_IS_EISA: -#ifdef CONFIG_ISA - iop = AscSearchIOPortAddr(iop, asc_bus[bus]); -#endif /* CONFIG_ISA */ - break; - default: ASC_PRINT1 ("advansys_detect: unknown bus type: %d\n", @@ -18667,6 +18591,87 @@ static int advansys_release(struct Scsi_Host *shost) return 0; } +static struct eisa_device_id advansys_eisa_table[] __devinitdata = { + { "ABP7401" }, + { "ABP7501" }, + { "" } +}; + +MODULE_DEVICE_TABLE(eisa, advansys_eisa_table); + +/* + * EISA is a little more tricky than PCI; each EISA device may have two + * channels, and this driver is written to make each channel its own Scsi_Host + */ +struct eisa_scsi_data { + struct Scsi_Host *host[2]; +}; + +static int __devinit advansys_eisa_probe(struct device *dev) +{ + int i, ioport; + int err; + struct eisa_device *edev = to_eisa_device(dev); + struct eisa_scsi_data *data; + + err = -ENOMEM; + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + goto fail; + ioport = edev->base_addr + 0xc30; + + err = -ENODEV; + for (i = 0; i < 2; i++, ioport += 0x20) { + if (!AscFindSignature(ioport)) + continue; + /* + * I don't know why we need to do this for EISA chips, but + * not for any others. It looks to be equivalent to + * AscGetChipCfgMsw, but I may have overlooked something, + * so I'm not converting it until I get an EISA board to + * test with. + */ + inw(ioport + 4); + data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA); + if (data->host[i]) + err = 0; + } + + if (err) { + kfree(data); + } else { + dev_set_drvdata(dev, data); + } + + fail: + return err; +} + +static __devexit int advansys_eisa_remove(struct device *dev) +{ + int i; + struct eisa_scsi_data *data = dev_get_drvdata(dev); + + for (i = 0; i < 2; i++) { + struct Scsi_Host *shost = data->host[i]; + if (!shost) + continue; + advansys_release(shost); + } + + kfree(data); + return 0; +} + +static struct eisa_driver advansys_eisa_driver = { + .id_table = advansys_eisa_table, + .driver = { + .name = "advansys", + .probe = advansys_eisa_probe, + .remove = __devexit_p(advansys_eisa_remove), + } +}; + /* PCI Devices supported by this driver */ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A, @@ -18732,12 +18737,19 @@ static int __init advansys_init(void) { int i, error; advansys_detect(); - error = pci_register_driver(&advansys_pci_driver); + + error = eisa_driver_register(&advansys_eisa_driver); if (error) goto fail; + error = pci_register_driver(&advansys_pci_driver); + if (error) + goto unregister_eisa; + return 0; + unregister_eisa: + eisa_driver_unregister(&advansys_eisa_driver); fail: for (i = 0; i < asc_legacy_count; i++) advansys_release(asc_host[i]); @@ -18750,6 +18762,7 @@ static void __exit advansys_exit(void) int i; pci_unregister_driver(&advansys_pci_driver); + eisa_driver_unregister(&advansys_eisa_driver); for (i = 0; i < asc_legacy_count; i++) advansys_release(asc_host[i]); -- cgit v1.1 From c304ec94733aec764396813f3f05dfbe02f4a6da Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 09:18:45 -0600 Subject: [SCSI] advansys: Convert to ISA driver model Register two isa_drivers, one for ISA and one for VLB, in order to preserve detection order. When deleting advansys_detect, we lose the last vestiges of the code that limited IO port scanning. This code has been effectively disabled for many years anyway; I'll restore it in a module_param later. We also lose the code that placed all ISA PnP cards into WaitForKey state -- drivers shouldn't be doing this anyway. The asc_host array goes away too. Also remove some IOADR and other definitions, such as ASC_NUM_BOARD_SUPPORTED. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 412 +++++++++++++----------------------------------- 1 file changed, 113 insertions(+), 299 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e096f19..eda41f2 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -280,7 +280,7 @@ AdvanSys SCSI adapter files have the following path name format: - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] + /proc/scsi/advansys/{0,1,2,3,...} This information can be displayed with cat. For example: @@ -769,6 +769,7 @@ #include #include #include +#include #include #include #include @@ -1362,18 +1363,6 @@ typedef struct asc_risc_sg_list_q { #define ASC_MAX_INRAM_TAG_QNG 16 #define ASC_IOADR_TABLE_MAX_IX 11 #define ASC_IOADR_GAP 0x10 -#define ASC_SEARCH_IOP_GAP 0x10 -#define ASC_MIN_IOP_ADDR (PortAddr)0x0100 -#define ASC_MAX_IOP_ADDR (PortAddr)0x3F0 -#define ASC_IOADR_1 (PortAddr)0x0110 -#define ASC_IOADR_2 (PortAddr)0x0130 -#define ASC_IOADR_3 (PortAddr)0x0150 -#define ASC_IOADR_4 (PortAddr)0x0190 -#define ASC_IOADR_5 (PortAddr)0x0210 -#define ASC_IOADR_6 (PortAddr)0x0230 -#define ASC_IOADR_7 (PortAddr)0x0250 -#define ASC_IOADR_8 (PortAddr)0x0330 -#define ASC_IOADR_DEF ASC_IOADR_8 #define ASC_LIB_SCSIQ_WK_SP 256 #define ASC_MAX_SYN_XFER_NO 16 #define ASC_SYN_MAX_OFFSET 0x0F @@ -1934,9 +1923,6 @@ static int AscIsrQDone(ASC_DVC_VAR *); static int AscCompareString(uchar *, uchar *, int); #ifdef CONFIG_ISA static ushort AscGetEisaChipCfg(PortAddr); -static PortAddr AscSearchIOPortAddr11(PortAddr); -static PortAddr AscSearchIOPortAddr(PortAddr, ushort); -static void AscSetISAPNPWaitForKey(void); #endif /* CONFIG_ISA */ static uchar AscGetChipScsiCtrl(PortAddr); static uchar AscSetChipScsiID(PortAddr, uchar); @@ -3405,10 +3391,6 @@ typedef struct { * --- Driver Constants and Macros */ -#define ASC_NUM_BOARD_SUPPORTED 16 -#define ASC_NUM_IOPORT_PROBE 4 -#define ASC_NUM_BUS 2 - /* Reference Scsi_Host hostdata */ #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) @@ -3836,10 +3818,6 @@ typedef struct asc_board { /* Number of boards detected in system. */ static int asc_board_count; -/* Number of boards detected by advansys_detect */ -static int asc_legacy_count; -static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL }; - /* Overrun buffer used by all narrow boards. */ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; @@ -3849,27 +3827,10 @@ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; static ASC_SCSI_Q asc_scsi_q = { {0} }; static ASC_SG_HEAD asc_sg_head = { 0 }; -/* List of bus types probed in advansys_detect. */ -static ushort asc_bus[ASC_NUM_BUS] __initdata = { - ASC_IS_ISA, - ASC_IS_VL, -}; - -static int asc_iopflag = ASC_FALSE; -static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 }; - #ifdef ADVANSYS_DEBUG -static char *asc_bus_name[ASC_NUM_BUS] = { - "ASC_IS_ISA", - "ASC_IS_VL", -}; - static int asc_dbglvl = 3; #endif /* ADVANSYS_DEBUG */ -/* Declaration for Asc Library internal data referenced by driver. */ -static PortAddr _asc_def_iop_base[]; - /* * --- Driver Function Prototypes * @@ -3932,7 +3893,7 @@ static void asc_prt_hex(char *f, uchar *, int); #ifdef CONFIG_PROC_FS /* - * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] + * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...} * * *buffer: I/O buffer * **start: if inout == FALSE pointer into buffer where user read should start @@ -8196,77 +8157,6 @@ static int AscFindSignature(PortAddr iop_base) return (0); } -static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = { - 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4, - ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 -}; - -#ifdef CONFIG_ISA -static uchar _isa_pnp_inited __initdata = 0; - -static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type) -{ - if (bus_type & ASC_IS_VL) { - while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { - if (AscGetChipVersion(iop_beg, bus_type) <= - ASC_CHIP_MAX_VER_VL) { - return (iop_beg); - } - } - return (0); - } - if (bus_type & ASC_IS_ISA) { - if (_isa_pnp_inited == 0) { - AscSetISAPNPWaitForKey(); - _isa_pnp_inited++; - } - while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { - if ((AscGetChipVersion(iop_beg, bus_type) & - ASC_CHIP_VER_ISA_BIT) != 0) { - return (iop_beg); - } - } - return (0); - } - return (0); -} - -static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr) -{ - int i; - PortAddr iop_base; - - for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) { - if (_asc_def_iop_base[i] > s_addr) { - break; - } - } - for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { - iop_base = _asc_def_iop_base[i]; - if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { - ASC_DBG1(1, - "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n", - iop_base); - continue; - } - ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", - iop_base); - release_region(iop_base, ASC_IOADR_GAP); - if (AscFindSignature(iop_base)) { - return (iop_base); - } - } - return (0); -} - -static void __init AscSetISAPNPWaitForKey(void) -{ - outp(ASC_ISA_PNP_PORT_ADDR, 0x02); - outp(ASC_ISA_PNP_PORT_WRITE, 0x02); - return; -} -#endif /* CONFIG_ISA */ - static void __devinit AscToggleIRQAct(PortAddr iop_base) { AscSetChipStatus(iop_base, CIW_IRQ_ACT); @@ -18389,181 +18279,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) } /* - * advansys_detect() - * - * Detect function for AdvanSys adapters. - * - * Argument is a pointer to the host driver's scsi_hosts entry. - * - * Return number of adapters found. - * - * Note: Because this function is called during system initialization - * it must not call SCSI mid-level functions including scsi_malloc() - * and scsi_free(). - */ -static int __init advansys_detect(void) -{ - int iop; - int bus; - int ioport = 0; - struct Scsi_Host *shost; - - ASC_DBG(1, "advansys_detect: begin\n"); - - asc_legacy_count = 0; - - /* - * If I/O port probing has been modified, then verify and - * clean-up the 'asc_ioport' list. - */ - if (asc_iopflag == ASC_TRUE) { - for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { - ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n", - ioport, asc_ioport[ioport]); - if (asc_ioport[ioport] != 0) { - for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; - iop++) { - if (_asc_def_iop_base[iop] == - asc_ioport[ioport]) { - break; - } - } - if (iop == ASC_IOADR_TABLE_MAX_IX) { - printk - ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n", - asc_ioport[ioport]); - asc_ioport[ioport] = 0; - } - } - } - ioport = 0; - } - - for (bus = 0; bus < ASC_NUM_BUS; bus++) { - - ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n", - bus, asc_bus_name[bus]); - iop = 0; - - while (asc_legacy_count < ASC_NUM_BOARD_SUPPORTED) { - - ASC_DBG1(2, "advansys_detect: asc_legacy_count %d\n", - asc_legacy_count); - - switch (asc_bus[bus]) { - case ASC_IS_ISA: - case ASC_IS_VL: -#ifdef CONFIG_ISA - if (asc_iopflag == ASC_FALSE) { - iop = - AscSearchIOPortAddr(iop, - asc_bus[bus]); - } else { - /* - * ISA and VL I/O port scanning has either been - * eliminated or limited to selected ports on - * the LILO command line, /etc/lilo.conf, or - * by setting variables when the module was loaded. - */ - ASC_DBG(1, - "advansys_detect: I/O port scanning modified\n"); - ioport_try_again: - iop = 0; - for (; ioport < ASC_NUM_IOPORT_PROBE; - ioport++) { - if ((iop = - asc_ioport[ioport]) != 0) { - break; - } - } - if (iop) { - ASC_DBG1(1, - "advansys_detect: probing I/O port 0x%x...\n", - iop); - if (!request_region - (iop, ASC_IOADR_GAP, - "advansys")) { - printk - ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", - iop); - /* Don't try this I/O port twice. */ - asc_ioport[ioport] = 0; - goto ioport_try_again; - } else if (AscFindSignature(iop) - == ASC_FALSE) { - printk - ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", - iop); - /* Don't try this I/O port twice. */ - release_region(iop, - ASC_IOADR_GAP); - asc_ioport[ioport] = 0; - goto ioport_try_again; - } else { - /* - * If this isn't an ISA board, then it must be - * a VL board. If currently looking an ISA - * board is being looked for then try for - * another ISA board in 'asc_ioport'. - */ - if (asc_bus[bus] == - ASC_IS_ISA - && - (AscGetChipVersion - (iop, - ASC_IS_ISA) & - ASC_CHIP_VER_ISA_BIT) - == 0) { - /* - * Don't clear 'asc_ioport[ioport]'. Try - * this board again for VL. Increment - * 'ioport' past this board. - */ - ioport++; - release_region - (iop, - ASC_IOADR_GAP); - goto ioport_try_again; - } - } - /* - * This board appears good, don't try the I/O port - * again by clearing its value. Increment 'ioport' - * for the next iteration. - */ - asc_ioport[ioport++] = 0; - } - } -#endif /* CONFIG_ISA */ - break; - - default: - ASC_PRINT1 - ("advansys_detect: unknown bus type: %d\n", - asc_bus[bus]); - break; - } - ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop); - - /* - * Adapter not found, try next bus type. - */ - if (iop == 0) - break; - - shost = advansys_board_found(iop, NULL, asc_bus[bus]); - if (shost) { - asc_host[asc_legacy_count++] = shost; - } - } - } - - ASC_DBG1(1, "advansys_detect: done: asc_legacy_count %d\n", - asc_legacy_count); - return asc_legacy_count; -} - -/* * advansys_release() * * Release resources allocated for a single AdvanSys adapter. @@ -18591,6 +18306,98 @@ static int advansys_release(struct Scsi_Host *shost) return 0; } +static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = { + 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190, + 0x0210, 0x0230, 0x0250, 0x0330 +}; + +static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) +{ + PortAddr iop_base = _asc_def_iop_base[id]; + struct Scsi_Host *shost; + + if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { + ASC_DBG1(1, "advansys_isa_match: check_region() failed " + "I/O port 0x%x\n", iop_base); + return -ENODEV; + } + ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); + release_region(iop_base, ASC_IOADR_GAP); + if (!AscFindSignature(iop_base)) + goto nodev; + if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) + goto nodev; + + shost = advansys_board_found(iop_base, dev, ASC_IS_ISA); + + if (!shost) + goto nodev; + + dev_set_drvdata(dev, shost); + return 0; + + nodev: + return -ENODEV; +} + +static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) +{ + advansys_release(dev_get_drvdata(dev)); + return 0; +} + +static struct isa_driver advansys_isa_driver = { + .probe = advansys_isa_probe, + .remove = __devexit_p(advansys_isa_remove), + .driver = { + .owner = THIS_MODULE, + .name = "advansys", + }, +}; + +static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) +{ + PortAddr iop_base = _asc_def_iop_base[id]; + struct Scsi_Host *shost; + + if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { + ASC_DBG1(1, "advansys_vlb_match: check_region() failed " + "I/O port 0x%x\n", iop_base); + return -ENODEV; + } + ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); + release_region(iop_base, ASC_IOADR_GAP); + if (!AscFindSignature(iop_base)) + goto nodev; + /* + * I don't think this condition can actually happen, but the old + * driver did it, and the chances of finding a VLB setup in 2007 + * to do testing with is slight to none. + */ + if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL) + goto nodev; + + shost = advansys_board_found(iop_base, dev, ASC_IS_VL); + + if (!shost) + goto nodev; + + dev_set_drvdata(dev, shost); + return 0; + + nodev: + return -ENODEV; +} + +static struct isa_driver advansys_vlb_driver = { + .probe = advansys_vlb_probe, + .remove = __devexit_p(advansys_isa_remove), + .driver = { + .owner = THIS_MODULE, + .name = "advansys", + }, +}; + static struct eisa_device_id advansys_eisa_table[] __devinitdata = { { "ABP7401" }, { "ABP7501" }, @@ -18735,13 +18542,22 @@ static struct pci_driver advansys_pci_driver = { static int __init advansys_init(void) { - int i, error; - advansys_detect(); + int error; - error = eisa_driver_register(&advansys_eisa_driver); + error = isa_register_driver(&advansys_isa_driver, + ASC_IOADR_TABLE_MAX_IX); if (error) goto fail; + error = isa_register_driver(&advansys_vlb_driver, + ASC_IOADR_TABLE_MAX_IX); + if (error) + goto unregister_isa; + + error = eisa_driver_register(&advansys_eisa_driver); + if (error) + goto unregister_vlb; + error = pci_register_driver(&advansys_pci_driver); if (error) goto unregister_eisa; @@ -18750,22 +18566,20 @@ static int __init advansys_init(void) unregister_eisa: eisa_driver_unregister(&advansys_eisa_driver); + unregister_vlb: + isa_unregister_driver(&advansys_vlb_driver); + unregister_isa: + isa_unregister_driver(&advansys_isa_driver); fail: - for (i = 0; i < asc_legacy_count; i++) - advansys_release(asc_host[i]); - return error; } static void __exit advansys_exit(void) { - int i; - pci_unregister_driver(&advansys_pci_driver); eisa_driver_unregister(&advansys_eisa_driver); - - for (i = 0; i < asc_legacy_count; i++) - advansys_release(asc_host[i]); + isa_unregister_driver(&advansys_vlb_driver); + isa_unregister_driver(&advansys_isa_driver); } module_init(advansys_init); -- cgit v1.1 From 71f36115d20e8d8b0ef10479ff0cde877ec56f98 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 08:04:53 -0600 Subject: [SCSI] advansys: Update resource management Make sure the resources are reserved and released by all the callers of advansys_board_found(). This eliminates the check_region-style race. It also allows us to use the pci_request_regions() API. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 70 +++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index eda41f2..d51ca86 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -17681,14 +17681,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) boardp->id, pci_memory_address, iolen); goto err_shost; } - ASC_DBG1(1, - "advansys_board_found: ioremap_addr: 0x%lx\n", + ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n", (ulong)boardp->ioremap_addr); adv_dvc_varp->iop_base = (AdvPortAddr) (boardp->ioremap_addr + (pci_memory_address - (pci_memory_address & PAGE_MASK))); - ASC_DBG1(1, - "advansys_board_found: iop_base: 0x%lx\n", + ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n", adv_dvc_varp->iop_base); #endif /* CONFIG_PCI */ @@ -18169,25 +18167,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Register Board Resources - I/O Port, DMA, IRQ */ - /* - * Register I/O port range. - * - * For Wide boards the I/O ports are not used to access - * the board, but request the region anyway. - * - * 'shost->n_io_port' is not referenced, because it may be truncated. - */ - ASC_DBG2(2, - "advansys_board_found: request_region port 0x%lx, len 0x%x\n", - (ulong)shost->io_port, boardp->asc_n_io_port); - if (request_region(shost->io_port, boardp->asc_n_io_port, - "advansys") == NULL) { - ASC_PRINT3 - ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n", - boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port); - goto err_free_proc; - } - /* Register DMA Channel for Narrow boards. */ shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ #ifdef CONFIG_ISA @@ -18200,7 +18179,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_PRINT3 ("advansys_board_found: board %d: request_dma() %d failed %d\n", boardp->id, shost->dma_channel, ret); - goto err_free_region; + goto err_free_proc; } AscEnableIsaDma(shost->dma_channel); } @@ -18266,8 +18245,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) err_free_dma: if (shost->dma_channel != NO_ISA_DMA) free_dma(shost->dma_channel); - err_free_region: - release_region(shost->io_port, boardp->asc_n_io_port); err_free_proc: kfree(boardp->prtbuf); err_unmap: @@ -18295,7 +18272,6 @@ static int advansys_release(struct Scsi_Host *shost) ASC_DBG(1, "advansys_release: free_dma()\n"); free_dma(shost->dma_channel); } - release_region(shost->io_port, boardp->asc_n_io_port); if (ASC_WIDE_BOARD(boardp)) { iounmap(boardp->ioremap_addr); advansys_wide_free_mem(boardp); @@ -18317,19 +18293,17 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) struct Scsi_Host *shost; if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { - ASC_DBG1(1, "advansys_isa_match: check_region() failed " - "I/O port 0x%x\n", iop_base); + ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n", + iop_base); return -ENODEV; } ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); - release_region(iop_base, ASC_IOADR_GAP); if (!AscFindSignature(iop_base)) goto nodev; if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) goto nodev; shost = advansys_board_found(iop_base, dev, ASC_IS_ISA); - if (!shost) goto nodev; @@ -18337,12 +18311,15 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) return 0; nodev: + release_region(iop_base, ASC_IOADR_GAP); return -ENODEV; } static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) { + int ioport = _asc_def_iop_base[id]; advansys_release(dev_get_drvdata(dev)); + release_region(ioport, ASC_IOADR_GAP); return 0; } @@ -18361,12 +18338,11 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) struct Scsi_Host *shost; if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { - ASC_DBG1(1, "advansys_vlb_match: check_region() failed " - "I/O port 0x%x\n", iop_base); + ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n", + iop_base); return -ENODEV; } ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); - release_region(iop_base, ASC_IOADR_GAP); if (!AscFindSignature(iop_base)) goto nodev; /* @@ -18378,7 +18354,6 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) goto nodev; shost = advansys_board_found(iop_base, dev, ASC_IS_VL); - if (!shost) goto nodev; @@ -18386,6 +18361,7 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) return 0; nodev: + release_region(iop_base, ASC_IOADR_GAP); return -ENODEV; } @@ -18429,8 +18405,16 @@ static int __devinit advansys_eisa_probe(struct device *dev) err = -ENODEV; for (i = 0; i < 2; i++, ioport += 0x20) { - if (!AscFindSignature(ioport)) + if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) { + printk(KERN_WARNING "Region %x-%x busy\n", ioport, + ioport + ASC_IOADR_GAP - 1); + continue; + } + if (!AscFindSignature(ioport)) { + release_region(ioport, ASC_IOADR_GAP); continue; + } + /* * I don't know why we need to do this for EISA chips, but * not for any others. It looks to be equivalent to @@ -18440,8 +18424,11 @@ static int __devinit advansys_eisa_probe(struct device *dev) */ inw(ioport + 4); data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA); - if (data->host[i]) + if (data->host[i]) { err = 0; + } else { + release_region(ioport, ASC_IOADR_GAP); + } } if (err) { @@ -18460,10 +18447,13 @@ static __devexit int advansys_eisa_remove(struct device *dev) struct eisa_scsi_data *data = dev_get_drvdata(dev); for (i = 0; i < 2; i++) { + int ioport; struct Scsi_Host *shost = data->host[i]; if (!shost) continue; + ioport = shost->io_port; advansys_release(shost); + release_region(ioport, ASC_IOADR_GAP); } kfree(data); @@ -18507,6 +18497,9 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_enable_device(pdev); if (err) goto fail; + err = pci_request_regions(pdev, "advansys"); + if (err) + goto disable_device; if (pci_resource_len(pdev, 0) == 0) goto nodev; @@ -18522,6 +18515,8 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) nodev: err = -ENODEV; + pci_release_regions(pdev); + disable_device: pci_disable_device(pdev); fail: return err; @@ -18530,6 +18525,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static void __devexit advansys_pci_remove(struct pci_dev *pdev) { advansys_release(pci_get_drvdata(pdev)); + pci_release_regions(pdev); pci_disable_device(pdev); } -- cgit v1.1 From 9649af39e30d8d2668c35d008e8e14ae138e4d40 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 21:51:47 -0600 Subject: [SCSI] advansys: More PCI cleanups - Remove wrappers around the PCI configuration space accessors - Call pci_set_master() instead of poking at config space directly - Move the latency setting into one function called for both narrow and wide boards. - Tidy up AdvInitGetConfig() a little. - Delete a few unused prototypes and definitions. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 254 +++++++----------------------------------------- 1 file changed, 34 insertions(+), 220 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index d51ca86..424549d 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -854,15 +854,6 @@ typedef unsigned char uchar; #define ERR (-1) #define UW_ERR (uint)(0xFFFF) #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) -#define AscPCIConfigVendorIDRegister 0x0000 -#define AscPCIConfigDeviceIDRegister 0x0002 -#define AscPCIConfigCommandRegister 0x0004 -#define AscPCIConfigStatusRegister 0x0006 -#define AscPCIConfigRevisionIDRegister 0x0008 -#define AscPCIConfigCacheSize 0x000C -#define AscPCIConfigLatencyTimer 0x000D -#define AscPCIIOBaseRegister 0x0010 -#define AscPCICmdRegBits_IOMemBusMaster 0x0007 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) @@ -1936,17 +1927,11 @@ static uchar AscSetChipIRQ(PortAddr, uchar, ushort); static ushort AscGetChipBiosAddress(PortAddr, ushort); static inline ulong DvcEnterCritical(void); static inline void DvcLeaveCritical(ulong); -#ifdef CONFIG_PCI -static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort); -static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar); -#endif /* CONFIG_PCI */ static ushort AscGetChipBiosAddress(PortAddr, ushort); static void DvcSleepMilliSecond(ASC_DCNT); static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); static void DvcGetQinfo(PortAddr, ushort, uchar *, int); -static ushort AscInitGetConfig(ASC_DVC_VAR *); -static ushort AscInitSetConfig(ASC_DVC_VAR *); static ushort AscInitAsc1000Driver(ASC_DVC_VAR *); static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *); static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *); @@ -3077,8 +3062,6 @@ typedef struct adv_scsi_req_q { static inline ulong DvcEnterCritical(void); static inline void DvcLeaveCritical(ulong); static void DvcSleepMilliSecond(ADV_DCNT); -static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort); -static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar); static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, uchar *, ASC_SDCNT *, int); static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); @@ -3112,12 +3095,6 @@ static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); static void AdvWaitEEPCmd(AdvPortAddr); static ushort AdvReadEEPWord(AdvPortAddr, int); -/* - * PCI Bus Definitions - */ -#define AscPCICmdRegBits_BusMastering 0x0007 -#define AscPCICmdRegBits_ParErrRespCtrl 0x0040 - /* Read byte from a register. */ #define AdvReadByteRegister(iop_base, reg_off) \ (ADV_MEM_READB((iop_base) + (reg_off))) @@ -7327,31 +7304,6 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) } /* - * Read a PCI configuration byte. - */ -static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset) -{ -#ifdef CONFIG_PCI - uchar byte_data; - pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); - return byte_data; -#else /* !defined(CONFIG_PCI) */ - return 0; -#endif /* !defined(CONFIG_PCI) */ -} - -/* - * Write a PCI configuration byte. - */ -static void __devinit -DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) -{ -#ifdef CONFIG_PCI - pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); -#endif /* CONFIG_PCI */ -} - -/* * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ @@ -7424,33 +7376,6 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, } /* - * Read a PCI configuration byte. - */ -static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset) -{ -#ifdef CONFIG_PCI - uchar byte_data; - pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); - return byte_data; -#else /* CONFIG_PCI */ - return 0; -#endif /* CONFIG_PCI */ -} - -/* - * Write a PCI configuration byte. - */ -static void __devinit -DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) -{ -#ifdef CONFIG_PCI - pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); -#else /* CONFIG_PCI */ - return; -#endif /* CONFIG_PCI */ -} - -/* * --- Tracing and Debugging Functions */ @@ -10321,89 +10246,15 @@ static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) } #endif /* CONFIG_ISA */ -static ushort __devinit -AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset) -{ - uchar lsb, msb; - - lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset); - msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1); - return ((ushort)((msb << 8) | lsb)); -} - static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) { - ushort warn_code; - PortAddr iop_base; - ushort PCIDeviceID; - ushort PCIVendorID; - uchar PCIRevisionID; - uchar prevCmdRegBits; + unsigned short warn_code = 0; - warn_code = 0; - iop_base = asc_dvc->iop_base; asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; - if (asc_dvc->err_code != 0) { + if (asc_dvc->err_code != 0) return (UW_ERR); - } - if (asc_dvc->bus_type == ASC_IS_PCI) { - PCIVendorID = AscReadPCIConfigWord(asc_dvc, - AscPCIConfigVendorIDRegister); - - PCIDeviceID = AscReadPCIConfigWord(asc_dvc, - AscPCIConfigDeviceIDRegister); - - PCIRevisionID = DvcReadPCIConfigByte(asc_dvc, - AscPCIConfigRevisionIDRegister); - if (PCIVendorID != PCI_VENDOR_ID_ASP) { - warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; - } - prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc, - AscPCIConfigCommandRegister); - - if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) != - AscPCICmdRegBits_IOMemBusMaster) { - DvcWritePCIConfigByte(asc_dvc, - AscPCIConfigCommandRegister, - (prevCmdRegBits | - AscPCICmdRegBits_IOMemBusMaster)); - - if ((DvcReadPCIConfigByte(asc_dvc, - AscPCIConfigCommandRegister) - & AscPCICmdRegBits_IOMemBusMaster) - != AscPCICmdRegBits_IOMemBusMaster) { - warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; - } - } - if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) || - (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) { - DvcWritePCIConfigByte(asc_dvc, - AscPCIConfigLatencyTimer, 0x00); - if (DvcReadPCIConfigByte - (asc_dvc, AscPCIConfigLatencyTimer) - != 0x00) { - warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; - } - } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) { - if (DvcReadPCIConfigByte(asc_dvc, - AscPCIConfigLatencyTimer) < - 0x20) { - DvcWritePCIConfigByte(asc_dvc, - AscPCIConfigLatencyTimer, - 0x20); - - if (DvcReadPCIConfigByte(asc_dvc, - AscPCIConfigLatencyTimer) - < 0x20) { - warn_code |= - ASC_WARN_SET_PCI_CONFIG_SPACE; - } - } - } - } - - if (AscFindSignature(iop_base)) { + if (AscFindSignature(asc_dvc->iop_base)) { warn_code |= AscInitAscDvcVar(asc_dvc); warn_code |= AscInitFromEEP(asc_dvc); asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; @@ -10437,13 +10288,8 @@ static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) PortAddr iop_base; ushort cfg_msw; ushort warn_code; - ushort pci_device_id = 0; iop_base = asc_dvc->iop_base; -#ifdef CONFIG_PCI - if (asc_dvc->cfg->dev) - pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device; -#endif warn_code = 0; cfg_msw = AscGetChipCfgMsw(iop_base); if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { @@ -10465,19 +10311,23 @@ static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; } } +#ifdef CONFIG_PCI if (asc_dvc->bus_type & ASC_IS_PCI) { + struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev); cfg_msw &= 0xFFC0; AscSetChipCfgMsw(iop_base, cfg_msw); if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { } else { - if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) || - (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) { + if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || + (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; } } - } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) { + } else +#endif /* CONFIG_PCI */ + if (asc_dvc->bus_type == ASC_IS_ISAPNP) { if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == ASC_CHIP_VER_ASYN_BUG) { asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; @@ -13875,55 +13725,13 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = */ static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) { - ushort warn_code; - AdvPortAddr iop_base; - uchar pci_cmd_reg; + unsigned short warn_code = 0; + AdvPortAddr iop_base = asc_dvc->iop_base; + struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev); + u16 cmd; int status; - warn_code = 0; asc_dvc->err_code = 0; - iop_base = asc_dvc->iop_base; - - /* - * PCI Command Register - * - * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes - * I/O Space Control, Memory Space Control and Bus Master Control bits. - */ - - if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc, - AscPCIConfigCommandRegister)) - & AscPCICmdRegBits_BusMastering) - != AscPCICmdRegBits_BusMastering) { - pci_cmd_reg |= AscPCICmdRegBits_BusMastering; - - DvcAdvWritePCIConfigByte(asc_dvc, - AscPCIConfigCommandRegister, - pci_cmd_reg); - - if (((DvcAdvReadPCIConfigByte - (asc_dvc, AscPCIConfigCommandRegister)) - & AscPCICmdRegBits_BusMastering) - != AscPCICmdRegBits_BusMastering) { - warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; - } - } - - /* - * PCI Latency Timer - * - * If the "latency timer" register is 0x20 or above, then we don't need - * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it - * comes up less than 0x20). - */ - if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) { - DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, - 0x20); - if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < - 0x20) { - warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; - } - } /* * Save the state of the PCI Configuration Command Register @@ -13932,10 +13740,9 @@ static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) * DMA parity errors. */ asc_dvc->cfg->control_flag = 0; - if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister) - & AscPCICmdRegBits_ParErrRespCtrl)) == 0) { + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if ((cmd & PCI_COMMAND_PARITY) == 0) asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; - } asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | ADV_LIB_VERSION_MINOR; @@ -13977,19 +13784,11 @@ static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) ADV_CTRL_REG_CMD_WR_IO_REG); if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - if ((status = - AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) { - return ADV_ERROR; - } + status = AdvInitFrom38C1600EEP(asc_dvc); } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { - if ((status = - AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) { - return ADV_ERROR; - } + status = AdvInitFrom38C0800EEP(asc_dvc); } else { - if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) { - return ADV_ERROR; - } + status = AdvInitFrom3550EEP(asc_dvc); } warn_code |= status; } @@ -18488,6 +18287,19 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); +static void __devinit advansys_set_latency(struct pci_dev *pdev) +{ + if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || + (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0); + } else { + u8 latency; + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); + if (latency < 0x20) + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20); + } +} + static int __devinit advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -18500,6 +18312,8 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_request_regions(pdev, "advansys"); if (err) goto disable_device; + pci_set_master(pdev); + advansys_set_latency(pdev); if (pci_resource_len(pdev, 0) == 0) goto nodev; -- cgit v1.1 From ce3a7f1202e02324841ef87d7d3f08ff351d07c7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:39:17 -0400 Subject: [SCSI] advansys: remove AscCompareString() AscCompareString() is just another name for strncmp Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 424549d..277002a 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1911,7 +1911,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *); static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, ASC_QDONE_INFO *, ASC_DCNT); static int AscIsrQDone(ASC_DVC_VAR *); -static int AscCompareString(uchar *, uchar *, int); #ifdef CONFIG_ISA static ushort AscGetEisaChipCfg(PortAddr); #endif /* CONFIG_ISA */ @@ -10998,8 +10997,7 @@ AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) { if (!(asc_dvc->init_sdtr & tid_bits)) { if ((dvc_type == TYPE_ROM) && - (AscCompareString((uchar *)inq->vendor_id, - (uchar *)"HP ", 3) == 0)) { + (strncmp(inq->vendor_id, "HP ", 3) == 0)) { asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; } asc_dvc->pci_fix_asyn_xfer |= tid_bits; @@ -11022,10 +11020,8 @@ AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq) { if ((inq->add_len >= 32) && - (AscCompareString((uchar *)inq->vendor_id, - (uchar *)"QUANTUM XP34301", 15) == 0) && - (AscCompareString((uchar *)inq->product_rev_level, - (uchar *)"1071", 4) == 0)) { + (strncmp(inq->vendor_id, "QUANTUM XP34301", 15) == 0) && + (strncmp(inq->product_rev_level, "1071", 4) == 0)) { return 0; } return 1; @@ -11076,19 +11072,6 @@ AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) return; } -static int AscCompareString(uchar *str1, uchar *str2, int len) -{ - int i; - int diff; - - for (i = 0; i < len; i++) { - diff = (int)(str1[i] - str2[i]); - if (diff != 0) - return (diff); - } - return (0); -} - static uchar AscReadLramByte(PortAddr iop_base, ushort addr) { uchar byte_data; -- cgit v1.1 From 2ffb45c672eff6a797712c5c8b5a6ddf3692187a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:39:46 -0400 Subject: [SCSI] Add QUANTUM XP34301 to the blacklist According to the AdvanSys driver, this device has a problem with tagged queueing. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index e2ea739..348cc5a 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -214,6 +214,7 @@ static struct { {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"Promise", "", NULL, BLIST_SPARSELUN}, + {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ -- cgit v1.1 From 47d853ccbe7fc6b79aeddd97cf6f5b08bf81d58b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:41:33 -0400 Subject: [SCSI] advansys: remove INQUIRY sniffing Use slave_configure() to do all the work that used to be done in AscInquiryHandling and AdvInquiryHandling. Split slave_configure into two functions, one for wide and one for narrow controllers. Remove some unused definitions, duplicate definitions, unnecessary declarations, and scsireqq, cap_info and inquiry from struct asc_board. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 637 ++++++++++++++++-------------------------------- 1 file changed, 211 insertions(+), 426 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 277002a..5885ce4 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -944,10 +944,6 @@ typedef unsigned char uchar; #define ASC_MAX_CDB_LEN 12 #define ASC_SCSI_RESET_HOLD_TIME_US 60 -#define ADV_INQ_CLOCKING_ST_ONLY 0x0 -#define ADV_INQ_CLOCKING_DT_ONLY 0x1 -#define ADV_INQ_CLOCKING_ST_AND_DT 0x3 - /* * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data) * and CmdDt (Command Support Data) field bit definitions. @@ -966,57 +962,8 @@ typedef unsigned char uchar; #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) -#define MS_CMD_DONE 0x00 -#define MS_EXTEND 0x01 #define MS_SDTR_LEN 0x03 -#define MS_SDTR_CODE 0x01 #define MS_WDTR_LEN 0x02 -#define MS_WDTR_CODE 0x03 -#define MS_MDP_LEN 0x05 -#define MS_MDP_CODE 0x00 - -/* - * Inquiry data structure and bitfield macros - * - * Only quantities of more than 1 bit are shifted, since the others are - * just tested for true or false. C bitfields aren't portable between big - * and little-endian platforms so they are not used. - */ - -#define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) -#define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) -#define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) -#define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) -#define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) -#define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) -#define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) -#define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) -#define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) -#define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) -#define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) -#define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) -#define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) -#define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10) -#define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20) -#define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40) -#define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) -#define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) -#define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) -#define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) - -typedef struct { - uchar periph; - uchar devtype; - uchar ver; - uchar byte3; - uchar add_len; - uchar res1; - uchar res2; - uchar flags; - uchar vendor_id[8]; - uchar product_id[16]; - uchar product_rev_level[4]; -} ASC_SCSI_INQUIRY; #define ASC_SG_LIST_PER_Q 7 #define QS_FREE 0x00 @@ -1932,9 +1879,7 @@ static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); static void DvcGetQinfo(PortAddr, ushort, uchar *, int); static ushort AscInitAsc1000Driver(ASC_DVC_VAR *); -static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *); -static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *); -static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *); +static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *); static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *); static int AscISR(ASC_DVC_VAR *); static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar); @@ -3081,7 +3026,6 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc); * Internal Adv Library functions. */ static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT); -static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); static int AdvInitFrom3550EEP(ADV_DVC_VAR *); static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *); static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *); @@ -3296,74 +3240,6 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config; ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) /* - * Inquiry data structure and bitfield macros - * - * Using bitfields to access the subchar data isn't portable across - * endianness, so instead mask and shift. Only quantities of more - * than 1 bit are shifted, since the others are just tested for true - * or false. - */ - -#define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) -#define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) -#define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) -#define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) -#define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) -#define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) -#define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) -#define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) -#define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) -#define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) -#define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) -#define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) -#define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) -#define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10) -#define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20) -#define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40) -#define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) -#define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) -#define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) -#define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) - -typedef struct { - uchar periph; /* peripheral device type [0:4] */ - /* peripheral qualifier [5:7] */ - uchar devtype; /* device type modifier (for SCSI I) [0:6] */ - /* RMB - removable medium bit [7] */ - uchar ver; /* ANSI approved version [0:2] */ - /* ECMA version [3:5] */ - /* ISO version [6:7] */ - uchar byte3; /* response data format [0:3] */ - /* 0 SCSI 1 */ - /* 1 CCS */ - /* 2 SCSI-2 */ - /* 3-F reserved */ - /* reserved [4:5] */ - /* terminate I/O process bit (see 5.6.22) [6] */ - /* asynch. event notification (processor) [7] */ - uchar add_len; /* additional length */ - uchar res1; /* reserved */ - uchar res2; /* reserved */ - uchar flags; /* soft reset implemented [0] */ - /* command queuing [1] */ - /* reserved [2] */ - /* linked command for this logical unit [3] */ - /* synchronous data transfer [4] */ - /* wide bus 16 bit data transfer [5] */ - /* wide bus 32 bit data transfer [6] */ - /* relative addressing mode [7] */ - uchar vendor_id[8]; /* vendor identification */ - uchar product_id[16]; /* product identification */ - uchar product_rev_level[4]; /* product revision level */ - uchar vendor_specific[20]; /* vendor specific */ - uchar info; /* information unit supported [0] */ - /* quick arbitrate supported [1] */ - /* clocking field [2:3] */ - /* reserved [4:7] */ - uchar res3; /* reserved */ -} ADV_SCSI_INQUIRY; /* 58 bytes */ - -/* * --- Driver Constants and Macros */ @@ -3771,10 +3647,6 @@ typedef struct asc_board { /* * The following fields are used only for Narrow Boards. */ - /* The following three structures must be in DMA-able memory. */ - ASC_SCSI_REQ_Q scsireqq; - ASC_CAP_INFO cap_info; - ASC_SCSI_INQUIRY inquiry; uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */ /* * The following fields are used only for Wide Boards. @@ -3809,8 +3681,6 @@ static int asc_dbglvl = 3; /* * --- Driver Function Prototypes - * - * advansys.h contains function prototypes for functions global to Linux. */ static int advansys_slave_configure(struct scsi_device *); @@ -4622,38 +4492,203 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) return result; } +static void +advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc) +{ + ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id; + ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng; + + if (sdev->lun == 0) { + ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr; + if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) { + asc_dvc->init_sdtr |= tid_bit; + } else { + asc_dvc->init_sdtr &= ~tid_bit; + } + + if (orig_init_sdtr != asc_dvc->init_sdtr) + AscAsyncFix(asc_dvc, sdev); + } + + if (sdev->tagged_supported) { + if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) { + if (sdev->lun == 0) { + asc_dvc->cfg->can_tagged_qng |= tid_bit; + asc_dvc->use_tagged_qng |= tid_bit; + } + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, + asc_dvc->max_dvc_qng[sdev->id]); + } + } else { + if (sdev->lun == 0) { + asc_dvc->cfg->can_tagged_qng &= ~tid_bit; + asc_dvc->use_tagged_qng &= ~tid_bit; + } + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); + } + + if ((sdev->lun == 0) && + (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) { + AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, + asc_dvc->cfg->disc_enable); + AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, + asc_dvc->use_tagged_qng); + AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, + asc_dvc->cfg->can_tagged_qng); + + asc_dvc->max_dvc_qng[sdev->id] = + asc_dvc->cfg->max_tag_qng[sdev->id]; + AscWriteLramByte(asc_dvc->iop_base, + (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id), + asc_dvc->max_dvc_qng[sdev->id]); + } +} + /* - * Set the number of commands to queue per device for the - * specified host adapter. + * Wide Transfers + * + * If the EEPROM enabled WDTR for the device and the device supports wide + * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and + * write the new value to the microcode. */ -static int advansys_slave_configure(struct scsi_device *device) +static void +advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask) { - asc_board_t *boardp; + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); + if ((cfg_word & tidmask) != 0) + return; + + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); - boardp = ASC_BOARDP(device->host); - boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; /* - * Save a pointer to the device and set its initial/maximum - * queue depth. Only save the pointer for a lun0 dev though. + * Clear the microcode SDTR and WDTR negotiation done indicators for + * the target to cause it to negotiate with the new setting set above. + * WDTR when accepted causes the target to enter asynchronous mode, so + * SDTR must be negotiated. */ - if (device->lun == 0) - boardp->device[device->id] = device; - if (device->tagged_supported) { - if (ASC_NARROW_BOARD(boardp)) { - scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, - boardp->dvc_var.asc_dvc_var. - max_dvc_qng[device->id]); - } else { - scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, - boardp->dvc_var.adv_dvc_var. - max_dvc_qng); + AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); +} + +/* + * Synchronous Transfers + * + * If the EEPROM enabled SDTR for the device and the device + * supports synchronous transfers, then turn on the device's + * 'sdtr_able' bit. Write the new value to the microcode. + */ +static void +advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask) +{ + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); + if ((cfg_word & tidmask) != 0) + return; + + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); + + /* + * Clear the microcode "SDTR negotiation" done indicator for the + * target to cause it to negotiate with the new setting set above. + */ + AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); +} + +/* + * PPR (Parallel Protocol Request) Capable + * + * If the device supports DT mode, then it must be PPR capable. + * The PPR message will be used in place of the SDTR and WDTR + * messages to negotiate synchronous speed and offset, transfer + * width, and protocol options. + */ +static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc, + AdvPortAddr iop_base, unsigned short tidmask) +{ + AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); + adv_dvc->ppr_able |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); +} + +static void +advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) +{ + AdvPortAddr iop_base = adv_dvc->iop_base; + unsigned short tidmask = 1 << sdev->id; + + if (sdev->lun == 0) { + /* + * Handle WDTR, SDTR, and Tag Queuing. If the feature + * is enabled in the EEPROM and the device supports the + * feature, then enable it in the microcode. + */ + + if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr) + advansys_wide_enable_wdtr(iop_base, tidmask); + if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr) + advansys_wide_enable_sdtr(iop_base, tidmask); + if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr) + advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask); + + /* + * Tag Queuing is disabled for the BIOS which runs in polled + * mode and would see no benefit from Tag Queuing. Also by + * disabling Tag Queuing in the BIOS devices with Tag Queuing + * bugs will at least work with the BIOS. + */ + if ((adv_dvc->tagqng_able & tidmask) && + sdev->tagged_supported) { + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, + cfg_word); + AdvWriteByteLram(iop_base, + ASC_MC_NUMBER_OF_MAX_CMD + sdev->id, + adv_dvc->max_dvc_qng); } + } + + if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) { + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, + adv_dvc->max_dvc_qng); } else { - scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun); + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); } - ASC_DBG4(1, - "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n", - (ulong)device, (ulong)boardp, device->id, device->queue_depth); +} + +/* + * Set the number of commands to queue per device for the + * specified host adapter. + */ +static int advansys_slave_configure(struct scsi_device *sdev) +{ + asc_board_t *boardp = ASC_BOARDP(sdev->host); + boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; + + /* + * Save a pointer to the sdev and set its initial/maximum + * queue depth. Only save the pointer for a lun0 dev though. + */ + if (sdev->lun == 0) + boardp->device[sdev->id] = sdev; + + if (ASC_NARROW_BOARD(boardp)) + advansys_narrow_slave_configure(sdev, + &boardp->dvc_var.asc_dvc_var); + else + advansys_wide_slave_configure(sdev, + &boardp->dvc_var.adv_dvc_var); + return 0; } @@ -5406,21 +5441,10 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) scp->result = 0; /* - * If an INQUIRY command completed successfully, then call - * the AscInquiryHandling() function to set-up the device. - */ - if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 && - (scp->request_bufflen - qdonep->remain_bytes) >= 8) { - AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7, - (ASC_SCSI_INQUIRY *)scp-> - request_buffer); - } - - /* * Check for an underrun condition. * * If there was no error and an underrun condition, then - * then return the number of underrun bytes. + * return the number of underrun bytes. */ if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && qdonep->remain_bytes <= scp->request_bufflen) { @@ -8229,8 +8253,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) (uchar *)&ext_msg, sizeof(EXT_MSG) >> 1); - if (ext_msg.msg_type == MS_EXTEND && - ext_msg.msg_req == MS_SDTR_CODE && + if (ext_msg.msg_type == EXTENDED_MESSAGE && + ext_msg.msg_req == EXTENDED_SDTR && ext_msg.msg_len == MS_SDTR_LEN) { sdtr_accept = TRUE; if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { @@ -8312,8 +8336,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) q_cntl); AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); return (0); - } else if (ext_msg.msg_type == MS_EXTEND && - ext_msg.msg_req == MS_WDTR_CODE && + } else if (ext_msg.msg_type == EXTENDED_MESSAGE && + ext_msg.msg_req == EXTENDED_WDTR && ext_msg.msg_len == MS_WDTR_LEN) { ext_msg.wdtr_width = 0; @@ -8406,9 +8430,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) (uchar *)&out_msg, sizeof(EXT_MSG) >> 1); - if ((out_msg.msg_type == MS_EXTEND) && + if ((out_msg.msg_type == EXTENDED_MESSAGE) && (out_msg.msg_len == MS_SDTR_LEN) && - (out_msg.msg_req == MS_SDTR_CODE)) { + (out_msg.msg_req == EXTENDED_SDTR)) { asc_dvc->init_sdtr &= ~target_id; asc_dvc->sdtr_done &= ~target_id; @@ -9901,9 +9925,9 @@ AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset) PortAddr iop_base; iop_base = asc_dvc->iop_base; - sdtr_buf.msg_type = MS_EXTEND; + sdtr_buf.msg_type = EXTENDED_MESSAGE; sdtr_buf.msg_len = MS_SDTR_LEN; - sdtr_buf.msg_req = MS_SDTR_CODE; + sdtr_buf.msg_req = EXTENDED_SDTR; sdtr_buf.xfer_period = sdtr_period; sdtr_offset &= ASC_SYN_MAX_OFFSET; sdtr_buf.req_ack_offset = sdtr_offset; @@ -10985,91 +11009,31 @@ AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) return (n_error); } -static void -AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) +static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev) { - uchar dvc_type; - ASC_SCSI_BIT_ID_TYPE tid_bits; - - dvc_type = ASC_INQ_DVC_TYPE(inq); - tid_bits = ASC_TIX_TO_TARGET_ID(tid_no); + char type = sdev->type; + ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id; if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) { if (!(asc_dvc->init_sdtr & tid_bits)) { - if ((dvc_type == TYPE_ROM) && - (strncmp(inq->vendor_id, "HP ", 3) == 0)) { + if ((type == TYPE_ROM) && + (strncmp(sdev->vendor, "HP ", 3) == 0)) { asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; } asc_dvc->pci_fix_asyn_xfer |= tid_bits; - if ((dvc_type == TYPE_PROCESSOR) || - (dvc_type == TYPE_SCANNER) || - (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) { + if ((type == TYPE_PROCESSOR) || + (type == TYPE_SCANNER) || (type == TYPE_ROM) || + (type == TYPE_TAPE)) { asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; } if (asc_dvc->pci_fix_asyn_xfer & tid_bits) { AscSetRunChipSynRegAtID(asc_dvc->iop_base, - tid_no, - ASYN_SDTR_DATA_FIX_PCI_REV_AB); + sdev->id, + ASYN_SDTR_DATA_FIX_PCI_REV_AB); } } } - return; -} - -static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq) -{ - if ((inq->add_len >= 32) && - (strncmp(inq->vendor_id, "QUANTUM XP34301", 15) == 0) && - (strncmp(inq->product_rev_level, "1071", 4) == 0)) { - return 0; - } - return 1; -} - -static void -AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) -{ - ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no); - ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng; - - orig_init_sdtr = asc_dvc->init_sdtr; - orig_use_tagged_qng = asc_dvc->use_tagged_qng; - - asc_dvc->init_sdtr &= ~tid_bit; - asc_dvc->cfg->can_tagged_qng &= ~tid_bit; - asc_dvc->use_tagged_qng &= ~tid_bit; - - if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) { - if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) { - asc_dvc->init_sdtr |= tid_bit; - } - if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && - ASC_INQ_CMD_QUEUE(inq)) { - if (AscTagQueuingSafe(inq)) { - asc_dvc->use_tagged_qng |= tid_bit; - asc_dvc->cfg->can_tagged_qng |= tid_bit; - } - } - } - if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) { - AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, - asc_dvc->cfg->disc_enable); - AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, - asc_dvc->use_tagged_qng); - AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, - asc_dvc->cfg->can_tagged_qng); - - asc_dvc->max_dvc_qng[tid_no] = - asc_dvc->cfg->max_tag_qng[tid_no]; - AscWriteLramByte(asc_dvc->iop_base, - (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no), - asc_dvc->max_dvc_qng[tid_no]); - } - if (orig_init_sdtr != asc_dvc->init_sdtr) { - AscAsyncFix(asc_dvc, tid_no, inq); - } - return; } static uchar AscReadLramByte(PortAddr iop_base, ushort addr) @@ -13998,7 +13962,7 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) /* * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in AdvInquiryHandling() based on what a + * queuing will be set in slave_configure() based on what a * device reports it is capable of in Inquiry byte 7. * * If SCSI Bus Resets have been disabled, then directly set @@ -14649,7 +14613,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) /* * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in AdvInquiryHandling() based on what a + * queuing will be set in slave_configure() based on what a * device reports it is capable of in Inquiry byte 7. * * If SCSI Bus Resets have been disabled, then directly set @@ -15269,7 +15233,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) /* * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in AdvInquiryHandling() based on what a + * queuing will be set in slave_configure() based on what a * device reports it is capable of in Inquiry byte 7. * * If SCSI Bus Resets have been disabled, then directly set @@ -16953,23 +16917,6 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) scsiq->cntl = 0; /* - * If the command that completed was a SCSI INQUIRY and - * LUN 0 was sent the command, then process the INQUIRY - * command information for the device. - * - * Note: If data returned were either VPD or CmdDt data, - * don't process the INQUIRY command information for - * the device, otherwise may erroneously set *_able bits. - */ - if (scsiq->done_status == QD_NO_ERROR && - scsiq->cdb[0] == INQUIRY && - scsiq->target_lun == 0 && - (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT) - == ADV_INQ_RTN_STD_INQUIRY_DATA) { - AdvInquiryHandling(asc_dvc, scsiq); - } - - /* * Notify the driver of the completed request by passing * the ADV_SCSI_REQ_Q pointer to its callback function. */ @@ -17074,168 +17021,6 @@ AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, return ADV_ERROR; } -/* - * Inquiry Information Byte 7 Handling - * - * Handle SCSI Inquiry Command information for a device by setting - * microcode operating variables that affect WDTR, SDTR, and Tag - * Queuing. - */ -static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) -{ - AdvPortAddr iop_base; - uchar tid; - ADV_SCSI_INQUIRY *inq; - ushort tidmask; - ushort cfg_word; - - /* - * AdvInquiryHandling() requires up to INQUIRY information Byte 7 - * to be available. - * - * If less than 8 bytes of INQUIRY information were requested or less - * than 8 bytes were transferred, then return. cdb[4] is the request - * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the - * microcode to the transfer residual count. - */ - - if (scsiq->cdb[4] < 8 || - (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) { - return; - } - - iop_base = asc_dvc->iop_base; - tid = scsiq->target_id; - - inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr; - - /* - * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. - */ - if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) { - return; - } else { - /* - * INQUIRY Byte 7 Handling - * - * Use a device's INQUIRY byte 7 to determine whether it - * supports WDTR, SDTR, and Tag Queuing. If the feature - * is enabled in the EEPROM and the device supports the - * feature, then enable it in the microcode. - */ - - tidmask = ADV_TID_TO_TIDMASK(tid); - - /* - * Wide Transfers - * - * If the EEPROM enabled WDTR for the device and the device - * supports wide bus (16 bit) transfers, then turn on the - * device's 'wdtr_able' bit and write the new value to the - * microcode. - */ - if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) { - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); - if ((cfg_word & tidmask) == 0) { - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, - cfg_word); - - /* - * Clear the microcode "SDTR negotiation" and "WDTR - * negotiation" done indicators for the target to cause - * it to negotiate with the new setting set above. - * WDTR when accepted causes the target to enter - * asynchronous mode, so SDTR must be negotiated. - */ - AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, - cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, - cfg_word); - AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, - cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, - cfg_word); - } - } - - /* - * Synchronous Transfers - * - * If the EEPROM enabled SDTR for the device and the device - * supports synchronous transfers, then turn on the device's - * 'sdtr_able' bit. Write the new value to the microcode. - */ - if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) { - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); - if ((cfg_word & tidmask) == 0) { - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, - cfg_word); - - /* - * Clear the microcode "SDTR negotiation" done indicator - * for the target to cause it to negotiate with the new - * setting set above. - */ - AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, - cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, - cfg_word); - } - } - /* - * If the Inquiry data included enough space for the SPI-3 - * Clocking field, then check if DT mode is supported. - */ - if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 && - (scsiq->cdb[4] >= 57 || - (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) { - /* - * PPR (Parallel Protocol Request) Capable - * - * If the device supports DT mode, then it must be PPR capable. - * The PPR message will be used in place of the SDTR and WDTR - * messages to negotiate synchronous speed and offset, transfer - * width, and protocol options. - */ - if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) { - AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, - asc_dvc->ppr_able); - asc_dvc->ppr_able |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, - asc_dvc->ppr_able); - } - } - - /* - * If the EEPROM enabled Tag Queuing for the device and the - * device supports Tag Queueing, then turn on the device's - * 'tagqng_enable' bit in the microcode and set the microcode - * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' - * value. - * - * Tag Queuing is disabled for the BIOS which runs in polled - * mode and would see no benefit from Tag Queuing. Also by - * disabling Tag Queuing in the BIOS devices with Tag Queuing - * bugs will at least work with the BIOS. - */ - if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) { - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, - cfg_word); - - AdvWriteByteLram(iop_base, - ASC_MC_NUMBER_OF_MAX_CMD + tid, - asc_dvc->max_dvc_qng); - } - } -} - static int __devinit advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) { -- cgit v1.1 From ecec1947479e52eeb4378cc5706d6d46b0cf5172 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 08:08:22 -0600 Subject: [SCSI] advansys: misc reformatting Remove some useless forward declarations Reformat some comments, debug messages, and the occasional piece of real code Removal of unnecessary braces Remove duplicate setting of shost->irq Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 260 ++++++++++++++++++++---------------------------- 1 file changed, 110 insertions(+), 150 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 5885ce4..dc9dca3 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1815,9 +1815,6 @@ static void AscEnableInterrupt(PortAddr); static void AscSetBank(PortAddr, uchar); static int AscResetChipAndScsiBus(ASC_DVC_VAR *); #ifdef CONFIG_ISA -static ushort AscGetIsaDmaChannel(PortAddr); -static ushort AscSetIsaDmaChannel(PortAddr, ushort); -static uchar AscSetIsaDmaSpeed(PortAddr, uchar); static uchar AscGetIsaDmaSpeed(PortAddr); #endif /* CONFIG_ISA */ static uchar AscReadLramByte(PortAddr, ushort); @@ -1862,18 +1859,11 @@ static int AscIsrQDone(ASC_DVC_VAR *); static ushort AscGetEisaChipCfg(PortAddr); #endif /* CONFIG_ISA */ static uchar AscGetChipScsiCtrl(PortAddr); -static uchar AscSetChipScsiID(PortAddr, uchar); static uchar AscGetChipVersion(PortAddr, ushort); -static ushort AscGetChipBusType(PortAddr); static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort); -static int AscFindSignature(PortAddr); static void AscToggleIRQAct(PortAddr); -static uchar AscGetChipIRQ(PortAddr, ushort); -static uchar AscSetChipIRQ(PortAddr, uchar, ushort); -static ushort AscGetChipBiosAddress(PortAddr, ushort); static inline ulong DvcEnterCritical(void); static inline void DvcLeaveCritical(ulong); -static ushort AscGetChipBiosAddress(PortAddr, ushort); static void DvcSleepMilliSecond(ASC_DCNT); static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); @@ -1887,7 +1877,6 @@ static int AscSgListToQueue(int); #ifdef CONFIG_ISA static void AscEnableIsaDma(uchar); #endif /* CONFIG_ISA */ -static ASC_DCNT AscGetMaxDmaCount(ushort); static const char *advansys_info(struct Scsi_Host *shost); /* @@ -3710,10 +3699,6 @@ static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int); static int asc_prt_line(char *, int, char *fmt, ...); #endif /* CONFIG_PROC_FS */ -/* Declaration for Asc Library internal functions referenced by driver. */ -static int AscFindSignature(PortAddr); -static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); - /* Statistics function prototypes. */ #ifdef ADVANSYS_STATS #ifdef CONFIG_PROC_FS @@ -3822,8 +3807,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, cp = boardp->prtbuf; cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); - cnt = - asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -3910,11 +3894,10 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) { cp = boardp->prtbuf; cplen = asc_prt_target_stats(shost, tgt_id, cp, - ASC_PRTBUF_SIZE); + ASC_PRTBUF_SIZE); ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); - cnt = - asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, - cplen); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, + cplen); totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { @@ -4004,15 +3987,14 @@ static const char *advansys_info(struct Scsi_Host *shost) } } else { busname = "?"; - ASC_PRINT2 - ("advansys_info: board %d: unknown bus type %d\n", - boardp->id, asc_dvc_varp->bus_type); + ASC_PRINT2("advansys_info: board %d: unknown " + "bus type %d\n", boardp->id, + asc_dvc_varp->bus_type); } /* Don't reference 'shost->n_io_port'; It may be truncated. */ sprintf(info, "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", - ASC_VERSION, busname, - (ulong)shost->io_port, + ASC_VERSION, busname, (ulong)shost->io_port, (ulong)shost->io_port + boardp->asc_n_io_port - 1, shost->irq); } @@ -4193,18 +4175,16 @@ static int advansys_reset(struct scsi_cmnd *scp) /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ if (asc_dvc_varp->err_code) { - ASC_PRINT2 - ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n", - boardp->id, asc_dvc_varp->err_code); + ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " + "error: 0x%x\n", boardp->id, + asc_dvc_varp->err_code); ret = FAILED; } else if (status) { - ASC_PRINT2 - ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n", - boardp->id, status); + ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " + "warning: 0x%x\n", boardp->id, status); } else { - ASC_PRINT1 - ("advansys_reset: board %d: SCSI bus reset successful.\n", - boardp->id); + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "successful.\n", boardp->id); } ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); @@ -4225,15 +4205,13 @@ static int advansys_reset(struct scsi_cmnd *scp) ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); switch (AdvResetChipAndSB(adv_dvc_varp)) { case ASC_TRUE: - ASC_PRINT1 - ("advansys_reset: board %d: SCSI bus reset successful.\n", - boardp->id); + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "successful.\n", boardp->id); break; case ASC_FALSE: default: - ASC_PRINT1 - ("advansys_reset: board %d: SCSI bus reset error.\n", - boardp->id); + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "error.\n", boardp->id); ret = FAILED; break; } @@ -4254,8 +4232,8 @@ static int advansys_reset(struct scsi_cmnd *scp) * is returned in 'last_scp'. */ if (done_scp == NULL) { - done_scp = - asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL); + done_scp = asc_dequeue_list(&boardp->active, &last_scp, + ASC_TID_ALL); for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { tscp->result = HOST_BYTE(DID_RESET); } @@ -4281,8 +4259,8 @@ static int advansys_reset(struct scsi_cmnd *scp) * to DID_RESET. */ if (done_scp == NULL) { - done_scp = - asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL); + done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, + ASC_TID_ALL); for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { tscp->result = HOST_BYTE(DID_RESET); } @@ -4313,9 +4291,8 @@ static int advansys_reset(struct scsi_cmnd *scp) /* * Complete all the 'done_scp' requests. */ - if (done_scp != NULL) { + if (done_scp) asc_scsi_done_list(done_scp); - } ASC_DBG1(1, "advansys_reset: ret %d\n", ret); @@ -4829,33 +4806,33 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) case ASC_NOERROR: ASC_STATS(scp->device->host, exe_noerror); /* - * Increment monotonically increasing per device successful - * request counter. Wrapping doesn't matter. + * Increment monotonically increasing per device + * successful request counter. Wrapping doesn't matter. */ boardp->reqcnt[scp->device->id]++; asc_enqueue(&boardp->active, scp, ASC_BACK); - ASC_DBG(1, - "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n"); + ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), " + "ASC_NOERROR\n"); break; case ASC_BUSY: /* - * Caller will enqueue request on the target's waiting queue - * and retry later. + * Caller will enqueue request on the target's waiting + * queue and retry later. */ ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: - ASC_PRINT2 - ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", + boardp->id, asc_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; default: - ASC_PRINT2 - ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AscExeScsiQueue() unknown, err_code 0x%x\n", + boardp->id, asc_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); @@ -4875,20 +4852,21 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) */ switch (adv_build_req(boardp, scp, &adv_scsiqp)) { case ASC_NOERROR: - ASC_DBG(3, - "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n"); + ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_NOERROR\n"); break; case ASC_BUSY: - ASC_DBG(1, - "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n"); + ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_BUSY\n"); /* - * If busy is returned the request has not been enqueued. - * It will be enqueued by the caller on the target's waiting - * queue and retried later. + * If busy is returned the request has not been + * enqueued. It will be enqueued by the caller on the + * target's waiting queue and retried later. * - * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg' - * count wide board busy conditions. They are updated in - * adv_build_req and adv_get_sglist, respectively. + * The asc_stats fields 'adv_build_noreq' and + * 'adv_build_nosg' count wide board busy conditions. + * They are updated in adv_build_req and + * adv_get_sglist, respectively. */ return ASC_BUSY; case ASC_ERROR: @@ -4898,8 +4876,8 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * by the caller. */ default: - ASC_DBG(1, - "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n"); + ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_ERROR\n"); ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } @@ -4912,33 +4890,33 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) case ASC_NOERROR: ASC_STATS(scp->device->host, exe_noerror); /* - * Increment monotonically increasing per device successful - * request counter. Wrapping doesn't matter. + * Increment monotonically increasing per device + * successful request counter. Wrapping doesn't matter. */ boardp->reqcnt[scp->device->id]++; asc_enqueue(&boardp->active, scp, ASC_BACK); - ASC_DBG(1, - "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n"); + ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), " + "ASC_NOERROR\n"); break; case ASC_BUSY: /* - * Caller will enqueue request on the target's waiting queue - * and retry later. + * Caller will enqueue request on the target's waiting + * queue and retry later. */ ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: - ASC_PRINT2 - ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", + boardp->id, adv_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; default: - ASC_PRINT2 - ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AdvExeScsiQueue() unknown, err_code 0x%x\n", + boardp->id, adv_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); @@ -4981,9 +4959,9 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) * is supported. */ if (scp->cmd_len > ASC_MAX_CDB_LEN) { - ASC_PRINT3 - ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n", - boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN); + ASC_PRINT3("asc_build_req: board %d: cmd_len %d > " + "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len, + ASC_MAX_CDB_LEN); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; @@ -7330,27 +7308,27 @@ DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) * Return the BIOS address of the adapter at the specified * I/O port and with the specified bus type. */ -static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type) +static unsigned short __devinit +AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type) { - ushort cfg_lsw; - ushort bios_addr; + unsigned short cfg_lsw; + unsigned short bios_addr; /* * The PCI BIOS is re-located by the motherboard BIOS. Because * of this the driver can not determine where a PCI BIOS is * loaded and executes. */ - if (bus_type & ASC_IS_PCI) { - return (0); - } + if (bus_type & ASC_IS_PCI) + return 0; + #ifdef CONFIG_ISA if ((bus_type & ASC_IS_EISA) != 0) { cfg_lsw = AscGetEisaChipCfg(iop_base); cfg_lsw &= 0x000F; - bios_addr = (ushort)(ASC_BIOS_MIN_ADDR + - (cfg_lsw * ASC_BIOS_BANK_SIZE)); - return (bios_addr); - } /* if */ + bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE; + return bios_addr; + } #endif /* CONFIG_ISA */ cfg_lsw = AscGetChipCfgLsw(iop_base); @@ -7358,13 +7336,10 @@ static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type /* * ISA PnP uses the top bit as the 32K BIOS flag */ - if (bus_type == ASC_IS_ISAPNP) { + if (bus_type == ASC_IS_ISAPNP) cfg_lsw &= 0x7FFF; - } - /* if */ - bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + - ASC_BIOS_MIN_ADDR); - return (bios_addr); + bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE; + return bios_addr; } /* @@ -7661,10 +7636,8 @@ static void asc_prt_scsi_cmnd(struct scsi_cmnd *s) printk(" timeout_per_command %d\n", s->timeout_per_command); - printk - (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n", - (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble, - s->result); + printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n", + s->scsi_done, s->done, s->host_scribble, s->result); printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid); } @@ -7676,34 +7649,31 @@ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) { printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h); - printk - (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n", - h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); + printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl " + "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); - printk - (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n", - h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback, - (unsigned)h->init_sdtr); + printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, " + "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback, + h->exe_callback, (unsigned)h->init_sdtr); - printk - (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n", - (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng, - (unsigned)h->unit_not_ready, (unsigned)h->chip_no); + printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, " + "chip_no 0x%x,\n", (unsigned)h->sdtr_done, + (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready, + (unsigned)h->chip_no); - printk - (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n", - (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor, - (unsigned)h->scsi_reset_wait); + printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait " + "%u,\n", (unsigned)h->queue_full_or_busy, + (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); - printk - (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n", - (unsigned)h->is_in_int, (unsigned)h->max_total_qng, - (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt); + printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, " + "in_critical_cnt %u,\n", (unsigned)h->is_in_int, + (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng, + (unsigned)h->in_critical_cnt); - printk - (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n", - (unsigned)h->last_q_shortage, (unsigned)h->init_state, - (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer); + printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, " + "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage, + (unsigned)h->init_state, (unsigned)h->no_scam, + (unsigned)h->pci_fix_asyn_xfer); printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); } @@ -8007,27 +7977,28 @@ static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) return (AscGetChipScsiID(iop_base)); } -static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base) +static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base) { - uchar sc; + unsigned char sc; AscSetBank(iop_base, 1); sc = inp(iop_base + IOP_REG_SC); AscSetBank(iop_base, 0); - return (sc); + return sc; } -static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type) +static unsigned char __devinit +AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) { - if ((bus_type & ASC_IS_EISA) != 0) { + if (bus_type & ASC_IS_EISA) { PortAddr eisa_iop; - uchar revision; + unsigned char revision; eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | (PortAddr) ASC_EISA_REV_IOP_MASK; revision = inp(eisa_iop); - return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision)); + return ASC_CHIP_MIN_VER_EISA - 1 + revision; } - return (AscGetChipVerNo(iop_base)); + return AscGetChipVerNo(iop_base); } static ushort __devinit AscGetChipBusType(PortAddr iop_base) @@ -10281,13 +10252,12 @@ static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) warn_code |= AscInitAscDvcVar(asc_dvc); warn_code |= AscInitFromEEP(asc_dvc); asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; - if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) { + if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; - } } else { asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; } - return (warn_code); + return warn_code; } static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc) @@ -17154,14 +17124,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type) int ret; /* - * Adapter found. - * * Register the adapter, get its configuration, and * initialize it. */ ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n"); shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t)); - if (!shost) return NULL; @@ -17169,8 +17136,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) boardp = ASC_BOARDP(shost); memset(boardp, 0, sizeof(asc_board_t)); boardp->id = asc_board_count++; - - /* Initialize spinlock. */ spin_lock_init(&boardp->lock); /* @@ -17590,11 +17555,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) */ boardp->init_tidmask |= ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id); - - /* - * Finish initializing the 'Scsi_Host' structure. - */ - shost->irq = adv_dvc_varp->irq_no; } /* -- cgit v1.1 From 59fcf844095a89fe5e42b4e9bfc4b49dd6909e6b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:54:15 -0400 Subject: [SCSI] advansys: delete AscGetChipBusType By moving a test from AscGetChipBusType into its only caller, we can delete the whole function Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index dc9dca3..e661986 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -8001,34 +8001,6 @@ AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) return AscGetChipVerNo(iop_base); } -static ushort __devinit AscGetChipBusType(PortAddr iop_base) -{ - ushort chip_ver; - - chip_ver = AscGetChipVerNo(iop_base); - if ((chip_ver >= ASC_CHIP_MIN_VER_VL) - && (chip_ver <= ASC_CHIP_MAX_VER_VL) - ) { - if (((iop_base & 0x0C30) == 0x0C30) - || ((iop_base & 0x0C50) == 0x0C50) - ) { - return (ASC_IS_EISA); - } - return (ASC_IS_VL); - } - if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) && - (chip_ver <= ASC_CHIP_MAX_VER_ISA)) { - if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) { - return (ASC_IS_ISAPNP); - } - return (ASC_IS_ISA); - } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) && - (chip_ver <= ASC_CHIP_MAX_VER_PCI)) { - return (ASC_IS_PCI); - } - return (0); -} - static ASC_DCNT AscLoadMicroCode(PortAddr iop_base, ushort s_addr, uchar *mcode_buf, ushort mcode_size) @@ -10468,12 +10440,12 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) } asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; - if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) { - AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); - asc_dvc->bus_type = ASC_IS_ISAPNP; - } #ifdef CONFIG_ISA if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { + if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) { + AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); + asc_dvc->bus_type = ASC_IS_ISAPNP; + } asc_dvc->cfg->isa_dma_channel = (uchar)AscGetIsaDmaChannel(iop_base); } -- cgit v1.1 From 57ba5fe988f6e0845c459bbe75ecd6aea536805d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:55:07 -0400 Subject: [SCSI] advansys: ioremap no longer needs page-aligned addresses At some point during Linux 2.1 development, ioremap() gained the ability to handle addresses which weren't page-aligned. Also expand the CONFIG_PCI range to encompass that entire section of wide board initialisation, since all wide boards are PCI. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 52 ++++++++++++------------------------------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e661986..2f37076 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -17090,8 +17090,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_DVC_VAR *asc_dvc_varp = NULL; ADV_DVC_VAR *adv_dvc_varp = NULL; int share_irq; - int iolen = 0; - ADV_PADDR pci_memory_address; int warn_code, err_code; int ret; @@ -17136,13 +17134,13 @@ advansys_board_found(int iop, struct device *dev, int bus_type) asc_dvc_varp->iop_base = iop; asc_dvc_varp->isr_callback = asc_isr_callback; } else { +#ifdef CONFIG_PCI ASC_DBG(1, "advansys_board_found: wide board\n"); adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; adv_dvc_varp->drv_ptr = boardp; adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; adv_dvc_varp->isr_callback = adv_isr_callback; adv_dvc_varp->async_callback = adv_async_callback; -#ifdef CONFIG_PCI if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) { ASC_DBG(1, "advansys_board_found: ASC-3550\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; @@ -17153,46 +17151,20 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_DBG(1, "advansys_board_found: ASC-38C1600\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600; } -#endif /* CONFIG_PCI */ - /* - * Map the board's registers into virtual memory for - * PCI slave access. Only memory accesses are used to - * access the board's registers. - * - * Note: The PCI register base address is not always - * page aligned, but the address passed to ioremap() - * must be page aligned. It is guaranteed that the - * PCI register base address will not cross a page - * boundary. - */ - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - iolen = ADV_3550_IOLEN; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - iolen = ADV_38C0800_IOLEN; - } else { - iolen = ADV_38C1600_IOLEN; - } -#ifdef CONFIG_PCI - pci_memory_address = pci_resource_start(pdev, 1); - ASC_DBG1(1, - "advansys_board_found: pci_memory_address: 0x%lx\n", - (ulong)pci_memory_address); - if ((boardp->ioremap_addr = - ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) { + boardp->asc_n_io_port = pci_resource_len(pdev, 1); + boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1), + boardp->asc_n_io_port); + if (!boardp->ioremap_addr) { ASC_PRINT3 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", - boardp->id, pci_memory_address, iolen); + boardp->id, pci_resource_start(pdev, 1), + boardp->asc_n_io_port); goto err_shost; } - ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n", - (ulong)boardp->ioremap_addr); - adv_dvc_varp->iop_base = (AdvPortAddr) - (boardp->ioremap_addr + - (pci_memory_address - (pci_memory_address & PAGE_MASK))); + adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n", adv_dvc_varp->iop_base); -#endif /* CONFIG_PCI */ /* * Even though it isn't used to access wide boards, other @@ -17201,9 +17173,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type) */ boardp->ioport = iop; - ASC_DBG2(1, - "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n", - (ushort)inp(iop + 1), (ushort)inpw(iop)); + ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, " + "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1), + (ushort)inpw(iop)); +#endif /* CONFIG_PCI */ } #ifdef CONFIG_PROC_FS @@ -17556,7 +17529,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * PCI Memory Mapped I/O. */ shost->io_port = iop; - boardp->asc_n_io_port = iolen; shost->this_id = adv_dvc_varp->chip_scsi_id; -- cgit v1.1 From 4a2d31c811542d37258b3976975395cb1c0fba1c Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:55:34 -0400 Subject: [SCSI] advansys: Stop using n_io_port in Scsi_Host structure n_io_port isn't suitable for advansys because some of the boards have more than 255 bytes of io port space. There's already a driver-private replacement, asc_n_io_port, but for some reason the driver was still setting and occasionally reporting n_io_port. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 2f37076..e79f795 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2289,10 +2289,8 @@ typedef struct adveep_38C1600_config { #define BIOS_CTRL_AIPP_DIS 0x2000 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ -#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */ #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ -#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */ /* * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is @@ -2302,8 +2300,6 @@ typedef struct adveep_38C1600_config { * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory * */ #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ -#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */ -#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */ /* * Byte I/O register address from base of 'iop_base'. @@ -3952,7 +3948,6 @@ static const char *advansys_info(struct Scsi_Host *shost) ASC_DVC_VAR *asc_dvc_varp; ADV_DVC_VAR *adv_dvc_varp; char *busname; - int iolen; char *widename = NULL; boardp = ASC_BOARDP(shost); @@ -3966,13 +3961,12 @@ static const char *advansys_info(struct Scsi_Host *shost) } else { busname = "ISA"; } - /* Don't reference 'shost->n_io_port'; It may be truncated. */ sprintf(info, "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", ASC_VERSION, busname, (ulong)shost->io_port, - (ulong)shost->io_port + boardp->asc_n_io_port - - 1, shost->irq, shost->dma_channel); + (ulong)shost->io_port + ASC_IOADR_GAP - 1, + shost->irq, shost->dma_channel); } else { if (asc_dvc_varp->bus_type & ASC_IS_VL) { busname = "VL"; @@ -3991,12 +3985,11 @@ static const char *advansys_info(struct Scsi_Host *shost) "bus type %d\n", boardp->id, asc_dvc_varp->bus_type); } - /* Don't reference 'shost->n_io_port'; It may be truncated. */ sprintf(info, "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", ASC_VERSION, busname, (ulong)shost->io_port, - (ulong)shost->io_port + boardp->asc_n_io_port - - 1, shost->irq); + (ulong)shost->io_port + ASC_IOADR_GAP - 1, + shost->irq); } } else { /* @@ -4008,19 +4001,16 @@ static const char *advansys_info(struct Scsi_Host *shost) */ adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - iolen = ADV_3550_IOLEN; widename = "Ultra-Wide"; } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - iolen = ADV_38C0800_IOLEN; widename = "Ultra2-Wide"; } else { - iolen = ADV_38C1600_IOLEN; widename = "Ultra3-Wide"; } sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, - (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq); + (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); } ASC_ASSERT(strlen(info) < ASC_INFO_SIZE); ASC_DBG(1, "advansys_info: end\n"); @@ -6700,10 +6690,7 @@ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) boardp->asc_n_io_port); ASC_PRT_NEXT(); - /* 'shost->n_io_port' may be truncated because it is only one byte. */ - len = asc_prt_line(cp, leftlen, - " io_port 0x%x, n_io_port 0x%x\n", - shost->io_port, shost->n_io_port); + len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port); ASC_PRT_NEXT(); if (ASC_NARROW_BOARD(boardp)) { @@ -7595,8 +7582,8 @@ static void asc_prt_scsi_host(struct Scsi_Host *s) printk(" host_busy %u, host_no %d, last_reset %d,\n", s->host_busy, s->host_no, (unsigned)s->last_reset); - printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n", - (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq); + printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", + (ulong)s->base, (ulong)s->io_port, s->irq); printk(" dma_channel %d, this_id %d, can_queue %d,\n", s->dma_channel, s->this_id, s->can_queue); @@ -17537,15 +17524,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) } /* - * 'n_io_port' currently is one byte. - * - * Set a value to 'n_io_port', but never referenced it because - * it may be truncated. - */ - shost->n_io_port = boardp->asc_n_io_port <= 255 ? - boardp->asc_n_io_port : 255; - - /* * Following v1.3.89, 'cmd_per_lun' is no longer needed * and should be set to zero. * -- cgit v1.1 From 394dbf3f4005622fa52f1805eb950f08ce20f636 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:56:40 -0400 Subject: [SCSI] advansys: Move struct device out of the cfg structures The cfg structures are supposed to be disposable after initialisation; with the 'dev' used for DMA mapping in there, that's not possible. Move the dev to the board. Also inline AscInitFromAscDvcVar into its only caller, remove some unnecessary prototypes and sort out a few minor formatting issues. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 104 +++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e79f795..73d974a 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1380,7 +1380,6 @@ typedef struct asc_dvc_cfg { uchar sdtr_period_offset[ASC_MAX_TID + 1]; ushort pci_slot_info; uchar adapter_info[6]; - struct device *dev; } ASC_DVC_CFG; #define ASC_DEF_DVC_CNTL 0xFFFF @@ -1831,7 +1830,6 @@ static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int); static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int); static ushort AscInitAscDvcVar(ASC_DVC_VAR *); static ushort AscInitFromEEP(ASC_DVC_VAR *); -static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *); static ushort AscInitMicroCodeVar(ASC_DVC_VAR *); static int AscTestExternalLram(ASC_DVC_VAR *); static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar); @@ -2827,7 +2825,6 @@ typedef struct adv_dvc_cfg { ushort serial1; /* EEPROM serial number word 1 */ ushort serial2; /* EEPROM serial number word 2 */ ushort serial3; /* EEPROM serial number word 3 */ - struct device *dev; /* pointer to the pci dev structure for this board */ } ADV_DVC_CFG; struct adv_dvc_var; @@ -3000,7 +2997,6 @@ static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); */ static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); static int AdvISR(ADV_DVC_VAR *); -static int AdvInitGetConfig(ADV_DVC_VAR *); static int AdvInitAsc3550Driver(ADV_DVC_VAR *); static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *); static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *); @@ -3597,6 +3593,7 @@ typedef struct adv_req { * field. It is guaranteed to be allocated from DMA-able memory. */ typedef struct asc_board { + struct device *dev; int id; /* Board Id */ uint flags; /* Board flags */ union { @@ -4672,7 +4669,6 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) ASC_DBG(2, "asc_scsi_done_list: begin\n"); while (scp != NULL) { asc_board_t *boardp; - struct device *dev; ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp); tscp = REQPNEXT(scp); @@ -4680,17 +4676,12 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) boardp = ASC_BOARDP(scp->device->host); - if (ASC_NARROW_BOARD(boardp)) - dev = boardp->dvc_cfg.asc_dvc_cfg.dev; - else - dev = boardp->dvc_cfg.adv_dvc_cfg.dev; - if (scp->use_sg) - dma_unmap_sg(dev, + dma_unmap_sg(boardp->dev, (struct scatterlist *)scp->request_buffer, scp->use_sg, scp->sc_data_direction); else if (scp->request_bufflen) - dma_unmap_single(dev, scp->SCp.dma_handle, + dma_unmap_single(boardp->dev, scp->SCp.dma_handle, scp->request_bufflen, scp->sc_data_direction); @@ -4929,8 +4920,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) */ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) { - struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev; - /* * Mutually exclusive access is required to 'asc_scsi_q' and * 'asc_sg_head' until after the request is started. @@ -4994,7 +4983,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) */ ASC_STATS(scp->device->host, cont_cnt); scp->SCp.dma_handle = scp->request_bufflen ? - dma_map_single(dev, scp->request_buffer, + dma_map_single(boardp->dev, scp->request_buffer, scp->request_bufflen, scp->sc_data_direction) : 0; asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); @@ -5012,15 +5001,14 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) struct scatterlist *slp; slp = (struct scatterlist *)scp->request_buffer; - use_sg = - dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); + use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); if (use_sg > scp->device->host->sg_tablesize) { - ASC_PRINT3 - ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", - boardp->id, use_sg, - scp->device->host->sg_tablesize); - dma_unmap_sg(dev, slp, scp->use_sg, + ASC_PRINT3("asc_build_req: board %d: use_sg %d > " + "sg_tablesize %d\n", boardp->id, use_sg, + scp->device->host->sg_tablesize); + dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); @@ -5081,7 +5069,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, ADV_SCSI_REQ_Q *scsiqp; int i; int ret; - struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev; /* * Allocate an adv_req_t structure from the board to execute @@ -5168,7 +5155,7 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, if (scp->request_bufflen) { scsiqp->vdata_addr = scp->request_buffer; scp->SCp.dma_handle = - dma_map_single(dev, scp->request_buffer, + dma_map_single(boardp->dev, scp->request_buffer, scp->request_bufflen, scp->sc_data_direction); } else { @@ -5189,22 +5176,21 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, int use_sg; slp = (struct scatterlist *)scp->request_buffer; - use_sg = - dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); + use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); if (use_sg > ADV_MAX_SG_LIST) { - ASC_PRINT3 - ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", - boardp->id, use_sg, - scp->device->host->sg_tablesize); - dma_unmap_sg(dev, slp, scp->use_sg, + ASC_PRINT3("adv_build_req: board %d: use_sg %d > " + "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg, + scp->device->host->sg_tablesize); + dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); /* - * Free the 'adv_req_t' structure by adding it back to the - * board free list. + * Free the 'adv_req_t' structure by adding it back + * to the board free list. */ reqp->next_reqp = boardp->adv_reqp; boardp->adv_reqp = reqp; @@ -5212,12 +5198,11 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, return ASC_ERROR; } - if ((ret = - adv_get_sglist(boardp, reqp, scp, - use_sg)) != ADV_SUCCESS) { + ret = adv_get_sglist(boardp, reqp, scp, use_sg); + if (ret != ADV_SUCCESS) { /* - * Free the adv_req_t structure by adding it back to the - * board free list. + * Free the adv_req_t structure by adding it back to + * the board free list. */ reqp->next_reqp = boardp->adv_reqp; boardp->adv_reqp = reqp; @@ -10219,30 +10204,21 @@ static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) return warn_code; } -static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc) +static unsigned short __devinit +AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc) { - ushort warn_code = 0; + PortAddr iop_base = asc_dvc->iop_base; + unsigned short cfg_msw; + unsigned short warn_code = 0; asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; if (asc_dvc->err_code != 0) - return (UW_ERR); - if (AscFindSignature(asc_dvc->iop_base)) { - warn_code |= AscInitFromAscDvcVar(asc_dvc); - asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; - } else { + return UW_ERR; + if (!AscFindSignature(asc_dvc->iop_base)) { asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; + return 0; } - return (warn_code); -} - -static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) -{ - PortAddr iop_base; - ushort cfg_msw; - ushort warn_code; - iop_base = asc_dvc->iop_base; - warn_code = 0; cfg_msw = AscGetChipCfgMsw(iop_base); if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); @@ -10265,7 +10241,6 @@ static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) } #ifdef CONFIG_PCI if (asc_dvc->bus_type & ASC_IS_PCI) { - struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev); cfg_msw &= 0xFFC0; AscSetChipCfgMsw(iop_base, cfg_msw); if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { @@ -10295,7 +10270,9 @@ static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); } #endif /* CONFIG_ISA */ - return (warn_code); + + asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; + return warn_code; } static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) @@ -13599,11 +13576,11 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = * For a non-fatal error return a warning code. If there are no warnings * then 0 is returned. */ -static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) +static int __devinit +AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc) { unsigned short warn_code = 0; AdvPortAddr iop_base = asc_dvc->iop_base; - struct pci_dev *pdev = to_pci_dev(asc_dvc->cfg->dev); u16 cmd; int status; @@ -17094,6 +17071,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) memset(boardp, 0, sizeof(asc_board_t)); boardp->id = asc_board_count++; spin_lock_init(&boardp->lock); + boardp->dev = dev; /* * Handle both narrow and wide boards. @@ -17180,7 +17158,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #endif /* CONFIG_PROC_FS */ if (ASC_NARROW_BOARD(boardp)) { - asc_dvc_varp->cfg->dev = dev; /* * Set the board bus type and PCI IRQ before * calling AscInitGetConfig(). @@ -17220,7 +17197,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) break; } } else { - adv_dvc_varp->cfg->dev = dev; /* * For Wide boards set PCI information before calling * AdvInitGetConfig(). @@ -17289,7 +17265,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type) } } else { ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); - if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) { + + ret = AdvInitGetConfig(pdev, adv_dvc_varp); + if (ret != 0) { ASC_PRINT2 ("AdvInitGetConfig: board %d: warning: 0x%x\n", boardp->id, ret); @@ -17345,7 +17323,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Modify board configuration. */ ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); - switch (ret = AscInitSetConfig(asc_dvc_varp)) { + switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) { case 0: /* No error. */ break; case ASC_WARN_IO_PORT_ROTATE: -- cgit v1.1 From 895d6b4ca88ecc69b9301675eb220c6a926d8bb1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:57:06 -0400 Subject: [SCSI] advansys: Remove library-style callback routines Convert adv_isr_callback, adv_async_callback and asc_isr_callback into direct calls. Remove the unused asc_exe_callback. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 50 ++++++++----------------------------------------- 1 file changed, 8 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 73d974a..310b926 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1404,17 +1404,12 @@ typedef struct asc_dvc_cfg { struct asc_dvc_var; /* Forward Declaration. */ -typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *); -typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *); - typedef struct asc_dvc_var { PortAddr iop_base; ushort err_code; ushort dvc_cntl; ushort bug_fix_cntl; ushort bus_type; - ASC_ISR_CALLBACK isr_callback; - ASC_EXE_CALLBACK exe_callback; ASC_SCSI_BIT_ID_TYPE init_sdtr; ASC_SCSI_BIT_ID_TYPE sdtr_done; ASC_SCSI_BIT_ID_TYPE use_tagged_qng; @@ -2830,12 +2825,6 @@ typedef struct adv_dvc_cfg { struct adv_dvc_var; struct adv_scsi_req_q; -typedef void (*ADV_ISR_CALLBACK) - (struct adv_dvc_var *, struct adv_scsi_req_q *); - -typedef void (*ADV_ASYNC_CALLBACK) - (struct adv_dvc_var *, uchar); - /* * Adapter operation variable structure. * @@ -2852,8 +2841,6 @@ typedef struct adv_dvc_var { AdvPortAddr iop_base; /* I/O port address */ ushort err_code; /* fatal error code */ ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ - ADV_ISR_CALLBACK isr_callback; - ADV_ASYNC_CALLBACK async_callback; ushort wdtr_able; /* try WDTR for a device */ ushort sdtr_able; /* try SDTR for a device */ ushort ultra_able; /* try SDTR Ultra speed for a device */ @@ -3671,9 +3658,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *); static int asc_build_req(asc_board_t *, struct scsi_cmnd *); static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); -static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); -static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); -static void adv_async_callback(ADV_DVC_VAR *, uchar); static void asc_enqueue(asc_queue_t *, REQP, int); static REQP asc_dequeue(asc_queue_t *, int); static REQP asc_dequeue_list(asc_queue_t *, REQP *, int); @@ -7624,9 +7608,8 @@ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl " "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); - printk(" bus_type %d, isr_callback 0x%p, exe_callback 0x%p, " - "init_sdtr 0x%x,\n", h->bus_type, h->isr_callback, - h->exe_callback, (unsigned)h->init_sdtr); + printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type, + (unsigned)h->init_sdtr); printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, " "chip_no 0x%x,\n", (unsigned)h->sdtr_done, @@ -8631,10 +8614,8 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) ASC_QDONE_INFO scsiq_buf; ASC_QDONE_INFO *scsiq; int false_overrun; - ASC_ISR_CALLBACK asc_isr_callback; iop_base = asc_dvc->iop_base; - asc_isr_callback = asc_dvc->isr_callback; n_q_used = 1; scsiq = (ASC_QDONE_INFO *)&scsiq_buf; done_q_tail = (uchar)AscGetVarDoneQTail(iop_base); @@ -8746,7 +8727,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) } } if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { - (*asc_isr_callback) (asc_dvc, scsiq); + asc_isr_callback(asc_dvc, scsiq); } else { if ((AscReadLramByte(iop_base, (ushort)(q_addr + (ushort) @@ -8764,7 +8745,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); FATAL_ERR_QDONE: if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { - (*asc_isr_callback) (asc_dvc, scsiq); + asc_isr_callback(asc_dvc, scsiq); } return (0x80); } @@ -8790,9 +8771,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) return int_pending; } - if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) - || (asc_dvc->isr_callback == 0) - ) { + if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) { return (ERR); } if (asc_dvc->in_critical_cnt != 0) { @@ -9191,7 +9170,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) int disable_syn_offset_one_fix; int i; ASC_PADDR addr; - ASC_EXE_CALLBACK asc_exe_callback; ushort sg_entry_cnt = 0; ushort sg_entry_cnt_minus_one = 0; uchar target_ix; @@ -9205,7 +9183,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) iop_base = asc_dvc->iop_base; sg_head = scsiq->sg_head; - asc_exe_callback = asc_dvc->exe_callback; if (asc_dvc->err_code != 0) return (ERR); if (scsiq == (ASC_SCSI_Q *)0L) { @@ -9366,9 +9343,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) AscSendScsiQueue(asc_dvc, scsiq, n_q_required)) == 1) { asc_dvc->in_critical_cnt--; - if (asc_exe_callback != 0) { - (*asc_exe_callback) (asc_dvc, scsiq); - } DvcLeaveCritical(last_int_level); return (sta); } @@ -9414,9 +9388,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) if ((sta = AscSendScsiQueue(asc_dvc, scsiq, n_q_required)) == 1) { asc_dvc->in_critical_cnt--; - if (asc_exe_callback != 0) { - (*asc_exe_callback) (asc_dvc, scsiq); - } DvcLeaveCritical(last_int_level); return (sta); } @@ -16745,7 +16716,7 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) /* * Notify the driver of an asynchronous microcode condition by - * calling the ADV_DVC_VAR.async_callback function. The function + * calling the adv_async_callback function. The function * is passed the microcode ASC_MC_INTRB_CODE byte value. */ if (int_stat & ADV_INTR_STATUS_INTRB) { @@ -16767,9 +16738,7 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) } } - if (asc_dvc->async_callback != 0) { - (*asc_dvc->async_callback) (asc_dvc, intrb_code); - } + adv_async_callback(asc_dvc, intrb_code); } /* @@ -16827,7 +16796,7 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) * the ADV_SCSI_REQ_Q pointer to its callback function. */ scsiq->a_flag |= ADV_SCSIQ_DONE; - (*asc_dvc->isr_callback) (asc_dvc, scsiq); + adv_isr_callback(asc_dvc, scsiq); /* * Note: After the driver callback function is called, 'scsiq' * can no longer be referenced. @@ -17097,15 +17066,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; asc_dvc_varp->iop_base = iop; - asc_dvc_varp->isr_callback = asc_isr_callback; } else { #ifdef CONFIG_PCI ASC_DBG(1, "advansys_board_found: wide board\n"); adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; adv_dvc_varp->drv_ptr = boardp; adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; - adv_dvc_varp->isr_callback = adv_isr_callback; - adv_dvc_varp->async_callback = adv_async_callback; if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) { ASC_DBG(1, "advansys_board_found: ASC-3550\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; -- cgit v1.1 From 13ac2d9c791469d4af51aa65653ab0fbd0916fcc Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 08:10:23 -0600 Subject: [SCSI] advansys: Remove pci_slot_info The driver kept a copy of the PCI config address; refer to the pci_dev associated with the card instead. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 310b926..986c52a 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -854,8 +854,6 @@ typedef unsigned char uchar; #define ERR (-1) #define UW_ERR (uint)(0xFFFF) #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) -#define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) -#define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) #define ASC_DVCLIB_CALL_DONE (1) #define ASC_DVCLIB_CALL_FAILED (0) @@ -1378,7 +1376,6 @@ typedef struct asc_dvc_cfg { uchar max_tag_qng[ASC_MAX_TID + 1]; uchar *overrun_buf; uchar sdtr_period_offset[ASC_MAX_TID + 1]; - ushort pci_slot_info; uchar adapter_info[6]; } ASC_DVC_CFG; @@ -2814,9 +2811,6 @@ typedef struct adv_dvc_cfg { ushort control_flag; /* Microcode Control Flag */ ushort mcode_date; /* Microcode date */ ushort mcode_version; /* Microcode version */ - ushort pci_slot_info; /* high byte device/function number */ - /* bits 7-3 device num., bits 2-0 function num. */ - /* low byte bus num. */ ushort serial1; /* EEPROM serial number word 1 */ ushort serial2; /* EEPROM serial number word 2 */ ushort serial3; /* EEPROM serial number word 3 */ @@ -3632,6 +3626,10 @@ typedef struct asc_board { ushort bios_codelen; /* BIOS Code Segment Length. */ } asc_board_t; +#define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ + dvc_var.adv_dvc_var) +#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) + /* Number of boards detected in system. */ static int asc_board_count; @@ -7764,8 +7762,7 @@ static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); - printk(" control_flag 0x%x, pci_slot_info 0x%x\n", - h->control_flag, h->pci_slot_info); + printk(" control_flag 0x%x\n", h->control_flag); } /* @@ -15201,6 +15198,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) * ready to be 'ored' into SCSI_CFG1. */ if ((asc_dvc->cfg->termination & TERM_SE) == 0) { + struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); /* SE automatic termination control is enabled. */ switch (scsi_cfg1 & C_DET_SE) { /* TERM_SE_HI: on, TERM_SE_LO: on */ @@ -15211,7 +15209,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) break; case 0x0: - if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) { + if (PCI_FUNC(pdev->devfn) == 0) { /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ } else { /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ @@ -15817,15 +15815,14 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) */ if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum) { + struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); warn_code |= ASC_WARN_EEPROM_CHKSUM; /* * Set EEPROM default values. */ for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) { - if (i == 1 - && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != - 0) { + if (i == 1 && PCI_FUNC(pdev->devfn) != 0) { /* * Set Function 1 EEPROM Word 0 MSB * @@ -17146,10 +17143,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #ifdef CONFIG_PCI case ASC_IS_PCI: shost->irq = asc_dvc_varp->irq_no = pdev->irq; - asc_dvc_varp->cfg->pci_slot_info = - ASC_PCI_MKID(pdev->bus->number, - PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); shost->unchecked_isa_dma = FALSE; share_irq = IRQF_SHARED; break; @@ -17169,10 +17162,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) */ #ifdef CONFIG_PCI shost->irq = adv_dvc_varp->irq_no = pdev->irq; - adv_dvc_varp->cfg->pci_slot_info = - ASC_PCI_MKID(pdev->bus->number, - PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); shost->unchecked_isa_dma = FALSE; share_irq = IRQF_SHARED; #endif /* CONFIG_PCI */ -- cgit v1.1 From d68f4321357165346fb15ef41dbbf9dce7894f29 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Jul 2007 11:58:12 -0400 Subject: [SCSI] advansys: use memcpy instead of open-coded loop Use memcpy to initialise eep_config instead of a loop. For AdvInitFrom38C1600EEP where we need to modify the default EEPROM configuration, do it after the loop, and do it using the structure definition, not by finding the right byte. I think it was wrong for big-endian machines. Also delete some non-useful comments and prototypes. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 119 ++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 79 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 986c52a..19c2d19 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3168,13 +3168,6 @@ do { \ #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ /* - * Default EEPROM Configuration structure defined in a_init.c. - */ -static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config; -static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config; -static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config; - -/* * DvcGetPhyAddr() flag arguments */ #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */ @@ -13183,7 +13176,6 @@ static unsigned char _adv_asc38C1600_buf[] = { static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */ -/* a_init.c */ /* * EEPROM Configuration. * @@ -15443,7 +15435,6 @@ static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) AdvPortAddr iop_base; ushort warn_code; ADVEEP_3550_CONFIG eep_config; - int i; iop_base = asc_dvc->iop_base; @@ -15460,15 +15451,12 @@ static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) /* * Set EEPROM default values. */ - for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) { - *((uchar *)&eep_config + i) = - *((uchar *)&Default_3550_EEPROM_Config + i); - } + memcpy(&eep_config, &Default_3550_EEPROM_Config, + sizeof(ADVEEP_3550_CONFIG)); /* - * Assume the 6 byte board serial number that was read - * from EEPROM is correct even if the EEPROM checksum - * failed. + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. */ eep_config.serial_number_word3 = AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); @@ -15597,7 +15585,6 @@ static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) AdvPortAddr iop_base; ushort warn_code; ADVEEP_38C0800_CONFIG eep_config; - int i; uchar tid, termination; ushort sdtr_speed = 0; @@ -15617,15 +15604,12 @@ static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) /* * Set EEPROM default values. */ - for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) { - *((uchar *)&eep_config + i) = - *((uchar *)&Default_38C0800_EEPROM_Config + i); - } + memcpy(&eep_config, &Default_38C0800_EEPROM_Config, + sizeof(ADVEEP_38C0800_CONFIG)); /* - * Assume the 6 byte board serial number that was read - * from EEPROM is correct even if the EEPROM checksum - * failed. + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. */ eep_config.serial_number_word3 = AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); @@ -15800,7 +15784,6 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) AdvPortAddr iop_base; ushort warn_code; ADVEEP_38C1600_CONFIG eep_config; - int i; uchar tid, termination; ushort sdtr_speed = 0; @@ -15821,68 +15804,46 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) /* * Set EEPROM default values. */ - for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) { - if (i == 1 && PCI_FUNC(pdev->devfn) != 0) { - /* - * Set Function 1 EEPROM Word 0 MSB - * - * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11) - * EEPROM bits. - * - * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and - * old Mac system booting problem. The Expansion ROM must - * be disabled in Function 1 for these systems. - * - */ - *((uchar *)&eep_config + i) = - ((* - ((uchar *)&Default_38C1600_EEPROM_Config - + - i)) & - (~ - (((ADV_EEPROM_BIOS_ENABLE | - ADV_EEPROM_INTAB) >> 8) & 0xFF))); + memcpy(&eep_config, &Default_38C1600_EEPROM_Config, + sizeof(ADVEEP_38C1600_CONFIG)); - /* - * Set the INTAB (bit 11) if the GPIO 0 input indicates - * the Function 1 interrupt line is wired to INTA. - * - * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: - * 1 - Function 1 interrupt line wired to INT A. - * 0 - Function 1 interrupt line wired to INT B. - * - * Note: Adapter boards always have Function 0 wired to INTA. - * Put all 5 GPIO bits in input mode and then read - * their input values. - */ - AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, - 0); - if (AdvReadByteRegister - (iop_base, IOPB_GPIO_DATA) & 0x01) { - /* Function 1 interrupt wired to INTA; Set EEPROM bit. */ - *((uchar *)&eep_config + i) |= - ((ADV_EEPROM_INTAB >> 8) & 0xFF); - } - } else { - *((uchar *)&eep_config + i) = - *((uchar *)&Default_38C1600_EEPROM_Config - + i); - } + if (PCI_FUNC(pdev->devfn) != 0) { + u8 ints; + /* + * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 + * and old Mac system booting problem. The Expansion + * ROM must be disabled in Function 1 for these systems + */ + eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE; + /* + * Clear the INTAB (bit 11) if the GPIO 0 input + * indicates the Function 1 interrupt line is wired + * to INTB. + * + * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: + * 1 - Function 1 interrupt line wired to INT A. + * 0 - Function 1 interrupt line wired to INT B. + * + * Note: Function 0 is always wired to INTA. + * Put all 5 GPIO bits in input mode and then read + * their input values. + */ + AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0); + ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA); + if ((ints & 0x01) == 0) + eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB; } /* - * Assume the 6 byte board serial number that was read - * from EEPROM is correct even if the EEPROM checksum - * failed. + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. */ eep_config.serial_number_word3 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); - + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); eep_config.serial_number_word2 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); - + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); eep_config.serial_number_word1 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); AdvSet38C1600EEPConfig(iop_base, &eep_config); } -- cgit v1.1 From 4bd6d7f35661a32ed50b72f02b684f894feeaa48 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 30 Jul 2007 08:41:03 -0600 Subject: [SCSI] advansys: Move documentation to Documentation/scsi The 700+-line comment at the top of the advansys driver fits more comfortably in Documentation/scsi. Delete the sections on: - kernels supported - other files modified (obsolete) - source comments (obsolete) - tests to run - release history (that's what a VCS is for) - contacting connectcom (the domain has expired and the phone number is now in use by another organisation) Known problems/fix list is moved down to the section where jejb put his FIXME. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- Documentation/scsi/advansys.txt | 243 +++++++++++++ drivers/scsi/advansys.c | 766 +--------------------------------------- 2 files changed, 262 insertions(+), 747 deletions(-) create mode 100644 Documentation/scsi/advansys.txt diff --git a/Documentation/scsi/advansys.txt b/Documentation/scsi/advansys.txt new file mode 100644 index 0000000..4a3db62 --- /dev/null +++ b/Documentation/scsi/advansys.txt @@ -0,0 +1,243 @@ +AdvanSys (Advanced System Products, Inc.) manufactures the following +RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow +(8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI +buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit +transfer) SCSI Host Adapters for the PCI bus. + +The CDB counts below indicate the number of SCSI CDB (Command +Descriptor Block) requests that can be stored in the RISC chip +cache and board LRAM. A CDB is a single SCSI command. The driver +detect routine will display the number of CDBs available for each +adapter detected. The number of CDBs used by the driver can be +lowered in the BIOS by changing the 'Host Queue Size' adapter setting. + +Laptop Products: + ABP-480 - Bus-Master CardBus (16 CDB) + +Connectivity Products: + ABP510/5150 - Bus-Master ISA (240 CDB) + ABP5140 - Bus-Master ISA PnP (16 CDB) + ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) + ABP902/3902 - Bus-Master PCI (16 CDB) + ABP3905 - Bus-Master PCI (16 CDB) + ABP915 - Bus-Master PCI (16 CDB) + ABP920 - Bus-Master PCI (16 CDB) + ABP3922 - Bus-Master PCI (16 CDB) + ABP3925 - Bus-Master PCI (16 CDB) + ABP930 - Bus-Master PCI (16 CDB) + ABP930U - Bus-Master PCI Ultra (16 CDB) + ABP930UA - Bus-Master PCI Ultra (16 CDB) + ABP960 - Bus-Master PCI MAC/PC (16 CDB) + ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) + +Single Channel Products: + ABP542 - Bus-Master ISA with floppy (240 CDB) + ABP742 - Bus-Master EISA (240 CDB) + ABP842 - Bus-Master VL (240 CDB) + ABP940 - Bus-Master PCI (240 CDB) + ABP940U - Bus-Master PCI Ultra (240 CDB) + ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB) + ABP970 - Bus-Master PCI MAC/PC (240 CDB) + ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) + ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB) + ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB) + ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB) + ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB) + +Multi-Channel Products: + ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) + ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) + ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) + ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel) + ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) + ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) + ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.) + ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB) + ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB) + +Driver Compile Time Options and Debugging + +The following constants can be defined in the source file. + +1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled) + + Enabling this option adds assertion logic statements to the + driver. If an assertion fails a message will be displayed to + the console, but the system will continue to operate. Any + assertions encountered should be reported to the person + responsible for the driver. Assertion statements may proactively + detect problems with the driver and facilitate fixing these + problems. Enabling assertions will add a small overhead to the + execution of the driver. + +2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled) + + Enabling this option adds tracing functions to the driver and the + ability to set a driver tracing level at boot time. This option is + very useful for debugging the driver, but it will add to the size + of the driver execution image and add overhead to the execution of + the driver. + + The amount of debugging output can be controlled with the global + variable 'asc_dbglvl'. The higher the number the more output. By + default the debug level is 0. + + If the driver is loaded at boot time and the LILO Driver Option + is included in the system, the debug level can be changed by + specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The + first three hex digits of the pseudo I/O Port must be set to + 'deb' and the fourth hex digit specifies the debug level: 0 - F. + The following command line will look for an adapter at 0x330 + and set the debug level to 2. + + linux advansys=0x330,0,0,0,0xdeb2 + + If the driver is built as a loadable module this variable can be + defined when the driver is loaded. The following insmod command + will set the debug level to one. + + insmod advansys.o asc_dbglvl=1 + + Debugging Message Levels: + 0: Errors Only + 1: High-Level Tracing + 2-N: Verbose Tracing + + To enable debug output to console, please make sure that: + + a. System and kernel logging is enabled (syslogd, klogd running). + b. Kernel messages are routed to console output. Check + /etc/syslog.conf for an entry similar to this: + + kern.* /dev/console + + c. klogd is started with the appropriate -c parameter + (e.g. klogd -c 8) + + This will cause printk() messages to be be displayed on the + current console. Refer to the klogd(8) and syslogd(8) man pages + for details. + + Alternatively you can enable printk() to console with this + program. However, this is not the 'official' way to do this. + Debug output is logged in /var/log/messages. + + main() + { + syscall(103, 7, 0, 0); + } + + Increasing LOG_BUF_LEN in kernel/printk.c to something like + 40960 allows more debug messages to be buffered in the kernel + and written to the console or log file. + +3. ADVANSYS_STATS - Enable statistics (Def: Enabled) + + Enabling this option adds statistics collection and display + through /proc to the driver. The information is useful for + monitoring driver and device performance. It will add to the + size of the driver execution image and add minor overhead to + the execution of the driver. + + Statistics are maintained on a per adapter basis. Driver entry + point call counts and transfer size counts are maintained. + Statistics are only available for kernels greater than or equal + to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured. + + AdvanSys SCSI adapter files have the following path name format: + + /proc/scsi/advansys/{0,1,2,3,...} + + This information can be displayed with cat. For example: + + cat /proc/scsi/advansys/0 + + When ADVANSYS_STATS is not defined the AdvanSys /proc files only + contain adapter and device configuration information. + +Driver LILO Option + +If init/main.c is modified as described in the 'Directions for Adding +the AdvanSys Driver to Linux' section (B.4.) above, the driver will +recognize the 'advansys' LILO command line and /etc/lilo.conf option. +This option can be used to either disable I/O port scanning or to limit +scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and +PCI boards will still be searched for and detected. This option only +affects searching for ISA and VL boards. + +Examples: + 1. Eliminate I/O port scanning: + boot: linux advansys= + or + boot: linux advansys=0x0 + 2. Limit I/O port scanning to one I/O port: + boot: linux advansys=0x110 + 3. Limit I/O port scanning to four I/O ports: + boot: linux advansys=0x110,0x210,0x230,0x330 + +For a loadable module the same effect can be achieved by setting +the 'asc_iopflag' variable and 'asc_ioport' array when loading +the driver, e.g. + + insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330 + +If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1) +I/O Port may be added to specify the driver debug level. Refer to +the 'Driver Compile Time Options and Debugging' section above for +more information. + +Credits (Chronological Order) + +Bob Frey wrote the AdvanSys SCSI driver +and maintained it up to 3.3F. He continues to answer questions +and help maintain the driver. + +Nathan Hartwell provided the directions and +basis for the Linux v1.3.X changes which were included in the +1.2 release. + +Thomas E Zerucha pointed out a bug +in advansys_biosparam() which was fixed in the 1.3 release. + +Erik Ratcliffe has done testing of the +AdvanSys driver in the Caldera releases. + +Rik van Riel provided a patch to +AscWaitTixISRDone() which he found necessary to make the +driver work with a SCSI-1 disk. + +Mark Moran has helped test Ultra-Wide +support in the 3.1A driver. + +Doug Gilbert has made changes and +suggestions to improve the driver and done a lot of testing. + +Ken Mort reported a DEBUG compile bug fixed +in 3.2K. + +Tom Rini provided the CONFIG_ISA +patch and helped with PowerPC wide and narrow board support. + +Philip Blundell provided an +advansys_interrupts_enabled patch. + +Dave Jones reported the compiler +warnings generated when CONFIG_PROC_FS was not defined in +the 3.2M driver. + +Jerry Quinn fixed PowerPC support (endian +problems) for wide cards. + +Bryan Henderson helped debug narrow +card error handling. + +Manuel Veloso worked hard on PowerPC narrow +board support and fixed a bug in AscGetEEPConfig(). + +Arnaldo Carvalho de Melo made +save_flags/restore_flags changes. + +Andy Kellner continued the Advansys SCSI +driver development for ConnectCom (Version > 3.3F). + +Ken Witherow for extensive testing during the development of version 3.4. diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 19c2d19..4d4d7c9 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -20,743 +20,6 @@ * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets */ -/* - - Documentation for the AdvanSys Driver - - A. Linux Kernels Supported by this Driver - B. Adapters Supported by this Driver - C. Linux source files modified by AdvanSys Driver - D. Source Comments - E. Driver Compile Time Options and Debugging - F. Driver LILO Option - G. Tests to run before releasing new driver - H. Release History - I. Known Problems/Fix List - J. Credits (Chronological Order) - - A. Linux Kernels Supported by this Driver - - This driver has been tested in the following Linux kernels: v2.2.18 - v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86, - alpha, and PowerPC platforms. - - B. Adapters Supported by this Driver - - AdvanSys (Advanced System Products, Inc.) manufactures the following - RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow - (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI - buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit - transfer) SCSI Host Adapters for the PCI bus. - - The CDB counts below indicate the number of SCSI CDB (Command - Descriptor Block) requests that can be stored in the RISC chip - cache and board LRAM. A CDB is a single SCSI command. The driver - detect routine will display the number of CDBs available for each - adapter detected. The number of CDBs used by the driver can be - lowered in the BIOS by changing the 'Host Queue Size' adapter setting. - - Laptop Products: - ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater) - - Connectivity Products: - ABP510/5150 - Bus-Master ISA (240 CDB) - ABP5140 - Bus-Master ISA PnP (16 CDB) - ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) - ABP902/3902 - Bus-Master PCI (16 CDB) - ABP3905 - Bus-Master PCI (16 CDB) - ABP915 - Bus-Master PCI (16 CDB) - ABP920 - Bus-Master PCI (16 CDB) - ABP3922 - Bus-Master PCI (16 CDB) - ABP3925 - Bus-Master PCI (16 CDB) - ABP930 - Bus-Master PCI (16 CDB) - ABP930U - Bus-Master PCI Ultra (16 CDB) - ABP930UA - Bus-Master PCI Ultra (16 CDB) - ABP960 - Bus-Master PCI MAC/PC (16 CDB) - ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) - - Single Channel Products: - ABP542 - Bus-Master ISA with floppy (240 CDB) - ABP742 - Bus-Master EISA (240 CDB) - ABP842 - Bus-Master VL (240 CDB) - ABP940 - Bus-Master PCI (240 CDB) - ABP940U - Bus-Master PCI Ultra (240 CDB) - ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB) - ABP970 - Bus-Master PCI MAC/PC (240 CDB) - ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) - ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB) - ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB) - ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB) - ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB) - - Multi-Channel Products: - ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) - ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) - ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) - ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel) - ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) - ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) - ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.) - ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB) - ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB) - - C. Linux source files modified by AdvanSys Driver - - This section for historical purposes documents the changes - originally made to the Linux kernel source to add the advansys - driver. As Linux has changed some of these files have also - been modified. - - 1. linux/arch/i386/config.in: - - bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y - - 2. linux/drivers/scsi/hosts.c: - - #ifdef CONFIG_SCSI_ADVANSYS - #include "advansys.h" - #endif - - and after "static struct scsi_host_template builtin_scsi_hosts[] =": - - #ifdef CONFIG_SCSI_ADVANSYS - ADVANSYS, - #endif - - 3. linux/drivers/scsi/Makefile: - - ifdef CONFIG_SCSI_ADVANSYS - SCSI_SRCS := $(SCSI_SRCS) advansys.c - SCSI_OBJS := $(SCSI_OBJS) advansys.o - else - SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o - endif - - 4. linux/init/main.c: - - extern void advansys_setup(char *str, int *ints); - - and add the following lines to the bootsetups[] array. - - #ifdef CONFIG_SCSI_ADVANSYS - { "advansys=", advansys_setup }, - #endif - - D. Source Comments - - 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'. - - 2. This driver should be maintained in multiple files. But to make - it easier to include with Linux and to follow Linux conventions, - the whole driver is maintained in the source files advansys.h and - advansys.c. In this file logical sections of the driver begin with - a comment that contains '---'. The following are the logical sections - of the driver below. - - --- Linux Version - --- Linux Include File - --- Driver Options - --- Debugging Header - --- Asc Library Constants and Macros - --- Adv Library Constants and Macros - --- Driver Constants and Macros - --- Driver Structures - --- Driver Data - --- Driver Function Prototypes - --- Linux 'struct scsi_host_template' and advansys_setup() Functions - --- Loadable Driver Support - --- Miscellaneous Driver Functions - --- Functions Required by the Asc Library - --- Functions Required by the Adv Library - --- Tracing and Debugging Functions - --- Asc Library Functions - --- Adv Library Functions - - 3. The string 'XXX' is used to flag code that needs to be re-written - or that contains a problem that needs to be addressed. - - 4. I have stripped comments from and reformatted the source for the - Asc Library and Adv Library to reduce the size of this file. This - source can be found under the following headings. The Asc Library - is used to support Narrow Boards. The Adv Library is used to - support Wide Boards. - - --- Asc Library Constants and Macros - --- Adv Library Constants and Macros - --- Asc Library Functions - --- Adv Library Functions - - E. Driver Compile Time Options and Debugging - - In this source file the following constants can be defined. They are - defined in the source below. Both of these options are enabled by - default. - - 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled) - - Enabling this option adds assertion logic statements to the - driver. If an assertion fails a message will be displayed to - the console, but the system will continue to operate. Any - assertions encountered should be reported to the person - responsible for the driver. Assertion statements may proactively - detect problems with the driver and facilitate fixing these - problems. Enabling assertions will add a small overhead to the - execution of the driver. - - 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled) - - Enabling this option adds tracing functions to the driver and - the ability to set a driver tracing level at boot time. This - option will also export symbols not required outside the driver to - the kernel name space. This option is very useful for debugging - the driver, but it will add to the size of the driver execution - image and add overhead to the execution of the driver. - - The amount of debugging output can be controlled with the global - variable 'asc_dbglvl'. The higher the number the more output. By - default the debug level is 0. - - If the driver is loaded at boot time and the LILO Driver Option - is included in the system, the debug level can be changed by - specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The - first three hex digits of the pseudo I/O Port must be set to - 'deb' and the fourth hex digit specifies the debug level: 0 - F. - The following command line will look for an adapter at 0x330 - and set the debug level to 2. - - linux advansys=0x330,0,0,0,0xdeb2 - - If the driver is built as a loadable module this variable can be - defined when the driver is loaded. The following insmod command - will set the debug level to one. - - insmod advansys.o asc_dbglvl=1 - - Debugging Message Levels: - 0: Errors Only - 1: High-Level Tracing - 2-N: Verbose Tracing - - To enable debug output to console, please make sure that: - - a. System and kernel logging is enabled (syslogd, klogd running). - b. Kernel messages are routed to console output. Check - /etc/syslog.conf for an entry similar to this: - - kern.* /dev/console - - c. klogd is started with the appropriate -c parameter - (e.g. klogd -c 8) - - This will cause printk() messages to be be displayed on the - current console. Refer to the klogd(8) and syslogd(8) man pages - for details. - - Alternatively you can enable printk() to console with this - program. However, this is not the 'official' way to do this. - Debug output is logged in /var/log/messages. - - main() - { - syscall(103, 7, 0, 0); - } - - Increasing LOG_BUF_LEN in kernel/printk.c to something like - 40960 allows more debug messages to be buffered in the kernel - and written to the console or log file. - - 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0) - - Enabling this option adds statistics collection and display - through /proc to the driver. The information is useful for - monitoring driver and device performance. It will add to the - size of the driver execution image and add minor overhead to - the execution of the driver. - - Statistics are maintained on a per adapter basis. Driver entry - point call counts and transfer size counts are maintained. - Statistics are only available for kernels greater than or equal - to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured. - - AdvanSys SCSI adapter files have the following path name format: - - /proc/scsi/advansys/{0,1,2,3,...} - - This information can be displayed with cat. For example: - - cat /proc/scsi/advansys/0 - - When ADVANSYS_STATS is not defined the AdvanSys /proc files only - contain adapter and device configuration information. - - F. Driver LILO Option - - If init/main.c is modified as described in the 'Directions for Adding - the AdvanSys Driver to Linux' section (B.4.) above, the driver will - recognize the 'advansys' LILO command line and /etc/lilo.conf option. - This option can be used to either disable I/O port scanning or to limit - scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and - PCI boards will still be searched for and detected. This option only - affects searching for ISA and VL boards. - - Examples: - 1. Eliminate I/O port scanning: - boot: linux advansys= - or - boot: linux advansys=0x0 - 2. Limit I/O port scanning to one I/O port: - boot: linux advansys=0x110 - 3. Limit I/O port scanning to four I/O ports: - boot: linux advansys=0x110,0x210,0x230,0x330 - - For a loadable module the same effect can be achieved by setting - the 'asc_iopflag' variable and 'asc_ioport' array when loading - the driver, e.g. - - insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330 - - If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1) - I/O Port may be added to specify the driver debug level. Refer to - the 'Driver Compile Time Options and Debugging' section above for - more information. - - G. Tests to run before releasing new driver - - 1. In the supported kernels verify there are no warning or compile - errors when the kernel is built as both a driver and as a module - and with the following options: - - ADVANSYS_DEBUG - enabled and disabled - CONFIG_SMP - enabled and disabled - CONFIG_PROC_FS - enabled and disabled - - 2. Run tests on an x86, alpha, and PowerPC with at least one narrow - card and one wide card attached to a hard disk and CD-ROM drive: - fdisk, mkfs, fsck, bonnie, copy/compare test from the - CD-ROM to the hard drive. - - H. Release History - - BETA-1.0 (12/23/95): - First Release - - BETA-1.1 (12/28/95): - 1. Prevent advansys_detect() from being called twice. - 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'. - - 1.2 (1/12/96): - 1. Prevent re-entrancy in the interrupt handler which - resulted in the driver hanging Linux. - 2. Fix problem that prevented ABP-940 cards from being - recognized on some PCI motherboards. - 3. Add support for the ABP-5140 PnP ISA card. - 4. Fix check condition return status. - 5. Add conditionally compiled code for Linux v1.3.X. - - 1.3 (2/23/96): - 1. Fix problem in advansys_biosparam() that resulted in the - wrong drive geometry being returned for drives > 1GB with - extended translation enabled. - 2. Add additional tracing during device initialization. - 3. Change code that only applies to ISA PnP adapter. - 4. Eliminate 'make dep' warning. - 5. Try to fix problem with handling resets by increasing their - timeout value. - - 1.4 (5/8/96): - 1. Change definitions to eliminate conflicts with other subsystems. - 2. Add versioning code for the shared interrupt changes. - 3. Eliminate problem in asc_rmqueue() with iterating after removing - a request. - 4. Remove reset request loop problem from the "Known Problems or - Issues" section. This problem was isolated and fixed in the - mid-level SCSI driver. - - 1.5 (8/8/96): - 1. Add support for ABP-940U (PCI Ultra) adapter. - 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for - request_irq and supplying a dev_id pointer to both request_irq() - and free_irq(). - 3. In AscSearchIOPortAddr11() restore a call to check_region() which - should be used before I/O port probing. - 4. Fix bug in asc_prt_hex() which resulted in the displaying - the wrong data. - 5. Incorporate miscellaneous Asc Library bug fixes and new microcode. - 6. Change driver versioning to be specific to each Linux sub-level. - 7. Change statistics gathering to be per adapter instead of global - to the driver. - 8. Add more information and statistics to the adapter /proc file: - /proc/scsi/advansys[0...]. - 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list. - This problem has been addressed with the SCSI mid-level changes - made in v1.3.89. The advansys_select_queue_depths() function - was added for the v1.3.89 changes. - - 1.6 (9/10/96): - 1. Incorporate miscellaneous Asc Library bug fixes and new microcode. - - 1.7 (9/25/96): - 1. Enable clustering and optimize the setting of the maximum number - of scatter gather elements for any particular board. Clustering - increases CPU utilization, but results in a relatively larger - increase in I/O throughput. - 2. Improve the performance of the request queuing functions by - adding a last pointer to the queue structure. - 3. Correct problems with reset and abort request handling that - could have hung or crashed Linux. - 4. Add more information to the adapter /proc file: - /proc/scsi/advansys[0...]. - 5. Remove the request timeout issue form the driver issues list. - 6. Miscellaneous documentation additions and changes. - - 1.8 (10/4/96): - 1. Make changes to handle the new v2.1.0 kernel memory mapping - in which a kernel virtual address may not be equivalent to its - bus or DMA memory address. - 2. Change abort and reset request handling to make it yet even - more robust. - 3. Try to mitigate request starvation by sending ordered requests - to heavily loaded, tag queuing enabled devices. - 4. Maintain statistics on request response time. - 5. Add request response time statistics and other information to - the adapter /proc file: /proc/scsi/advansys[0...]. - - 1.9 (10/21/96): - 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to - make use of mid-level SCSI driver device queue depth flow - control mechanism. This will eliminate aborts caused by a - device being unable to keep up with requests and eliminate - repeat busy or QUEUE FULL status returned by a device. - 2. Incorporate miscellaneous Asc Library bug fixes. - 3. To allow the driver to work in kernels with broken module - support set 'cmd_per_lun' if the driver is compiled as a - module. This change affects kernels v1.3.89 to present. - 4. Remove PCI BIOS address from the driver banner. The PCI BIOS - is relocated by the motherboard BIOS and its new address can - not be determined by the driver. - 5. Add mid-level SCSI queue depth information to the adapter - /proc file: /proc/scsi/advansys[0...]. - - 2.0 (11/14/96): - 1. Change allocation of global structures used for device - initialization to guarantee they are in DMA-able memory. - Previously when the driver was loaded as a module these - structures might not have been in DMA-able memory, causing - device initialization to fail. - - 2.1 (12/30/96): - 1. In advansys_reset(), if the request is a synchronous reset - request, even if the request serial number has changed, then - complete the request. - 2. Add Asc Library bug fixes including new microcode. - 3. Clear inquiry buffer before using it. - 4. Correct ifdef typo. - - 2.2 (1/15/97): - 1. Add Asc Library bug fixes including new microcode. - 2. Add synchronous data transfer rate information to the - adapter /proc file: /proc/scsi/advansys[0...]. - 3. Change ADVANSYS_DEBUG to be disabled by default. This - will reduce the size of the driver image, eliminate execution - overhead, and remove unneeded symbols from the kernel symbol - space that were previously added by the driver. - 4. Add new compile-time option ADVANSYS_ASSERT for assertion - code that used to be defined within ADVANSYS_DEBUG. This - option is enabled by default. - - 2.8 (5/26/97): - 1. Change version number to 2.8 to synchronize the Linux driver - version numbering with other AdvanSys drivers. - 2. Reformat source files without tabs to present the same view - of the file to everyone regardless of the editor tab setting - being used. - 3. Add Asc Library bug fixes. - - 3.1A (1/8/98): - 1. Change version number to 3.1 to indicate that support for - Ultra-Wide adapters (ABP-940UW) is included in this release. - 2. Add Asc Library (Narrow Board) bug fixes. - 3. Report an underrun condition with the host status byte set - to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which - causes the underrun condition to be ignored. When Linux defines - its own DID_UNDERRUN the constant defined in this file can be - removed. - 4. Add patch to AscWaitTixISRDone(). - 5. Add support for up to 16 different AdvanSys host adapter SCSI - channels in one system. This allows four cards with four channels - to be used in one system. - - 3.1B (1/9/98): - 1. Handle that PCI register base addresses are not always page - aligned even though ioremap() requires that the address argument - be page aligned. - - 3.1C (1/10/98): - 1. Update latest BIOS version checked for from the /proc file. - 2. Don't set microcode SDTR variable at initialization. Instead - wait until device capabilities have been detected from an Inquiry - command. - - 3.1D (1/21/98): - 1. Improve performance when the driver is compiled as module by - allowing up to 64 scatter-gather elements instead of 8. - - 3.1E (5/1/98): - 1. Set time delay in AscWaitTixISRDone() to 1000 ms. - 2. Include SMP locking changes. - 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS - access functions. - 4. Update board serial number printing. - 5. Try allocating an IRQ both with and without the IRQF_DISABLED - flag set to allow IRQ sharing with drivers that do not set - the IRQF_DISABLED flag. Also display a more descriptive error - message if request_irq() fails. - 6. Update to latest Asc and Adv Libraries. - - 3.2A (7/22/99): - 1. Update Adv Library to 4.16 which includes support for - the ASC38C0800 (Ultra2/LVD) IC. - - 3.2B (8/23/99): - 1. Correct PCI compile time option for v2.1.93 and greater - kernels, advansys_info() string, and debug compile time - option. - 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater - kernels. This caused an LVD detection/BIST problem problem - among other things. - 3. Sort PCI cards by PCI Bus, Slot, Function ascending order - to be consistent with the BIOS. - 4. Update to Asc Library S121 and Adv Library 5.2. - - 3.2C (8/24/99): - 1. Correct PCI card detection bug introduced in 3.2B that - prevented PCI cards from being detected in kernels older - than v2.1.93. - - 3.2D (8/26/99): - 1. Correct /proc device synchronous speed information display. - Also when re-negotiation is pending for a target device - note this condition with an * and footnote. - 2. Correct initialization problem with Ultra-Wide cards that - have a pre-3.2 BIOS. A microcode variable changed locations - in 3.2 and greater BIOSes which caused WDTR to be attempted - erroneously with drives that don't support WDTR. - - 3.2E (8/30/99): - 1. Fix compile error caused by v2.3.13 PCI structure change. - 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM - checksum error for ISA cards. - 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level - SCSI changes that it depended on were never included in Linux. - - 3.2F (9/3/99): - 1. Handle new initial function code added in v2.3.16 for all - driver versions. - - 3.2G (9/8/99): - 1. Fix PCI board detection in v2.3.13 and greater kernels. - 2. Fix comiple errors in v2.3.X with debugging enabled. - - 3.2H (9/13/99): - 1. Add 64-bit address, long support for Alpha and UltraSPARC. - The driver has been verified to work on an Alpha system. - 2. Add partial byte order handling support for Power PC and - other big-endian platforms. This support has not yet been - completed or verified. - 3. For wide boards replace block zeroing of request and - scatter-gather structures with individual field initialization - to improve performance. - 4. Correct and clarify ROM BIOS version detection. - - 3.2I (10/8/99): - 1. Update to Adv Library 5.4. - 2. Add v2.3.19 underrun reporting to asc_isr_callback() and - adv_isr_callback(). Remove DID_UNDERRUN constant and other - no longer needed code that previously documented the lack - of underrun handling. - - 3.2J (10/14/99): - 1. Eliminate compile errors for v2.0 and earlier kernels. - - 3.2K (11/15/99): - 1. Correct debug compile error in asc_prt_adv_scsi_req_q(). - 2. Update Adv Library to 5.5. - 3. Add ifdef handling for /proc changes added in v2.3.28. - 4. Increase Wide board scatter-gather list maximum length to - 255 when the driver is compiled into the kernel. - - 3.2L (11/18/99): - 1. Fix bug in adv_get_sglist() that caused an assertion failure - at line 7475. The reqp->sgblkp pointer must be initialized - to NULL in adv_get_sglist(). - - 3.2M (11/29/99): - 1. Really fix bug in adv_get_sglist(). - 2. Incorporate v2.3.29 changes into driver. - - 3.2N (4/1/00): - 1. Add CONFIG_ISA ifdef code. - 2. Include advansys_interrupts_enabled name change patch. - 3. For >= v2.3.28 use new SCSI error handling with new function - advansys_eh_bus_reset(). Don't include an abort function - because of base library limitations. - 4. For >= v2.3.28 use per board lock instead of io_request_lock. - 5. For >= v2.3.28 eliminate advansys_command() and - advansys_command_done(). - 6. Add some changes for PowerPC (Big Endian) support, but it isn't - working yet. - 7. Fix "nonexistent resource free" problem that occurred on a module - unload for boards with an I/O space >= 255. The 'n_io_port' field - is only one byte and can not be used to hold an ioport length more - than 255. - - 3.3A (4/4/00): - 1. Update to Adv Library 5.8. - 2. For wide cards add support for CDBs up to 16 bytes. - 3. Eliminate warnings when CONFIG_PROC_FS is not defined. - - 3.3B (5/1/00): - 1. Support for PowerPC (Big Endian) wide cards. Narrow cards - still need work. - 2. Change bitfields to shift and mask access for endian - portability. - - 3.3C (10/13/00): - 1. Update for latest 2.4 kernel. - 2. Test ABP-480 CardBus support in 2.4 kernel - works! - 3. Update to Asc Library S123. - 4. Update to Adv Library 5.12. - - 3.3D (11/22/00): - 1. Update for latest 2.4 kernel. - 2. Create patches for 2.2 and 2.4 kernels. - - 3.3E (1/9/01): - 1. Now that 2.4 is released remove ifdef code for kernel versions - less than 2.2. The driver is now only supported in kernels 2.2, - 2.4, and greater. - 2. Add code to release and acquire the io_request_lock in - the driver entrypoint functions: advansys_detect and - advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver - still holds the io_request_lock on entry to SCSI low-level drivers. - This was supposed to be removed before 2.4 was released but never - happened. When the mid-level SCSI driver is changed all references - to the io_request_lock should be removed from the driver. - 3. Simplify error handling by removing advansys_abort(), - AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are - now handled by resetting the SCSI bus and fully re-initializing - the chip. This simple method of error recovery has proven to work - most reliably after attempts at different methods. Also now only - support the "new" error handling method and remove the obsolete - error handling interface. - 4. Fix debug build errors. - - 3.3F (1/24/01): - 1. Merge with ConnectCom version from Andy Kellner which - updates Adv Library to 5.14. - 2. Make PowerPC (Big Endian) work for narrow cards and - fix problems writing EEPROM for wide cards. - 3. Remove interrupts_enabled assertion function. - - 3.3G (2/16/01): - 1. Return an error from narrow boards if passed a 16 byte - CDB. The wide board can already handle 16 byte CDBs. - - 3.3GJ (4/15/02): - 1. hacks for lk 2.5 series (D. Gilbert) - - 3.3GJD (10/14/02): - 1. change select_queue_depths to slave_configure - 2. make cmd_per_lun be sane again - - 3.3K [2004/06/24]: - 1. continuing cleanup for lk 2.6 series - 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards - 3. Fix problem that oopsed ISA cards - - I. Known Problems/Fix List (XXX) - - 1. Need to add memory mapping workaround. Test the memory mapping. - If it doesn't work revert to I/O port access. Can a test be done - safely? - 2. Handle an interrupt not working. Keep an interrupt counter in - the interrupt handler. In the timeout function if the interrupt - has not occurred then print a message and run in polled mode. - 3. Allow bus type scanning order to be changed. - 4. Need to add support for target mode commands, cf. CAM XPT. - - J. Credits (Chronological Order) - - Bob Frey wrote the AdvanSys SCSI driver - and maintained it up to 3.3F. He continues to answer questions - and help maintain the driver. - - Nathan Hartwell provided the directions and - basis for the Linux v1.3.X changes which were included in the - 1.2 release. - - Thomas E Zerucha pointed out a bug - in advansys_biosparam() which was fixed in the 1.3 release. - - Erik Ratcliffe has done testing of the - AdvanSys driver in the Caldera releases. - - Rik van Riel provided a patch to - AscWaitTixISRDone() which he found necessary to make the - driver work with a SCSI-1 disk. - - Mark Moran has helped test Ultra-Wide - support in the 3.1A driver. - - Doug Gilbert has made changes and - suggestions to improve the driver and done a lot of testing. - - Ken Mort reported a DEBUG compile bug fixed - in 3.2K. - - Tom Rini provided the CONFIG_ISA - patch and helped with PowerPC wide and narrow board support. - - Philip Blundell provided an - advansys_interrupts_enabled patch. - - Dave Jones reported the compiler - warnings generated when CONFIG_PROC_FS was not defined in - the 3.2M driver. - - Jerry Quinn fixed PowerPC support (endian - problems) for wide cards. - - Bryan Henderson helped debug narrow - card error handling. - - Manuel Veloso worked hard on PowerPC narrow - board support and fixed a bug in AscGetEEPConfig(). - - Arnaldo Carvalho de Melo made - save_flags/restore_flags changes. - - Andy Kellner continues the Advansys SCSI - driver development for ConnectCom (Version > 3.3F). - - K. ConnectCom (AdvanSys) Contact Information - - Mail: ConnectCom Solutions, Inc. - 1150 Ringwood Court - San Jose, CA 95131 - Operator/Sales: 1-408-383-9400 - FAX: 1-408-383-9612 - Tech Support: 1-408-467-2930 - Tech Support E-Mail: linux@connectcom.net - FTP Site: ftp.connectcom.net (login: anonymous) - Web Site: http://www.connectcom.net - -*/ - -/* - * --- Linux Include Files - */ - #include #include #include @@ -785,20 +48,29 @@ #include #include -/* FIXME: (by jejb@steeleye.com) +/* FIXME: * - * Although all of the necessary command mapping places have the - * appropriate dma_map.. APIs, the driver still processes its internal - * queue using bus_to_virt() and virt_to_bus() which are illegal under - * the API. The entire queue processing structure will need to be - * altered to fix this. + * 1. Although all of the necessary command mapping places have the + * appropriate dma_map.. APIs, the driver still processes its internal + * queue using bus_to_virt() and virt_to_bus() which are illegal under + * the API. The entire queue processing structure will need to be + * altered to fix this. + * 2. Need to add memory mapping workaround. Test the memory mapping. + * If it doesn't work revert to I/O port access. Can a test be done + * safely? + * 3. Handle an interrupt not working. Keep an interrupt counter in + * the interrupt handler. In the timeout function if the interrupt + * has not occurred then print a message and run in polled mode. + * 4. Need to add support for target mode commands, cf. CAM XPT. + * 5. check DMA mapping functions for failure + * 6. Remove internal queueing + * 7. Use scsi_transport_spi + * 8. advansys_info is not safe against multiple simultaneous callers + * 9. Kill boardp->id + * 10. Add module_param to override ISA/VLB ioport array */ #warning this driver is still not properly converted to the DMA API -/* - * --- Driver Options - */ - /* Enable driver assertions. */ #define ADVANSYS_ASSERT -- cgit v1.1 From a43e6bd1be17573b4f9489190d440677bcb300f6 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 7 Aug 2007 17:38:20 +0900 Subject: [SCSI] fc4: convert to use the data buffer accessors - remove the unnecessary map_single path. - convert to use the new accessors for the sg lists and the parameters. Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/fc4/fc.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 22b62b3..82de9e1 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c @@ -427,15 +427,10 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd memcpy(SCpnt->sense_buffer, ((char *)(rsp+1)), sense_len); } - if (fcmd->data) { - if (SCpnt->use_sg) - dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer, - SCpnt->use_sg, - SCpnt->sc_data_direction); - else - dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen, - SCpnt->sc_data_direction); - } + if (fcmd->data) + dma_unmap_sg(fc->dev, scsi_sglist(SCpnt), + scsi_sg_count(SCpnt), + SCpnt->sc_data_direction); break; default: host_status=DID_ERROR; /* FIXME */ @@ -793,10 +788,14 @@ static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; } else fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED; - if (!SCpnt->request_bufflen && !SCpnt->use_sg) { + + if (!scsi_bufflen(SCpnt)) { cmd->fcp_cntl = fcp_cntl; fcmd->data = (dma_addr_t)NULL; } else { + struct scatterlist *sg; + int nents; + switch (SCpnt->cmnd[0]) { case WRITE_6: case WRITE_10: @@ -805,22 +804,12 @@ static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, default: cmd->fcp_cntl = (FCP_CNTL_READ | fcp_cntl); break; } - if (!SCpnt->use_sg) { - cmd->fcp_data_len = SCpnt->request_bufflen; - fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer, - SCpnt->request_bufflen, - SCpnt->sc_data_direction); - } else { - struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer; - int nents; - - FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) - nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg, - SCpnt->sc_data_direction); - if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yet\n", fc->name, nents, SCpnt->use_sg); - fcmd->data = sg_dma_address(sg); - cmd->fcp_data_len = sg_dma_len(sg); - } + + sg = scsi_sglist(SCpnt); + nents = dma_map_sg(fc->dev, sg, scsi_sg_count(SCpnt), + SCpnt->sc_data_direction); + fcmd->data = sg_dma_address(sg); + cmd->fcp_data_len = sg_dma_len(sg); } memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len); -- cgit v1.1 From a0a74e45057cc3138c29173e7b0b3db8b30939ae Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 9 Aug 2007 20:47:15 +0200 Subject: [SCSI] lpfc: fix potential overflow of hbqs array The Coverity checker noticed that we may overrun a statically allocated array in drivers/scsi/lpfc/lpfc_sli.c::lpfc_sli_hbqbuf_find(). The case is this; In 'struct lpfc_hba' we have #define LPFC_MAX_HBQS 4 ... struct lpfc_hba { ... struct hbq_s hbqs[LPFC_MAX_HBQS]; ... }; But then in lpfc_sli_hbqbuf_find() we have this code hbqno = tag >> 16; if (hbqno > LPFC_MAX_HBQS) return NULL; if 'hbqno' ends up as exactely 4, then we won't return, and then this list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) { will cause an overflow of the statically allocated array at index 4, since the valid indices are only 0-3. I propose this patch, that simply changes the 'hbqno > LPFC_MAX_HBQS' into 'hbqno >= LPFC_MAX_HBQS' as a possible fix. Signed-off-by: Jesper Juhl Acked-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 ce5ff2b..e5337ad 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -675,7 +675,7 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) uint32_t hbqno; hbqno = tag >> 16; - if (hbqno > LPFC_MAX_HBQS) + if (hbqno >= LPFC_MAX_HBQS) return NULL; list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) { -- cgit v1.1 From 87f3bda35e306a449ea75c2bdb79a3c4d84cfa95 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Aug 2007 14:50:30 -0700 Subject: [SCSI] aacraid: rename check_reset Too generic, clashes with ISDN. Signed-off-by: Andrew Morton Acked-by: Mark Salyzyn Signed-off-by: James Bottomley --- drivers/scsi/aacraid/aachba.c | 8 ++++---- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 6800e57..80e448d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -177,9 +177,9 @@ int check_interval = 24 * 60 * 60; module_param(check_interval, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); -int check_reset = 1; -module_param(check_reset, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the adapter."); +int aac_check_reset = 1; +module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter."); int expose_physicals = -1; module_param(expose_physicals, int, S_IRUGO|S_IWUSR); @@ -1305,7 +1305,7 @@ int aac_get_adapter_info(struct aac_dev* dev) (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), dev->supplement_adapter_info.VpdInfo.Tsid); } - if (!check_reset || + if (!aac_check_reset || (dev->supplement_adapter_info.SupportedOptions2 & le32_to_cpu(AAC_OPTION_IGNORE_RESET))) { printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 94727b9..03b5102 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1871,4 +1871,4 @@ extern int aac_reset_devices; extern int aac_commit; extern int update_interval; extern int check_interval; -extern int check_reset; +extern int aac_check_reset; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index bb87090..240a0bb 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1372,8 +1372,9 @@ int aac_check_health(struct aac_dev * aac) printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); - if (!check_reset || (aac->supplement_adapter_info.SupportedOptions2 & - le32_to_cpu(AAC_OPTION_IGNORE_RESET))) + if (!aac_check_reset || + (aac->supplement_adapter_info.SupportedOptions2 & + le32_to_cpu(AAC_OPTION_IGNORE_RESET))) goto out; host = aac->scsi_host_ptr; if (aac->thread->pid != current->pid) -- cgit v1.1 From ffcde188a82497385139c62c6b6362aa4f29406f Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 10 Aug 2007 14:50:38 -0700 Subject: [SCSI] NCR_D700, lpfc: Clean up duplicate includes Signed-off-by: Jesper Juhl Acked-by: James Smart Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/NCR_D700.c | 1 - drivers/scsi/lpfc/lpfc_debugfs.c | 1 - drivers/scsi/lpfc/lpfc_init.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 3a80897..e0f1991 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -97,7 +97,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 2e3c01b..dcf808b 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -43,7 +43,6 @@ #include "lpfc_crtn.h" #include "lpfc_vport.h" #include "lpfc_version.h" -#include "lpfc_vport.h" #include "lpfc_debugfs.h" #ifdef CONFIG_LPFC_DEBUG_FS diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 414350a..42e2061 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -43,7 +43,6 @@ #include "lpfc_crtn.h" #include "lpfc_vport.h" #include "lpfc_version.h" -#include "lpfc_vport.h" static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); -- cgit v1.1 From 305aad0bf5b3f890bf6f59f8045bd553fd1051df Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 10 Aug 2007 14:50:52 -0700 Subject: [SCSI] ips: warning fix drivers/scsi/ips.c: In function 'ips_insert_device': drivers/scsi/ips.c:6957: warning: 'index' may be used uninitialized in this function Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 492a51b..b17771b 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -6946,7 +6946,7 @@ module_exit(ips_module_exit); static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) { - int index; + int uninitialized_var(index); int rc; METHOD_TRACE("ips_insert_device", 1); -- cgit v1.1 From 79ee8304429b497263734e59747df12117de2ea2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 10 Aug 2007 14:50:42 -0700 Subject: [SCSI] scsi_error.c should #include "scsi_transport_api.h" Every file should #include the headers containing the prototypes for its global functions (in this case for scsi_schedule_eh()). Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 8a525ab..c8e351f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -37,6 +37,7 @@ #include "scsi_priv.h" #include "scsi_logging.h" +#include "scsi_transport_api.h" #define SENSE_TIMEOUT (10*HZ) -- cgit v1.1 From 8d9e0f46b4a37077e112bdec3c6228e31547e3c9 Mon Sep 17 00:00:00 2001 From: Gabriel C Date: Fri, 10 Aug 2007 14:50:39 -0700 Subject: [SCSI] NCR5380: fix NCR53C400_PSEUDO_DMA is not defined In file included from drivers/scsi/g_NCR5380_mmio.c:9: drivers/scsi/g_NCR5380.c:559:5: warning: "NCR53C400_PSEUDO_DMA" is not defined Signed-off-by: Gabriel Craciunescu Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/g_NCR5380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 880f70d..607336f 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -556,7 +556,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, } #endif -#if NCR53C400_PSEUDO_DMA +#ifdef NCR53C400_PSEUDO_DMA /** * NCR5380_pread - pseudo DMA read -- cgit v1.1 From 8f8bf7e64ef76e1de66eb5212cd50f6a294d459f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 10 Aug 2007 14:50:43 -0700 Subject: [SCSI] make scsi_decode_sense_buffer and scsi_decode_sense_extras static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/constants.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 2a458d6..7bdeed1 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1235,7 +1235,7 @@ scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) } EXPORT_SYMBOL(scsi_print_sense_hdr); -void +static void scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, struct scsi_sense_hdr *sshdr) { @@ -1258,7 +1258,7 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, } } -void +static void scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, struct scsi_sense_hdr *sshdr) { -- cgit v1.1 From 1fbe85292f50ce6186619b83ed04d1bb91dda569 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 10 Aug 2007 14:50:41 -0700 Subject: [SCSI] dtc: clean up indent damage and add printk levels Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/dtc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 9d52e45..da7409e 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -137,11 +137,9 @@ static struct override { #ifdef OVERRIDE [] __initdata = OVERRIDE; #else -[4] __initdata = { { -0, IRQ_AUTO}, { -0, IRQ_AUTO}, { -0, IRQ_AUTO}, { -0, IRQ_AUTO}}; +[4] __initdata = { + { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO } +}; #endif #define NO_OVERRIDES ARRAY_SIZE(overrides) @@ -176,7 +174,7 @@ static const struct signature { * Inputs : str - unused, ints - array of integer parameters with ints[0] * equal to the number of ints. * -*/ + */ static void __init dtc_setup(char *str, int *ints) { @@ -233,7 +231,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) } else for (; !addr && (current_base < NO_BASES); ++current_base) { #if (DTCDEBUG & DTCDEBUG_INIT) - printk("scsi-dtc : probing address %08x\n", bases[current_base].address); + printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address); #endif if (bases[current_base].noauto) continue; @@ -244,7 +242,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { addr = bases[current_base].address; #if (DTCDEBUG & DTCDEBUG_INIT) - printk("scsi-dtc : detected board.\n"); + printk(KERB_DEBUG "scsi-dtc : detected board.\n"); #endif goto found; } @@ -253,7 +251,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) } #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) - printk("scsi-dtc : base = %08x\n", addr); + printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr); #endif if (!addr) -- cgit v1.1 From 6778a35bd02939767a17463d74da113541c9371f Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Tue, 14 Aug 2007 16:18:02 -0600 Subject: [SCSI] Addition to pci_ids.h for ATTO Technology, Inc. A new PCI_VENDOR_ID for pci_ids.h. signed-off-by: Eric Moore Signed-off-by: James Bottomley --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 07fc574..715a23e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1460,6 +1460,8 @@ #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 +#define PCI_VENDOR_ID_ATTO 0x117c + #define PCI_VENDOR_ID_RICOH 0x1180 #define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 #define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 -- cgit v1.1 From 232f08fc82b15fdcaffc68c558115bfb2b34db86 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Tue, 14 Aug 2007 17:28:27 -0600 Subject: [SCSI] mpt fusion: Add support for ATTO 4LD: Rebranded LSI 53C1030 Per request from Matthew Wilcox - using PCI_VENDOR_ATTO. Add support for ATTO UL4D, they are rebranded 53C1030. The changes are 1. Adding a new PCI vendor ID in pci table 2. The spi_port_page_2 is in different format than that of LSI generic spi_port_page_2 and hence mapping code is added. signed-off-by: Sathya Prakash signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/Kconfig | 1 + drivers/message/fusion/mptbase.c | 32 ++++++++++++++++++++++++++++++++ drivers/message/fusion/mptbase.h | 29 +++++++++++++++++++++++++++++ drivers/message/fusion/mptspi.c | 2 ++ 4 files changed, 64 insertions(+) diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index f55cc03..3c44a2f 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig @@ -20,6 +20,7 @@ config FUSION_SPI LSI53C1020A LSI53C1030 LSI53C1035 + ATTO UL4D config FUSION_FC tristate "Fusion MPT ScsiHost drivers for FC" diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 414c109..828f0ca 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -4888,6 +4888,38 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) /* Nvram data is left with INVALID mark */ rc = 1; + } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) { + + /* This is an ATTO adapter, read Page2 accordingly + */ + ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf; + ATTODeviceInfo_t *pdevice = NULL; + u16 ATTOFlags; + + /* Save the Port Page 2 data + * (reformat into a 32bit quantity) + */ + for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { + pdevice = &pPP2->DeviceSettings[ii]; + ATTOFlags = le16_to_cpu(pdevice->ATTOFlags); + data = 0; + + /* Translate ATTO device flags to LSI format + */ + if (ATTOFlags & ATTOFLAG_DISC) + data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE); + if (ATTOFlags & ATTOFLAG_ID_ENB) + data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE); + if (ATTOFlags & ATTOFLAG_LUN_ENB) + data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE); + if (ATTOFlags & ATTOFLAG_TAGGED) + data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE); + if (!(ATTOFlags & ATTOFLAG_WIDE_ENB)) + data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE); + + data = (data << 16) | (pdevice->Period << 8) | 10; + ioc->spi_data.nvram[ii] = data; + } } else { SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; MpiDeviceInfo_t *pdevice = NULL; diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 15ff226..a8c8080 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -194,6 +194,35 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* + * ATTO UL4D associated structures and defines + */ +#define ATTOFLAG_DISC 0x0001 +#define ATTOFLAG_TAGGED 0x0002 +#define ATTOFLAG_WIDE_ENB 0x0008 +#define ATTOFLAG_ID_ENB 0x0010 +#define ATTOFLAG_LUN_ENB 0x0060 + +typedef struct _ATTO_DEVICE_INFO +{ + u8 Offset; /* 00h */ + u8 Period; /* 01h */ + u16 ATTOFlags; /* 02h */ +} ATTO_DEVICE_INFO, MPI_POINTER PTR_ATTO_DEVICE_INFO, + ATTODeviceInfo_t, MPI_POINTER pATTODeviceInfo_t; + +typedef struct _ATTO_CONFIG_PAGE_SCSI_PORT_2 +{ + CONFIG_PAGE_HEADER Header; /* 00h */ + u16 PortFlags; /* 04h */ + u16 Unused1; /* 06h */ + u32 Unused2; /* 08h */ + ATTO_DEVICE_INFO DeviceSettings[16]; /* 0Ch */ +} fATTO_CONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_ATTO_CONFIG_PAGE_SCSI_PORT_2, + ATTO_SCSIPortPage2_t, MPI_POINTER pATTO_SCSIPortPage2_t; + + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* * MPT protocol driver defs... */ typedef enum { diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 8c98420..25df3bf 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -1190,6 +1190,8 @@ static struct spi_function_template mptspi_transport_functions = { static struct pci_device_id mptspi_pci_table[] = { { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030, PCI_ANY_ID, PCI_ANY_ID }, + { PCI_VENDOR_ID_ATTO, MPI_MANUFACTPAGE_DEVID_53C1030, + PCI_ANY_ID, PCI_ANY_ID }, { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035, PCI_ANY_ID, PCI_ANY_ID }, {0} /* Terminating entry */ -- cgit v1.1 From 7a195f464e0692607aca8150c8489a838fab684b Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Tue, 14 Aug 2007 16:08:40 +0530 Subject: [SCSI] mpt fusion: Usage of high priority request FIFO to send task management commands Added support for sending the task management requests through High priority request FIFO instead of Doorbell writes when firmware support High priority FIFO. signed-off-by: Sathya Prakash Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 33 +++++++++++++++++++++++++++++ drivers/message/fusion/mptbase.h | 4 +++- drivers/message/fusion/mptctl.c | 44 +++++++++++++++++++++++++-------------- drivers/message/fusion/mptsas.c | 8 +------ drivers/message/fusion/mptscsih.c | 14 +++++++++---- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 828f0ca..7ef86cb 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -842,6 +842,38 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); } +/** + * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame + * to a IOC using hi priority request queue. + * @handle: Handle of registered MPT protocol driver + * @ioc: Pointer to MPT adapter structure + * @mf: Pointer to MPT request frame + * + * This routine posts a MPT request frame to the request post FIFO of a + * specific MPT adapter. + **/ +void +mpt_put_msg_frame_hi_pri(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) +{ + u32 mf_dma_addr; + int req_offset; + u16 req_idx; /* Request index */ + + /* ensure values are reset properly! */ + mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; + req_offset = (u8 *)mf - (u8 *)ioc->req_frames; + req_idx = req_offset / ioc->req_sz; + mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); + mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; + + DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); + + mf_dma_addr = (ioc->req_frames_low_dma + req_offset); + dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n", + ioc->name, mf_dma_addr, req_idx)); + CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr); +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_free_msg_frame - Place MPT request frame back on FreeQ. @@ -7315,6 +7347,7 @@ EXPORT_SYMBOL(mpt_device_driver_register); EXPORT_SYMBOL(mpt_device_driver_deregister); EXPORT_SYMBOL(mpt_get_msg_frame); EXPORT_SYMBOL(mpt_put_msg_frame); +EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); EXPORT_SYMBOL(mpt_free_msg_frame); EXPORT_SYMBOL(mpt_add_sge); EXPORT_SYMBOL(mpt_send_handshake_request); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a8c8080..012be5e 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -336,7 +336,8 @@ typedef struct _SYSIF_REGS u32 Reserved2[2]; /* 38-3F reserved for future use */ u32 RequestFifo; /* 40 Request Post/Free FIFO */ u32 ReplyFifo; /* 44 Reply Post/Free FIFO */ - u32 Reserved3[2]; /* 48-4F reserved for future use */ + u32 RequestHiPriFifo; /* 48 Hi Priority Request FIFO */ + u32 Reserved3; /* 4C-4F reserved for future use */ u32 HostIndex; /* 50 Host Index register */ u32 Reserved4[15]; /* 54-8F */ u32 Fubar; /* 90 For Fubar usage */ @@ -893,6 +894,7 @@ extern void mpt_device_driver_deregister(int cb_idx); extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc); extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); +extern void mpt_put_msg_frame_hi_pri(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr); extern int mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 89695e7..dce1e9c 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -342,7 +342,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) SCSITaskMgmt_t *pScsiTm; MPT_SCSI_HOST *hd; int ii; - int retval; + int retval=0; ioctl->reset &= ~MPTCTL_RESET_OK; @@ -395,12 +395,19 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) DBG_DUMP_TM_REQUEST_FRAME(ioctl->ioc, (u32 *)mf); ioctl->wait_done=0; - if ((retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc, - sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { - dfailprintk(ioctl->ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!" - " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, - hd->ioc, mf)); - goto mptctl_bus_reset_done; + + if ((ioctl->ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && + (ioctl->ioc->facts.MsgVersion >= MPI_VERSION_01_05)) + mpt_put_msg_frame_hi_pri(mptctl_id, ioctl->ioc, mf); + else { + retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc, + sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP); + if (retval != 0) { + dfailprintk(ioctl->ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!" + " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, + hd->ioc, mf)); + goto mptctl_bus_reset_done; + } } /* Now wait for the command to complete */ @@ -2187,15 +2194,20 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf); - if (mpt_send_handshake_request(mptctl_id, ioc, - sizeof(SCSITaskMgmt_t), (u32*)mf, - CAN_SLEEP) != 0) { - dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!" - " (ioc %p, mf %p) \n", ioc->name, - ioc, mf)); - mptctl_free_tm_flags(ioc); - rc = -ENODATA; - goto done_free_mem; + if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && + (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) + mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf); + else { + rc =mpt_send_handshake_request(mptctl_id, ioc, + sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); + if (rc != 0) { + dfailprintk(ioc, printk(MYIOC_s_ERR_FMT + "_send_handshake FAILED! (ioc %p, mf %p)\n", + ioc->name, ioc, mf)); + mptctl_free_tm_flags(ioc); + rc = -ENODATA; + goto done_free_mem; + } } } else diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index b9c69bf..fe3b505 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -623,13 +623,7 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id) DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf); - if (mpt_send_handshake_request(ioc->TaskCtx, ioc, - sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) { - mpt_free_msg_frame(ioc, mf); - dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n", - ioc->name,__FUNCTION__, __LINE__)); - return 0; - } + mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf); return 1; } diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 5431529..b8b0598 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1717,12 +1717,18 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm); - if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, - sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { - dfailprintk(hd->ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!" + if ((hd->ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && + (hd->ioc->facts.MsgVersion >= MPI_VERSION_01_05)) + mpt_put_msg_frame_hi_pri(hd->ioc->TaskCtx, hd->ioc, mf); + else { + retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, + sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP); + if (retval) { + dfailprintk(hd->ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!" " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd, hd->ioc, mf, retval)); - goto fail_out; + goto fail_out; + } } if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { -- cgit v1.1 From f606f5718fa5a36e400000f91c44a5725b0f005d Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Tue, 14 Aug 2007 16:12:53 +0530 Subject: [SCSI] mpt fusion: Change call back indices to u8 from int The call back index requires only u8 but in lot of places it is referred as int, now everywhere the call back index variables are declared as u8 with uniform name cb_idx signed-off-by: Sathya Prakash Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 220 +++++++++++++++++++++------------------ drivers/message/fusion/mptbase.h | 33 +++--- drivers/message/fusion/mptctl.c | 5 +- drivers/message/fusion/mptfc.c | 6 +- drivers/message/fusion/mptlan.c | 16 +-- drivers/message/fusion/mptsas.c | 8 +- drivers/message/fusion/mptspi.c | 6 +- 7 files changed, 150 insertions(+), 144 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 7ef86cb..8cf0f51 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -102,8 +102,6 @@ static int mfcounter = 0; /* * Public data... */ -int mpt_lan_index = -1; -int mpt_stm_index = -1; struct proc_dir_entry *mpt_proc_root_dir; @@ -125,11 +123,14 @@ static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS]; static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; -static int mpt_base_index = -1; -static int last_drv_idx = -1; - static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq); +/* + * Driver Callback Index's + */ +static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS; +static u8 last_drv_idx; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Forward protos... @@ -235,6 +236,23 @@ static int mpt_set_debug_level(const char *val, struct kernel_param *kp) return 0; } +/** + * mpt_get_cb_idx - obtain cb_idx for registered driver + * @dclass: class driver enum + * + * Returns cb_idx, or zero means it wasn't found + **/ +static u8 +mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) +{ + u8 cb_idx; + + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) + if (MptDriverClass[cb_idx] == dclass) + return cb_idx; + return 0; +} + /* * Process turbo (context) reply... */ @@ -243,8 +261,8 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) { MPT_FRAME_HDR *mf = NULL; MPT_FRAME_HDR *mr = NULL; - int req_idx = 0; - int cb_idx; + u16 req_idx = 0; + u8 cb_idx; dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa)); @@ -256,7 +274,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) mf = MPT_INDEX_2_MFPTR(ioc, req_idx); break; case MPI_CONTEXT_REPLY_TYPE_LAN: - cb_idx = mpt_lan_index; + cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER); /* * Blind set of mf to NULL here was fatal * after lan_reply says "freeme" @@ -277,7 +295,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); break; case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET: - cb_idx = mpt_stm_index; + cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER); mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); break; default: @@ -286,7 +304,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) } /* Check for (valid) IO callback! */ - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", __FUNCTION__, ioc->name, cb_idx); @@ -304,8 +322,8 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) { MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mr; - int req_idx; - int cb_idx; + u16 req_idx; + u8 cb_idx; int freeme; u32 reply_dma_low; @@ -350,7 +368,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) mpt_iocstatus_info(ioc, (u32)ioc_stat, mf); /* Check for (valid) IO callback! */ - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", __FUNCTION__, ioc->name, cb_idx); @@ -563,28 +581,27 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) * in order to register separate callbacks; one for "normal" SCSI IO; * one for MptScsiTaskMgmt requests; one for Scan/DV requests. * - * Returns a positive integer valued "handle" in the - * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful. - * Any non-positive return value (including zero!) should be considered - * an error by the caller. + * Returns u8 valued "handle" in the range (and S.O.D. order) + * {N,...,7,6,5,...,1} if successful. + * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be + * considered an error by the caller. */ -int +u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) { - int i; - - last_drv_idx = -1; + u8 cb_idx; + last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; /* * Search for empty callback slot in this order: {N,...,7,6,5,...,1} * (slot/handle 0 is reserved!) */ - for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) { - if (MptCallbacks[i] == NULL) { - MptCallbacks[i] = cbfunc; - MptDriverClass[i] = dclass; - MptEvHandlers[i] = NULL; - last_drv_idx = i; + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + if (MptCallbacks[cb_idx] == NULL) { + MptCallbacks[cb_idx] = cbfunc; + MptDriverClass[cb_idx] = dclass; + MptEvHandlers[cb_idx] = NULL; + last_drv_idx = cb_idx; break; } } @@ -601,9 +618,9 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) * module is unloaded. */ void -mpt_deregister(int cb_idx) +mpt_deregister(u8 cb_idx) { - if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { + if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { MptCallbacks[cb_idx] = NULL; MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; MptEvHandlers[cb_idx] = NULL; @@ -625,9 +642,9 @@ mpt_deregister(int cb_idx) * Returns 0 for success. */ int -mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc) +mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) { - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -1; MptEvHandlers[cb_idx] = ev_cbfunc; @@ -645,9 +662,9 @@ mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc) * or when its module is unloaded. */ void -mpt_event_deregister(int cb_idx) +mpt_event_deregister(u8 cb_idx) { - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return; MptEvHandlers[cb_idx] = NULL; @@ -665,9 +682,9 @@ mpt_event_deregister(int cb_idx) * Returns 0 for success. */ int -mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func) +mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func) { - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -1; MptResetHandlers[cb_idx] = reset_func; @@ -684,9 +701,9 @@ mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func) * or when its module is unloaded. */ void -mpt_reset_deregister(int cb_idx) +mpt_reset_deregister(u8 cb_idx) { - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return; MptResetHandlers[cb_idx] = NULL; @@ -699,12 +716,12 @@ mpt_reset_deregister(int cb_idx) * @cb_idx: MPT protocol driver index */ int -mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) +mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx) { MPT_ADAPTER *ioc; const struct pci_device_id *id; - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -EINVAL; MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; @@ -726,12 +743,12 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) * @cb_idx: MPT protocol driver index */ void -mpt_device_driver_deregister(int cb_idx) +mpt_device_driver_deregister(u8 cb_idx) { struct mpt_pci_driver *dd_cbfunc; MPT_ADAPTER *ioc; - if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return; dd_cbfunc = MptDeviceDriverHandlers[cb_idx]; @@ -749,14 +766,14 @@ mpt_device_driver_deregister(int cb_idx) /** * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024) * allocated per MPT adapter. - * @handle: Handle of registered MPT protocol driver + * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * * Returns pointer to a MPT request frame or %NULL if none are available * or IOC is not active. */ MPT_FRAME_HDR* -mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) +mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) { MPT_FRAME_HDR *mf; unsigned long flags; @@ -781,7 +798,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) u.frame.linkage.list); list_del(&mf->u.frame.linkage.list); mf->u.frame.linkage.arg1 = 0; - mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */ + mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ req_offset = (u8 *)mf - (u8 *)ioc->req_frames; /* u16! */ req_idx = req_offset / ioc->req_sz; @@ -805,7 +822,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) #endif dmfprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n", - ioc->name, handle, ioc->id, mf)); + ioc->name, cb_idx, ioc->id, mf)); return mf; } @@ -813,7 +830,7 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) /** * mpt_put_msg_frame - Send a protocol specific MPT request frame * to a IOC. - * @handle: Handle of registered MPT protocol driver + * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * @@ -821,14 +838,14 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc) * specific MPT adapter. */ void -mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) +mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) { u32 mf_dma_addr; int req_offset; u16 req_idx; /* Request index */ /* ensure values are reset properly! */ - mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */ + mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ req_offset = (u8 *)mf - (u8 *)ioc->req_frames; /* u16! */ req_idx = req_offset / ioc->req_sz; @@ -845,7 +862,7 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) /** * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame * to a IOC using hi priority request queue. - * @handle: Handle of registered MPT protocol driver + * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * @@ -853,14 +870,14 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) * specific MPT adapter. **/ void -mpt_put_msg_frame_hi_pri(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) +mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) { u32 mf_dma_addr; int req_offset; u16 req_idx; /* Request index */ /* ensure values are reset properly! */ - mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; + mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; req_offset = (u8 *)mf - (u8 *)ioc->req_frames; req_idx = req_offset / ioc->req_sz; mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); @@ -931,7 +948,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mpt_send_handshake_request - Send MPT request via doorbell handshake method. - * @handle: Handle of registered MPT protocol driver + * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @reqBytes: Size of the request in bytes * @req: Pointer to MPT request frame @@ -946,7 +963,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) * Returns 0 for success, non-zero for failure. */ int -mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) +mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) { int r = 0; u8 *req_as_bytes; @@ -966,7 +983,7 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) { MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req; mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii); - mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; + mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; } /* Make sure there are no doorbells */ @@ -1432,6 +1449,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) u32 msize; u32 psize; int ii; + u8 cb_idx; int r = -ENODEV; u8 revision; u8 pcixcmd; @@ -1655,10 +1673,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) } /* call per device driver probe entry point */ - for(ii=0; iiprobe) { - MptDeviceDriverHandlers[ii]->probe(pdev,id); + for(cb_idx=0; cb_idxprobe) { + MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); } } @@ -1695,7 +1713,7 @@ mpt_detach(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); char pname[32]; - int ii; + u8 cb_idx; sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); remove_proc_entry(pname, NULL); @@ -1705,10 +1723,10 @@ mpt_detach(struct pci_dev *pdev) remove_proc_entry(pname, NULL); /* call per device driver remove entry point */ - for(ii=0; iiremove) { - MptDeviceDriverHandlers[ii]->remove(pdev); + for(cb_idx=0; cb_idxremove) { + MptDeviceDriverHandlers[cb_idx]->remove(pdev); } } @@ -1820,7 +1838,7 @@ mpt_resume(struct pci_dev *pdev) #endif static int -mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase) +mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) { if ((MptDriverClass[index] == MPTSPI_DRIVER && ioc->bus_type != SPI) || @@ -1862,6 +1880,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) int hard; int rc=0; int ii; + u8 cb_idx; int handlers; int ret = 0; int reset_alt_ioc_active = 0; @@ -2146,20 +2165,20 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) */ if (hard_reset_done) { rc = handlers = 0; - for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if ((ret == 0) && MptResetHandlers[ii]) { + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + if ((ret == 0) && MptResetHandlers[cb_idx]) { dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC post_reset handler #%d\n", - ioc->name, ii)); - rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET); + ioc->name, cb_idx)); + rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET); handlers++; } - if (alt_ioc_ready && MptResetHandlers[ii]) { + if (alt_ioc_ready && MptResetHandlers[cb_idx]) { drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s post_reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, ii)); - rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET); + ioc->name, ioc->alt_ioc->name, cb_idx)); + rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET); handlers++; } } @@ -3592,20 +3611,20 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) * MptResetHandlers[] registered yet. */ { - int ii; + u8 cb_idx; int r = 0; - for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if (MptResetHandlers[ii]) { + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + if (MptResetHandlers[cb_idx]) { dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC pre_reset handler #%d\n", - ioc->name, ii)); - r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET); + ioc->name, cb_idx)); + r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET); if (ioc->alt_ioc) { dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s pre_reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, ii)); - r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET); + ioc->name, ioc->alt_ioc->name, cb_idx)); + r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET); } } } @@ -5907,7 +5926,7 @@ procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eo static int procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) { - int ii; + u8 cb_idx; int scsi, fc, sas, lan, ctl, targ, dmp; char *drvname; int len; @@ -5916,10 +5935,10 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo len += sprintf(buf+len, " Fusion MPT base driver\n"); scsi = fc = sas = lan = ctl = targ = dmp = 0; - for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { + for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { drvname = NULL; - if (MptCallbacks[ii]) { - switch (MptDriverClass[ii]) { + if (MptCallbacks[cb_idx]) { + switch (MptDriverClass[cb_idx]) { case MPTSPI_DRIVER: if (!scsi++) drvname = "SPI host"; break; @@ -6163,18 +6182,18 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) * For all other protocol drivers, this is a no-op. */ { - int ii; + u8 cb_idx; int r = 0; - for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if (MptResetHandlers[ii]) { + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + if (MptResetHandlers[cb_idx]) { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n", - ioc->name, ii)); - r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET); + ioc->name, cb_idx)); + r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); if (ioc->alt_ioc) { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, ii)); - r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET); + ioc->name, ioc->alt_ioc->name, cb_idx)); + r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET); } } } @@ -6579,6 +6598,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply u32 evData0 = 0; // u32 evCtx; int ii; + u8 cb_idx; int r = 0; int handlers = 0; char evStr[EVENT_DESCR_STR_SZ]; @@ -6659,11 +6679,11 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply /* * Call each currently registered protocol event handler. */ - for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { - if (MptEvHandlers[ii]) { + for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + if (MptEvHandlers[cb_idx]) { devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n", - ioc->name, ii)); - r += (*(MptEvHandlers[ii]))(ioc, pEventReply); + ioc->name, cb_idx)); + r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); handlers++; } } @@ -7354,8 +7374,6 @@ EXPORT_SYMBOL(mpt_send_handshake_request); EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_print_ioc_summary); -EXPORT_SYMBOL(mpt_lan_index); -EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); EXPORT_SYMBOL(mpt_findImVolumes); @@ -7373,16 +7391,16 @@ EXPORT_SYMBOL(mpt_raid_phys_disk_pg0); static int __init fusion_init(void) { - int i; + u8 cb_idx; show_mptmod_ver(my_NAME, my_VERSION); printk(KERN_INFO COPYRIGHT "\n"); - for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) { - MptCallbacks[i] = NULL; - MptDriverClass[i] = MPTUNKNOWN_DRIVER; - MptEvHandlers[i] = NULL; - MptResetHandlers[i] = NULL; + for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { + MptCallbacks[cb_idx] = NULL; + MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; + MptEvHandlers[cb_idx] = NULL; + MptResetHandlers[cb_idx] = NULL; } /* Register ourselves (mptbase) in order to facilitate diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 012be5e..04ef0a3 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -679,9 +679,9 @@ typedef struct _MPT_ADAPTER u8 reload_fw; /* Force a FW Reload on next reset */ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */ u8 pad1[4]; - int DoneCtx; - int TaskCtx; - int InternalCtx; + u8 DoneCtx; + u8 TaskCtx; + u8 InternalCtx; spinlock_t initializing_hba_lock; int initializing_hba_lock_flag; struct list_head list; @@ -883,21 +883,21 @@ extern void mpt_detach(struct pci_dev *pdev); extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state); extern int mpt_resume(struct pci_dev *pdev); #endif -extern int mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass); -extern void mpt_deregister(int cb_idx); -extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc); -extern void mpt_event_deregister(int cb_idx); -extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func); -extern void mpt_reset_deregister(int cb_idx); -extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx); -extern void mpt_device_driver_deregister(int cb_idx); -extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc); +extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass); +extern void mpt_deregister(u8 cb_idx); +extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc); +extern void mpt_event_deregister(u8 cb_idx); +extern int mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func); +extern void mpt_reset_deregister(u8 cb_idx); +extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx); +extern void mpt_device_driver_deregister(u8 cb_idx); +extern MPT_FRAME_HDR *mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc); extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); -extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); -extern void mpt_put_msg_frame_hi_pri(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); +extern void mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); +extern void mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr); -extern int mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); +extern int mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); @@ -915,9 +915,6 @@ extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhys extern struct list_head ioc_list; extern struct proc_dir_entry *mpt_proc_root_dir; -extern int mpt_lan_index; /* needed by mptlan.c */ -extern int mpt_stm_index; /* needed by mptstm.c */ - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index dce1e9c..89cab57 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -83,7 +83,7 @@ MODULE_VERSION(my_VERSION); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static int mptctl_id = -1; +static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS; static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait ); @@ -2936,7 +2936,8 @@ static int __init mptctl_init(void) * Install our handler */ ++where; - if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) { + mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER); + if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) { printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); misc_deregister(&mptctl_miscdev); err = -EBUSY; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 8422c25..2b3e27a 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -90,9 +90,9 @@ static int max_lun = MPTFC_MAX_LUN; module_param(max_lun, int, 0); MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); -static int mptfcDoneCtx = -1; -static int mptfcTaskCtx = -1; -static int mptfcInternalCtx = -1; /* Used only for internal commands */ +static u8 mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; static int mptfc_target_alloc(struct scsi_target *starget); static int mptfc_slave_alloc(struct scsi_device *sdev); diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 01fc397..9d9eb76 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -154,7 +154,7 @@ static unsigned short mpt_lan_type_trans(struct sk_buff *skb, /* * Fusion MPT LAN private data */ -static int LanCtx = -1; +static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS; static u32 max_buckets_out = 127; static u32 tx_max_out_p = 127 - 16; @@ -165,12 +165,6 @@ DEFINE_RWLOCK(bad_naa_lock); #endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/* - * Fusion MPT LAN external data - */ -extern int mpt_lan_index; - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * lan_reply - Handle all data sent from the hardware. * @ioc: Pointer to MPT_ADAPTER structure @@ -1510,9 +1504,6 @@ static int __init mpt_lan_init (void) return -EBUSY; } - /* Set the callback index to be used by driver core for turbo replies */ - mpt_lan_index = LanCtx; - dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx)); if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset)) { @@ -1533,10 +1524,9 @@ static void __exit mpt_lan_exit(void) mpt_device_driver_deregister(MPTLAN_DRIVER); mpt_reset_deregister(LanCtx); - if (LanCtx >= 0) { + if (LanCtx) { mpt_deregister(LanCtx); - LanCtx = -1; - mpt_lan_index = 0; + LanCtx = MPT_MAX_PROTOCOL_DRIVERS; } } diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index fe3b505..ffbf0e5 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -89,10 +89,10 @@ static int max_lun = MPTSAS_MAX_LUN; module_param(max_lun, int, 0); MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); -static int mptsasDoneCtx = -1; -static int mptsasTaskCtx = -1; -static int mptsasInternalCtx = -1; /* Used only for internal commands */ -static int mptsasMgmtCtx = -1; +static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */ +static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS; static void mptsas_hotplug_work(struct work_struct *work); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 25df3bf..f0618c5 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -90,9 +90,9 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *, static struct scsi_transport_template *mptspi_transport_template = NULL; -static int mptspiDoneCtx = -1; -static int mptspiTaskCtx = -1; -static int mptspiInternalCtx = -1; /* Used only for internal commands */ +static u8 mptspiDoneCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptspiTaskCtx = MPT_MAX_PROTOCOL_DRIVERS; +static u8 mptspiInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */ /** * mptspi_setTargetNegoParms - Update the target negotiation parameters -- cgit v1.1 From 56af97ae477cf8c2983edf86db2559d6394ca860 Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Tue, 14 Aug 2007 16:15:38 +0530 Subject: [SCSI] mpt fusion: Creation of mptsas.h header file The data structure definitions from mptsas.c are moved to a new header file mptsas.h signed-off-by: Sathya Prakash Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 106 +-------------------------- drivers/message/fusion/mptsas.h | 158 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 105 deletions(-) create mode 100644 drivers/message/fusion/mptsas.h diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index ffbf0e5..5951fe0 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -61,6 +61,7 @@ #include "mptbase.h" #include "mptscsih.h" +#include "mptsas.h" #define my_NAME "Fusion MPT SAS Host driver" @@ -96,111 +97,6 @@ static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS; static void mptsas_hotplug_work(struct work_struct *work); -struct mptsas_target_reset_event { - struct list_head list; - EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data; - u8 target_reset_issued; -}; - -enum mptsas_hotplug_action { - MPTSAS_ADD_DEVICE, - MPTSAS_DEL_DEVICE, - MPTSAS_ADD_RAID, - MPTSAS_DEL_RAID, - MPTSAS_ADD_INACTIVE_VOLUME, - MPTSAS_IGNORE_EVENT, -}; - -struct mptsas_hotplug_event { - struct work_struct work; - MPT_ADAPTER *ioc; - enum mptsas_hotplug_action event_type; - u64 sas_address; - u8 channel; - u8 id; - u32 device_info; - u16 handle; - u16 parent_handle; - u8 phy_id; - u8 phys_disk_num_valid; /* hrc (hidden raid component) */ - u8 phys_disk_num; /* hrc - unique index*/ - u8 hidden_raid_component; /* hrc - don't expose*/ -}; - -struct mptsas_discovery_event { - struct work_struct work; - MPT_ADAPTER *ioc; -}; - -/* - * SAS topology structures - * - * The MPT Fusion firmware interface spreads information about the - * SAS topology over many manufacture pages, thus we need some data - * structure to collect it and process it for the SAS transport class. - */ - -struct mptsas_devinfo { - u16 handle; /* unique id to address this device */ - u16 handle_parent; /* unique id to address parent device */ - u16 handle_enclosure; /* enclosure identifier of the enclosure */ - u16 slot; /* physical slot in enclosure */ - u8 phy_id; /* phy number of parent device */ - u8 port_id; /* sas physical port this device - is assoc'd with */ - u8 id; /* logical target id of this device */ - u32 phys_disk_num; /* phys disk id, for csmi-ioctls */ - u8 channel; /* logical bus number of this device */ - u64 sas_address; /* WWN of this device, - SATA is assigned by HBA,expander */ - u32 device_info; /* bitfield detailed info about this device */ -}; - -/* - * Specific details on ports, wide/narrow - */ -struct mptsas_portinfo_details{ - u16 num_phys; /* number of phys belong to this port */ - u64 phy_bitmask; /* TODO, extend support for 255 phys */ - struct sas_rphy *rphy; /* transport layer rphy object */ - struct sas_port *port; /* transport layer port object */ - struct scsi_target *starget; - struct mptsas_portinfo *port_info; -}; - -struct mptsas_phyinfo { - u16 handle; /* unique id to address this */ - u8 phy_id; /* phy index */ - u8 port_id; /* firmware port identifier */ - u8 negotiated_link_rate; /* nego'd link rate for this phy */ - u8 hw_link_rate; /* hardware max/min phys link rate */ - u8 programmed_link_rate; /* programmed max/min phy link rate */ - u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/ - struct mptsas_devinfo identify; /* point to phy device info */ - struct mptsas_devinfo attached; /* point to attached device info */ - struct sas_phy *phy; /* transport layer phy object */ - struct mptsas_portinfo *portinfo; - struct mptsas_portinfo_details * port_details; -}; - -struct mptsas_portinfo { - struct list_head list; - u16 num_phys; /* number of phys */ - struct mptsas_phyinfo *phy_info; -}; - -struct mptsas_enclosure { - u64 enclosure_logical_id; /* The WWN for the enclosure */ - u16 enclosure_handle; /* unique id to address this */ - u16 flags; /* details enclosure management */ - u16 num_slot; /* num slots */ - u16 start_slot; /* first slot */ - u8 start_id; /* starting logical target id */ - u8 start_channel; /* starting logical channel id */ - u8 sep_id; /* SEP device logical target id */ - u8 sep_channel; /* SEP channel logical channel id */ -}; - static void mptsas_print_phy_data(MPT_ADAPTER *ioc, MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) { diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h new file mode 100644 index 0000000..7c150f5 --- /dev/null +++ b/drivers/message/fusion/mptsas.h @@ -0,0 +1,158 @@ +/* + * linux/drivers/message/fusion/mptsas.h + * High performance SCSI + LAN / Fibre Channel device drivers. + * For use with PCI chip/adapter(s): + * LSIFC9xx/LSI409xx Fibre Channel + * running LSI MPT (Message Passing Technology) firmware. + * + * Copyright (c) 1999-2007 LSI Corporation + * (mailto:DL-MPTFusionLinux@lsi.com) + * + */ +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + NO WARRANTY + THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT + LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to + the risks and costs of program errors, damage to or loss of data, + programs or equipment, and unavailability or interruption of operations. + + DISCLAIMER OF LIABILITY + NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef MPTSAS_H_INCLUDED +#define MPTSAS_H_INCLUDED +/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +struct mptsas_target_reset_event { + struct list_head list; + EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data; + u8 target_reset_issued; +}; + +enum mptsas_hotplug_action { + MPTSAS_ADD_DEVICE, + MPTSAS_DEL_DEVICE, + MPTSAS_ADD_RAID, + MPTSAS_DEL_RAID, + MPTSAS_ADD_INACTIVE_VOLUME, + MPTSAS_IGNORE_EVENT, +}; + +struct mptsas_hotplug_event { + struct work_struct work; + MPT_ADAPTER *ioc; + enum mptsas_hotplug_action event_type; + u64 sas_address; + u8 channel; + u8 id; + u32 device_info; + u16 handle; + u16 parent_handle; + u8 phy_id; + u8 phys_disk_num_valid; /* hrc (hidden raid component) */ + u8 phys_disk_num; /* hrc - unique index*/ + u8 hidden_raid_component; /* hrc - don't expose*/ +}; + +struct mptsas_discovery_event { + struct work_struct work; + MPT_ADAPTER *ioc; +}; + +/* + * SAS topology structures + * + * The MPT Fusion firmware interface spreads information about the + * SAS topology over many manufacture pages, thus we need some data + * structure to collect it and process it for the SAS transport class. + */ + +struct mptsas_devinfo { + u16 handle; /* unique id to address this device */ + u16 handle_parent; /* unique id to address parent device */ + u16 handle_enclosure; /* enclosure identifier of the enclosure */ + u16 slot; /* physical slot in enclosure */ + u8 phy_id; /* phy number of parent device */ + u8 port_id; /* sas physical port this device + is assoc'd with */ + u8 id; /* logical target id of this device */ + u32 phys_disk_num; /* phys disk id, for csmi-ioctls */ + u8 channel; /* logical bus number of this device */ + u64 sas_address; /* WWN of this device, + SATA is assigned by HBA,expander */ + u32 device_info; /* bitfield detailed info about this device */ +}; + +/* + * Specific details on ports, wide/narrow + */ +struct mptsas_portinfo_details{ + u16 num_phys; /* number of phys belong to this port */ + u64 phy_bitmask; /* TODO, extend support for 255 phys */ + struct sas_rphy *rphy; /* transport layer rphy object */ + struct sas_port *port; /* transport layer port object */ + struct scsi_target *starget; + struct mptsas_portinfo *port_info; +}; + +struct mptsas_phyinfo { + u16 handle; /* unique id to address this */ + u8 phy_id; /* phy index */ + u8 port_id; /* firmware port identifier */ + u8 negotiated_link_rate; /* nego'd link rate for this phy */ + u8 hw_link_rate; /* hardware max/min phys link rate */ + u8 programmed_link_rate; /* programmed max/min phy link rate */ + u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/ + struct mptsas_devinfo identify; /* point to phy device info */ + struct mptsas_devinfo attached; /* point to attached device info */ + struct sas_phy *phy; /* transport layer phy object */ + struct mptsas_portinfo *portinfo; + struct mptsas_portinfo_details * port_details; +}; + +struct mptsas_portinfo { + struct list_head list; + u16 num_phys; /* number of phys */ + struct mptsas_phyinfo *phy_info; +}; + +struct mptsas_enclosure { + u64 enclosure_logical_id; /* The WWN for the enclosure */ + u16 enclosure_handle; /* unique id to address this */ + u16 flags; /* details enclosure management */ + u16 num_slot; /* num slots */ + u16 start_slot; /* first slot */ + u8 start_id; /* starting logical target id */ + u8 start_channel; /* starting logical channel id */ + u8 sep_id; /* SEP device logical target id */ + u8 sep_channel; /* SEP channel logical channel id */ +}; + +/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +#endif -- cgit v1.1 From eb5329f40c13923e84a847204b5c5d62954eaf05 Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Tue, 14 Aug 2007 16:19:32 +0530 Subject: [SCSI] mpt fusion: Link speed change display support When there is state change in FC links, a message is displayed with old and new link speed. signed-off-by: Sathya Prakash Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 2 ++ drivers/message/fusion/mptfc.c | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 04ef0a3..1197eba 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -698,6 +698,8 @@ typedef struct _MPT_ADAPTER struct work_struct fc_setup_reset_work; struct list_head fc_rports; + struct work_struct fc_lsc_work; + u8 fc_link_speed[2]; spinlock_t fc_rescan_work_lock; struct work_struct fc_rescan_work; char fc_rescan_work_q_name[KOBJ_NAME_LEN]; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 2b3e27a..aadb071 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -675,6 +675,50 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) } /* + * mptfc_display_port_link_speed - displaying link speed + * @ioc: Pointer to MPT_ADAPTER structure + * @portnum: IOC Port number + * @pp0dest: port page0 data payload + * + */ +static void +mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest) +{ + u8 old_speed, new_speed, state; + char *old, *new; + + if (portnum >= 2) + return; + + old_speed = ioc->fc_link_speed[portnum]; + new_speed = pp0dest->CurrentSpeed; + state = pp0dest->PortState; + + if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE && + new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) { + + old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" : + old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" : + old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" : + "Unknown"; + new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" : + new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" : + new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" : + "Unknown"; + if (old_speed == 0) + printk(MYIOC_s_NOTE_FMT + "FC Link Established, Speed = %s\n", + ioc->name, new); + else if (old_speed != new_speed) + printk(MYIOC_s_WARN_FMT + "FC Link Speed Change, Old Speed = %s, New Speed = %s\n", + ioc->name, old, new); + + ioc->fc_link_speed[portnum] = new_speed; + } +} + +/* * mptfc_GetFcPortPage0 - Fetch FCPort config Page0. * @ioc: Pointer to MPT_ADAPTER structure * @portnum: IOC Port number @@ -773,6 +817,7 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) " complete.\n", ioc->name); } + mptfc_display_port_link_speed(ioc, portnum, pp0dest); } pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); @@ -1023,6 +1068,18 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) } static void +mptfc_link_status_change(struct work_struct *work) +{ + MPT_ADAPTER *ioc = + container_of(work, MPT_ADAPTER, fc_rescan_work); + int ii; + + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) + (void) mptfc_GetFcPortPage0(ioc, ii); + +} + +static void mptfc_setup_reset(struct work_struct *work) { MPT_ADAPTER *ioc = @@ -1163,6 +1220,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(&ioc->fc_rescan_work_lock); INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices); INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset); + INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change); spin_lock_irqsave(&ioc->FreeQlock, flags); @@ -1337,6 +1395,14 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) } spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); break; + case MPI_EVENT_LINK_STATUS_CHANGE: + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); + if (ioc->fc_rescan_work_q) { + queue_work(ioc->fc_rescan_work_q, + &ioc->fc_lsc_work); + } + spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + break; default: rc = mptscsih_event_process(ioc,pEvReply); break; -- cgit v1.1 From f36789e22ac32a6554b8e4d05ab6125fc1161745 Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Tue, 14 Aug 2007 16:22:54 +0530 Subject: [SCSI] mpt fusion: Change company name from LSI Logic to LSI Recently LSI Logic Corp was renamed as LSI Corp, so whereever there is a reference of LSI Logic, it is changed to LSI in mpt fusion driver code. signed-off-by: Sathya Prakash Acked-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/lsi/mpi.h | 2 +- drivers/message/fusion/lsi/mpi_cnfg.h | 2 +- drivers/message/fusion/lsi/mpi_fc.h | 2 +- drivers/message/fusion/lsi/mpi_history.txt | 2 +- drivers/message/fusion/lsi/mpi_init.h | 2 +- drivers/message/fusion/lsi/mpi_ioc.h | 2 +- drivers/message/fusion/lsi/mpi_lan.h | 2 +- drivers/message/fusion/lsi/mpi_log_fc.h | 2 +- drivers/message/fusion/lsi/mpi_log_sas.h | 2 +- drivers/message/fusion/lsi/mpi_raid.h | 2 +- drivers/message/fusion/lsi/mpi_sas.h | 2 +- drivers/message/fusion/lsi/mpi_targ.h | 2 +- drivers/message/fusion/lsi/mpi_tool.h | 2 +- drivers/message/fusion/lsi/mpi_type.h | 2 +- drivers/message/fusion/mptbase.c | 6 +++--- drivers/message/fusion/mptbase.h | 6 +++--- drivers/message/fusion/mptctl.c | 10 +++++----- drivers/message/fusion/mptctl.h | 4 ++-- drivers/message/fusion/mptfc.c | 6 +++--- drivers/message/fusion/mptlan.c | 6 +++--- drivers/message/fusion/mptlan.h | 8 ++++---- drivers/message/fusion/mptsas.c | 6 +++--- drivers/message/fusion/mptscsih.c | 6 +++--- drivers/message/fusion/mptscsih.h | 4 ++-- drivers/message/fusion/mptspi.c | 6 +++--- 25 files changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 6a92e3d..1acbdd6 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Logic Corporation. + * Copyright (c) 2000-2007 LSI Corporation. * * * Name: mpi.h diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index eda7697..2bd8ada 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Logic Corporation. + * Copyright (c) 2000-2007 LSI Corporation. * * * Name: mpi_cnfg.h diff --git a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h index 51a6aeb..627acfb 100644 --- a/drivers/message/fusion/lsi/mpi_fc.h +++ b/drivers/message/fusion/lsi/mpi_fc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Logic Corporation. + * Copyright (c) 2000-2004 LSI Corporation. * * * Name: mpi_fc.h diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index a1f4790..241592ab 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -3,7 +3,7 @@ MPI Header File Change History ============================== - Copyright (c) 2000-2007 LSI Logic Corporation. + Copyright (c) 2000-2007 LSI Corporation. --------------------------------------- Header Set Release Version: 01.05.16 diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index 3a02615..a9e3693 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Logic Corporation. + * Copyright (c) 2000-2007 LSI Corporation. * * * Name: mpi_init.h diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index b1893d1..5cbb6bd 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Logic Corporation. + * Copyright (c) 2000-2007 LSI Corporation. * * * Name: mpi_ioc.h diff --git a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h index dc0b52a..03253b5 100644 --- a/drivers/message/fusion/lsi/mpi_lan.h +++ b/drivers/message/fusion/lsi/mpi_lan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Logic Corporation. + * Copyright (c) 2000-2004 LSI Corporation. * * * Name: mpi_lan.h diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h index dc98d46..e4dafce 100644 --- a/drivers/message/fusion/lsi/mpi_log_fc.h +++ b/drivers/message/fusion/lsi/mpi_log_fc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved. + * Copyright (c) 2000-2001 LSI Corporation. All rights reserved. * * NAME: fc_log.h * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index 635bbe0..6be1f6b 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -1,6 +1,6 @@ /*************************************************************************** * * - * Copyright 2003 LSI Logic Corporation. All rights reserved. * + * Copyright 2003 LSI Corporation. All rights reserved. * * * * Description * * ------------ * diff --git a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h index 32819b1..2856108 100644 --- a/drivers/message/fusion/lsi/mpi_raid.h +++ b/drivers/message/fusion/lsi/mpi_raid.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2007 LSI Logic Corporation. + * Copyright (c) 2001-2007 LSI Corporation. * * * Name: mpi_raid.h diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 8e990a0..33fca83 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2006 LSI Logic Corporation. + * Copyright (c) 2004-2006 LSI Corporation. * * * Name: mpi_sas.h diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index 20b6673..ff8c37d 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Logic Corporation. + * Copyright (c) 2000-2004 LSI Corporation. * * * Name: mpi_targ.h diff --git a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h index aa9053d..8834ae6 100644 --- a/drivers/message/fusion/lsi/mpi_tool.h +++ b/drivers/message/fusion/lsi/mpi_tool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 LSI Logic Corporation. + * Copyright (c) 2001-2005 LSI Corporation. * * * Name: mpi_tool.h diff --git a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h index 32cc9b1..08dad9c 100644 --- a/drivers/message/fusion/lsi/mpi_type.h +++ b/drivers/message/fusion/lsi/mpi_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Logic Corporation. + * Copyright (c) 2000-2004 LSI Corporation. * * * Name: mpi_type.h diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 8cf0f51..22cb0f8 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -2,10 +2,10 @@ * linux/drivers/message/fusion/mptbase.c * This is the Fusion MPT base driver which supports multiple * (SCSI + LAN) specialized protocol drivers. - * For use with LSI Logic PCI chip/adapter(s) - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapter(s) + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 1197eba..53f7e38 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -3,9 +3,9 @@ * High performance SCSI + LAN / Fibre Channel device drivers. * For use with PCI chip/adapter(s): * LSIFC9xx/LSI409xx Fibre Channel - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -68,7 +68,7 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #ifndef MODULEAUTHOR -#define MODULEAUTHOR "LSI Logic Corporation" +#define MODULEAUTHOR "LSI Corporation" #endif #ifndef COPYRIGHT diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 89cab57..b9618f4 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1,10 +1,10 @@ /* * linux/drivers/message/fusion/mptctl.c * mpt Ioctl driver. - * For use with LSI Logic PCI chip/adapters - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapters + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -66,8 +66,8 @@ #include #include -#define COPYRIGHT "Copyright (c) 1999-2007 LSI Logic Corporation" -#define MODULEAUTHOR "LSI Logic Corporation" +#define COPYRIGHT "Copyright (c) 1999-2007 LSI Corporation" +#define MODULEAUTHOR "LSI Corporation" #include "mptbase.h" #include "mptctl.h" diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 180b3c1..2c18901 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -3,9 +3,9 @@ * Fusion MPT misc device (ioctl) driver. * For use with PCI chip/adapter(s): * LSIFC9xx/LSI409xx Fibre Channel - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index aadb071..0586f87 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -1,9 +1,9 @@ /* * linux/drivers/message/fusion/mptfc.c - * For use with LSI Logic PCI chip/adapter(s) - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapter(s) + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 9d9eb76..952e148 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1,10 +1,10 @@ /* * linux/drivers/message/fusion/mptlan.c * IP Over Fibre Channel device driver. - * For use with LSI Logic Fibre Channel PCI chip/adapters - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI Fibre Channel PCI chip/adapters + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2007 LSI Logic Corporation + * Copyright (c) 2000-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h index 8d08c2b..bafb67f 100644 --- a/drivers/message/fusion/mptlan.h +++ b/drivers/message/fusion/mptlan.h @@ -1,10 +1,10 @@ /* * linux/drivers/message/fusion/mptlan.h * IP Over Fibre Channel device driver. - * For use with LSI Logic Fibre Channel PCI chip/adapters - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI Fibre Channel PCI chip/adapters + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2007 LSI Logic Corporation + * Copyright (c) 2000-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -75,7 +75,7 @@ #include /* Override mptbase.h by pre-defining these! */ -#define MODULEAUTHOR "LSI Logic Corporation" +#define MODULEAUTHOR "LSI Corporation" #include "mptbase.h" diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 5951fe0..4333449 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1,9 +1,9 @@ /* * linux/drivers/message/fusion/mptsas.c - * For use with LSI Logic PCI chip/adapter(s) - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapter(s) + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * Copyright (c) 2005-2007 Dell */ diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b8b0598..f00c100 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1,9 +1,9 @@ /* * linux/drivers/message/fusion/mptscsih.c - * For use with LSI Logic PCI chip/adapter(s) - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapter(s) + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 67b088d..d289e97 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -3,9 +3,9 @@ * High performance SCSI / Fibre Channel SCSI Host device driver. * For use with PCI chip/adapter(s): * LSIFC9xx/LSI409xx Fibre Channel - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index f0618c5..3108788 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -1,9 +1,9 @@ /* * linux/drivers/message/fusion/mptspi.c - * For use with LSI Logic PCI chip/adapter(s) - * running LSI Logic Fusion MPT (Message Passing Technology) firmware. + * For use with LSI PCI chip/adapter(s) + * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2007 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ -- cgit v1.1 From bbfbbbc1182f8b44c8cc4c99f4a3f3a512149022 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 11 Aug 2007 10:13:24 +0200 Subject: [SCSI] kmalloc + memset conversion to kzalloc In NCR_D700, a4000t, aic7xxx_old, bvme6000, dpt_i2o, gdth, lpfc, megaraid, mvme16x osst, pluto, qla2xxx, zorro7xx Signed-off-by: Mariusz Kozlowski Signed-off-by: James Bottomley --- drivers/scsi/NCR_D700.c | 4 ++-- drivers/scsi/a4000t.c | 7 +++---- drivers/scsi/aic7xxx_old.c | 8 +++----- drivers/scsi/bvme6000_scsi.c | 7 +++---- drivers/scsi/dpt_i2o.c | 27 +++++++++++---------------- drivers/scsi/gdth.c | 7 +++---- drivers/scsi/lpfc/lpfc_debugfs.c | 4 +--- drivers/scsi/lpfc/lpfc_init.c | 3 +-- drivers/scsi/lpfc/lpfc_scsi.c | 3 +-- drivers/scsi/megaraid.c | 3 +-- drivers/scsi/mvme16x_scsi.c | 3 +-- drivers/scsi/osst.c | 5 ++--- drivers/scsi/pluto.c | 8 +++----- drivers/scsi/qla2xxx/qla_init.c | 14 ++++++-------- drivers/scsi/zorro7xx.c | 8 +++----- 15 files changed, 44 insertions(+), 67 deletions(-) diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index e0f1991..9e64b21 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -313,10 +313,10 @@ NCR_D700_probe(struct device *dev) break; } - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; - memset(p, '\0', sizeof(*p)); + p->dev = dev; snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id); if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) { diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 0c758d1..d4bda20 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -37,7 +37,7 @@ static struct platform_device *a4000t_scsi_device; static int __devinit a4000t_probe(struct device *dev) { - struct Scsi_Host * host = NULL; + struct Scsi_Host *host; struct NCR_700_Host_Parameters *hostdata; if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) @@ -47,12 +47,11 @@ static int __devinit a4000t_probe(struct device *dev) "A4000T builtin SCSI")) goto out; - hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); - if (hostdata == NULL) { + hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + if (!hostdata) { printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); goto out_release; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); /* Fill in the required pieces of hostdata */ hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 4998bb8..1a71b02 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -8416,10 +8416,9 @@ aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp) *p = *temp; p->host = host; - p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC); - if (p->scb_data != NULL) + p->scb_data = kzalloc(sizeof(scb_data_type), GFP_ATOMIC); + if (!p->scb_data) { - memset(p->scb_data, 0, sizeof(scb_data_type)); scbq_init (&p->scb_data->free_scbs); } else @@ -9196,10 +9195,9 @@ aic7xxx_detect(struct scsi_host_template *template) printk(KERN_INFO " this driver, we are ignoring it.\n"); } } - else if ( (temp_p = kmalloc(sizeof(struct aic7xxx_host), + else if ( (temp_p = kzalloc(sizeof(struct aic7xxx_host), GFP_ATOMIC)) != NULL ) { - memset(temp_p, 0, sizeof(struct aic7xxx_host)); temp_p->chip = aic_pdevs[i].chip | AHC_PCI; temp_p->flags = aic_pdevs[i].flags; temp_p->features = aic_pdevs[i].features; diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index cac3540..d858f3d 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c @@ -36,19 +36,18 @@ static struct platform_device *bvme6000_scsi_device; static __devinit int bvme6000_probe(struct device *dev) { - struct Scsi_Host * host = NULL; + struct Scsi_Host *host; struct NCR_700_Host_Parameters *hostdata; if (!MACH_IS_BVME6000) goto out; - hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); - if (hostdata == NULL) { + hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + if (!hostdata) { printk(KERN_ERR "bvme6000-scsi: " "Failed to allocate host data\n"); goto out; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); /* Fill in the required pieces of hostdata */ hostdata->base = (void __iomem *)BVME_NCR53C710_BASE; diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 502732a..9d7bdf7 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -949,16 +949,14 @@ static int adpt_install_hba(struct pci_dev* pDev) } // Allocate and zero the data structure - pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL); - if( pHba == NULL) { - if(msg_addr_virt != base_addr_virt){ + pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL); + if (!pHba) { + if (msg_addr_virt != base_addr_virt) iounmap(msg_addr_virt); - } iounmap(base_addr_virt); pci_release_regions(pDev); return -ENOMEM; } - memset(pHba, 0, sizeof(adpt_hba)); mutex_lock(&adpt_configuration_lock); @@ -2622,14 +2620,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) msg=(u32 __iomem *)(pHba->msg_addr_virt+m); - status = kmalloc(4,GFP_KERNEL|ADDR32); - if (status==NULL) { + status = kzalloc(4, GFP_KERNEL|ADDR32); + if (!status) { adpt_send_nop(pHba, m); printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", pHba->name); return -ENOMEM; } - memset(status, 0, 4); writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); @@ -2668,12 +2665,11 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) kfree(pHba->reply_pool); - pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); - if(!pHba->reply_pool){ - printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name); - return -1; + pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); + if (!pHba->reply_pool) { + printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name); + return -ENOMEM; } - memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4); ptr = pHba->reply_pool; for(i = 0; i < pHba->reply_fifo_size; i++) { @@ -2884,12 +2880,11 @@ static int adpt_i2o_build_sys_table(void) kfree(sys_tbl); - sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32); - if(!sys_tbl) { + sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32); + if (!sys_tbl) { printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); return -ENOMEM; } - memset(sys_tbl, 0, sys_tbl_len); sys_tbl->num_entries = hba_count; sys_tbl->version = I2OVERSION; diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 55e4d2d..b20c188 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -726,10 +726,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, DECLARE_COMPLETION_ONSTACK(wait); int rval; - scp = kmalloc(sizeof(*scp), GFP_KERNEL); + scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) return -ENOMEM; - memset(scp, 0, sizeof(*scp)); + scp->device = sdev; /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; @@ -5518,10 +5518,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, ha = HADATA(gdth_ctr_tab[hanum]); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - scp = kmalloc(sizeof(*scp), GFP_KERNEL); + scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) return -ENOMEM; - memset(scp, 0, sizeof(*scp)); scp->device = ha->sdev; scp->cmd_len = 12; scp->use_sg = 0; diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index dcf808b..149fdd2 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -901,7 +901,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } } - vport->disc_trc = kmalloc( + vport->disc_trc = kmzlloc( (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), GFP_KERNEL); @@ -912,8 +912,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) goto debug_failed; } atomic_set(&vport->disc_trc_cnt, 0); - memset(vport->disc_trc, 0, - (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc)); snprintf(name, sizeof(name), "discovery_trace"); vport->debug_disc_trc = diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 42e2061..ecebdfa 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1265,11 +1265,10 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) uint32_t *HashWorking; uint32_t *pwwnn = (uint32_t *) phba->wwnn; - HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); + HashWorking = kcalloc(80, sizeof(uint32_t), GFP_KERNEL); if (!HashWorking) return; - memset(HashWorking, 0, (80 * sizeof(uint32_t))); HashWorking[0] = HashWorking[78] = *pwwnn++; HashWorking[1] = HashWorking[79] = *pwwnn; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 17d7dc0..cd67493 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -202,10 +202,9 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport) dma_addr_t pdma_phys; uint16_t iotag; - psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); + psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); if (!psb) return NULL; - memset(psb, 0, sizeof (struct lpfc_scsi_buf)); /* * Get memory from the pci pool to map the virt space to pci bus space diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 3907f67..9023ec6 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -4408,8 +4408,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) scmd = &adapter->int_scmd; memset(scmd, 0, sizeof(Scsi_Cmnd)); - sdev = kmalloc(sizeof(struct scsi_device), GFP_KERNEL); - memset(sdev, 0, sizeof(struct scsi_device)); + sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); scmd->device = sdev; scmd->device->host = adapter->host; diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index 1bdddad..b264b49 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c @@ -48,13 +48,12 @@ mvme16x_probe(struct device *dev) goto out; } - hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); if (hostdata == NULL) { printk(KERN_ERR "mvme16x-scsi: " "Failed to allocate host data\n"); goto out; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); /* Fill in the required pieces of hostdata */ hostdata->base = (void __iomem *)0xfff47000UL; diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 08060fb..1197395 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5778,13 +5778,12 @@ static int osst_probe(struct device *dev) dev_num = i; /* allocate a struct osst_tape for this device */ - tpnt = kmalloc(sizeof(struct osst_tape), GFP_ATOMIC); - if (tpnt == NULL) { + tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC); + if (!tpnt) { write_unlock(&os_scsi_tapes_lock); printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); goto out_put_disk; } - memset(tpnt, 0, sizeof(struct osst_tape)); /* allocate a buffer for this device */ i = SDp->host->sg_tablesize; diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index d953d43..e221389 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -111,13 +111,12 @@ int __init pluto_detect(struct scsi_host_template *tpnt) #endif return 0; } - fcs = kmalloc(sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA); + fcs = kcalloc(fcscount, sizeof (struct ctrl_inquiry), GFP_DMA); if (!fcs) { printk ("PLUTO: Not enough memory to probe\n"); return 0; } - memset (fcs, 0, sizeof (struct ctrl_inquiry) * fcscount); memset (&dev, 0, sizeof(dev)); atomic_set (&fcss, fcscount); @@ -211,7 +210,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) char *p; long *ages; - ages = kmalloc (((inq->channels + 1) * inq->targets) * sizeof(long), GFP_KERNEL); + ages = kcalloc((inq->channels + 1) * inq->targets, sizeof(long), GFP_KERNEL); if (!ages) continue; host = scsi_register (tpnt, sizeof (struct pluto)); @@ -238,7 +237,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) fc->channels = inq->channels + 1; fc->targets = inq->targets; fc->ages = ages; - memset (ages, 0, ((inq->channels + 1) * inq->targets) * sizeof(long)); pluto->fc = fc; memcpy (pluto->rev_str, inq->revision, 4); @@ -260,7 +258,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) } else fc->fcp_register(fc, TYPE_SCSI_FCP, 1); } - kfree((char *)fcs); + kfree(fcs); if (nplutos) printk ("PLUTO: Total of %d SparcSTORAGE Arrays found\n", nplutos); return nplutos; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1a058ec..083997c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1786,12 +1786,11 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) { fc_port_t *fcport; - fcport = kmalloc(sizeof(fc_port_t), flags); - if (fcport == NULL) - return (fcport); + fcport = kzalloc(sizeof(fc_port_t), flags); + if (!fcport) + return NULL; /* Setup fcport template structure. */ - memset(fcport, 0, sizeof (fc_port_t)); fcport->ha = ha; fcport->vp_idx = ha->vp_idx; fcport->port_type = FCT_UNKNOWN; @@ -1801,7 +1800,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) fcport->supported_classes = FC_COS_UNSPECIFIED; spin_lock_init(&fcport->rport_lock); - return (fcport); + return fcport; } /* @@ -2473,13 +2472,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) rval = QLA_SUCCESS; /* Try GID_PT to get device list, else GAN. */ - swl = kmalloc(sizeof(sw_info_t) * MAX_FIBRE_DEVICES, GFP_ATOMIC); - if (swl == NULL) { + swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_ATOMIC); + if (!swl) { /*EMPTY*/ DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback " "on GA_NXT\n", ha->host_no)); } else { - memset(swl, 0, sizeof(sw_info_t) * MAX_FIBRE_DEVICES); if (qla2x00_gid_pt(ha, swl) != QLA_SUCCESS) { kfree(swl); swl = NULL; diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index c822deb..ac67394 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c @@ -69,7 +69,7 @@ static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = { static int __devinit zorro7xx_init_one(struct zorro_dev *z, const struct zorro_device_id *ent) { - struct Scsi_Host * host = NULL; + struct Scsi_Host *host; struct NCR_700_Host_Parameters *hostdata; struct zorro_driver_data *zdd; unsigned long board, ioaddr; @@ -89,14 +89,12 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z, return -EBUSY; } - hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); - if (hostdata == NULL) { + hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + if (!hostdata) { printk(KERN_ERR "zorro7xx: Failed to allocate host data\n"); goto out_release; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); - /* Fill in the required pieces of hostdata */ if (ioaddr > 0x01000000) hostdata->base = ioremap(ioaddr, zorro_resource_len(z)); -- cgit v1.1 From 2282f658914e316ca32fd120fded130d1c0e26e4 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Aug 2007 09:30:22 +0200 Subject: [SCSI] zfcp: correct indentation for nested if-else correct indentation for nested if-else Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9929997..13ed689 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3586,17 +3586,17 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, ZFCP_LOG_DEBUG( "Data did not fit into available buffer(s), " "waiting for more...\n"); - retval = -EIO; - } else { - ZFCP_LOG_NORMAL("error: No truncation implemented but " - "required. Shutting down unit " - "(adapter %s, port 0x%016Lx, " - "unit 0x%016Lx)\n", - zfcp_get_busid_by_unit(unit), - unit->port->wwpn, - unit->fcp_lun); - zfcp_erp_unit_shutdown(unit, 0); - retval = -EINVAL; + retval = -EIO; + } else { + ZFCP_LOG_NORMAL("error: No truncation implemented but " + "required. Shutting down unit " + "(adapter %s, port 0x%016Lx, " + "unit 0x%016Lx)\n", + zfcp_get_busid_by_unit(unit), + unit->port->wwpn, + unit->fcp_lun); + zfcp_erp_unit_shutdown(unit, 0); + retval = -EINVAL; } goto no_fit; } -- cgit v1.1 From cc16cebad086090891a3f39957ec771a2292359b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 28 Aug 2007 09:30:42 +0200 Subject: [SCSI] zfcp: avoid if (whatever) ; constructs. Avoid "if (whatever) ;" constructs since they seem to confuse people, even if there is a comment. Signed-off-by: Heiko Carstens Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_erp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d8cd75c..40fa056 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1687,8 +1687,8 @@ zfcp_erp_strategy_followup_actions(int action, break; case ZFCP_ERP_ACTION_REOPEN_UNIT: - if (status == ZFCP_ERP_SUCCEEDED) ; /* no further action */ - else + /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */ + if (status != ZFCP_ERP_SUCCEEDED) zfcp_erp_port_reopen_internal(unit->port, 0); break; } -- cgit v1.1 From 6ddd90a5b1618523dbfe3a11c50945f6660135a0 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Aug 2007 09:30:50 +0200 Subject: [SCSI] zfcp: Remove unnecessary assignment zfcp_adapter_enqueue initialized adapter->ccw_device twice with the same value. Remove the second assignment, since it is not necessary. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 90aa53f..eb3af41a3 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -1058,7 +1058,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* mark adapter unusable as long as sysfs registration is not complete */ atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); - adapter->ccw_device = ccw_device; dev_set_drvdata(&ccw_device->dev, adapter); if (zfcp_sysfs_adapter_create_files(&ccw_device->dev)) -- cgit v1.1 From 6b76a72141c57260adaf07977f79760ddb8618ee Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Aug 2007 09:30:59 +0200 Subject: [SCSI] zfcp: Remove braces for only one statement Remove braces for only one statement Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_scsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index ad7eb4a..3a7f3b8 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -189,10 +189,9 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) unit->device = NULL; zfcp_erp_unit_failed(unit); zfcp_unit_put(unit); - } else { + } else ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " "address %p\n", sdpnt); - } } /* @@ -361,12 +360,11 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id, list_for_each_entry(port, &adapter->port_list_head, list) { if (!port->rport || (id != port->rport->scsi_target_id)) continue; - list_for_each_entry(unit, &port->unit_list_head, list) { + list_for_each_entry(unit, &port->unit_list_head, list) if (lun == unit->scsi_lun) { retval = unit; goto out; } - } } out: return retval; -- cgit v1.1 From 03f002f778e58e9056e8e9a22952c5c6f4d76269 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Aug 2007 09:31:21 +0200 Subject: [SCSI] scsi_transport_fc: Introduce disable_target_scan flag This change has already been discussed on linux-scsi: http://marc.info/?t=118771096400003 http://marc.info/?t=118760913100005 Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Acked-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_fc.c | 4 +++- include/scsi/scsi_transport_fc.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 4705725..dd97f26 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2988,10 +2988,12 @@ fc_scsi_scan_rport(struct work_struct *work) struct fc_rport *rport = container_of(work, struct fc_rport, scan_work); struct Scsi_Host *shost = rport_to_shost(rport); + struct fc_internal *i = to_fc_internal(shost->transportt); unsigned long flags; if ((rport->port_state == FC_PORTSTATE_ONLINE) && - (rport->roles & FC_PORT_ROLE_FCP_TARGET)) { + (rport->roles & FC_PORT_ROLE_FCP_TARGET) && + !(i->f->disable_target_scan)) { scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, SCAN_WILD_CARD, 1); } diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index a0d80bc..616a96a 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -632,6 +632,8 @@ struct fc_function_template { unsigned long show_host_fabric_name:1; unsigned long show_host_symbolic_name:1; unsigned long show_host_system_hostname:1; + + unsigned long disable_target_scan:1; }; -- cgit v1.1 From 52ef11a7170e1b8a0d5f9a42dbb43c38c335c32e Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Tue, 28 Aug 2007 09:31:09 +0200 Subject: [SCSI] zfcp: cleanup, separation of ERP, non ERP-version for exchange_ functions cleanup, using ERP request mempool for all ERP versions of the exchange functions (exchange_config (ECD), exchange_port (EPD) ) providing individual versions of the ECD, EPD functions for ERP and other purposes (_sync). Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 8 +- drivers/s390/scsi/zfcp_fsf.c | 231 ++++++++++++++++++++++++++++++------------ drivers/s390/scsi/zfcp_scsi.c | 5 +- 4 files changed, 175 insertions(+), 71 deletions(-) diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 40fa056..31c2178 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -2197,7 +2197,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) zfcp_erp_action_to_running(erp_action); write_unlock_irq(&adapter->erp_lock); - ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); + ret = zfcp_fsf_exchange_port_data(erp_action); if (ret == -EOPNOTSUPP) { debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); return ZFCP_ERP_SUCCEEDED; diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 991d456..722c55b 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -82,9 +82,11 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); -extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *, - struct zfcp_adapter *, - struct fsf_qtcb_bottom_port *); +extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *, + struct fsf_qtcb_bottom_config *); +extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); +extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, + struct fsf_qtcb_bottom_port *); extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, u32, u32, struct zfcp_sg_list *); extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 13ed689..4aa8834 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1941,25 +1941,28 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; struct zfcp_fsf_req *fsf_req; + struct zfcp_adapter *adapter = erp_action->adapter; unsigned long lock_flags; - int retval = 0; + int retval; /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, + retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, + adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { + if (retval) { ZFCP_LOG_INFO("error: Could not create exchange configuration " "data request for adapter %s.\n", - zfcp_get_busid_by_adapter(erp_action->adapter)); - goto out; + zfcp_get_busid_by_adapter(adapter)); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, + lock_flags); + return retval; } sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; fsf_req->qtcb->bottom.config.feature_selection = FSF_FEATURE_CFDC | @@ -1971,23 +1974,71 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, + lock_flags); if (retval) { - ZFCP_LOG_INFO - ("error: Could not send exchange configuration data " - "command on the adapter %s\n", - zfcp_get_busid_by_adapter(erp_action->adapter)); + ZFCP_LOG_INFO("error: Could not send exchange configuration " + "data command on the adapter %s\n", + zfcp_get_busid_by_adapter(adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; - goto out; } + else + ZFCP_LOG_DEBUG("exchange configuration data request initiated " + "(adapter %s)\n", + zfcp_get_busid_by_adapter(adapter)); - ZFCP_LOG_DEBUG("exchange configuration data request initiated " - "(adapter %s)\n", - zfcp_get_busid_by_adapter(erp_action->adapter)); + return retval; +} - out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, +int +zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, + struct fsf_qtcb_bottom_config *data) +{ + volatile struct qdio_buffer_element *sbale; + struct zfcp_fsf_req *fsf_req; + unsigned long lock_flags; + int retval; + + /* setup new FSF request */ + retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, + 0, NULL, &lock_flags, &fsf_req); + if (retval) { + ZFCP_LOG_INFO("error: Could not create exchange configuration " + "data request for adapter %s.\n", + zfcp_get_busid_by_adapter(adapter)); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, + lock_flags); + return retval; + } + + sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + + fsf_req->qtcb->bottom.config.feature_selection = + FSF_FEATURE_CFDC | + FSF_FEATURE_LUN_SHARING | + FSF_FEATURE_NOTIFICATION_LOST | + FSF_FEATURE_UPDATE_ALERT; + + if (data) + fsf_req->data = (unsigned long) data; + + zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); + retval = zfcp_fsf_req_send(fsf_req); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + if (retval) + ZFCP_LOG_INFO("error: Could not send exchange configuration " + "data command on the adapter %s\n", + zfcp_get_busid_by_adapter(adapter)); + else + wait_event(fsf_req->completion_wq, + fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); + + zfcp_fsf_req_free(fsf_req); + return retval; } @@ -2016,11 +2067,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) adapter->peer_d_id = 0; if (xchg_ok) { + + if (fsf_req->data) + memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data, + bottom, sizeof (struct fsf_qtcb_bottom_config)); + fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; fc_host_speed(shost) = bottom->fc_link_speed; - fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; + fc_host_supported_classes(shost) = + FC_COS_CLASS2 | FC_COS_CLASS3; adapter->hydra_version = bottom->adapter_type; if (fc_host_permanent_port_name(shost) == -1) fc_host_permanent_port_name(shost) = @@ -2053,7 +2110,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) min(FC_SERIAL_NUMBER_SIZE, 17)); } - ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" + ZFCP_LOG_NORMAL("The adapter %s reported the following " + "characteristics:\n" "WWNN 0x%016Lx, " "WWPN 0x%016Lx, " "S_ID 0x%06x,\n" @@ -2090,7 +2148,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) return 0; } -/* +/** * function: zfcp_fsf_exchange_config_data_handler * * purpose: is called for finished Exchange Configuration Data command @@ -2125,7 +2183,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) adapter->peer_wwpn, adapter->peer_d_id); debug_text_event(fsf_req->adapter->erp_dbf, 0, - "top-p-to-p"); + "top-p-to-p"); break; case FC_PORTTYPE_NLPORT: ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " @@ -2138,8 +2196,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) return -EIO; case FC_PORTTYPE_NPORT: ZFCP_LOG_NORMAL("Switched fabric fibrechannel " - "network detected at adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); + "network detected at adapter %s.\n", + zfcp_get_busid_by_adapter(adapter)); break; default: ZFCP_LOG_NORMAL("bug: The fibrechannel topology " @@ -2179,7 +2237,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) return -EIO; - atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); zfcp_fsf_link_down_info_eval(adapter, &qtcb->header.fsf_status_qual.link_down_info); @@ -2187,7 +2246,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) default: debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); debug_event(fsf_req->adapter->erp_dbf, 0, - &fsf_req->qtcb->header.fsf_status, sizeof (u32)); + &fsf_req->qtcb->header.fsf_status, sizeof(u32)); zfcp_erp_adapter_shutdown(adapter, 0); return -EIO; } @@ -2197,74 +2256,118 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) /** * zfcp_fsf_exchange_port_data - request information about local port * @erp_action: ERP action for the adapter for which port data is requested - * @adapter: for which port data is requested - * @data: response to exchange port data request */ int -zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, - struct zfcp_adapter *adapter, - struct fsf_qtcb_bottom_port *data) +zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; + struct zfcp_fsf_req *fsf_req; + struct zfcp_adapter *adapter = erp_action->adapter; unsigned long lock_flags; - int retval = 0; + int retval; if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { ZFCP_LOG_INFO("error: exchange port data " - "command not supported by adapter %s\n", + "command not supported by adapter %s\n", zfcp_get_busid_by_adapter(adapter)); - return -EOPNOTSUPP; - } + return -EOPNOTSUPP; + } /* setup new FSF request */ retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, - erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0, - NULL, &lock_flags, &fsf_req); - if (retval < 0) { + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp, + &lock_flags, &fsf_req); + if (retval) { ZFCP_LOG_INFO("error: Out of resources. Could not create an " - "exchange port data request for" - "the adapter %s.\n", + "exchange port data request for" + "the adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); return retval; } - if (data) - fsf_req->data = (unsigned long) data; - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - if (erp_action) { - erp_action->fsf_req = fsf_req; - fsf_req->erp_action = erp_action; - zfcp_erp_start_timer(fsf_req); - } else - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); + erp_action->fsf_req = fsf_req; + fsf_req->erp_action = erp_action; + zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); + write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + if (retval) { ZFCP_LOG_INFO("error: Could not send an exchange port data " - "command on the adapter %s\n", + "command on the adapter %s\n", zfcp_get_busid_by_adapter(adapter)); zfcp_fsf_req_free(fsf_req); - if (erp_action) - erp_action->fsf_req = NULL; + erp_action->fsf_req = NULL; + } + else + ZFCP_LOG_DEBUG("exchange port data request initiated " + "(adapter %s)\n", + zfcp_get_busid_by_adapter(adapter)); + return retval; +} + + +/** + * zfcp_fsf_exchange_port_data_sync - request information about local port + * and wait until information is ready + */ +int +zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, + struct fsf_qtcb_bottom_port *data) +{ + volatile struct qdio_buffer_element *sbale; + struct zfcp_fsf_req *fsf_req; + unsigned long lock_flags; + int retval; + + if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { + ZFCP_LOG_INFO("error: exchange port data " + "command not supported by adapter %s\n", + zfcp_get_busid_by_adapter(adapter)); + return -EOPNOTSUPP; + } + + /* setup new FSF request */ + retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, + 0, NULL, &lock_flags, &fsf_req); + if (retval) { + ZFCP_LOG_INFO("error: Out of resources. Could not create an " + "exchange port data request for" + "the adapter %s.\n", + zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); return retval; } + if (data) + fsf_req->data = (unsigned long) data; + + sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + + zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); + retval = zfcp_fsf_req_send(fsf_req); write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); - if (!erp_action) { + if (retval) + ZFCP_LOG_INFO("error: Could not send an exchange port data " + "command on the adapter %s\n", + zfcp_get_busid_by_adapter(adapter)); + else wait_event(fsf_req->completion_wq, fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); - zfcp_fsf_req_free(fsf_req); - } + + zfcp_fsf_req_free(fsf_req); + return retval; } @@ -2277,18 +2380,16 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) { struct zfcp_adapter *adapter; - struct fsf_qtcb *qtcb; - struct fsf_qtcb_bottom_port *bottom, *data; + struct fsf_qtcb_bottom_port *bottom; struct Scsi_Host *shost; adapter = fsf_req->adapter; - qtcb = fsf_req->qtcb; - bottom = &qtcb->bottom.port; + bottom = &fsf_req->qtcb->bottom.port; shost = adapter->scsi_host; - data = (struct fsf_qtcb_bottom_port*) fsf_req->data; - if (data) - memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); + if (fsf_req->data) + memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom, + sizeof(struct fsf_qtcb_bottom_port)); if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) fc_host_permanent_port_name(shost) = bottom->wwpn; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 3a7f3b8..5fbbd21 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -731,7 +731,7 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost) if (!data) return NULL; - ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); + ret = zfcp_fsf_exchange_port_data_sync(adapter, data); if (ret) { kfree(data); return NULL; /* XXX return zeroed fc_stats? */ @@ -761,7 +761,7 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) if (!data) return; - ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); + ret = zfcp_fsf_exchange_port_data_sync(adapter, data); if (ret) { kfree(data); } else { @@ -800,6 +800,7 @@ struct fc_function_template zfcp_transport_functions = { .show_host_port_type = 1, .show_host_speed = 1, .show_host_port_id = 1, + .disable_target_scan = 1, }; /** -- cgit v1.1 From ff17a29d3cd9819a0977a07047e8f54e57dca7ce Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Aug 2007 09:31:41 +0200 Subject: [SCSI] zfcp: Enable debug feature before setting adapter online Already register the debug feature before the zfcp adapter is set online. This allows to use the debug feature to investigate the online/offline sequence. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 8 ++++++++ drivers/s390/scsi/zfcp_ccw.c | 8 +------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index eb3af41a3..4a67320 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -1038,6 +1038,10 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) spin_lock_init(&adapter->san_dbf_lock); spin_lock_init(&adapter->scsi_dbf_lock); + retval = zfcp_adapter_debug_register(adapter); + if (retval) + goto debug_register_failed; + /* initialize error recovery stuff */ rwlock_init(&adapter->erp_lock); @@ -1084,6 +1088,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) generic_services_failed: zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); sysfs_failed: + zfcp_adapter_debug_unregister(adapter); + debug_register_failed: dev_set_drvdata(&ccw_device->dev, NULL); zfcp_reqlist_free(adapter); failed_low_mem_buffers: @@ -1129,6 +1135,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) goto out; } + zfcp_adapter_debug_unregister(adapter); + /* remove specified adapter data structure from list */ write_lock_irq(&zfcp_data.config_lock); list_del(&adapter->list); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 1c8f71a..2773724 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -150,15 +150,12 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) down(&zfcp_data.config_sema); adapter = dev_get_drvdata(&ccw_device->dev); - retval = zfcp_adapter_debug_register(adapter); - if (retval) - goto out; retval = zfcp_erp_thread_setup(adapter); if (retval) { ZFCP_LOG_INFO("error: start of error recovery thread for " "adapter %s failed\n", zfcp_get_busid_by_adapter(adapter)); - goto out_erp_thread; + goto out; } retval = zfcp_adapter_scsi_register(adapter); @@ -177,8 +174,6 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) out_scsi_register: zfcp_erp_thread_kill(adapter); - out_erp_thread: - zfcp_adapter_debug_unregister(adapter); out: up(&zfcp_data.config_sema); return retval; @@ -201,7 +196,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_wait(adapter); zfcp_erp_thread_kill(adapter); - zfcp_adapter_debug_unregister(adapter); up(&zfcp_data.config_sema); return 0; } -- cgit v1.1 From db9b6e89ea8dc3f32dea1125c672de1a9710be7c Mon Sep 17 00:00:00 2001 From: HighPoint Linux Team Date: Thu, 30 Aug 2007 18:06:21 +0800 Subject: [SCSI] hptiop: adding new firmware interface and more PCI device IDs updated patch based on Jeff Garzik's comments. - check adapter firmware version and use appropriate interface accordingly - add new PCI device IDs and use PCI_VDEVICE macro - update driver version string - remove unused data structures - remove unnecessary typecasts Signed-off-by: HighPoint Linux Team Signed-off-by: James Bottomley --- drivers/scsi/hptiop.c | 63 ++++++++++---- drivers/scsi/hptiop.h | 229 +++----------------------------------------------- 2 files changed, 58 insertions(+), 234 deletions(-) diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 0e579ca..8b384fa 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1,6 +1,6 @@ /* * HighPoint RR3xxx controller driver for Linux - * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. + * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver"); static char driver_name[] = "hptiop"; static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; -static const char driver_ver[] = "v1.0 (060426)"; +static const char driver_ver[] = "v1.2 (070830)"; static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); @@ -76,7 +76,7 @@ static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec) static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) { - if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) + if (tag & IOPMU_QUEUE_ADDR_HOST_BIT) return hptiop_host_request_callback(hba, tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); else @@ -323,12 +323,22 @@ static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req) hba->req_list = req; } -static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) +static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 _tag) { struct hpt_iop_request_scsi_command *req; struct scsi_cmnd *scp; + u32 tag; + + if (hba->iopintf_v2) { + tag = _tag & ~ IOPMU_QUEUE_REQUEST_RESULT_BIT; + req = hba->reqs[tag].req_virt; + if (likely(_tag & IOPMU_QUEUE_REQUEST_RESULT_BIT)) + req->header.result = IOP_RESULT_SUCCESS; + } else { + tag = _tag; + req = hba->reqs[tag].req_virt; + } - req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt; dprintk("hptiop_host_request_callback: req=%p, type=%d, " "result=%d, context=0x%x tag=%d\n", req, req->header.type, req->header.result, @@ -497,7 +507,7 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, goto cmd_done; } - req = (struct hpt_iop_request_scsi_command *)_req->req_virt; + req = _req->req_virt; /* build S/G table */ sg_count = hptiop_buildsgl(scp, req->sg_list); @@ -521,8 +531,19 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); - writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, - &hba->iop->inbound_queue); + if (hba->iopintf_v2) { + u32 size_bits; + if (req->header.size < 256) + size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT; + else if (req->header.size < 512) + size_bits = IOPMU_QUEUE_ADDR_HOST_BIT; + else + size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT | + IOPMU_QUEUE_ADDR_HOST_BIT; + writel(_req->req_shifted_phy | size_bits, &hba->iop->inbound_queue); + } else + writel(_req->req_shifted_phy | IOPMU_QUEUE_ADDR_HOST_BIT, + &hba->iop->inbound_queue); return 0; @@ -688,6 +709,7 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, hba->pcidev = pcidev; hba->host = host; hba->initialized = 0; + hba->iopintf_v2 = 0; atomic_set(&hba->resetting, 0); atomic_set(&hba->reset_count, 0); @@ -722,8 +744,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, hba->max_request_size = le32_to_cpu(iop_config.request_size); hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); hba->firmware_version = le32_to_cpu(iop_config.firmware_version); + hba->interface_version = le32_to_cpu(iop_config.interface_version); hba->sdram_size = le32_to_cpu(iop_config.sdram_size); + if (hba->firmware_version > 0x01020000 || + hba->interface_version > 0x01020000) + hba->iopintf_v2 = 1; + host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; host->max_id = le32_to_cpu(iop_config.max_devices); host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); @@ -731,8 +758,15 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); host->max_cmd_len = 16; - set_config.vbus_id = cpu_to_le32(host->host_no); + req_size = sizeof(struct hpt_iop_request_scsi_command) + + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); + if ((req_size & 0x1f) != 0) + req_size = (req_size + 0x1f) & ~0x1f; + + memset(&set_config, 0, sizeof(struct hpt_iop_request_set_config)); set_config.iop_id = cpu_to_le32(host->host_no); + set_config.vbus_id = cpu_to_le16(host->host_no); + set_config.max_host_request_size = cpu_to_le16(req_size); if (iop_set_config(hba, &set_config)) { printk(KERN_ERR "scsi%d: set config failed\n", @@ -750,10 +784,6 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, } /* Allocate request mem */ - req_size = sizeof(struct hpt_iop_request_scsi_command) - + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); - if ((req_size& 0x1f) != 0) - req_size = (req_size + 0x1f) & ~0x1f; dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); @@ -879,8 +909,10 @@ static void hptiop_remove(struct pci_dev *pcidev) } static struct pci_device_id hptiop_id_table[] = { - { PCI_DEVICE(0x1103, 0x3220) }, - { PCI_DEVICE(0x1103, 0x3320) }, + { PCI_VDEVICE(TTI, 0x3220) }, + { PCI_VDEVICE(TTI, 0x3320) }, + { PCI_VDEVICE(TTI, 0x3520) }, + { PCI_VDEVICE(TTI, 0x4320) }, {}, }; @@ -910,3 +942,4 @@ module_init(hptiop_module_init); module_exit(hptiop_module_exit); MODULE_LICENSE("GPL"); + diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h index f04f7e8..2a5e46e 100644 --- a/drivers/scsi/hptiop.h +++ b/drivers/scsi/hptiop.h @@ -1,6 +1,6 @@ /* * HighPoint RR3xxx controller driver for Linux - * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. + * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,219 +18,6 @@ #ifndef _HPTIOP_H_ #define _HPTIOP_H_ -/* - * logical device type. - * Identify array (logical device) and physical device. - */ -#define LDT_ARRAY 1 -#define LDT_DEVICE 2 - -/* - * Array types - */ -#define AT_UNKNOWN 0 -#define AT_RAID0 1 -#define AT_RAID1 2 -#define AT_RAID5 3 -#define AT_RAID6 4 -#define AT_JBOD 7 - -#define MAX_NAME_LENGTH 36 -#define MAX_ARRAYNAME_LEN 16 - -#define MAX_ARRAY_MEMBERS_V1 8 -#define MAX_ARRAY_MEMBERS_V2 16 - -/* keep definition for source code compatiblity */ -#define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1 - -/* - * array flags - */ -#define ARRAY_FLAG_DISABLED 0x00000001 /* The array is disabled */ -#define ARRAY_FLAG_NEEDBUILDING 0x00000002 /* need to be rebuilt */ -#define ARRAY_FLAG_REBUILDING 0x00000004 /* in rebuilding process */ -#define ARRAY_FLAG_BROKEN 0x00000008 /* broken but still working */ -#define ARRAY_FLAG_BOOTDISK 0x00000010 /* has a active partition */ -#define ARRAY_FLAG_BOOTMARK 0x00000040 /* array has boot mark set */ -#define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ -#define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ -#define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ -#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ -#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ -#define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */ -#define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */ - -/* - * device flags - */ -#define DEVICE_FLAG_DISABLED 0x00000001 /* device is disabled */ -#define DEVICE_FLAG_UNINITIALIZED 0x00010000 /* device is not initialized */ -#define DEVICE_FLAG_LEGACY 0x00020000 /* lagacy drive */ -#define DEVICE_FLAG_IS_SPARE 0x80000000 /* is a spare disk */ - -/* - * ioctl codes - */ -#define HPT_CTL_CODE(x) (x+0xFF00) -#define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00) - -#define HPT_IOCTL_GET_CONTROLLER_INFO HPT_CTL_CODE(2) -#define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3) -#define HPT_IOCTL_GET_LOGICAL_DEVICES HPT_CTL_CODE(4) -#define HPT_IOCTL_GET_DRIVER_CAPABILITIES HPT_CTL_CODE(19) -#define HPT_IOCTL_GET_DEVICE_INFO_V3 HPT_CTL_CODE(46) -#define HPT_IOCTL_GET_CONTROLLER_INFO_V2 HPT_CTL_CODE(47) - -/* - * Controller information. - */ -struct hpt_controller_info { - u8 chip_type; /* chip type */ - u8 interrupt_level; /* IRQ level */ - u8 num_buses; /* bus count */ - u8 chip_flags; - - u8 product_id[MAX_NAME_LENGTH];/* product name */ - u8 vendor_id[MAX_NAME_LENGTH]; /* vendor name */ -} -__attribute__((packed)); - -/* - * Channel information. - */ -struct hpt_channel_info { - __le32 io_port; /* IDE Base Port Address */ - __le32 control_port; /* IDE Control Port Address */ - __le32 devices[2]; /* device connected to this channel */ -} -__attribute__((packed)); - -/* - * Array information. - */ -struct hpt_array_info_v3 { - u8 name[MAX_ARRAYNAME_LEN]; /* array name */ - u8 description[64]; /* array description */ - u8 create_manager[16]; /* who created it */ - __le32 create_time; /* when created it */ - - u8 array_type; /* array type */ - u8 block_size_shift; /* stripe size */ - u8 ndisk; /* Number of ID in Members[] */ - u8 reserved; - - __le32 flags; /* working flags, see ARRAY_FLAG_XXX */ - __le32 members[MAX_ARRAY_MEMBERS_V2]; /* member array/disks */ - - __le32 rebuilding_progress; - __le64 rebuilt_sectors; /* rebuilding point (LBA) for single member */ - - __le32 transform_source; - __le32 transform_target; /* destination device ID */ - __le32 transforming_progress; - __le32 signature; /* persistent identification*/ - __le16 critical_members; /* bit mask of critical members */ - __le16 reserve2; - __le32 reserve; -} -__attribute__((packed)); - -/* - * physical device information. - */ -#define MAX_PARENTS_PER_DISK 8 - -struct hpt_device_info_v2 { - u8 ctlr_id; /* controller id */ - u8 path_id; /* bus */ - u8 target_id; /* id */ - u8 device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */ - /* 5-7 MW DMA0-2, 8-13 UDMA0-5 */ - u8 device_type; /* device type */ - u8 usable_mode; /* highest usable mode */ - -#ifdef __BIG_ENDIAN_BITFIELD - u8 NCQ_enabled: 1; - u8 NCQ_supported: 1; - u8 TCQ_enabled: 1; - u8 TCQ_supported: 1; - u8 write_cache_enabled: 1; - u8 write_cache_supported: 1; - u8 read_ahead_enabled: 1; - u8 read_ahead_supported: 1; - u8 reserved6: 6; - u8 spin_up_mode: 2; -#else - u8 read_ahead_supported: 1; - u8 read_ahead_enabled: 1; - u8 write_cache_supported: 1; - u8 write_cache_enabled: 1; - u8 TCQ_supported: 1; - u8 TCQ_enabled: 1; - u8 NCQ_supported: 1; - u8 NCQ_enabled: 1; - u8 spin_up_mode: 2; - u8 reserved6: 6; -#endif - - __le32 flags; /* working flags, see DEVICE_FLAG_XXX */ - u8 ident[150]; /* (partitial) Identify Data of this device */ - - __le64 total_free; - __le64 max_free; - __le64 bad_sectors; - __le32 parent_arrays[MAX_PARENTS_PER_DISK]; -} -__attribute__((packed)); - -/* - * Logical device information. - */ -#define INVALID_TARGET_ID 0xFF -#define INVALID_BUS_ID 0xFF - -struct hpt_logical_device_info_v3 { - u8 type; /* LDT_ARRAY or LDT_DEVICE */ - u8 cache_policy; /* refer to CACHE_POLICY_xxx */ - u8 vbus_id; /* vbus sequence in vbus_list */ - u8 target_id; /* OS target id. 0xFF is invalid */ - /* OS name: DISK $VBusId_$TargetId */ - __le64 capacity; /* array capacity */ - __le32 parent_array; /* don't use this field for physical - device. use ParentArrays field in - hpt_device_info_v2 */ - /* reserved statistic fields */ - __le32 stat1; - __le32 stat2; - __le32 stat3; - __le32 stat4; - - union { - struct hpt_array_info_v3 array; - struct hpt_device_info_v2 device; - } __attribute__((packed)) u; - -} -__attribute__((packed)); - -/* - * ioctl structure - */ -#define HPT_IOCTL_MAGIC 0xA1B2C3D4 - -struct hpt_ioctl_u { - u32 magic; /* used to check if it's a valid ioctl packet */ - u32 ioctl_code; /* operation control code */ - void __user *inbuf; /* input data buffer */ - u32 inbuf_size; /* size of input data buffer */ - void __user *outbuf; /* output data buffer */ - u32 outbuf_size; /* size of output data buffer */ - void __user *bytes_returned; /* count of bytes returned */ -} -__attribute__((packed)); - - struct hpt_iopmu { __le32 resrved0[4]; @@ -252,6 +39,8 @@ struct hpt_iopmu #define IOPMU_QUEUE_EMPTY 0xffffffff #define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 #define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 +#define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 +#define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 #define IOPMU_OUTBOUND_INT_MSG0 1 #define IOPMU_OUTBOUND_INT_MSG1 2 @@ -336,7 +125,8 @@ struct hpt_iop_request_set_config { struct hpt_iop_request_header header; __le32 iop_id; - __le32 vbus_id; + __le16 vbus_id; + __le16 max_host_request_size; __le32 reserve[6]; }; @@ -412,9 +202,8 @@ struct hptiop_hba { struct Scsi_Host * host; struct pci_dev * pcidev; - struct list_head link; - /* IOP config info */ + u32 interface_version; u32 firmware_version; u32 sdram_size; u32 max_devices; @@ -423,8 +212,10 @@ struct hptiop_hba { u32 max_sg_descriptors; u32 req_size; /* host-allocated request buffer size */ - int initialized; - int msg_done; + + int iopintf_v2: 1; + int initialized: 1; + int msg_done: 1; struct hptiop_request * req_list; struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; -- cgit v1.1 From c0d9a413a59024e27298c39c2df30eb6076437b8 Mon Sep 17 00:00:00 2001 From: "Salyzyn, Mark" Date: Tue, 4 Sep 2007 12:55:47 -0400 Subject: [SCSI] aacraid: Add documentation for new Adaptec, SMC and SUN cards Add the SMC LP, SUN EM and Adaptec 5405 cards to the aacraid documentation list of supported products. These cards are picked up with family match, so no associated code changes. Signed-off-by: Mark Salyzyn Signed-off-by: James Bottomley --- Documentation/scsi/aacraid.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/scsi/aacraid.txt b/Documentation/scsi/aacraid.txt index cc12b55..a825784 100644 --- a/Documentation/scsi/aacraid.txt +++ b/Documentation/scsi/aacraid.txt @@ -38,10 +38,8 @@ Supported Cards/Chipsets 9005:0286:9005:02ac Adaptec 1800 (Typhoon44) 9005:0285:9005:02b5 Adaptec 5445 (Voodoo44) 9005:0285:15d9:02b5 SMC AOC-USAS-S4i - 9005:0285:15d9:02c9 SMC AOC-USAS-S4iR 9005:0285:9005:02b6 Adaptec 5805 (Voodoo80) 9005:0285:15d9:02b6 SMC AOC-USAS-S8i - 9005:0285:15d9:02ca SMC AOC-USAS-S8iR 9005:0285:9005:02b7 Adaptec 5085 (Voodoo08) 9005:0285:9005:02bb Adaptec 3405 (Marauder40LP) 9005:0285:9005:02bc Adaptec 3805 (Marauder80LP) @@ -50,9 +48,14 @@ Supported Cards/Chipsets 9005:0285:9005:02be Adaptec 31605 (Marauder160) 9005:0285:9005:02c3 Adaptec 51205 (Voodoo120) 9005:0285:9005:02c4 Adaptec 51605 (Voodoo160) + 9005:0285:15d9:02c9 SMC AOC-USAS-S4iR + 9005:0285:15d9:02ca SMC AOC-USAS-S8iR 9005:0285:9005:02ce Adaptec 51245 (Voodoo124) 9005:0285:9005:02cf Adaptec 51645 (Voodoo164) 9005:0285:9005:02d0 Adaptec 52445 (Voodoo244) + 9005:0285:9005:02d1 Adaptec 5405 (Voodoo40) + 9005:0285:15d9:02d2 SMC AOC-USAS-S8i-LP + 9005:0285:15d9:02d3 SMC AOC-USAS-S8iR-LP 1011:0046:9005:0364 Adaptec 5400S (Mustang) 9005:0287:9005:0800 Adaptec Themisto (Jupiter) 9005:0200:9005:0200 Adaptec Themisto (Jupiter) @@ -103,6 +106,7 @@ Supported Cards/Chipsets 9005:0285:108e:7aac SUN STK RAID REM (Voodoo44 Coyote) 9005:0285:108e:0286 SUN STK RAID INT (Cougar) 9005:0285:108e:0287 SUN STK RAID EXT (Prometheus) + 9005:0285:108e:7aae SUN STK RAID EM (Narvi) People ------------------------- -- cgit v1.1 From f9755bea9c44aaeae4d7f76e0cd86dfbbd5dfe12 Mon Sep 17 00:00:00 2001 From: Gilbert Wu Date: Wed, 5 Sep 2007 16:04:29 -0700 Subject: [SCSI] aic94xx: Add new PCI ID for ASC58300 Add new HBA PCI ID (0x416) for ASC58300 which has eight port SAS and SATA PCI-X 133MHz low profile host bus adapter with two mini SAS 4x external connectors. Signed-off-by: Gilbert Wu Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_hwi.h | 12 ------------ drivers/scsi/aic94xx/aic94xx_init.c | 25 +++++++++---------------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index c6c3d18..491e5d8 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h @@ -40,18 +40,6 @@ #define ASD_MAX_PHYS 8 #define ASD_PCBA_SN_SIZE 12 -/* Those are to be further named properly, the "RAZORx" part, and - * subsequently included in include/linux/pci_ids.h. - */ -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E -#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3F 0x43F - struct asd_ha_addrspace { void __iomem *addr; unsigned long start; /* pci resource start */ diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 63bcde2..63d1045 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -829,22 +829,15 @@ static struct sas_domain_function_template aic94xx_transport_functions = { }; static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR10), - 0, 0, 1}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR12), - 0, 0, 1}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), - 0, 0, 1}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), - 0, 0, 1}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), - 0, 0, 2}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), - 0, 0, 2}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3E), - 0, 0, 2}, - {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3F), - 0, 0, 2}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41E),0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41F),0, 0, 1}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x430),0, 0, 2}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x432),0, 0, 2}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43E),0, 0, 2}, + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43F),0, 0, 2}, {} }; -- cgit v1.1 From 8184fe9b6e8928c8d5be3e2a1326b8b9183e409d Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 1 Sep 2007 02:02:16 +0900 Subject: [SCSI] tgt: fix can_queue bug should use host->can_queue instead of host->hostt->can_queue. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_tgt_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 5851c8e..66c692f 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -237,7 +237,7 @@ int scsi_tgt_alloc_queue(struct Scsi_Host *shost) * command as is recvd to userspace. uspace can then make * sure we do not overload the HBA */ - q->nr_requests = shost->hostt->can_queue; + q->nr_requests = shost->can_queue; /* * We currently only support software LLDs so this does * not matter for now. Do we need this for the cards we support? -- cgit v1.1 From 5dc2b89e124251662f580f4ba3c9f6195d1eaff6 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 1 Sep 2007 02:02:20 +0900 Subject: [SCSI] add supported_mode and active_mode attributes to the host This adds supported_mode and active_mode attributes to /sys/class/sys_host/hostX/ for specifying the mode that a lld supports and the currently activated mode. The output format is similar to fc rport roles: luce:/sys/class/scsi_host/host0$ cat supported_mode Initiator luce:/sys/class/scsi_host/host0$ cat active_mode Initiator The mode values uses bitmap since we would support dual-mode llds in the future like this: luce:/sys/class/scsi_host/host0$ cat supported_mode Initiator, Target The supported_mode attribute looks at a scsi_host_template and the active_mode attribute looks at a scsi_host. We would add a hook to a scsi_host_template to change the active_mode attribute dynamically. But now there is no hook since no lld supports that feature. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/hosts.c | 1 + drivers/scsi/scsi_sysfs.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_host.h | 9 +++++++++ 3 files changed, 52 insertions(+) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 96bc312..adc9559 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -342,6 +342,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost->unchecked_isa_dma = sht->unchecked_isa_dma; shost->use_clustering = sht->use_clustering; shost->ordered_tag = sht->ordered_tag; + shost->active_mode = sht->supported_mode; if (sht->max_host_blocked) shost->max_host_blocked = sht->max_host_blocked; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 34cdce6..a3d227f 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -190,6 +190,46 @@ show_shost_state(struct class_device *class_dev, char *buf) static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state); +static ssize_t +show_shost_mode(unsigned int mode, char *buf) +{ + ssize_t len = 0; + + if (mode & MODE_INITIATOR) + len = sprintf(buf, "%s", "Initiator"); + + if (mode & MODE_TARGET) + len += sprintf(buf + len, "%s%s", len ? ", " : "", "Target"); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static ssize_t show_shost_supported_mode(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + + if (shost->hostt->supported_mode == MODE_UNKNOWN) + return snprintf(buf, 20, "unknown\n"); + else + return show_shost_mode(shost->hostt->supported_mode, buf); +} + +static CLASS_DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL); + +static ssize_t show_shost_active_mode(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + + if (shost->active_mode == MODE_UNKNOWN) + return snprintf(buf, 20, "unknown\n"); + else + return show_shost_mode(shost->active_mode, buf); +} + +static CLASS_DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL); + shost_rd_attr(unique_id, "%u\n"); shost_rd_attr(host_busy, "%hu\n"); shost_rd_attr(cmd_per_lun, "%hd\n"); @@ -208,6 +248,8 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { &class_device_attr_proc_name, &class_device_attr_scan, &class_device_attr_state, + &class_device_attr_supported_mode, + &class_device_attr_active_mode, NULL }; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 88f6871..5b79697 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -32,6 +32,9 @@ struct blk_queue_tags; #define SG_NONE 0 #define SG_ALL 0xff +#define MODE_UNKNOWN 0x00 +#define MODE_INITIATOR 0x01 +#define MODE_TARGET 0x02 #define DISABLE_CLUSTERING 0 #define ENABLE_CLUSTERING 1 @@ -405,6 +408,11 @@ struct scsi_host_template { unsigned char present; /* + * This specifies the mode that a LLD supports. + */ + unsigned supported_mode:2; + + /* * true if this host adapter uses unchecked DMA onto an ISA bus. */ unsigned unchecked_isa_dma:1; @@ -574,6 +582,7 @@ struct Scsi_Host { */ unsigned long cmd_serial_number, cmd_pid; + unsigned active_mode:2; unsigned unchecked_isa_dma:1; unsigned use_clustering:1; unsigned use_blk_tcq:1; -- cgit v1.1 From 7525236d0bc7ad17eb5e0733417896cab745d6c8 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 1 Sep 2007 02:02:27 +0900 Subject: [SCSI] fc_transport: add target driver support This adds minimum target driver support like the srp transport does: - fc_remote_port_{rolechg,delete} calls scsi_tgt_it_nexus_{create,destroy} for target drivers. - add callbacks to notify target drivers of the nexus and tmf operation results to fc_function_template. Signed-off-by: FUJITA Tomonori Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 7 +++++++ drivers/scsi/scsi_transport_fc.c | 29 +++++++++++++++++++++++++++++ drivers/scsi/scsi_transport_fc_internal.h | 26 ++++++++++++++++++++++++++ include/scsi/scsi_transport_fc.h | 4 ++++ 4 files changed, 66 insertions(+) create mode 100644 drivers/scsi/scsi_transport_fc_internal.h diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 7877dfd..e1efa0e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -272,6 +272,13 @@ config SCSI_FC_ATTRS each attached FiberChannel device to sysfs, say Y. Otherwise, say N. +config SCSI_FC_TGT_ATTRS + bool "SCSI target support for FiberChannel Transport Attributes" + depends on SCSI_FC_ATTRS + depends on SCSI_TGT = y || SCSI_TGT = SCSI_FC_ATTRS + help + If you want to use SCSI target mode drivers enable this option. + config SCSI_ISCSI_ATTRS tristate "iSCSI Transport Attributes" depends on SCSI && NET diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index dd97f26..8df0f08 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -36,6 +36,7 @@ #include #include #include "scsi_priv.h" +#include "scsi_transport_fc_internal.h" static int fc_queue_work(struct Scsi_Host *, struct work_struct *); static void fc_vport_sched_delete(struct work_struct *work); @@ -1956,6 +1957,19 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel, return 0; } +static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, + int result) +{ + struct fc_internal *i = to_fc_internal(shost->transportt); + return i->f->tsk_mgmt_response(shost, nexus, tm_id, result); +} + +static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) +{ + struct fc_internal *i = to_fc_internal(shost->transportt); + return i->f->it_nexus_response(shost, nexus, result); +} + struct scsi_transport_template * fc_attach_transport(struct fc_function_template *ft) { @@ -1999,6 +2013,10 @@ fc_attach_transport(struct fc_function_template *ft) i->t.user_scan = fc_user_scan; + /* target-mode drivers' functions */ + i->t.tsk_mgmt_response = fc_tsk_mgmt_response; + i->t.it_nexus_response = fc_it_nexus_response; + /* * Setup SCSI Target Attributes. */ @@ -2756,6 +2774,10 @@ fc_remote_port_delete(struct fc_rport *rport) spin_unlock_irqrestore(shost->host_lock, flags); + if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR && + shost->active_mode & MODE_TARGET) + fc_tgt_it_nexus_destroy(shost, (unsigned long)rport); + scsi_target_block(&rport->dev); /* see if we need to kill io faster than waiting for device loss */ @@ -2796,6 +2818,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; int create = 0; + int ret; spin_lock_irqsave(shost->host_lock, flags); if (roles & FC_PORT_ROLE_FCP_TARGET) { @@ -2804,6 +2827,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) create = 1; } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) create = 1; + } else if (shost->active_mode & MODE_TARGET) { + ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport, + (char *)&rport->node_name); + if (ret) + printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n", + ret); } rport->roles = roles; diff --git a/drivers/scsi/scsi_transport_fc_internal.h b/drivers/scsi/scsi_transport_fc_internal.h new file mode 100644 index 0000000..e7bfbe7 --- /dev/null +++ b/drivers/scsi/scsi_transport_fc_internal.h @@ -0,0 +1,26 @@ +#include + +#ifdef CONFIG_SCSI_FC_TGT_ATTRS +static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + return scsi_tgt_it_nexus_create(shost, itn_id, initiator); +} + +static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + return scsi_tgt_it_nexus_destroy(shost, itn_id); +} +#else +static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + return 0; +} + +static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + return 0; +} + +#endif diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 616a96a..e466d88 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -589,6 +589,10 @@ struct fc_function_template { int (*vport_disable)(struct fc_vport *, bool); int (*vport_delete)(struct fc_vport *); + /* target-mode drivers' functions */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + /* allocation lengths for host-specific data */ u32 dd_fcrport_size; u32 dd_fcvport_size; -- cgit v1.1 From 72e39ea7e03d0685945d177dc8cb8fe633ca9400 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 1 Sep 2007 02:03:39 +0900 Subject: [SCSI] srp_transport: convert to use supported_mode attribute srp transport works for target drivers without supported_mode attribute but it would be better to use it explicitly. Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvstgt.c | 1 + drivers/scsi/scsi_transport_srp.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 3db03dd..82bcab6 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -820,6 +820,7 @@ static struct scsi_host_template ibmvstgt_sht = { .eh_abort_handler = ibmvstgt_eh_abort_handler, .shost_attrs = ibmvstgt_attrs, .proc_name = TGT_NAME, + .supported_mode = MODE_TARGET, }; static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 430501e..44a340b 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -222,7 +222,8 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, return ERR_PTR(ret); } - if (ids->roles == SRP_RPORT_ROLE_INITIATOR) { + if (shost->active_mode & MODE_TARGET && + ids->roles == SRP_RPORT_ROLE_INITIATOR) { ret = srp_tgt_it_nexus_create(shost, (unsigned long)rport, rport->port_id); if (ret) { @@ -249,10 +250,11 @@ EXPORT_SYMBOL_GPL(srp_rport_add); void srp_rport_del(struct srp_rport *rport) { struct device *dev = &rport->dev; + struct Scsi_Host *shost = dev_to_shost(dev->parent); - if (rport->roles == SRP_RPORT_ROLE_INITIATOR) - srp_tgt_it_nexus_destroy(dev_to_shost(dev->parent), - (unsigned long)rport); + if (shost->active_mode & MODE_TARGET && + rport->roles == SRP_RPORT_ROLE_INITIATOR) + srp_tgt_it_nexus_destroy(shost, (unsigned long)rport); transport_remove_device(dev); device_del(dev); -- cgit v1.1 From 1d9a3d06511751f02d9767de3e4d28d4dafc63b3 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 10 Aug 2007 14:50:37 -0700 Subject: [SCSI] mpt fusion: Use menuconfig objects Change Kconfig objects from "menu, config" into "menuconfig" so that the user can disable the whole feature without having to enter the menu first. Signed-off-by: Jan Engelhardt Acked-by: "Moore, Eric Dean" Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/message/fusion/Kconfig | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index 3c44a2f..9b87c2f 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig @@ -1,15 +1,19 @@ -menu "Fusion MPT device support" +menuconfig FUSION + bool "Fusion MPT device support" depends on PCI + ---help--- + Say Y here to get to see options for Fusion Message + Passing Technology (MPT) drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. -config FUSION - bool - default n +if FUSION config FUSION_SPI tristate "Fusion MPT ScsiHost drivers for SPI" depends on PCI && SCSI - select FUSION select SCSI_SPI_ATTRS ---help--- SCSI HOST support for a parallel SCSI host adapters. @@ -25,7 +29,6 @@ config FUSION_SPI config FUSION_FC tristate "Fusion MPT ScsiHost drivers for FC" depends on PCI && SCSI - select FUSION select SCSI_FC_ATTRS ---help--- SCSI HOST support for a Fiber Channel host adapters. @@ -43,7 +46,6 @@ config FUSION_FC config FUSION_SAS tristate "Fusion MPT ScsiHost drivers for SAS" depends on PCI && SCSI - select FUSION select SCSI_SAS_ATTRS ---help--- SCSI HOST support for a SAS host adapters. @@ -57,7 +59,6 @@ config FUSION_SAS config FUSION_MAX_SGE int "Maximum number of scatter gather entries (16 - 128)" - depends on FUSION default "128" range 16 128 help @@ -117,4 +118,4 @@ config FUSION_LOGGING There are various debug levels that an be found in the source: file:drivers/message/fusion/mptdebug.h -endmenu +endif # FUSION -- cgit v1.1 From d7383a234626b58dc6bc210ed806a6911c1f44e1 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 14:50:50 -0700 Subject: [SCSI] mpt fusion: mostly kmalloc + memset conversion to kzalloc This patch does kmalloc + memset conversion to kzalloc anSigned-off-by: Mariusz Kozlowski d simplifies mptctl_probe(). drivers/message/fusion/mptctl.c | 82092 -> 81884 (-208 bytes) drivers/message/fusion/mptctl.o | 201784 -> 200648 (-1136 bytes) Signed-off-by: Mariusz Kozlowski Acked-by: "Moore, Eric Dean" Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b9618f4..12dfa2e 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -977,10 +977,9 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags, * structures for the SG elements. */ i = MAX_SGL_BYTES / 8; - buflist = kmalloc(i, GFP_USER); - if (buflist == NULL) + buflist = kzalloc(i, GFP_USER); + if (!buflist) return NULL; - memset(buflist, 0, i); buflist_ent = 0; /* Allocate a single block of memory to store the sg elements and @@ -1379,13 +1378,12 @@ mptctl_gettargetinfo (unsigned long arg) * 15- 8: Bus Number * 7- 0: Target ID */ - pmem = kmalloc(numBytes, GFP_KERNEL); - if (pmem == NULL) { + pmem = kzalloc(numBytes, GFP_KERNEL); + if (!pmem) { printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n", __FILE__, __LINE__); return -ENOMEM; } - memset(pmem, 0, numBytes); pdata = (int *) pmem; /* Get number of devices @@ -1570,12 +1568,11 @@ mptctl_eventenable (unsigned long arg) /* Have not yet allocated memory - do so now. */ int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); - ioc->events = kmalloc(sz, GFP_KERNEL); - if (ioc->events == NULL) { + ioc->events = kzalloc(sz, GFP_KERNEL); + if (!ioc->events) { printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } - memset(ioc->events, 0, sz); ioc->alloc_total += sz; ioc->eventContext = 0; @@ -2865,31 +2862,22 @@ static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long a static int mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - int err; - int sz; - u8 *mem; + MPT_IOCTL *mem; MPT_ADAPTER *ioc = pci_get_drvdata(pdev); /* * Allocate and inite a MPT_IOCTL structure */ - sz = sizeof (MPT_IOCTL); - mem = kmalloc(sz, GFP_KERNEL); - if (mem == NULL) { - err = -ENOMEM; - goto out_fail; + mem = kzalloc(sizeof(MPT_IOCTL), GFP_KERNEL); + if (!mem) { + mptctl_remove(pdev); + return -ENOMEM; } - memset(mem, 0, sz); - ioc->ioctl = (MPT_IOCTL *) mem; + ioc->ioctl = mem; ioc->ioctl->ioc = ioc; mutex_init(&ioc->ioctl->ioctl_mutex); return 0; - -out_fail: - - mptctl_remove(pdev); - return err; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -- cgit v1.1 From 568761955ad01c6d238d8b12d21a554c1226a37b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 10 Aug 2007 14:50:51 -0700 Subject: [SCSI] mpt fusion: fix two potential mem leaks The Coverity checker spotted two potential memory leaks in drivers/message/fusion/mptbase.c::mpt_attach(). There are two returns that may leak the storage allocated for 'ioc' (sizeof(MPT_ADAPTER) bytes). A simple fix would be to simply add two kfree() calls before the return statements, but a better fix (that this patch implements) is to reorder the code so that if we hit the first return condition we don't have to do the allocation at all and then just add a kfree() call for the second case. Signed-off-by: Jesper Juhl Acked-by: "Moore, Eric Dean" Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 22cb0f8..635defd 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1458,18 +1458,18 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) struct proc_dir_entry *dent, *ent; #endif + if (mpt_debug_level) + printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); + + if (pci_enable_device(pdev)) + return r; + ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); if (ioc == NULL) { printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; } - ioc->debug_level = mpt_debug_level; - if (mpt_debug_level) - printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); - - if (pci_enable_device(pdev)) - return r; dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n")); @@ -1478,6 +1478,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n"); + kfree(ioc); return r; } -- cgit v1.1 From 82d1ce505d1a77a03acb9d22240ef5a63a18b653 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 14:50:53 -0700 Subject: [SCSI] mpt fusion: remove redundant memset alloc_fcdev() calls alloc_netdev() which uses kzalloc to alloc all the memory together with dev->priv region hence no zeroing of structs inside struct mpt_lan_priv needed. Signed-off-by: Mariusz Kozlowski Acked-by: "Moore, Eric Dean" Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/message/fusion/mptlan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 952e148..b550471 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1345,10 +1345,11 @@ mpt_lan_post_receive_buckets_work(struct work_struct *work) static struct net_device * mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) { - struct net_device *dev = alloc_fcdev(sizeof(struct mpt_lan_priv)); - struct mpt_lan_priv *priv = NULL; + struct net_device *dev; + struct mpt_lan_priv *priv; u8 HWaddr[FC_ALEN], *a; + dev = alloc_fcdev(sizeof(struct mpt_lan_priv)); if (!dev) return NULL; @@ -1360,7 +1361,6 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) priv->mpt_dev = mpt_dev; priv->pnum = pnum; - memset(&priv->post_buckets_task, 0, sizeof(priv->post_buckets_task)); INIT_DELAYED_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets_work); priv->post_buckets_active = 0; @@ -1385,8 +1385,6 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) spin_lock_init(&priv->txfidx_lock); spin_lock_init(&priv->rxfidx_lock); - memset(&priv->stats, 0, sizeof(priv->stats)); - /* Grab pre-fetched LANPage1 stuff. :-) */ a = (u8 *) &mpt_dev->lan_cnfg_page1.HardwareAddressLow; -- cgit v1.1 From 41fa2adabc0a750a40d6fe86d5ce2f75fb3ad287 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Fri, 7 Sep 2007 09:15:31 +0200 Subject: [SCSI] zfcp: whitespace cleanup Cleanup the whitepace from the entire zfcp driver to prevent to have those changes in future feature or function patches. Signed-off-by: Swen Schillig Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 4 +- drivers/s390/scsi/zfcp_def.h | 46 ++++++------- drivers/s390/scsi/zfcp_erp.c | 134 ++++++++++++++++++------------------ drivers/s390/scsi/zfcp_ext.h | 30 ++++---- drivers/s390/scsi/zfcp_fsf.c | 40 +++++------ drivers/s390/scsi/zfcp_fsf.h | 30 ++++---- drivers/s390/scsi/zfcp_qdio.c | 7 +- drivers/s390/scsi/zfcp_scsi.c | 36 +++++----- drivers/s390/scsi/zfcp_sysfs_unit.c | 4 +- 9 files changed, 165 insertions(+), 166 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 4a67320..7507067 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -891,7 +891,7 @@ zfcp_unit_dequeue(struct zfcp_unit *unit) /* * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI * commands. - * It also genrates fcp-nameserver request/response buffer and unsolicited + * It also genrates fcp-nameserver request/response buffer and unsolicited * status read fsf_req buffers. * * locks: must only be called with zfcp_data.config_sema taken @@ -982,7 +982,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) struct zfcp_adapter *adapter; /* - * Note: It is safe to release the list_lock, as any list changes + * Note: It is safe to release the list_lock, as any list changes * are protected by the config_sema, which must be held to get here */ diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index b36dfc4..16e5563 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -1,23 +1,23 @@ -/* +/* * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * * (C) Copyright IBM Corp. 2002, 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #ifndef ZFCP_DEF_H #define ZFCP_DEF_H @@ -90,7 +90,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) #define ZFCP_DEVICE_TYPE 0x1732 #define ZFCP_DEVICE_MODEL 0x03 #define ZFCP_DEVICE_MODEL_PRIV 0x04 - + /* allow as many chained SBALs as are supported by hardware */ #define ZFCP_MAX_SBALS_PER_REQ FSF_MAX_SBALS_PER_REQ #define ZFCP_MAX_SBALS_PER_CT_REQ FSF_MAX_SBALS_PER_REQ @@ -508,7 +508,7 @@ struct zfcp_rc_entry { /* * this allows removal of logging code by the preprocessor - * (the most detailed log level still to be compiled in is specified, + * (the most detailed log level still to be compiled in is specified, * higher log levels are removed) */ #define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_TRACE @@ -546,7 +546,7 @@ do { \ if (ZFCP_LOG_CHECK(level)) \ _ZFCP_LOG(fmt, ##args); \ } while (0) - + #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL # define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0) #else @@ -583,8 +583,8 @@ do { \ /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ -/* - * Note, the leftmost status byte is common among adapter, port +/* + * Note, the leftmost status byte is common among adapter, port * and unit */ #define ZFCP_COMMON_FLAGS 0xfff00000 @@ -1007,8 +1007,8 @@ struct zfcp_fsf_req { u32 fsf_command; /* FSF Command copy */ struct fsf_qtcb *qtcb; /* address of associated QTCB */ u32 seq_no; /* Sequence number of request */ - unsigned long data; /* private data of request */ - struct timer_list timer; /* used for erp or scsi er */ + unsigned long data; /* private data of request */ + struct timer_list timer; /* used for erp or scsi er */ struct zfcp_erp_action *erp_action; /* used if this request is issued on behalf of erp */ mempool_t *pool; /* used if request was alloacted diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 31c2178..16bfc66 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1,22 +1,22 @@ -/* +/* * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * * (C) Copyright IBM Corp. 2002, 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP @@ -191,7 +191,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) } /* - * function: + * function: * * purpose: called if an adapter failed, * initiates adapter recovery which is done @@ -228,7 +228,7 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) } /* - * function: + * function: * * purpose: Wrappper for zfcp_erp_adapter_reopen_internal * used to ensure the correct locking @@ -476,7 +476,7 @@ zfcp_test_link(struct zfcp_port *port) /* - * function: + * function: * * purpose: called if a port failed to be opened normally * initiates Forced Reopen recovery which is done @@ -517,7 +517,7 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask) } /* - * function: + * function: * * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal * used to ensure the correct locking @@ -543,7 +543,7 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask) } /* - * function: + * function: * * purpose: called if a port is to be opened * initiates Reopen recovery which is done @@ -612,7 +612,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask) } /* - * function: + * function: * * purpose: called if a unit is to be opened * initiates Reopen recovery which is done @@ -704,7 +704,7 @@ static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) } /* - * function: + * function: * * purpose: disable I/O, * return any open requests and clean them up, @@ -725,7 +725,7 @@ zfcp_erp_port_block(struct zfcp_port *port, int clear_mask) } /* - * function: + * function: * * purpose: enable I/O * @@ -742,7 +742,7 @@ zfcp_erp_port_unblock(struct zfcp_port *port) } /* - * function: + * function: * * purpose: disable I/O, * return any open requests and clean them up, @@ -763,7 +763,7 @@ zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) } /* - * function: + * function: * * purpose: enable I/O * @@ -792,7 +792,7 @@ zfcp_erp_action_ready(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * * purpose: * @@ -967,7 +967,7 @@ void zfcp_erp_timeout_handler(unsigned long data) * zfcp_erp_action_dismiss - dismiss an erp_action * * adapter->erp_lock must be held - * + * * Dismissal of an erp_action is usually required if an erp_action of * higher priority is generated. */ @@ -1005,9 +1005,9 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: * @@ -1094,7 +1094,7 @@ zfcp_erp_thread(void *data) } /* - * function: + * function: * * purpose: drives single error recovery action and schedules higher and * subordinate actions, if necessary @@ -1206,7 +1206,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) /* * put this target through the erp mill again if someone has - * requested to change the status of a target being online + * requested to change the status of a target being online * to offline or the other way around * (old retval is preserved if nothing has to be done here) */ @@ -1228,7 +1228,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) unlock: write_unlock(&adapter->erp_lock); read_unlock_irqrestore(&zfcp_data.config_lock, flags); - + if (retval != ZFCP_ERP_CONTINUES) zfcp_erp_action_cleanup(action, adapter, port, unit, retval); @@ -1250,9 +1250,9 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_DISMISSED - if action has been dismissed * retval - otherwise @@ -1322,7 +1322,7 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * * purpose: triggers retry of this action after a certain amount of time * by means of timer provided by erp_action @@ -1346,7 +1346,7 @@ zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) return retval; } -/* +/* * function: zfcp_erp_adapter_failed * * purpose: sets the adapter and all underlying devices to ERP_FAILED @@ -1362,7 +1362,7 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter) debug_text_event(adapter->erp_dbf, 2, "a_afail"); } -/* +/* * function: zfcp_erp_port_failed * * purpose: sets the port and all underlying devices to ERP_FAILED @@ -1386,7 +1386,7 @@ zfcp_erp_port_failed(struct zfcp_port *port) debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t)); } -/* +/* * function: zfcp_erp_unit_failed * * purpose: sets the unit to ERP_FAILED @@ -1417,7 +1417,7 @@ zfcp_erp_unit_failed(struct zfcp_unit *unit) * successfully is reset. * * returns: ZFCP_ERP_CONTINUES - action continues (not considered) - * ZFCP_ERP_SUCCEEDED - action finished successfully + * ZFCP_ERP_SUCCEEDED - action finished successfully * ZFCP_ERP_EXIT - action failed and will not continue */ static int @@ -1646,7 +1646,7 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit) } /* - * function: + * function: * * purpose: remaining things in good cases, * escalation in bad cases @@ -1815,7 +1815,7 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear) } /* - * function: + * function: * * purpose: Wrappper for zfcp_erp_port_reopen_all_internal * used to ensure the correct locking @@ -1852,9 +1852,9 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: FIXME */ @@ -1871,7 +1871,7 @@ zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask) } /* - * function: + * function: * * purpose: this routine executes the 'Reopen Adapter' action * (the entire action is processed synchronously, since @@ -1908,9 +1908,9 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_SUCCEEDED - action finished successfully * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -1930,9 +1930,9 @@ zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_SUCCEEDED - action finished successfully * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -1957,7 +1957,7 @@ zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action) * purpose: allocate the irq associated with this devno and register * the FSF adapter with the SCSI stack * - * returns: + * returns: */ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) @@ -2249,7 +2249,7 @@ zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action } /* - * function: + * function: * * purpose: this routine executes the 'Reopen Physical Port' action * @@ -2308,7 +2308,7 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * * purpose: this routine executes the 'Reopen Port' action * @@ -2530,7 +2530,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * * purpose: makes the erp thread continue with reopen (physical) port * actions which have been paused until the name server port @@ -2570,9 +2570,9 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2626,9 +2626,9 @@ zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2663,9 +2663,9 @@ zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2700,9 +2700,9 @@ zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2737,7 +2737,7 @@ zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * * purpose: this routine executes the 'Reopen Unit' action * currently no retries @@ -2825,9 +2825,9 @@ zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2865,9 +2865,9 @@ zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) } /* - * function: + * function: * - * purpose: + * purpose: * * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * ZFCP_ERP_FAILED - action finished unsuccessfully @@ -2913,7 +2913,7 @@ void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req) } /* - * function: + * function: * * purpose: enqueue the specified error recovery action, if needed * @@ -2992,7 +2992,7 @@ zfcp_erp_action_enqueue(int action, port->erp_action.action); debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drp"); - } else + } else debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drpcp"); debug_event(adapter->erp_dbf, 4, &port->wwpn, diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 722c55b..8534cf0 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -1,22 +1,22 @@ -/* +/* * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * * (C) Copyright IBM Corp. 2002, 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef ZFCP_EXT_H diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 4aa8834..ff866eb 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -80,10 +80,10 @@ static const char zfcp_act_subtable_type[5][8] = { /* * function: zfcp_fsf_req_alloc * - * purpose: Obtains an fsf_req and potentially a qtcb (for all but + * purpose: Obtains an fsf_req and potentially a qtcb (for all but * unsolicited requests) via helper functions * Does some initial fsf request set-up. - * + * * returns: pointer to allocated fsf_req if successfull * NULL otherwise * @@ -192,7 +192,7 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) * returns: 0 - success * !0 - failure * - * context: + * context: */ int zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) @@ -214,8 +214,8 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) } /* - * fsf_req may be deleted due to waking up functions, so - * cleanup is saved here and used later + * fsf_req may be deleted due to waking up functions, so + * cleanup is saved here and used later */ if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) cleanup = 1; @@ -259,9 +259,9 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) * and initiates appropriate actions * (usually calling FSF command specific handlers) * - * returns: + * returns: * - * context: + * context: * * locks: */ @@ -638,7 +638,7 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, * * purpose: calls the appropriate command specific handler * - * returns: + * returns: */ static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) @@ -854,7 +854,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) * * purpose: is called for finished Open Port command * - * returns: + * returns: */ static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) @@ -1088,7 +1088,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) * returns: address of initiated FSF request * NULL - request could not be initiated * - * FIXME(design): should be watched by a timeout !!! + * FIXME(design): should be watched by a timeout !!! * FIXME(design) shouldn't this be modified to return an int * also...don't know how though */ @@ -1157,7 +1157,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, * * purpose: is called for finished Abort FCP Command request * - * returns: + * returns: */ static int zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) @@ -2437,10 +2437,10 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) /* * function: zfcp_fsf_open_port * - * purpose: + * purpose: * * returns: address of initiated FSF request - * NULL - request could not be initiated + * NULL - request could not be initiated */ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) @@ -2501,7 +2501,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) * * purpose: is called for finished Open Port command * - * returns: + * returns: */ static int zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) @@ -3103,7 +3103,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) * * purpose: is called for finished Open LUN command * - * returns: + * returns: */ static int zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) @@ -3366,7 +3366,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) * purpose: * * returns: address of fsf_req - request successfully initiated - * NULL - + * NULL - * * assumptions: This routine does not check whether the associated * remote port/lun has already been opened. This should be @@ -3828,7 +3828,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, * * purpose: is called for finished Send FCP Command * - * returns: + * returns: */ static int zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) @@ -4065,7 +4065,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) * * purpose: evaluates FCP_RSP IU * - * returns: + * returns: */ static int zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) @@ -4293,7 +4293,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) * * purpose: evaluates FCP_RSP IU * - * returns: + * returns: */ static int zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) @@ -4736,7 +4736,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, INIT_LIST_HEAD(&fsf_req->list); init_timer(&fsf_req->timer); - /* initialize waitqueue which may be used to wait on + /* initialize waitqueue which may be used to wait on this request completion */ init_waitqueue_head(&fsf_req->completion_wq); diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 7118661..8cce5cc 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -1,22 +1,22 @@ -/* +/* * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * * (C) Copyright IBM Corp. 2002, 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef FSF_H diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index c6899ef..3f105fd 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -174,10 +174,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, * That is why we need to clear the link-down flag * which is set again in case we have missed by a mile. */ - zfcp_erp_adapter_reopen( - adapter, - ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | - ZFCP_STATUS_COMMON_ERP_FAILED); + zfcp_erp_adapter_reopen(adapter, + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | + ZFCP_STATUS_COMMON_ERP_FAILED); } return retval; } diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 5fbbd21..abae202 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -1,22 +1,22 @@ -/* +/* * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * * (C) Copyright IBM Corp. 2002, 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI @@ -101,7 +101,7 @@ zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd) ((unsigned char *) fcp_cmd + sizeof (struct fcp_cmnd_iu) + additional_length); /* - * fcp_dl_addr = start address of fcp_cmnd structure + + * fcp_dl_addr = start address of fcp_cmnd structure + * size of fixed part + size of dynamically sized add_dcp_cdb field * SEE FCP-2 documentation */ @@ -194,7 +194,7 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) "address %p\n", sdpnt); } -/* +/* * called from scsi midlayer to allow finetuning of a device. */ static int @@ -372,7 +372,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id, /** * zfcp_scsi_eh_abort_handler - abort the specified SCSI command - * @scpnt: pointer to scsi_cmnd to be aborted + * @scpnt: pointer to scsi_cmnd to be aborted * Return: SUCCESS - command has been aborted and cleaned up in internal * bookkeeping, SCSI stack won't be called for aborted command * FAILED - otherwise diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c index 81a4841..63f75ee 100644 --- a/drivers/s390/scsi/zfcp_sysfs_unit.c +++ b/drivers/s390/scsi/zfcp_sysfs_unit.c @@ -139,7 +139,7 @@ static struct attribute_group zfcp_unit_attr_group = { .attrs = zfcp_unit_attrs, }; -/** +/** * zfcp_sysfs_create_unit_files - create sysfs unit files * @dev: pointer to belonging device * @@ -151,7 +151,7 @@ zfcp_sysfs_unit_create_files(struct device *dev) return sysfs_create_group(&dev->kobj, &zfcp_unit_attr_group); } -/** +/** * zfcp_sysfs_remove_unit_files - remove sysfs unit files * @dev: pointer to belonging device * -- cgit v1.1 From b8e5152bf107d7b1b982e682b00a426b515bf15f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:26 -0600 Subject: [SCSI] advansys: Fix VLB driver name You can't have two drivers for the same bus type with the same name. Since ISA and VLB are both isa_drivers, rename the VLB one to advansys_vlb. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 4d4d7c9..27b3e95 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -16985,7 +16985,7 @@ static struct isa_driver advansys_vlb_driver = { .remove = __devexit_p(advansys_isa_remove), .driver = { .owner = THIS_MODULE, - .name = "advansys", + .name = "advansys_vlb", }, }; -- cgit v1.1 From a9f4a59a949c5de6313dcf4ebe2f91448c008a37 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:27 -0600 Subject: [SCSI] advansys: Create AdvBuildCarrierFreelist Split AdvBuildCarrierFreelist out of AdvInitAsc3550Driver, AdvInitAsc38C0800Driver and AdvInitAsc38C1600Driver. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 219 ++++++++++++------------------------------------ 1 file changed, 53 insertions(+), 166 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 27b3e95..c216d6a 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -12881,6 +12881,56 @@ AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc) return warn_code; } +static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) +{ + ADV_CARR_T *carrp; + ADV_SDCNT buf_size; + ADV_PADDR carr_paddr; + + BUG_ON(!asc_dvc->carrier_buf); + + carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); + asc_dvc->carr_freelist = NULL; + if (carrp == asc_dvc->carrier_buf) { + buf_size = ADV_CARRIER_BUFSIZE; + } else { + buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); + } + + do { + /* Get physical address of the carrier 'carrp'. */ + ADV_DCNT contig_len = sizeof(ADV_CARR_T); + carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, + (uchar *)carrp, + (ADV_SDCNT *)&contig_len, + ADV_IS_CARRIER_FLAG)); + + buf_size -= sizeof(ADV_CARR_T); + + /* + * If the current carrier is not physically contiguous, then + * maybe there was a page crossing. Try the next carrier + * aligned start address. + */ + if (contig_len < sizeof(ADV_CARR_T)) { + carrp++; + continue; + } + + carrp->carr_pa = carr_paddr; + carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); + + /* + * Insert the carrier at the beginning of the freelist. + */ + carrp->next_vpa = + cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); + asc_dvc->carr_freelist = carrp; + + carrp++; + } while (buf_size > 0); +} + /* * Initialize the ASC-3550. * @@ -12902,10 +12952,6 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) int word; int j; int adv_asc3550_expanded_size; - ADV_CARR_T *carrp; - ADV_DCNT contig_len; - ADV_SDCNT buf_size; - ADV_PADDR carr_paddr; int i; ushort scsi_cfg1; uchar tid; @@ -13307,57 +13353,7 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); - /* - * Build carrier freelist. - * - * Driver must have already allocated memory and set 'carrier_buf'. - */ - ASC_ASSERT(asc_dvc->carrier_buf != NULL); - - carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); - asc_dvc->carr_freelist = NULL; - if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { - buf_size = ADV_CARRIER_BUFSIZE; - } else { - buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); - } - - do { - /* - * Get physical address of the carrier 'carrp'. - */ - contig_len = sizeof(ADV_CARR_T); - carr_paddr = - cpu_to_le32(DvcGetPhyAddr - (asc_dvc, NULL, (uchar *)carrp, - (ADV_SDCNT *)&contig_len, - ADV_IS_CARRIER_FLAG)); - - buf_size -= sizeof(ADV_CARR_T); - - /* - * If the current carrier is not physically contiguous, then - * maybe there was a page crossing. Try the next carrier aligned - * start address. - */ - if (contig_len < sizeof(ADV_CARR_T)) { - carrp++; - continue; - } - - carrp->carr_pa = carr_paddr; - carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); - - /* - * Insert the carrier at the beginning of the freelist. - */ - carrp->next_vpa = - cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); - asc_dvc->carr_freelist = carrp; - - carrp++; - } - while (buf_size > 0); + AdvBuildCarrierFreelist(asc_dvc); /* * Set-up the Host->RISC Initiator Command Queue (ICQ). @@ -13471,10 +13467,6 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) int word; int j; int adv_asc38C0800_expanded_size; - ADV_CARR_T *carrp; - ADV_DCNT contig_len; - ADV_SDCNT buf_size; - ADV_PADDR carr_paddr; int i; ushort scsi_cfg1; uchar byte; @@ -13920,57 +13912,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); - /* - * Build the carrier freelist. - * - * Driver must have already allocated memory and set 'carrier_buf'. - */ - ASC_ASSERT(asc_dvc->carrier_buf != NULL); - - carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); - asc_dvc->carr_freelist = NULL; - if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { - buf_size = ADV_CARRIER_BUFSIZE; - } else { - buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); - } - - do { - /* - * Get physical address for the carrier 'carrp'. - */ - contig_len = sizeof(ADV_CARR_T); - carr_paddr = - cpu_to_le32(DvcGetPhyAddr - (asc_dvc, NULL, (uchar *)carrp, - (ADV_SDCNT *)&contig_len, - ADV_IS_CARRIER_FLAG)); - - buf_size -= sizeof(ADV_CARR_T); - - /* - * If the current carrier is not physically contiguous, then - * maybe there was a page crossing. Try the next carrier aligned - * start address. - */ - if (contig_len < sizeof(ADV_CARR_T)) { - carrp++; - continue; - } - - carrp->carr_pa = carr_paddr; - carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); - - /* - * Insert the carrier at the beginning of the freelist. - */ - carrp->next_vpa = - cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); - asc_dvc->carr_freelist = carrp; - - carrp++; - } - while (buf_size > 0); + AdvBuildCarrierFreelist(asc_dvc); /* * Set-up the Host->RISC Initiator Command Queue (ICQ). @@ -14087,10 +14029,6 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) long word; int j; int adv_asc38C1600_expanded_size; - ADV_CARR_T *carrp; - ADV_DCNT contig_len; - ADV_SDCNT buf_size; - ADV_PADDR carr_paddr; int i; ushort scsi_cfg1; uchar byte; @@ -14544,58 +14482,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); - /* - * Build the carrier freelist. - * - * Driver must have already allocated memory and set 'carrier_buf'. - */ - - ASC_ASSERT(asc_dvc->carrier_buf != NULL); - - carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); - asc_dvc->carr_freelist = NULL; - if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { - buf_size = ADV_CARRIER_BUFSIZE; - } else { - buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); - } - - do { - /* - * Get physical address for the carrier 'carrp'. - */ - contig_len = sizeof(ADV_CARR_T); - carr_paddr = - cpu_to_le32(DvcGetPhyAddr - (asc_dvc, NULL, (uchar *)carrp, - (ADV_SDCNT *)&contig_len, - ADV_IS_CARRIER_FLAG)); - - buf_size -= sizeof(ADV_CARR_T); - - /* - * If the current carrier is not physically contiguous, then - * maybe there was a page crossing. Try the next carrier aligned - * start address. - */ - if (contig_len < sizeof(ADV_CARR_T)) { - carrp++; - continue; - } - - carrp->carr_pa = carr_paddr; - carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); - - /* - * Insert the carrier at the beginning of the freelist. - */ - carrp->next_vpa = - cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); - asc_dvc->carr_freelist = carrp; - - carrp++; - } - while (buf_size > 0); + AdvBuildCarrierFreelist(asc_dvc); /* * Set-up the Host->RISC Initiator Command Queue (ICQ). -- cgit v1.1 From b9d9661400dde3fb2027f5da8db600c66d0f876b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:28 -0600 Subject: [SCSI] advansys: Create AdvLoadMicrocode Split AdvLoadMicrocode out of AdvInitAsc3550Driver, AdvInitAsc38C0800Driver and AdvInitAsc38C1600Driver. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 382 ++++++++++++++---------------------------------- 1 file changed, 107 insertions(+), 275 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index c216d6a..0f02f3f 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -12932,6 +12932,78 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) } /* + * Load the Microcode + * + * Write the microcode image to RISC memory starting at address 0. + * + * The microcode is stored compressed in the following format: + * + * 254 word (508 byte) table indexed by byte code followed + * by the following byte codes: + * + * 1-Byte Code: + * 00: Emit word 0 in table. + * 01: Emit word 1 in table. + * . + * FD: Emit word 253 in table. + * + * Multi-Byte Code: + * FE WW WW: (3 byte code) Word to emit is the next word WW WW. + * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. + * + * Returns 0 or an error if the checksum doesn't match + */ +static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, + int memsize, int chksum) +{ + int i, j, end, len = 0; + ADV_DCNT sum; + + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); + + for (i = 253 * 2; i < size; i++) { + if (buf[i] == 0xff) { + unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; + for (j = 0; j < buf[i + 1]; j++) { + AdvWriteWordAutoIncLram(iop_base, word); + len += 2; + } + i += 3; + } else if (buf[i] == 0xfe) { + unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; + AdvWriteWordAutoIncLram(iop_base, word); + i += 2; + len += 2; + } else { + unsigned char off = buf[i] * 2; + unsigned short word = (buf[off + 1] << 8) | buf[off]; + AdvWriteWordAutoIncLram(iop_base, word); + len += 2; + } + } + + end = len; + + while (len < memsize) { + AdvWriteWordAutoIncLram(iop_base, 0); + len += 2; + } + + /* Verify the microcode checksum. */ + sum = 0; + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); + + for (len = 0; len < end; len += 2) { + sum += AdvReadWordAutoIncLram(iop_base); + } + + if (sum != chksum) + return ASC_IERR_MCODE_CHKSUM; + + return 0; +} + +/* * Initialize the ASC-3550. * * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. @@ -12945,13 +13017,10 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; - ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; - int j; - int adv_asc3550_expanded_size; int i; ushort scsi_cfg1; uchar tid; @@ -12960,15 +13029,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ - if (asc_dvc->err_code != 0) { + if (asc_dvc->err_code != 0) return ADV_ERROR; - } /* * The caller must set 'chip_type' to ADV_CHIP_ASC3550. */ if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { - asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; + asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; return ADV_ERROR; } @@ -13012,84 +13080,11 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) max_cmd[tid]); } - /* - * Load the Microcode - * - * Write the microcode image to RISC memory starting at address 0. - */ - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - /* Assume the following compressed format of the microcode buffer: - * - * 254 word (508 byte) table indexed by byte code followed - * by the following byte codes: - * - * 1-Byte Code: - * 00: Emit word 0 in table. - * 01: Emit word 1 in table. - * . - * FD: Emit word 253 in table. - * - * Multi-Byte Code: - * FE WW WW: (3 byte code) Word to emit is the next word WW WW. - * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. - */ - word = 0; - for (i = 253 * 2; i < _adv_asc3550_size; i++) { - if (_adv_asc3550_buf[i] == 0xff) { - for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc3550_buf - [i + - 3] << 8) | - _adv_asc3550_buf - [i + 2])); - word++; - } - i += 3; - } else if (_adv_asc3550_buf[i] == 0xfe) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc3550_buf[i + - 2] - << 8) | - _adv_asc3550_buf[i + - 1])); - i += 2; - word++; - } else { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2])); - word++; - } - } - - /* - * Set 'word' for later use to clear the rest of memory and save - * the expanded mcode size. - */ - word *= 2; - adv_asc3550_expanded_size = word; - - /* - * Clear the rest of ASC-3550 Internal RAM (8KB). - */ - for (; word < ADV_3550_MEMSIZE; word += 2) { - AdvWriteWordAutoIncLram(iop_base, 0); - } - - /* - * Verify the microcode checksum. - */ - sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - for (word = 0; word < adv_asc3550_expanded_size; word += 2) { - sum += AdvReadWordAutoIncLram(iop_base); - } - - if (sum != _adv_asc3550_chksum) { - asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, + _adv_asc3550_size, ADV_3550_MEMSIZE, + _adv_asc3550_chksum); + if (asc_dvc->err_code) return ADV_ERROR; - } /* * Restore the RISC memory BIOS region. @@ -13460,13 +13455,10 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; - ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; - int j; - int adv_asc38C0800_expanded_size; int i; ushort scsi_cfg1; uchar byte; @@ -13476,9 +13468,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ - if (asc_dvc->err_code != 0) { + if (asc_dvc->err_code != 0) return ADV_ERROR; - } /* * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. @@ -13550,7 +13541,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { - asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } @@ -13558,7 +13549,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { - asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } @@ -13577,99 +13568,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ - asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; + asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - /* - * Load the Microcode - * - * Write the microcode image to RISC memory starting at address 0. - * - */ - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - /* Assume the following compressed format of the microcode buffer: - * - * 254 word (508 byte) table indexed by byte code followed - * by the following byte codes: - * - * 1-Byte Code: - * 00: Emit word 0 in table. - * 01: Emit word 1 in table. - * . - * FD: Emit word 253 in table. - * - * Multi-Byte Code: - * FE WW WW: (3 byte code) Word to emit is the next word WW WW. - * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. - */ - word = 0; - for (i = 253 * 2; i < _adv_asc38C0800_size; i++) { - if (_adv_asc38C0800_buf[i] == 0xff) { - for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C0800_buf - [i + - 3] << 8) | - _adv_asc38C0800_buf - [i + 2])); - word++; - } - i += 3; - } else if (_adv_asc38C0800_buf[i] == 0xfe) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C0800_buf - [i + - 2] << 8) | - _adv_asc38C0800_buf[i - + - 1])); - i += 2; - word++; - } else { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2])); - word++; - } - } - - /* - * Set 'word' for later use to clear the rest of memory and save - * the expanded mcode size. - */ - word *= 2; - adv_asc38C0800_expanded_size = word; - - /* - * Clear the rest of ASC-38C0800 Internal RAM (16KB). - */ - for (; word < ADV_38C0800_MEMSIZE; word += 2) { - AdvWriteWordAutoIncLram(iop_base, 0); - } - - /* - * Verify the microcode checksum. - */ - sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) { - sum += AdvReadWordAutoIncLram(iop_base); - } - ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i); - - ASC_DBG2(1, - "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n", - (ulong)sum, (ulong)_adv_asc38C0800_chksum); - - if (sum != _adv_asc38C0800_chksum) { - asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, + _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, + _adv_asc38C0800_chksum); + if (asc_dvc->err_code) return ADV_ERROR; - } /* * Restore the RISC memory BIOS region. @@ -13807,16 +13717,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) } /* - * All kind of combinations of devices attached to one of four connectors - * are acceptable except HVD device attached. For example, LVD device can - * be attached to SE connector while SE device attached to LVD connector. - * If LVD device attached to SE connector, it only runs up to Ultra speed. + * All kind of combinations of devices attached to one of four + * connectors are acceptable except HVD device attached. For example, + * LVD device can be attached to SE connector while SE device attached + * to LVD connector. If LVD device attached to SE connector, it only + * runs up to Ultra speed. * - * If an HVD device is attached to one of LVD connectors, return an error. - * However, there is no way to detect HVD device attached to SE connectors. + * If an HVD device is attached to one of LVD connectors, return an + * error. However, there is no way to detect HVD device attached to + * SE connectors. */ if (scsi_cfg1 & HVD) { - asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; + asc_dvc->err_code = ASC_IERR_HVD_DEVICE; return ADV_ERROR; } @@ -13825,8 +13737,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) * set the termination value based on a table listed in a_condor.h. * * If manual termination was specified with an EEPROM setting then - * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to - * be 'ored' into SCSI_CFG1. + * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready + * to be 'ored' into SCSI_CFG1. */ if ((asc_dvc->cfg->termination & TERM_SE) == 0) { /* SE automatic termination control is enabled. */ @@ -13872,9 +13784,9 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); /* - * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits - * and set possibly modified termination control bits in the Microcode - * SCSI_CFG1 Register Value. + * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE + * bits and set possibly modified termination control bits in the + * Microcode SCSI_CFG1 Register Value. */ scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); @@ -14022,13 +13934,10 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; - ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; long word; - int j; - int adv_asc38C1600_expanded_size; int i; ushort scsi_cfg1; uchar byte; @@ -14113,7 +14022,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { - asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } @@ -14121,7 +14030,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { - asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } @@ -14140,95 +14049,18 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ - asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; + asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - /* - * Load the Microcode - * - * Write the microcode image to RISC memory starting at address 0. - * - */ - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - /* - * Assume the following compressed format of the microcode buffer: - * - * 254 word (508 byte) table indexed by byte code followed - * by the following byte codes: - * - * 1-Byte Code: - * 00: Emit word 0 in table. - * 01: Emit word 1 in table. - * . - * FD: Emit word 253 in table. - * - * Multi-Byte Code: - * FE WW WW: (3 byte code) Word to emit is the next word WW WW. - * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. - */ - word = 0; - for (i = 253 * 2; i < _adv_asc38C1600_size; i++) { - if (_adv_asc38C1600_buf[i] == 0xff) { - for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C1600_buf - [i + - 3] << 8) | - _adv_asc38C1600_buf - [i + 2])); - word++; - } - i += 3; - } else if (_adv_asc38C1600_buf[i] == 0xfe) { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C1600_buf - [i + - 2] << 8) | - _adv_asc38C1600_buf[i - + - 1])); - i += 2; - word++; - } else { - AdvWriteWordAutoIncLram(iop_base, (((ushort) - _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2])); - word++; - } - } - - /* - * Set 'word' for later use to clear the rest of memory and save - * the expanded mcode size. - */ - word *= 2; - adv_asc38C1600_expanded_size = word; - - /* - * Clear the rest of ASC-38C1600 Internal RAM (32KB). - */ - for (; word < ADV_38C1600_MEMSIZE; word += 2) { - AdvWriteWordAutoIncLram(iop_base, 0); - } - - /* - * Verify the microcode checksum. - */ - sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) { - sum += AdvReadWordAutoIncLram(iop_base); - } - - if (sum != _adv_asc38C1600_chksum) { - asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, + _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, + _adv_asc38C1600_chksum); + if (asc_dvc->err_code) return ADV_ERROR; - } /* * Restore the RISC memory BIOS region. -- cgit v1.1 From 629d688d5c3805194b311ad6dcd6f0e90a924ca6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:29 -0600 Subject: [SCSI] advansys: Reformat microcode It's just data, so format it to something that looks more visually appealing (and saves some lines) Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 3163 ++++++++++++++++++----------------------------- 1 file changed, 1186 insertions(+), 1977 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 0f02f3f..5649bf4 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -8111,293 +8111,197 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) /* Microcode buffer is kept after initialization for error recovery. */ static uchar _asc_mcode_buf[] = { 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, - 0x00, 0xFF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, - 0x00, 0x00, 0x00, 0x00, - 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, - 0x03, 0x23, 0x36, 0x40, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04, + 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, - 0xC2, 0x00, 0x92, 0x80, - 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, - 0xB6, 0x00, 0x92, 0x80, - 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, - 0x92, 0x80, 0x80, 0x62, + 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, + 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, + 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, - 0xCD, 0x04, 0x4D, 0x00, - 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, - 0xE6, 0x84, 0xD2, 0xC1, - 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, - 0xC6, 0x81, 0xC2, 0x88, + 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, + 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04, + 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, - 0x84, 0x97, 0x07, 0xA6, - 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, - 0xC2, 0x88, 0xCE, 0x00, - 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, - 0x80, 0x63, 0x07, 0xA6, + 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, + 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, + 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, - 0x34, 0x01, 0x00, 0x33, - 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, - 0x68, 0x98, 0x4D, 0x04, - 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, - 0xF8, 0x88, 0xFB, 0x23, + 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, + 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, + 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23, 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, - 0x00, 0x33, 0x0A, 0x00, - 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, - 0xC2, 0x88, 0xCD, 0x04, - 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, - 0x06, 0xAB, 0x82, 0x01, + 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, + 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, + 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01, 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, - 0x3C, 0x01, 0x00, 0x05, - 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, - 0x15, 0x23, 0xA1, 0x01, - 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, - 0x06, 0x61, 0x00, 0xA0, + 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, + 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23, + 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, - 0xC2, 0x88, 0x06, 0x23, - 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, - 0x57, 0x60, 0x00, 0xA0, - 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, - 0x4B, 0x00, 0x06, 0x61, + 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, + 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84, + 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, - 0x4F, 0x00, 0x84, 0x97, - 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, - 0x48, 0x04, 0x84, 0x80, - 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, - 0x81, 0x73, 0x06, 0x29, + 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, + 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, + 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, - 0x04, 0x98, 0xF0, 0x80, - 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, - 0x34, 0x02, 0x03, 0xA6, - 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, - 0x46, 0x82, 0xFE, 0x95, + 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, + 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82, + 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, - 0x07, 0xA6, 0x5A, 0x02, - 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, - 0x48, 0x82, 0x60, 0x96, - 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, - 0x04, 0x01, 0x0C, 0xDC, + 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, + 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23, + 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, - 0x6F, 0x00, 0xA5, 0x01, - 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, - 0x02, 0xA6, 0xAA, 0x02, - 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, - 0x01, 0xA6, 0xB4, 0x02, + 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, + 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02, + 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02, 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, - 0x80, 0x63, 0x00, 0x43, - 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, - 0x04, 0x61, 0x84, 0x01, - 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, - 0x00, 0x00, 0xEA, 0x82, + 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, + 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, + 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, - 0x00, 0x33, 0x1F, 0x00, - 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, - 0xB6, 0x2D, 0x01, 0xA6, - 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, - 0x10, 0x03, 0x03, 0xA6, + 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, + 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6, + 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6, 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, - 0x7C, 0x95, 0xEE, 0x82, - 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, - 0x04, 0x01, 0x2D, 0xC8, - 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, - 0x05, 0x05, 0x86, 0x98, + 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, + 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01, + 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, - 0x3C, 0x04, 0x06, 0xA6, - 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, - 0x7C, 0x95, 0x32, 0x83, - 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, - 0xEB, 0x04, 0x00, 0x33, + 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, + 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83, + 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33, 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, - 0xFF, 0xA2, 0x7A, 0x03, - 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, - 0x00, 0xA2, 0x9A, 0x03, - 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, - 0x01, 0xA6, 0x96, 0x03, + 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, + 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00, + 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03, 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, - 0xA4, 0x03, 0x00, 0xA6, - 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, - 0x07, 0xA6, 0xB2, 0x03, - 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, - 0xA8, 0x98, 0x80, 0x42, + 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, + 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95, + 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42, 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, - 0xC0, 0x83, 0x00, 0x33, - 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, - 0xA0, 0x01, 0x12, 0x23, - 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, - 0x80, 0x67, 0x05, 0x23, + 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, + 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84, + 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, - 0x06, 0xA6, 0x0A, 0x04, - 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, - 0xF4, 0x83, 0x20, 0x84, - 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, - 0x83, 0x03, 0x80, 0x63, + 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, + 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4, + 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, - 0x38, 0x04, 0x00, 0x33, - 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, - 0x1D, 0x01, 0x06, 0xCC, - 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, - 0xA2, 0x0D, 0x80, 0x63, + 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, + 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84, + 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, - 0x80, 0x63, 0xA3, 0x01, - 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, - 0x76, 0x04, 0xE0, 0x00, - 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, - 0x00, 0x33, 0x1E, 0x00, + 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, + 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, + 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, - 0x08, 0x23, 0x22, 0xA3, - 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, - 0xC4, 0x04, 0x42, 0x23, - 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, - 0xF8, 0x88, 0x04, 0x98, + 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, + 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00, + 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98, 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, - 0x81, 0x62, 0xE8, 0x81, - 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, - 0x00, 0x33, 0x00, 0x81, - 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, - 0xF8, 0x88, 0x04, 0x23, + 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, + 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62, + 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23, 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, - 0xF4, 0x04, 0x00, 0x33, - 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, - 0x04, 0x23, 0xA0, 0x01, - 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, - 0x00, 0xA3, 0x22, 0x05, + 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, + 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95, + 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, - 0x46, 0x97, 0xCD, 0x04, - 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, - 0x82, 0x01, 0x34, 0x85, - 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, - 0x1D, 0x01, 0x04, 0xD6, + 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, + 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01, + 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, - 0x49, 0x00, 0x81, 0x01, - 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, - 0x49, 0x04, 0x80, 0x01, - 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, - 0x01, 0x23, 0xEA, 0x00, + 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, + 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05, + 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, - 0x07, 0xA4, 0xF8, 0x05, - 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, - 0xC2, 0x88, 0x04, 0xA0, - 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, - 0x00, 0xA2, 0xA4, 0x05, + 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, + 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63, + 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, - 0x62, 0x97, 0x04, 0x85, - 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, - 0xF4, 0x85, 0x03, 0xA0, - 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, - 0xCC, 0x86, 0x07, 0xA0, + 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, + 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85, + 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, - 0x80, 0x67, 0x80, 0x63, - 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, - 0xF8, 0x88, 0x07, 0x23, - 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, - 0x00, 0x63, 0x4A, 0x00, + 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, + 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87, + 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, - 0x07, 0x41, 0x83, 0x03, - 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, - 0x1D, 0x01, 0x01, 0xD6, - 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, - 0x07, 0xA6, 0x7C, 0x05, + 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, + 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60, + 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, - 0x52, 0x00, 0x06, 0x61, - 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, - 0x00, 0x63, 0x1D, 0x01, - 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, - 0x07, 0x41, 0x00, 0x63, + 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, + 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33, + 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, - 0xDF, 0x00, 0x06, 0xA6, - 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, - 0x00, 0x40, 0xC0, 0x20, - 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, - 0x06, 0xA6, 0x94, 0x06, + 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, + 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, + 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, - 0x40, 0x0E, 0x80, 0x63, - 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, - 0x80, 0x63, 0x00, 0x43, - 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, - 0x80, 0x67, 0x40, 0x0E, + 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, + 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06, + 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, - 0x07, 0xA6, 0xD6, 0x06, - 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, - 0x0A, 0x2B, 0x07, 0xA6, - 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, - 0xF4, 0x06, 0xC0, 0x0E, + 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, + 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33, + 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, - 0x81, 0x62, 0x04, 0x01, - 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, - 0x8C, 0x06, 0x00, 0x33, - 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, - 0x80, 0x63, 0x06, 0xA6, + 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, + 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88, + 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, - 0x00, 0x00, 0x80, 0x67, - 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, - 0xBF, 0x23, 0x04, 0x61, - 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, - 0x00, 0x01, 0xF2, 0x00, + 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, + 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, + 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, - 0x80, 0x05, 0x81, 0x05, - 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, - 0x70, 0x00, 0x81, 0x01, - 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, - 0x70, 0x00, 0x80, 0x01, + 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, + 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, + 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, - 0xF1, 0x00, 0x70, 0x00, - 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, - 0x71, 0x04, 0x70, 0x00, - 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, - 0xA3, 0x01, 0xA2, 0x01, + 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, + 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, + 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, - 0xC4, 0x07, 0x00, 0x33, - 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, - 0x48, 0x00, 0xB0, 0x01, - 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, - 0x00, 0xA2, 0xE4, 0x07, + 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, + 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, + 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, - 0x05, 0x05, 0x00, 0x63, - 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, - 0x76, 0x08, 0x80, 0x02, - 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, - 0x00, 0x02, 0x00, 0xA0, + 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, + 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, + 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, - 0x00, 0x63, 0xF3, 0x04, - 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, - 0x00, 0xA2, 0x44, 0x08, - 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, - 0x24, 0x08, 0x04, 0x98, + 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, + 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01, + 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, - 0x5A, 0x88, 0x02, 0x01, - 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, - 0x00, 0xA3, 0x64, 0x08, - 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, - 0x06, 0xA6, 0x76, 0x08, + 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, + 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88, + 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, - 0x00, 0x63, 0x38, 0x2B, - 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, - 0x05, 0x05, 0xB2, 0x09, - 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, - 0x80, 0x32, 0x80, 0x36, + 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, + 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, + 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, - 0x40, 0x36, 0x40, 0x3A, - 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, - 0x5D, 0x00, 0xFE, 0xC3, - 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, - 0xFF, 0xFD, 0x80, 0x73, + 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, + 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73, + 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, - 0xA1, 0x23, 0xA1, 0x01, - 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, - 0x80, 0x00, 0x03, 0xC2, - 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, - 0xA0, 0x01, 0xE6, 0x84, + 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, + 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23, + 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, }; static ushort _asc_mcode_size = sizeof(_asc_mcode_buf); @@ -10343,633 +10247,424 @@ AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) /* Microcode buffer is kept after initialization for error recovery. */ static unsigned char _adv_asc3550_buf[] = { 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, - 0x01, 0x00, 0x48, 0xe4, - 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, - 0x28, 0x0e, 0x9e, 0xe7, - 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, - 0x55, 0xf0, 0x01, 0xf6, + 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, + 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, + 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6, 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, - 0x00, 0xec, 0x85, 0xf0, - 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, - 0x86, 0xf0, 0xb4, 0x00, - 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, - 0xaa, 0x18, 0x02, 0x80, + 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, + 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01, + 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80, 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, - 0x00, 0x57, 0x01, 0xea, - 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, - 0x03, 0xe6, 0xb6, 0x00, - 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, - 0x02, 0x4a, 0xb9, 0x54, + 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, + 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01, + 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, - 0x3e, 0x00, 0x80, 0x00, - 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, - 0x74, 0x01, 0x76, 0x01, - 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, - 0x4c, 0x1c, 0xbb, 0x55, + 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, + 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a, + 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55, 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, - 0x03, 0xf7, 0x06, 0xf7, - 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, - 0x30, 0x13, 0x64, 0x15, - 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, - 0x04, 0xea, 0x5d, 0xf0, + 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, + 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c, + 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0, 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, - 0xcc, 0x00, 0x20, 0x01, - 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, - 0x40, 0x13, 0x30, 0x1c, - 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, - 0x59, 0xf0, 0xa7, 0xf0, + 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, + 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56, + 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0, 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, - 0xa4, 0x00, 0xb5, 0x00, - 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, - 0x14, 0x0e, 0x02, 0x10, - 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, - 0x10, 0x15, 0x14, 0x15, + 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, + 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, + 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15, 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, - 0x91, 0x44, 0x0a, 0x45, - 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, - 0x83, 0x59, 0x05, 0xe6, - 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, - 0x02, 0xfa, 0x03, 0xfa, + 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, + 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, + 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, - 0x9e, 0x00, 0xa8, 0x00, - 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, - 0x7a, 0x01, 0xc0, 0x01, - 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, - 0x69, 0x08, 0xba, 0x08, + 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, + 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02, + 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08, 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, - 0xf1, 0x10, 0x06, 0x12, - 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, - 0x8a, 0x15, 0xc6, 0x17, - 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, - 0x0e, 0x47, 0x48, 0x47, + 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, + 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18, + 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47, 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, - 0x14, 0x56, 0x77, 0x57, - 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, - 0xf0, 0x29, 0x02, 0xfe, - 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, - 0xfe, 0x80, 0x01, 0xff, + 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, + 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10, + 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, - 0x00, 0xfe, 0x57, 0x24, - 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, - 0x00, 0x00, 0xff, 0x08, - 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, - 0xff, 0xff, 0xff, 0x0f, + 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, + 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, + 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, - 0xfe, 0x04, 0xf7, 0xcf, - 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, - 0x0b, 0x3c, 0x2a, 0xfe, - 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, - 0xfe, 0xf0, 0x01, 0xfe, + 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, + 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, + 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, - 0x02, 0xfe, 0xd4, 0x0c, - 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, - 0x1c, 0x05, 0xfe, 0xa6, - 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, - 0xf0, 0xfe, 0x86, 0x02, + 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, + 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12, + 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, - 0xfe, 0x46, 0xf0, 0xfe, - 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, - 0x44, 0x02, 0xfe, 0x44, - 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, - 0xa0, 0x17, 0x06, 0x18, + 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, + 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02, + 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18, 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, - 0x1e, 0x1c, 0xfe, 0xe9, - 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, - 0x0a, 0x6b, 0x01, 0x9e, - 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, - 0x01, 0x82, 0xfe, 0xbd, + 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, + 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d, + 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd, 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, - 0x58, 0x1c, 0x17, 0x06, - 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, - 0xfe, 0x94, 0x02, 0xfe, - 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, - 0x01, 0xfe, 0x54, 0x0f, + 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, + 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe, + 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f, 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, - 0x69, 0x10, 0x17, 0x06, - 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, - 0xf6, 0xc7, 0x01, 0xfe, - 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, - 0x02, 0x29, 0x0a, 0x40, + 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, + 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a, + 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, - 0x58, 0x0a, 0x99, 0x01, - 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, - 0x2a, 0x46, 0xfe, 0x02, - 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, - 0x01, 0xfe, 0x07, 0x4b, + 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, + 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe, + 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, - 0xfe, 0x56, 0x03, 0xfe, - 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, - 0xfe, 0x9f, 0xf0, 0xfe, - 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, - 0x1c, 0xeb, 0x09, 0x04, + 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, + 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f, + 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04, 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, - 0x01, 0x0e, 0xac, 0x75, - 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, - 0xfe, 0x82, 0xf0, 0xfe, - 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, - 0x32, 0x1f, 0xfe, 0xb4, + 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, + 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11, + 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4, 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, - 0x0a, 0xf0, 0xfe, 0x7a, - 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, - 0x01, 0x33, 0x8f, 0xfe, - 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, - 0xf7, 0xfe, 0x48, 0x1c, + 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, + 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1, + 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c, 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, - 0x0a, 0xca, 0x01, 0x0e, - 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, - 0x2c, 0x01, 0x33, 0x8f, - 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, - 0xfe, 0x3c, 0x04, 0x1f, + 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, + 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, + 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f, 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, - 0x12, 0x2b, 0xff, 0x02, - 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, - 0x22, 0x30, 0x2e, 0xd5, - 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, - 0xfe, 0x4c, 0x54, 0x64, + 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, + 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe, + 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, - 0xfe, 0x2a, 0x13, 0x2f, - 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, - 0xd3, 0xfa, 0xef, 0x86, - 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, - 0x1d, 0xfe, 0x1c, 0x12, + 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, + 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe, + 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, - 0x70, 0x0c, 0x02, 0x22, - 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, - 0x01, 0x33, 0x02, 0x29, - 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, - 0x80, 0xfe, 0x31, 0xe4, + 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, + 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67, + 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, - 0xfe, 0x70, 0x12, 0x49, - 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, - 0x80, 0x05, 0xfe, 0x31, - 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, - 0x28, 0xfe, 0x42, 0x12, + 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, + 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04, + 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12, 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, - 0x11, 0xfe, 0xe3, 0x00, - 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, - 0x64, 0x05, 0x83, 0x24, - 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, - 0x09, 0x48, 0x01, 0x08, + 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, + 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1, + 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, - 0x86, 0x24, 0x06, 0x12, - 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, - 0x01, 0xa7, 0x14, 0x92, - 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, - 0x02, 0x22, 0x05, 0xfe, + 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, + 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, + 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, - 0x47, 0x01, 0xa7, 0x26, - 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, - 0x01, 0xfe, 0xaa, 0x14, - 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, - 0x05, 0x50, 0xb4, 0x0c, + 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, + 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05, + 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, - 0x13, 0x01, 0xfe, 0x14, - 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, - 0xff, 0x02, 0x00, 0x57, - 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, - 0x72, 0x06, 0x49, 0x04, + 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, + 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, + 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04, 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, - 0x06, 0x11, 0x9a, 0x01, - 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, - 0x01, 0xa7, 0xec, 0x72, - 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, - 0xfe, 0x0a, 0xf0, 0xfe, + 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, + 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87, + 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, - 0x8d, 0x81, 0x02, 0x22, - 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, - 0x01, 0x08, 0x15, 0x00, - 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, - 0x00, 0x02, 0xfe, 0x32, + 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, + 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, + 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32, 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, - 0xfe, 0x1b, 0x00, 0x01, - 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, - 0x08, 0x15, 0x06, 0x01, - 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, - 0x9a, 0x81, 0x4b, 0x1d, + 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, + 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02, + 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d, 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, - 0x45, 0xfe, 0x32, 0x12, - 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, - 0xfe, 0x32, 0x07, 0x8d, - 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, - 0x06, 0x15, 0x19, 0x02, + 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, + 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c, + 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02, 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, - 0x90, 0x77, 0xfe, 0xca, - 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, - 0x10, 0xfe, 0x0e, 0x12, - 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, - 0x83, 0xe7, 0xc4, 0xa1, + 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, + 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80, + 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1, 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, - 0x40, 0x12, 0x58, 0x01, - 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, - 0x51, 0x83, 0xfb, 0xfe, - 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, - 0xfe, 0x40, 0x50, 0xfe, + 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, + 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52, + 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, - 0xfe, 0x2a, 0x12, 0xfe, - 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, - 0x85, 0x01, 0xa8, 0xfe, - 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, - 0x18, 0x57, 0xfb, 0xfe, + 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, + 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58, + 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, - 0x0c, 0x39, 0x18, 0x3a, - 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, - 0x11, 0x65, 0xfe, 0x48, - 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, - 0xdd, 0xb8, 0xfe, 0x80, + 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, + 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0, + 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80, 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, - 0xfe, 0x7a, 0x08, 0x8d, - 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, - 0x10, 0x61, 0x04, 0x06, - 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, - 0x12, 0xfe, 0x2e, 0x1c, + 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, + 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61, + 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, - 0x52, 0x12, 0xfe, 0x2c, - 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, - 0x08, 0xfe, 0x8a, 0x10, - 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, - 0x24, 0x0a, 0xab, 0xfe, + 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, + 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10, + 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, - 0x1c, 0x12, 0xb5, 0xfe, - 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, - 0x1c, 0x06, 0x16, 0x9d, - 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, - 0x14, 0x92, 0x01, 0x33, + 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, + 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d, + 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33, 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, - 0xfe, 0x74, 0x18, 0x1c, - 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, - 0x01, 0xe6, 0x1e, 0x27, - 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, - 0x09, 0x04, 0x6a, 0xfe, + 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, + 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02, + 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe, 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, - 0xfe, 0x83, 0x80, 0xfe, - 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, - 0x27, 0xfe, 0x40, 0x59, - 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, - 0x7c, 0xbe, 0x54, 0xbf, + 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, + 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77, + 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf, 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, - 0x79, 0x56, 0x68, 0x57, - 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, - 0xa2, 0x23, 0x0c, 0x7b, - 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, - 0x16, 0xd7, 0x79, 0x39, + 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, + 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56, + 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39, 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, - 0xfe, 0x10, 0x58, 0xfe, - 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, - 0x19, 0x16, 0xd7, 0x09, - 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, - 0xfe, 0x10, 0x90, 0xfe, + 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, + 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00, + 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, - 0x11, 0x9b, 0x09, 0x04, - 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, - 0xfe, 0x0c, 0x58, 0xfe, - 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, - 0x0b, 0xfe, 0x1a, 0x12, + 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, + 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d, + 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, - 0x14, 0x7a, 0x01, 0x33, - 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, - 0xfe, 0xed, 0x19, 0xbf, - 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, - 0x34, 0xfe, 0x74, 0x10, + 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, + 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, + 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10, 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, - 0x84, 0x05, 0xcb, 0x1c, - 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, - 0xf0, 0xfe, 0xc4, 0x0a, - 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, - 0xce, 0xf0, 0xfe, 0xca, + 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, + 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33, + 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca, 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, - 0x22, 0x00, 0x02, 0x5a, - 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, - 0xfe, 0xd0, 0xf0, 0xfe, - 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, - 0x4c, 0xfe, 0x10, 0x10, + 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, + 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93, + 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, - 0x2a, 0x13, 0xfe, 0x4e, - 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, - 0x16, 0x32, 0x2a, 0x73, - 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, - 0x32, 0x8c, 0xfe, 0x48, + 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, + 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9, + 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48, 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, - 0xdb, 0x10, 0x11, 0xfe, - 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, - 0x22, 0x30, 0x2e, 0xd8, - 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, - 0x45, 0x0f, 0xfe, 0x42, + 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, + 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f, + 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42, 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, - 0x09, 0x04, 0x0b, 0xfe, - 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, - 0x00, 0x21, 0xfe, 0xa6, - 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, - 0xfe, 0xe2, 0x10, 0x01, + 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, + 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01, + 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, - 0x01, 0x6f, 0x02, 0x29, - 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, - 0x01, 0x86, 0x3e, 0x0b, - 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, - 0x3e, 0x0b, 0x0f, 0xfe, + 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, + 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01, + 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, - 0xe8, 0x59, 0x11, 0x2d, - 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, - 0x04, 0x0b, 0x84, 0x3e, - 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, - 0x09, 0x04, 0x1b, 0xfe, + 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, + 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe, + 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, - 0x1c, 0x1c, 0xfe, 0x9d, - 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, - 0xfe, 0x15, 0x00, 0xfe, - 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, - 0x0f, 0xfe, 0x47, 0x00, + 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, + 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f, + 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00, 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, - 0xab, 0x70, 0x05, 0x6b, - 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, - 0x1c, 0x42, 0x59, 0x01, - 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, - 0x00, 0x37, 0x97, 0x01, + 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, + 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea, + 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, - 0x1d, 0xfe, 0xce, 0x45, - 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, - 0x57, 0x05, 0x51, 0xfe, - 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, - 0x46, 0x09, 0x04, 0x1d, + 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, + 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38, + 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d, 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, - 0x99, 0x01, 0x0e, 0xfe, - 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, - 0xfe, 0xee, 0x14, 0xee, - 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, - 0x13, 0x02, 0x29, 0x1e, + 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, + 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce, + 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, - 0xce, 0x1e, 0x2d, 0x47, - 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, - 0x12, 0x4d, 0x01, 0xfe, - 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, - 0xf0, 0x0d, 0xfe, 0x02, + 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, + 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe, + 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02, 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, - 0xf6, 0xfe, 0x34, 0x01, - 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, - 0xaf, 0xfe, 0x02, 0xea, - 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, - 0x05, 0xfe, 0x38, 0x01, + 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, + 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe, + 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01, 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, - 0x0c, 0xfe, 0x62, 0x01, - 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, - 0x03, 0x23, 0x03, 0x1e, - 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, - 0x71, 0x13, 0xfe, 0x24, + 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, + 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12, + 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, - 0xdc, 0xfe, 0x73, 0x57, - 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, - 0x80, 0x5d, 0x03, 0xfe, - 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, - 0x75, 0x03, 0x09, 0x04, + 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, + 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23, + 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04, 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, - 0xfe, 0x1e, 0x80, 0xe1, - 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, - 0x90, 0xa3, 0xfe, 0x3c, - 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, - 0x16, 0x2f, 0x07, 0x2d, + 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, + 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, + 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d, 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, - 0xe8, 0x11, 0xfe, 0xe9, - 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, - 0x1e, 0x1c, 0xfe, 0x14, - 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, - 0x09, 0x04, 0x4f, 0xfe, + 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, + 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, + 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, - 0x40, 0x12, 0x20, 0x63, - 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, - 0x1c, 0x05, 0xfe, 0xac, - 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, - 0xfe, 0xb0, 0x00, 0xfe, + 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, + 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, + 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, - 0x24, 0x69, 0x12, 0xc9, - 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, - 0x90, 0x4d, 0xfe, 0x91, - 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, - 0xfe, 0x90, 0x4d, 0xfe, + 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, + 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08, + 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, - 0x46, 0x1e, 0x20, 0xed, - 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, - 0x70, 0xfe, 0x14, 0x1c, - 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, - 0xfe, 0x07, 0xe6, 0x1d, + 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, + 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, + 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, - 0xfa, 0xef, 0xfe, 0x42, - 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, - 0xfe, 0x36, 0x12, 0xf0, - 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, - 0x3d, 0x75, 0x07, 0x10, + 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, + 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, + 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, - 0x10, 0x07, 0x7e, 0x45, - 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, - 0xfe, 0x01, 0xec, 0x97, - 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, - 0x27, 0x01, 0xda, 0xfe, + 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, + 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe, + 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe, 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, - 0xfe, 0x48, 0x12, 0x07, - 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, - 0xfe, 0x3e, 0x11, 0x07, - 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, - 0x11, 0x07, 0x19, 0xfe, + 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, + 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16, + 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, - 0x01, 0x08, 0x8c, 0x43, - 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, - 0x7e, 0x02, 0x29, 0x2b, - 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, - 0xfc, 0x10, 0x09, 0x04, + 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, + 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe, + 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, - 0xc6, 0x10, 0x1e, 0x58, - 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, - 0x54, 0x18, 0x55, 0x23, - 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, - 0xa5, 0xc0, 0x38, 0xc1, + 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, + 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, + 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1, 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, - 0x05, 0xfa, 0x4e, 0xfe, - 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, - 0x0c, 0x56, 0x18, 0x57, - 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, - 0x00, 0x56, 0xfe, 0xa1, + 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, + 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1, + 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, - 0x58, 0xfe, 0x1f, 0x40, - 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, - 0x31, 0x57, 0xfe, 0x44, - 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, - 0x8a, 0x50, 0x05, 0x39, + 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, + 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, + 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39, 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, - 0x12, 0xcd, 0x02, 0x5b, - 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, - 0x2f, 0x07, 0x9b, 0x21, - 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, - 0x39, 0x68, 0x3a, 0xfe, + 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, + 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c, + 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe, 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, - 0x51, 0xfe, 0x8e, 0x51, - 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, - 0x01, 0x08, 0x25, 0x32, - 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, - 0x3b, 0x02, 0x44, 0x01, + 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, + 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, + 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, - 0x01, 0x08, 0x1f, 0xa2, - 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, - 0x00, 0x28, 0x84, 0x49, - 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, - 0x78, 0x3d, 0xfe, 0xda, + 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, + 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f, + 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda, 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, - 0x05, 0xc6, 0x28, 0x84, - 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, - 0x14, 0xfe, 0x03, 0x17, - 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, - 0xfe, 0xaa, 0x14, 0x02, + 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, + 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c, + 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02, 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, - 0x21, 0x44, 0x01, 0xfe, - 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, - 0xfe, 0x4a, 0xf4, 0x0b, - 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, - 0x85, 0x02, 0x5b, 0x05, + 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, + 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a, + 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, - 0xd8, 0x14, 0x02, 0x5c, - 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, - 0x01, 0x08, 0x23, 0x72, - 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, - 0x12, 0x5e, 0x2b, 0x01, + 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, + 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc, + 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, - 0x1c, 0xfe, 0xff, 0x7f, - 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, - 0x57, 0x48, 0x8b, 0x1c, - 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, - 0x00, 0x57, 0x48, 0x8b, + 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, + 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56, + 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, - 0x03, 0x0a, 0x50, 0x01, - 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, - 0x54, 0xfe, 0x00, 0xf4, - 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, - 0x03, 0x7c, 0x63, 0x27, + 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, + 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00, + 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27, 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, - 0xfe, 0x82, 0x4a, 0xfe, - 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, - 0x42, 0x48, 0x5f, 0x60, - 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, - 0x1f, 0xfe, 0xa2, 0x14, + 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, + 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f, + 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, - 0xcc, 0x12, 0x49, 0x04, - 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, - 0xe8, 0x13, 0x3b, 0x13, - 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, - 0xa1, 0xff, 0x02, 0x83, + 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, + 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78, + 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83, 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, - 0x13, 0x06, 0xfe, 0x56, - 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, - 0x64, 0x00, 0x17, 0x93, - 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, - 0xc8, 0x00, 0x8e, 0xe4, + 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, + 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28, + 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, - 0x01, 0xba, 0xfe, 0x4e, - 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, - 0xfe, 0x60, 0x14, 0xfe, - 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, - 0xfe, 0x22, 0x13, 0x1c, + 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, + 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe, + 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c, 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, - 0xfe, 0x9c, 0x14, 0xb7, - 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, - 0xfe, 0x9c, 0x14, 0xb7, - 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, - 0xfe, 0xb4, 0x56, 0xfe, + 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, + 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23, + 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, - 0xe5, 0x15, 0x0b, 0x01, - 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, - 0x49, 0x01, 0x08, 0x03, - 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, - 0x15, 0x06, 0x01, 0x08, + 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, + 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08, + 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, - 0x4a, 0x01, 0x08, 0x03, - 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, - 0xfe, 0x49, 0xf4, 0x00, - 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, - 0x08, 0x2f, 0x07, 0xfe, + 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, + 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e, + 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, - 0x01, 0x43, 0x1e, 0xcd, - 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, - 0xed, 0x88, 0x07, 0x10, - 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, - 0x80, 0x01, 0x0e, 0x88, + 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, + 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01, + 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, - 0x88, 0x03, 0x0a, 0x42, - 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, - 0xfe, 0x80, 0x80, 0xf2, - 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, - 0x01, 0x82, 0x03, 0x17, + 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, + 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10, + 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17, 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, - 0xfe, 0x24, 0x1c, 0xfe, - 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, - 0x91, 0x1d, 0x66, 0xfe, - 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, - 0xda, 0x10, 0x17, 0x10, + 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, + 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, + 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10, 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, - 0x05, 0xfe, 0x66, 0x01, - 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, - 0xfe, 0x3c, 0x50, 0x66, - 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, - 0x40, 0x16, 0xfe, 0xb6, + 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, + 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe, + 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, - 0x10, 0x71, 0xfe, 0x83, - 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, - 0xfe, 0x62, 0x16, 0xfe, - 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, - 0xfe, 0x98, 0xe7, 0x00, + 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, + 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10, + 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, - 0xfe, 0x30, 0xbc, 0xfe, - 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, - 0xc5, 0x90, 0xfe, 0x9a, - 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, - 0x42, 0x10, 0xfe, 0x02, + 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, + 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14, + 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, - 0xfe, 0x1d, 0xf7, 0x4f, - 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, - 0x47, 0xfe, 0x83, 0x58, - 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, - 0xfe, 0xdd, 0x00, 0x63, + 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, + 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, + 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63, 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, - 0x06, 0x37, 0x95, 0xa9, - 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, - 0x18, 0x1c, 0x1a, 0x5d, - 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, - 0xe1, 0x10, 0x78, 0x2c, + 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, + 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71, + 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c, 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, - 0x13, 0x3c, 0x8a, 0x0a, - 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, - 0xe3, 0xfe, 0x00, 0xcc, - 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, - 0x0e, 0xf2, 0x01, 0x6f, + 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, + 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, + 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f, 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, - 0xf6, 0xfe, 0xd6, 0xf0, - 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, - 0x15, 0x00, 0x59, 0x76, - 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, - 0x11, 0x2d, 0x01, 0x6f, + 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, + 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17, + 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f, 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, - 0xc8, 0xfe, 0x48, 0x55, - 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, - 0x99, 0x01, 0x0e, 0xf0, - 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, - 0x75, 0x03, 0x0a, 0x42, + 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, + 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e, + 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, - 0x0e, 0x73, 0x75, 0x03, - 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, - 0xfe, 0x3a, 0x45, 0x5b, - 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, - 0xfe, 0x02, 0xe6, 0x1b, + 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, + 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2, + 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b, 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, - 0xfe, 0x94, 0x00, 0xfe, - 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, - 0xe6, 0x2c, 0xfe, 0x4e, - 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, - 0x03, 0x07, 0x7a, 0xfe, + 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, + 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12, + 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe, 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, - 0x07, 0x1b, 0xfe, 0x5a, - 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, - 0x24, 0x2c, 0xdc, 0x07, - 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, - 0x9f, 0xad, 0x03, 0x14, + 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, + 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93, + 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14, 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, - 0x03, 0x25, 0xfe, 0xca, - 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, - 0x00, 0x00, + 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, + 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00, }; static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */ @@ -10978,672 +10673,449 @@ static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian ch /* Microcode buffer is kept after initialization for error recovery. */ static unsigned char _adv_asc38C0800_buf[] = { 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, - 0x01, 0x00, 0x48, 0xe4, - 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, - 0x1c, 0x0f, 0x00, 0xf6, - 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, - 0x09, 0xe7, 0x55, 0xf0, + 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, + 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00, + 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, - 0x18, 0xf4, 0x08, 0x00, - 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, - 0x86, 0xf0, 0xb1, 0xf0, - 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, - 0x3c, 0x00, 0xbb, 0x00, + 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, + 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc, + 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00, 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, - 0xba, 0x13, 0x18, 0x40, - 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, - 0x6e, 0x01, 0x74, 0x01, - 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, - 0xc0, 0x00, 0x01, 0x01, + 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, + 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54, + 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, - 0x08, 0x12, 0x02, 0x4a, - 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, - 0x5d, 0xf0, 0x02, 0xfa, - 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, - 0x68, 0x01, 0x6a, 0x01, + 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, + 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00, + 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, - 0x06, 0x13, 0x4c, 0x1c, - 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, - 0x0f, 0x00, 0x47, 0x00, - 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, - 0x4e, 0x1c, 0x10, 0x44, + 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, + 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01, + 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, - 0x05, 0x00, 0x34, 0x00, - 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, - 0x42, 0x0c, 0x12, 0x0f, - 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, - 0x00, 0x4e, 0x42, 0x54, + 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, + 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11, + 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54, 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, - 0x59, 0xf0, 0xb8, 0xf0, - 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, - 0x19, 0x00, 0x33, 0x00, - 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, - 0xe7, 0x00, 0xe2, 0x03, + 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, + 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, + 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03, 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, - 0x12, 0x13, 0x24, 0x14, - 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, - 0x36, 0x1c, 0x08, 0x44, - 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, - 0x3a, 0x55, 0x83, 0x55, + 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, + 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, + 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55, 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, - 0x0c, 0xf0, 0x04, 0xf8, - 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, - 0xa8, 0x00, 0xaa, 0x00, - 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, - 0xc4, 0x01, 0xc6, 0x01, + 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, + 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, + 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01, 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, - 0x68, 0x08, 0x69, 0x08, - 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, - 0xed, 0x10, 0xf1, 0x10, - 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, - 0x1e, 0x13, 0x46, 0x14, + 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, + 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12, + 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14, 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, - 0xca, 0x18, 0xe6, 0x19, - 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, - 0xf0, 0x2b, 0x02, 0xfe, - 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, - 0xfe, 0x84, 0x01, 0xff, + 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, + 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10, + 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, - 0x00, 0xfe, 0x57, 0x24, - 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, - 0x00, 0x00, 0xff, 0x08, - 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, - 0xff, 0xff, 0xff, 0x11, + 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, + 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, + 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, - 0xfe, 0x04, 0xf7, 0xd6, - 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, - 0x0a, 0x42, 0x2c, 0xfe, - 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, - 0xfe, 0xf4, 0x01, 0xfe, + 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, + 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, + 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, - 0x02, 0xfe, 0xc8, 0x0d, - 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, - 0x1c, 0x03, 0xfe, 0xa6, - 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, - 0xf0, 0xfe, 0x8a, 0x02, + 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, + 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12, + 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, - 0xfe, 0x46, 0xf0, 0xfe, - 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, - 0x48, 0x02, 0xfe, 0x44, - 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, - 0xaa, 0x18, 0x06, 0x14, + 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, + 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02, + 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14, 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, - 0x1e, 0x1c, 0xfe, 0xe9, - 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, - 0x09, 0x70, 0x01, 0xa8, - 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, - 0x01, 0x87, 0xfe, 0xbd, + 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, + 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59, + 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, - 0x58, 0x1c, 0x18, 0x06, - 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, - 0xfe, 0x98, 0x02, 0xfe, - 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, - 0x01, 0xfe, 0x48, 0x10, + 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, + 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe, + 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, - 0x69, 0x10, 0x18, 0x06, - 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, - 0xf6, 0xce, 0x01, 0xfe, - 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, - 0x82, 0x16, 0x02, 0x2b, + 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, + 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54, + 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, - 0xfe, 0x41, 0x58, 0x09, - 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, - 0x82, 0x16, 0x02, 0x2b, - 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, - 0xfe, 0x77, 0x57, 0xfe, + 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, + 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02, + 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, - 0xfe, 0x40, 0x1c, 0x1c, - 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, - 0x03, 0xfe, 0x11, 0xf0, - 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, - 0xfe, 0x11, 0x00, 0x02, + 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, + 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10, + 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02, 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, - 0x21, 0x22, 0xa3, 0xb7, - 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, - 0x12, 0xd1, 0x1c, 0xd9, - 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, - 0xfe, 0xe4, 0x00, 0x27, + 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, + 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9, + 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27, 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, - 0x06, 0xf0, 0xfe, 0xc8, - 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, - 0x70, 0x28, 0x17, 0xfe, - 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, - 0xf9, 0x2c, 0x99, 0x19, + 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, + 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d, + 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, - 0x74, 0x01, 0xaf, 0x8c, - 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, - 0x8d, 0x51, 0x64, 0x79, - 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, - 0xfe, 0x6a, 0x02, 0x02, + 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, + 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28, + 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, - 0xfe, 0x3c, 0x04, 0x3b, - 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, - 0x00, 0x10, 0x01, 0x0b, - 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, - 0xfe, 0x4c, 0x44, 0xfe, + 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, + 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04, + 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, - 0xda, 0x4f, 0x79, 0x2a, - 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, - 0xfe, 0x2a, 0x13, 0x32, - 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, - 0x54, 0x6b, 0xda, 0xfe, + 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, + 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52, + 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, - 0x08, 0x13, 0x32, 0x07, - 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, - 0x08, 0x05, 0x06, 0x4d, - 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, - 0x2d, 0x12, 0xfe, 0xe6, + 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, + 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, + 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, - 0x02, 0x2b, 0xfe, 0x42, - 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, - 0xfe, 0x87, 0x80, 0xfe, - 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, - 0x07, 0x19, 0xfe, 0x7c, + 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, + 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08, + 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c, 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, - 0x17, 0xfe, 0x90, 0x05, - 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, - 0xa0, 0x00, 0x28, 0xfe, - 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, - 0x34, 0xfe, 0x89, 0x48, + 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, + 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff, + 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, - 0x12, 0xfe, 0xe3, 0x00, - 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, - 0x70, 0x05, 0x88, 0x25, - 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, - 0x09, 0x48, 0xff, 0x02, + 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, + 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab, + 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, - 0x08, 0x53, 0x05, 0xcb, - 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, - 0x05, 0x1b, 0xfe, 0x22, - 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, - 0x0d, 0x00, 0x01, 0x36, + 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, + 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2, + 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, - 0x03, 0x5c, 0x28, 0xfe, - 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, - 0x05, 0x1f, 0xfe, 0x02, - 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, - 0x01, 0x4b, 0x12, 0xfe, + 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, + 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe, + 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, - 0x12, 0x03, 0x45, 0x28, - 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, - 0x43, 0x48, 0xc4, 0xcc, - 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, - 0x6e, 0x41, 0x01, 0xb2, + 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, + 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02, + 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, - 0xfe, 0xcc, 0x15, 0x1d, - 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, - 0x45, 0xc1, 0x0c, 0x45, - 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, - 0xe2, 0x00, 0x27, 0xdb, + 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, + 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2, + 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb, 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, - 0xfe, 0x06, 0xf0, 0xfe, - 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, - 0x16, 0x19, 0x01, 0x0b, - 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, - 0xfe, 0x99, 0xa4, 0x01, + 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, + 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, + 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, - 0x12, 0x08, 0x05, 0x1a, - 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, - 0x0b, 0x16, 0x00, 0x01, - 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, - 0xe2, 0x6c, 0x58, 0xbe, + 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, + 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, + 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe, 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, - 0xfe, 0x09, 0x6f, 0xba, - 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, - 0xfe, 0x54, 0x07, 0x1c, - 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, - 0x07, 0x02, 0x24, 0x01, + 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, + 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0, + 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01, 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, - 0x2c, 0x90, 0xfe, 0xae, - 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, - 0x37, 0x22, 0x20, 0x07, - 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, - 0xfe, 0x06, 0x10, 0xfe, + 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, + 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12, + 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, - 0x37, 0x01, 0xb3, 0xb8, - 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, - 0x50, 0xfe, 0x44, 0x51, - 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, - 0x14, 0x5f, 0xfe, 0x0c, + 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, + 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88, + 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, - 0x14, 0x3e, 0xfe, 0x4a, - 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, - 0x90, 0x0c, 0x60, 0x14, - 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, - 0xfe, 0x44, 0x90, 0xfe, + 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, + 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b, + 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, - 0x0c, 0x5e, 0x14, 0x5f, - 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, - 0x14, 0x3c, 0x21, 0x0c, - 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, - 0x27, 0xdd, 0xfe, 0x9e, + 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, + 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08, + 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e, 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, - 0x9a, 0x08, 0xc6, 0xfe, - 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, - 0x95, 0x86, 0x02, 0x24, - 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, - 0x06, 0xfe, 0x10, 0x12, + 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, + 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9, + 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12, 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, - 0x1c, 0x02, 0xfe, 0x18, - 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, - 0x2c, 0x1c, 0xfe, 0xaa, - 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, - 0xde, 0x09, 0xfe, 0xb7, + 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, + 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09, + 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, - 0xfe, 0xf1, 0x18, 0xfe, - 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, - 0x14, 0x59, 0xfe, 0x95, - 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, - 0xfe, 0xf0, 0x08, 0xb5, + 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, + 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe, + 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5, 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, - 0x0b, 0xb6, 0xfe, 0xbf, - 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, - 0x12, 0xc2, 0xfe, 0xd2, - 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, - 0x06, 0x17, 0x85, 0xc5, + 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, + 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76, + 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5, 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, - 0x9d, 0x01, 0x36, 0x10, - 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, - 0x98, 0x80, 0xfe, 0x19, - 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, - 0xfe, 0x44, 0x54, 0xbe, + 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, + 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a, + 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe, 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, - 0x02, 0x4a, 0x08, 0x05, - 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, - 0x9c, 0x3c, 0xfe, 0x6c, - 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, - 0x3b, 0x40, 0x03, 0x49, + 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, + 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18, + 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49, 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, - 0x8f, 0xfe, 0xe3, 0x54, - 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, - 0xda, 0x09, 0xfe, 0x8b, - 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, - 0x0a, 0x3a, 0x49, 0x3b, + 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, + 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09, + 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b, 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, - 0xad, 0xfe, 0x01, 0x59, - 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, - 0x49, 0x8f, 0xfe, 0xe3, - 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, - 0x4a, 0x3a, 0x49, 0x3b, + 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, + 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d, + 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b, 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, - 0x02, 0x4a, 0x08, 0x05, - 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, - 0xb7, 0xfe, 0x03, 0xa1, - 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, - 0xfe, 0x86, 0x91, 0x6a, + 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, + 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe, + 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a, 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, - 0x61, 0x0c, 0x7f, 0x14, - 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, - 0x9b, 0x2e, 0x9c, 0x3c, - 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, - 0xfa, 0x3c, 0x01, 0xef, + 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, + 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40, + 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef, 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, - 0xe4, 0x08, 0x05, 0x1f, - 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, - 0x03, 0x5e, 0x29, 0x5f, - 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, - 0xf4, 0x09, 0x08, 0x05, + 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, + 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe, + 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, - 0x81, 0x50, 0xfe, 0x10, - 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, - 0x08, 0x09, 0x12, 0xa6, - 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, - 0x08, 0x09, 0xfe, 0x0c, + 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, + 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe, + 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, - 0x08, 0x05, 0x0a, 0xfe, - 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, - 0xf0, 0xe2, 0x15, 0x7e, - 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, - 0x57, 0x3d, 0xfe, 0xed, + 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, + 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, + 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed, 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, - 0x00, 0xff, 0x35, 0xfe, - 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, - 0x1e, 0x19, 0x8a, 0x03, - 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, - 0xfe, 0xd1, 0xf0, 0xfe, + 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, + 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe, + 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe, 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, - 0x10, 0xfe, 0xce, 0xf0, - 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, - 0x10, 0xfe, 0x22, 0x00, - 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, - 0x02, 0x65, 0xfe, 0xd0, + 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, + 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb, + 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0, 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, - 0x0b, 0x10, 0x58, 0xfe, - 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, - 0x12, 0x00, 0x2c, 0x0f, - 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, - 0x0c, 0xbc, 0x17, 0x34, + 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, + 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, + 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, - 0x0c, 0x1c, 0x34, 0x94, - 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, - 0x4b, 0xfe, 0xdb, 0x10, - 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, - 0x89, 0xf0, 0x24, 0x33, + 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, + 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00, + 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33, 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, - 0x33, 0x31, 0xdf, 0xbc, - 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, - 0x17, 0xfe, 0x2c, 0x0d, - 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, - 0x12, 0x55, 0xfe, 0x28, + 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, + 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe, + 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28, 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, - 0x44, 0xfe, 0x28, 0x00, - 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, - 0x0f, 0x64, 0x12, 0x2f, - 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, - 0x0a, 0xfe, 0xb4, 0x10, + 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, + 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b, + 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10, 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, - 0xfe, 0x34, 0x46, 0xac, - 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, - 0x37, 0x01, 0xf5, 0x01, - 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, - 0xfe, 0x2e, 0x03, 0x08, + 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, + 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f, + 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08, 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, - 0x1a, 0xfe, 0x58, 0x12, - 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, - 0xfe, 0x50, 0x0d, 0xfe, - 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, - 0xfe, 0xa9, 0x10, 0x10, + 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, + 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, + 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, - 0xfe, 0x13, 0x00, 0xfe, - 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, - 0x24, 0x00, 0x8c, 0xb5, - 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, - 0xfe, 0x9d, 0x41, 0xfe, + 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, + 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70, + 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, - 0xb4, 0x15, 0xfe, 0x31, - 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, - 0xec, 0xd0, 0xfc, 0x44, - 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, - 0x4b, 0x91, 0xfe, 0x75, + 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, + 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, + 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75, 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, - 0x0e, 0xfe, 0x44, 0x48, - 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, - 0xfe, 0x41, 0x58, 0x09, - 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, - 0x2e, 0x03, 0x09, 0x5d, + 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, + 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, + 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d, 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, - 0xce, 0x47, 0xfe, 0xad, - 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, - 0x59, 0x13, 0x9f, 0x13, - 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, - 0xe0, 0x0e, 0x0f, 0x06, + 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, + 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41, + 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06, 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, - 0x3a, 0x01, 0x56, 0xfe, - 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, - 0x20, 0x4f, 0xfe, 0x05, - 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, - 0x48, 0xf4, 0x0d, 0xfe, + 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, + 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, + 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, - 0x15, 0x1a, 0x39, 0xa0, - 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, - 0x0c, 0xfe, 0x60, 0x01, - 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, - 0x06, 0x13, 0x2f, 0x12, + 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, + 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01, + 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12, 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, - 0x22, 0x9f, 0xb7, 0x13, - 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, - 0xa0, 0xb4, 0xfe, 0xd9, - 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, - 0xc3, 0xfe, 0x03, 0xdc, + 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, + 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03, + 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, - 0xfe, 0x00, 0xcc, 0x04, - 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, - 0xfe, 0x1c, 0x80, 0x07, - 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, - 0xfe, 0x0c, 0x90, 0xfe, + 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, + 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, + 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, - 0x0a, 0xfe, 0x3c, 0x50, - 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, - 0x16, 0x08, 0x05, 0x1b, - 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, - 0xfe, 0x2c, 0x13, 0x01, + 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, + 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01, + 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, - 0x0c, 0xfe, 0x64, 0x01, - 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, - 0x80, 0x8d, 0xfe, 0x01, - 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, - 0x22, 0x20, 0xfb, 0x79, + 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, + 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, + 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, - 0x03, 0xfe, 0xae, 0x00, - - 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, - 0xb2, 0x00, 0xfe, 0x09, - 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, - 0x45, 0x0f, 0x46, 0x52, + 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, + 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, + 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52, 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, - 0x0f, 0x44, 0x11, 0x0f, - 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, - 0x25, 0x11, 0x13, 0x20, - 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, - 0x56, 0xfe, 0xd6, 0xf0, + 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, + 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22, + 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, - 0x18, 0x1c, 0x04, 0x42, - 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, - 0xf5, 0x13, 0x04, 0x01, - 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, - 0x13, 0x32, 0x07, 0x2f, + 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, + 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f, + 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f, 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, - 0x41, 0x48, 0xfe, 0x45, - 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, - 0x07, 0x11, 0xac, 0x09, - 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, - 0x82, 0x4e, 0xfe, 0x14, + 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, + 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, + 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, - 0xfe, 0x01, 0xec, 0xa2, - 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, - 0x2a, 0x01, 0xe3, 0xfe, - 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, - 0xfe, 0x48, 0x12, 0x07, + 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, + 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7, + 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07, 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, - 0xfe, 0x32, 0x12, 0x07, - 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, - 0x1f, 0xfe, 0x12, 0x12, - 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, - 0x94, 0x4b, 0x04, 0x2d, + 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, + 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24, + 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d, 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, - 0x32, 0x07, 0xa6, 0xfe, - 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, - 0x5a, 0xfe, 0x72, 0x12, - 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, - 0xfe, 0x26, 0x13, 0x03, + 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, + 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c, + 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03, 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, - 0x0c, 0x7f, 0x0c, 0x80, - 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, - 0x3c, 0xfe, 0x04, 0x55, - 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, - 0x91, 0x10, 0x03, 0x3f, + 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, + 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, + 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, - 0x88, 0x9b, 0x2e, 0x9c, - 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, - 0x56, 0x0c, 0x5e, 0x14, - 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, - 0x03, 0x60, 0x29, 0x61, + 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, + 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a, + 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, - 0x50, 0xfe, 0xc6, 0x50, - 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, - 0x29, 0x3e, 0xfe, 0x40, - 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, - 0x2d, 0x01, 0x0b, 0x1d, + 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, + 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, + 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d, 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, - 0x72, 0x01, 0xaf, 0x1e, - 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, - 0x0a, 0x55, 0x35, 0xfe, - 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, - 0x02, 0x72, 0xfe, 0x19, + 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, + 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d, + 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19, 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, - 0x1d, 0xe8, 0x33, 0x31, - 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, - 0x0b, 0x1c, 0x34, 0x1d, - 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, - 0x33, 0x31, 0xfe, 0xe8, + 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, + 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf, + 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, - 0x05, 0x1f, 0x35, 0xa9, - 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, - 0x14, 0x01, 0xaf, 0x8c, - 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, - 0x03, 0x45, 0x28, 0x35, + 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, + 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee, + 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35, 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, - 0x03, 0x5c, 0xc1, 0x0c, - 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, - 0x89, 0x01, 0x0b, 0x1c, - 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, - 0xfe, 0x42, 0x58, 0xf1, + 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, + 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33, + 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1, 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, - 0xf4, 0x06, 0xea, 0x32, - 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, - 0x01, 0x0b, 0x26, 0x89, - 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, - 0x26, 0xfe, 0xd4, 0x13, + 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, + 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15, + 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13, 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, - 0x13, 0x1c, 0xfe, 0xd0, - 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, - 0x0f, 0x71, 0xff, 0x02, - 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, - 0x00, 0x5c, 0x04, 0x0f, + 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, + 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, + 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, - 0xfe, 0x00, 0x5c, 0x04, - 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, - 0x02, 0x00, 0x57, 0x52, - 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, - 0x87, 0x04, 0xfe, 0x03, + 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, + 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58, + 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03, 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, - 0xfe, 0x00, 0x7d, 0xfe, - 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, - 0x14, 0x5f, 0x57, 0x3f, - 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, - 0x5a, 0x8d, 0x04, 0x01, + 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, + 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd, + 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01, 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, - 0xfe, 0x96, 0x15, 0x33, - 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, - 0x0a, 0xfe, 0xc1, 0x59, - 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, - 0x21, 0x69, 0x1a, 0xee, + 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, + 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe, + 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee, 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, - 0x30, 0xfe, 0x78, 0x10, - 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, - 0x98, 0xfe, 0x30, 0x00, - 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, - 0x98, 0xfe, 0x64, 0x00, + 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, + 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d, + 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, - 0x10, 0x69, 0x06, 0xfe, - 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, - 0x18, 0x59, 0x0f, 0x06, - 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, - 0x43, 0xf4, 0x9f, 0xfe, + 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, + 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90, + 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe, 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, - 0x9e, 0xfe, 0xf3, 0x10, - 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, - 0x17, 0xfe, 0x4d, 0xe4, - 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, - 0x17, 0xfe, 0x4d, 0xe4, + 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, + 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90, + 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, - 0xf4, 0x00, 0xe9, 0x91, - 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, - 0x04, 0x16, 0x06, 0x01, - 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, - 0x0b, 0x26, 0xf3, 0x76, + 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, + 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16, + 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, - 0x16, 0x19, 0x01, 0x0b, - 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, - 0x0b, 0x26, 0xb1, 0x76, - 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, - 0xfe, 0x48, 0x13, 0xb8, + 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, + 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01, + 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8, 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, - 0xec, 0xfe, 0x27, 0x01, - 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, - 0x07, 0xfe, 0xe3, 0x00, - 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, - 0x22, 0xd4, 0x07, 0x06, + 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, + 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d, + 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06, 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, - 0x07, 0x11, 0xae, 0x09, - 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, - 0x0e, 0x8e, 0xfe, 0x80, - 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, - 0x09, 0x48, 0x01, 0x0e, + 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, + 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11, + 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, - 0x80, 0xfe, 0x80, 0x4c, - 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, - 0x09, 0x5d, 0x01, 0x87, - 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, - 0x19, 0xde, 0xfe, 0x24, + 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, + 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75, + 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, - 0x17, 0xad, 0x9a, 0x1b, - 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, - 0x16, 0xfe, 0xda, 0x10, - 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, - 0x18, 0x58, 0x03, 0xfe, + 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, + 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03, + 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, - 0xf4, 0x06, 0xfe, 0x3c, - 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, - 0x97, 0xfe, 0x38, 0x17, - 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, - 0x10, 0x18, 0x11, 0x75, + 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, + 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35, + 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, - 0x2e, 0x97, 0xfe, 0x5a, - 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, - 0xfe, 0x98, 0xe7, 0x00, - 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, - 0xfe, 0x30, 0xbc, 0xfe, + 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, + 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe, + 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, - 0xcb, 0x97, 0xfe, 0x92, - 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, - 0x42, 0x10, 0xfe, 0x02, - 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, - 0x03, 0xa1, 0xfe, 0x1d, + 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, + 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe, + 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d, 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, - 0x9a, 0x5b, 0x41, 0xfe, - 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, - 0x11, 0x12, 0xfe, 0xdd, - 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, - 0x17, 0x15, 0x06, 0x39, + 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, + 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04, + 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39, 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, - 0xfe, 0x7e, 0x18, 0x1e, - 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, - 0x12, 0xfe, 0xe1, 0x10, - 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, - 0x13, 0x42, 0x92, 0x09, + 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, + 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32, + 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, - 0xf0, 0xfe, 0x00, 0xcc, - 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, - 0x0e, 0xfe, 0x80, 0x4c, - 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, - 0x24, 0x12, 0xfe, 0x14, + 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, + 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16, + 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, - 0xe7, 0x0a, 0x10, 0xfe, - 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, - 0x08, 0x54, 0x1b, 0x37, - 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, - 0x90, 0x3a, 0xce, 0x3b, + 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, + 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73, + 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b, 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, - 0x13, 0xa3, 0x04, 0x09, - 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, - 0x44, 0x17, 0xfe, 0xe8, - 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, - 0x5d, 0x01, 0xa8, 0x09, + 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, + 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04, + 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09, 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, - 0x1c, 0x19, 0x03, 0xfe, - 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, - 0x6b, 0xfe, 0x2e, 0x19, - 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, - 0xfe, 0x0b, 0x00, 0x6b, + 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, + 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00, + 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b, 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, - 0x08, 0x10, 0x03, 0xfe, - 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, - 0x04, 0x68, 0x54, 0xe7, - 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, - 0x1a, 0xf4, 0xfe, 0x00, + 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, + 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08, + 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, - 0x04, 0x07, 0x7e, 0xfe, - 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, - 0x07, 0x1a, 0xfe, 0x5a, - 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, - 0x25, 0x6d, 0xe5, 0x07, + 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, + 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19, + 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07, 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, - 0xa9, 0xb8, 0x04, 0x15, - 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, - 0x40, 0x5c, 0x04, 0x1c, - 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, - 0xf7, 0xfe, 0x82, 0xf0, + 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, + 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0, + 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0, 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00, }; @@ -11653,796 +11125,533 @@ static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian /* Microcode buffer is kept after initialization for error recovery. */ static unsigned char _adv_asc38C1600_buf[] = { 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, - 0x18, 0xe4, 0x01, 0x00, - 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, - 0x07, 0x17, 0xc0, 0x5f, - 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, - 0x85, 0xf0, 0x86, 0xf0, + 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, + 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff, + 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0, 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, - 0x98, 0x57, 0x01, 0xe6, - 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, - 0x38, 0x54, 0x32, 0xf0, - 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, - 0x00, 0xe6, 0xb1, 0xf0, + 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, + 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e, + 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0, 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, - 0x06, 0x13, 0x0c, 0x1c, - 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, - 0xb9, 0x54, 0x00, 0x80, - 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, - 0x03, 0xe6, 0x01, 0xea, + 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, + 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12, + 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea, 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, - 0x04, 0x13, 0xbb, 0x55, - 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, - 0xbb, 0x00, 0xc0, 0x00, - 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, - 0x4c, 0x1c, 0x4e, 0x1c, + 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, + 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c, 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, - 0x24, 0x01, 0x3c, 0x01, - 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, - 0x78, 0x01, 0x7c, 0x01, - 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, - 0x6e, 0x1e, 0x02, 0x48, + 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, + 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10, + 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48, 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, - 0x03, 0xfc, 0x06, 0x00, - 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, - 0x30, 0x1c, 0x38, 0x1c, - 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, - 0x5d, 0xf0, 0xa7, 0xf0, + 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, + 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c, + 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, - 0x33, 0x00, 0x34, 0x00, - 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, - 0x79, 0x01, 0x3c, 0x09, - 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, - 0x40, 0x16, 0x50, 0x16, + 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, + 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10, + 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16, 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, - 0x05, 0xf0, 0x09, 0xf0, - 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, - 0x9c, 0x00, 0xa4, 0x00, - 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, - 0xe9, 0x09, 0x5c, 0x0c, + 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, + 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, + 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c, 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, - 0x42, 0x1d, 0x08, 0x44, - 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, - 0x83, 0x55, 0x83, 0x59, - 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, - 0x4b, 0xf4, 0x04, 0xf8, + 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, + 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6, + 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, - 0xa8, 0x00, 0xaa, 0x00, - 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, - 0x7a, 0x01, 0x82, 0x01, - 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, - 0x68, 0x08, 0x10, 0x0d, + 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, + 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01, + 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d, 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, - 0xf3, 0x10, 0x06, 0x12, - 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, - 0xf0, 0x35, 0x05, 0xfe, - 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, - 0xfe, 0x88, 0x01, 0xff, + 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, + 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10, + 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, - 0x00, 0xfe, 0x57, 0x24, - 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, - 0x00, 0x00, 0xff, 0x08, - 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, - 0xff, 0xff, 0xff, 0x13, + 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, + 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, + 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, - 0xfe, 0x04, 0xf7, 0xe8, - 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, - 0x0d, 0x51, 0x37, 0xfe, - 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, - 0xfe, 0xf8, 0x01, 0xfe, + 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, + 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, + 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, - 0x05, 0xfe, 0x08, 0x0f, - 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, - 0x28, 0x1c, 0x03, 0xfe, - 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, - 0x48, 0xf0, 0xfe, 0x90, + 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, + 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1, + 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90, 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, - 0x02, 0xfe, 0x46, 0xf0, - 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, - 0xfe, 0x4e, 0x02, 0xfe, - 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, - 0x0d, 0xa2, 0x1c, 0x07, + 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, + 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52, + 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, - 0x1c, 0xf5, 0xfe, 0x1e, - 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, - 0xde, 0x0a, 0x81, 0x01, - 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, - 0x81, 0x01, 0x5c, 0xfe, + 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, + 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f, + 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, - 0xfe, 0x58, 0x1c, 0x1c, - 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, - 0x2b, 0xfe, 0x9e, 0x02, - 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, - 0x00, 0x47, 0xb8, 0x01, + 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, + 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe, + 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, - 0x1a, 0x31, 0xfe, 0x69, - 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, - 0x1e, 0x1e, 0x20, 0x2c, - 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, - 0x44, 0x15, 0x56, 0x51, + 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, + 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde, + 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, - 0x01, 0x18, 0x09, 0x00, - 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, - 0x18, 0xfe, 0xc8, 0x54, - 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, - 0xfe, 0x02, 0xe8, 0x30, + 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, + 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03, + 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, - 0xfe, 0xe4, 0x01, 0xfe, - 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, - 0x26, 0xf0, 0xfe, 0x66, - 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, - 0xef, 0x10, 0xfe, 0x9f, + 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, + 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0, + 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, - 0x70, 0x37, 0xfe, 0x48, - 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, - 0x21, 0xb9, 0xc7, 0x20, - 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, - 0xe1, 0x2a, 0xeb, 0xfe, + 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, + 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01, + 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe, 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, - 0x15, 0xfe, 0xe4, 0x00, - 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, - 0xfe, 0x06, 0xf0, 0xfe, - 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, - 0x03, 0x81, 0x1e, 0x1b, + 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, + 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0, + 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b, 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, - 0xea, 0xfe, 0x46, 0x1c, - 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, - 0xfe, 0x48, 0x1c, 0x75, - 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, - 0xe1, 0x01, 0x18, 0x77, + 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, + 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a, + 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77, 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, - 0x8f, 0xfe, 0x70, 0x02, - 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, - 0x16, 0xfe, 0x4a, 0x04, - 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, - 0x02, 0x00, 0x10, 0x01, + 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, + 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00, + 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, - 0xee, 0xfe, 0x4c, 0x44, - 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, - 0x7b, 0xec, 0x60, 0x8d, - 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, - 0x0c, 0x06, 0x28, 0xfe, + 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, + 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e, + 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, - 0x13, 0x34, 0xfe, 0x4c, - 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, - 0x13, 0x01, 0x0c, 0x06, - 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, - 0x28, 0xf9, 0x1f, 0x7f, + 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, + 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43, + 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, - 0xfe, 0xa4, 0x0e, 0x05, - 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, - 0x9c, 0x93, 0x3a, 0x0b, - 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, - 0x7d, 0x1d, 0xfe, 0x46, + 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, + 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f, + 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, - 0xfe, 0x87, 0x83, 0xfe, - 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, - 0x13, 0x0f, 0xfe, 0x20, - 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, - 0x12, 0x01, 0x38, 0x06, + 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, + 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0, + 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06, 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, - 0x05, 0xd0, 0x54, 0x01, - 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, - 0x50, 0x12, 0x5e, 0xff, - 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, - 0x00, 0x10, 0x2f, 0xfe, + 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, + 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f, + 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, - 0x38, 0xfe, 0x4a, 0xf0, - 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, - 0x21, 0x00, 0xf1, 0x2e, - 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, - 0x10, 0x2f, 0xfe, 0xd0, + 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, + 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2, + 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, - 0x1c, 0x00, 0x4d, 0x01, - 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, - 0x28, 0xfe, 0x24, 0x12, - 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, - 0x0d, 0x00, 0x01, 0x42, + 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, + 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f, + 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, - 0x03, 0xb6, 0x1e, 0xfe, - 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, - 0xfe, 0x72, 0x06, 0x0a, - 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, - 0x19, 0x16, 0xfe, 0x68, + 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, + 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06, + 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, - 0x03, 0x9a, 0x1e, 0xfe, - 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, - 0x48, 0xfe, 0x92, 0x06, - 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, - 0x58, 0xff, 0x02, 0x00, + 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, + 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe, + 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, - 0xfe, 0xea, 0x06, 0x01, - 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, - 0xfe, 0xe0, 0x06, 0x15, - 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, - 0x01, 0x84, 0xfe, 0xae, + 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, + 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, + 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae, 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, - 0x1e, 0xfe, 0x1a, 0x12, - 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, - 0x43, 0x48, 0x62, 0x80, - 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, - 0x36, 0xfe, 0x02, 0xf6, + 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, + 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95, + 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6, 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, - 0xd0, 0x0d, 0x17, 0xfe, - 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, - 0x9e, 0x15, 0x82, 0x01, - 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, - 0x57, 0x10, 0xe6, 0x05, + 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, + 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21, + 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05, 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, - 0xfe, 0x9c, 0x32, 0x5f, - 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, - 0xfe, 0x0a, 0xf0, 0xfe, - 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, - 0xaf, 0xa0, 0x05, 0x29, + 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, + 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe, + 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, - 0x00, 0x01, 0x08, 0x14, - 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, - 0x14, 0x00, 0x05, 0xfe, - 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, - 0x12, 0xfe, 0x30, 0x13, + 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, + 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76, + 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13, 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, - 0x01, 0x08, 0x14, 0x00, - 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, - 0x78, 0x4f, 0x0f, 0xfe, - 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, - 0x28, 0x48, 0xfe, 0x6c, + 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, + 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe, + 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c, 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, - 0x12, 0x53, 0x63, 0x4e, - 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, - 0x6c, 0x08, 0xaf, 0xa0, - 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, - 0x05, 0xed, 0xfe, 0x9c, + 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, + 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08, + 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c, 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, - 0x1e, 0xfe, 0x99, 0x58, - 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, - 0x22, 0x6b, 0x01, 0x0c, - 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, - 0x1e, 0x47, 0x2c, 0x7a, + 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, + 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21, + 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a, 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, - 0x01, 0x0c, 0x61, 0x65, - 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, - 0x16, 0xfe, 0x08, 0x50, - 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, - 0x01, 0xfe, 0xce, 0x1e, + 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, + 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, + 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e, 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, - 0x01, 0xfe, 0xfe, 0x1e, - 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, - 0x10, 0x01, 0x0c, 0x06, - 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, - 0x10, 0x6a, 0x22, 0x6b, + 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, + 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12, + 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, - 0xfe, 0x9f, 0x83, 0x33, - 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, - 0x3a, 0x0b, 0xfe, 0xc6, - 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, - 0x01, 0xfe, 0xce, 0x1e, + 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, + 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6, + 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e, 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, - 0x04, 0xfe, 0xc0, 0x93, - 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, - 0x10, 0x4b, 0x22, 0x4c, - 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, - 0x4e, 0x11, 0x2f, 0xfe, + 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, + 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34, + 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, - 0x3c, 0x37, 0x88, 0xf5, - 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, - 0xd3, 0xfe, 0x42, 0x0a, - 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, - 0x05, 0x29, 0x01, 0x41, + 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, + 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a, + 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41, 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, - 0xfe, 0x14, 0x12, 0x01, - 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, - 0x2e, 0x1c, 0x05, 0xfe, - 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, - 0xfe, 0x2c, 0x1c, 0xfe, + 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, + 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76, + 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, - 0x92, 0x10, 0xc4, 0xf6, - 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, - 0xe7, 0x10, 0xfe, 0x2b, - 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, - 0xac, 0xfe, 0xd2, 0xf0, + 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, + 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b, + 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0, 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, - 0x1b, 0xbf, 0xd4, 0x5b, - 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, - 0x5e, 0x32, 0x1f, 0x7f, - 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, - 0x05, 0x70, 0xfe, 0x74, + 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, + 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe, + 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74, 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, - 0x0f, 0x4d, 0x01, 0xfe, - 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, - 0x0d, 0x2b, 0xfe, 0xe2, - 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, - 0xfe, 0x88, 0x13, 0x21, + 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, + 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06, + 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21, 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, - 0x83, 0x83, 0xfe, 0xc9, - 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, - 0x91, 0x04, 0xfe, 0x84, - 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, - 0xfe, 0xcb, 0x57, 0x0b, + 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, + 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57, + 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b, 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, - 0x6a, 0x3b, 0x6b, 0x10, - 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, - 0x20, 0x6e, 0xdb, 0x64, - 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, - 0xfe, 0x04, 0xfa, 0x64, + 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, + 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c, + 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, - 0x10, 0x98, 0x91, 0x6c, - 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, - 0x4b, 0x7e, 0x4c, 0x01, - 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, - 0x58, 0xfe, 0x91, 0x58, + 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, + 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7, + 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, - 0x1b, 0x40, 0x01, 0x0c, - 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, - 0xfe, 0x10, 0x90, 0x04, - 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, - 0x79, 0x0b, 0x0e, 0xfe, + 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, + 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a, + 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe, 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, - 0x01, 0x0c, 0x06, 0x0d, - 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, - 0x0c, 0x58, 0xfe, 0x8d, - 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, - 0x83, 0x33, 0x0b, 0x0e, + 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, + 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26, + 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, - 0x19, 0xfe, 0x19, 0x41, - 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, - 0x19, 0xfe, 0x44, 0x00, - 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, - 0x4c, 0xfe, 0x0c, 0x51, + 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, + 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe, + 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, - 0x76, 0x10, 0xac, 0xfe, - 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, - 0xe3, 0x23, 0x07, 0xfe, - 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, - 0xcc, 0x0c, 0x1f, 0x92, + 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, + 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe, + 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, - 0x0c, 0xfe, 0x3e, 0x10, - 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, - 0xfe, 0xcb, 0xf0, 0xfe, - 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, - 0xf4, 0x0c, 0x19, 0x94, + 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, + 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe, + 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94, 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, - 0xfe, 0xcc, 0xf0, 0xef, - 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, - 0x4e, 0x11, 0x2f, 0xfe, - 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, - 0x3c, 0x37, 0x88, 0xf5, + 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, + 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e, + 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, - 0x2f, 0xfe, 0x3e, 0x0d, - 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, - 0xd2, 0x9f, 0xd3, 0x9f, - 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, - 0xc5, 0x75, 0xd7, 0x99, + 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, + 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41, + 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99, 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, - 0x9c, 0x2f, 0xfe, 0x8c, - 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, - 0x42, 0x00, 0x05, 0x70, - 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, - 0x0d, 0xfe, 0x44, 0x13, + 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, + 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81, + 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13, 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, - 0xfe, 0xda, 0x0e, 0x0a, - 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, - 0x10, 0x01, 0xfe, 0xf4, - 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, - 0x15, 0x56, 0x01, 0x85, + 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, + 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, + 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85, 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, - 0xcc, 0x10, 0x01, 0xa7, - 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, - 0xfe, 0x99, 0x83, 0xfe, - 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, - 0x43, 0x00, 0xfe, 0xa2, + 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, + 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e, + 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2, 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, - 0x00, 0x1d, 0x40, 0x15, - 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, - 0xfe, 0x3a, 0x03, 0x01, - 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, - 0x76, 0x06, 0x12, 0xfe, + 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, + 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d, + 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, - 0xfe, 0x9d, 0xf0, 0xfe, - 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, - 0x0c, 0x61, 0x12, 0x44, - 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, - 0xfe, 0x2e, 0x10, 0x19, + 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, + 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19, + 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, - 0xfe, 0x41, 0x00, 0xa2, - 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, - 0xea, 0x4f, 0xfe, 0x04, - 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, - 0x35, 0xfe, 0x12, 0x1c, + 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, + 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d, + 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c, 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, - 0xfe, 0xd4, 0x11, 0x05, - 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, - 0xce, 0x45, 0x31, 0x51, - 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, - 0x67, 0xfe, 0x98, 0x56, + 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, + 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0, + 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, - 0x0c, 0x06, 0x28, 0xfe, - 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, - 0xfe, 0xfa, 0x14, 0xfe, - 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, - 0xfe, 0xe0, 0x14, 0xfe, + 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, + 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe, + 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, - 0xfe, 0xad, 0x13, 0x05, - 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, - 0xe7, 0xfe, 0x08, 0x1c, - 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, - 0x48, 0x55, 0xa5, 0x3b, + 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, + 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe, + 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b, 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, - 0xf0, 0x1a, 0x03, 0xfe, - 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, - 0xec, 0xe7, 0x53, 0x00, - 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, - 0x01, 0xfe, 0x62, 0x1b, + 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, + 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec, + 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, - 0xea, 0xe7, 0x53, 0x92, - 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, - 0xfe, 0x38, 0x01, 0x23, - 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, - 0x01, 0x01, 0xfe, 0x1e, + 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, + 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10, + 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, - 0x26, 0x02, 0x21, 0x96, - 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, - 0xc3, 0xfe, 0xe1, 0x10, - 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, - 0xfe, 0x03, 0xdc, 0xfe, + 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, + 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc, + 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, - 0x00, 0xcc, 0x02, 0xfe, - 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, - 0x0f, 0xfe, 0x1c, 0x80, - 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, - 0x0f, 0xfe, 0x1e, 0x80, + 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, + 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83, + 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80, 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, - 0x1d, 0x80, 0x04, 0xfe, - 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, - 0x1e, 0xac, 0xfe, 0x14, - 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, - 0x1f, 0xfe, 0x30, 0xf4, + 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, + 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe, + 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, - 0x56, 0xfb, 0x01, 0xfe, - 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, - 0xfe, 0x00, 0x1d, 0x15, - 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, - 0x22, 0x1b, 0xfe, 0x1e, + 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, + 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01, + 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e, 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, - 0x96, 0x90, 0x04, 0xfe, - 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, - 0x01, 0x01, 0x0c, 0x06, - 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, - 0x0e, 0x77, 0xfe, 0x01, + 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, + 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe, + 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01, 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, - 0x21, 0x2c, 0xfe, 0x00, - 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, - 0x06, 0x58, 0x03, 0xfe, - 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, - 0x03, 0xfe, 0xb2, 0x00, + 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, + 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, + 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, - 0x66, 0x10, 0x55, 0x10, - 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, - 0x54, 0x2b, 0xfe, 0x88, - 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, - 0x91, 0x54, 0x2b, 0xfe, + 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, + 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13, + 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, - 0x00, 0x40, 0x8d, 0x2c, - 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, - 0x12, 0x1c, 0x75, 0xfe, - 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, - 0x14, 0xfe, 0x0e, 0x47, + 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, + 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10, + 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47, 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, - 0xa7, 0x90, 0x34, 0x60, - 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, - 0x09, 0x56, 0xfe, 0x34, - 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, - 0xfe, 0x45, 0x48, 0x01, + 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, + 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01, + 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, - 0x09, 0x1a, 0xa5, 0x0a, - 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, - 0xfe, 0x14, 0x56, 0xfe, - 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, - 0xec, 0xb8, 0xfe, 0x9e, + 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, + 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec, + 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, - 0xf4, 0xfe, 0xdd, 0x10, - 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, - 0x12, 0x09, 0x0d, 0xfe, - 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, - 0x13, 0x09, 0xfe, 0x23, + 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, + 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d, + 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23, 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, - 0x24, 0xfe, 0x12, 0x12, - 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, - 0xae, 0x41, 0x02, 0x32, - 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, - 0x35, 0x32, 0x01, 0x43, + 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, + 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a, + 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43, 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, - 0x13, 0x01, 0x0c, 0x06, - 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, - 0xe5, 0x55, 0xb0, 0xfe, - 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, - 0xfe, 0xb6, 0x0e, 0x10, + 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, + 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e, + 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10, 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, - 0x88, 0x20, 0x6e, 0x01, - 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, - 0x55, 0xfe, 0x04, 0xfa, - 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, - 0xfe, 0x40, 0x56, 0xfe, + 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, + 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa, + 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, - 0x44, 0x55, 0xfe, 0xe5, - 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, - 0x68, 0x22, 0x69, 0x01, - 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, - 0x6b, 0xfe, 0x2c, 0x50, + 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, + 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9, + 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, - 0x50, 0x03, 0x68, 0x3b, - 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, - 0x40, 0x50, 0xfe, 0xc2, - 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, - 0x16, 0x3d, 0x27, 0x25, + 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, + 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e, + 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25, 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, - 0xa6, 0x23, 0x3f, 0x1b, - 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, - 0xfe, 0x0a, 0x55, 0x31, - 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, - 0x51, 0x05, 0x72, 0x01, + 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, + 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9, + 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01, 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, - 0x2a, 0x3c, 0x16, 0xc0, - 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, - 0xfe, 0x66, 0x15, 0x05, - 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, - 0x2b, 0x3d, 0x01, 0x08, + 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, + 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a, + 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08, 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, - 0xb6, 0x1e, 0x83, 0x01, - 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, - 0x07, 0x90, 0x3f, 0x01, - 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, - 0x01, 0x43, 0x09, 0x82, + 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, + 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01, + 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82, 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, - 0x05, 0x72, 0xfe, 0xc0, - 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, - 0x32, 0x01, 0x08, 0x17, - 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, - 0x3d, 0x27, 0x25, 0xbd, + 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, + 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56, + 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, - 0xe8, 0x14, 0x01, 0xa6, - 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, - 0x0e, 0x12, 0x01, 0x43, - 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, - 0x01, 0x08, 0x17, 0x73, + 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, + 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, + 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, - 0x27, 0x25, 0xbd, 0x09, - 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, - 0xb6, 0x14, 0x86, 0xa8, - 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, - 0x82, 0x4e, 0x05, 0x72, + 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, + 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d, + 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, - 0xfe, 0xc0, 0x19, 0x05, - 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, - 0xcc, 0x01, 0x08, 0x26, - 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, - 0xcc, 0x15, 0x5e, 0x32, + 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, + 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe, + 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32, 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, - 0xad, 0x23, 0xfe, 0xff, - 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, - 0x00, 0x57, 0x52, 0xad, - 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, - 0x02, 0x00, 0x57, 0x52, + 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, + 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30, + 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, - 0x02, 0x13, 0x58, 0xff, - 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, - 0x5c, 0x0a, 0x55, 0x01, - 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, - 0xff, 0x03, 0x00, 0x54, + 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, + 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01, + 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, - 0x7c, 0x3a, 0x0b, 0x0e, - 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, - 0xfe, 0x1a, 0xf7, 0x00, - 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, - 0xda, 0x6d, 0x02, 0xfe, + 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, + 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00, + 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, - 0x02, 0x01, 0xc6, 0xfe, - 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, - 0x25, 0xbe, 0x01, 0x08, - 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, - 0x03, 0x9a, 0x1e, 0xfe, + 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, + 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, + 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe, 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, - 0x48, 0xfe, 0x08, 0x17, - 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, - 0x17, 0x4d, 0x13, 0x07, - 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, - 0xff, 0x02, 0x83, 0x55, + 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, + 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04, + 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55, 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, - 0x17, 0x1c, 0x63, 0x13, - 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, - 0x00, 0xb0, 0xfe, 0x80, - 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, - 0x53, 0x07, 0xfe, 0x60, + 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, + 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64, + 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60, 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, - 0x00, 0x1c, 0x95, 0x13, - 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, - 0xfe, 0x43, 0xf4, 0x96, - 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, - 0xf4, 0x94, 0xf6, 0x8b, + 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, + 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, + 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b, 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, - 0xda, 0x17, 0x62, 0x49, - 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, - 0x71, 0x50, 0x26, 0xfe, - 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, - 0x58, 0x02, 0x50, 0x13, + 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, + 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7, + 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13, 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, - 0x25, 0xbe, 0xfe, 0x03, - 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, - 0x0a, 0x01, 0x08, 0x16, - 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, - 0x01, 0x08, 0x16, 0xa9, + 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, + 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, + 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, - 0x08, 0x16, 0xa9, 0x27, - 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, - 0x01, 0x38, 0x06, 0x24, - 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, - 0x78, 0x03, 0x9a, 0x1e, + 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, + 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2, + 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, - 0xfe, 0x40, 0x5a, 0x23, - 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, - 0x80, 0x48, 0xfe, 0xaa, - 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, - 0xfe, 0xac, 0x1d, 0xfe, + 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, + 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe, + 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, - 0x43, 0x48, 0x2d, 0x93, - 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, - 0x36, 0xfe, 0x34, 0xf4, - 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, - 0x28, 0x10, 0xfe, 0xc0, + 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, + 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10, + 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0, 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, - 0x18, 0x45, 0xfe, 0x1c, - 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, - 0x19, 0xfe, 0x04, 0xf4, - 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, - 0x21, 0xfe, 0x7f, 0x01, + 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, + 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4, + 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01, 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, - 0x7e, 0x01, 0xfe, 0xc8, - 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, - 0x21, 0xfe, 0x81, 0x01, - 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, - 0x13, 0x0d, 0x02, 0x14, + 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, + 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e, + 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, - 0xfe, 0x82, 0x19, 0x14, - 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, - 0x08, 0x02, 0x14, 0x07, - 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, - 0x01, 0x08, 0x17, 0xc1, + 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, + 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1, + 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, - 0x08, 0x02, 0x50, 0x02, - 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, - 0x14, 0x12, 0x01, 0x08, - 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, - 0x08, 0x17, 0x74, 0xfe, + 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, + 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89, + 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, - 0x74, 0x5f, 0xcc, 0x01, - 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, - 0xfe, 0x49, 0xf4, 0x00, - 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, - 0x02, 0x00, 0x10, 0x2f, + 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, + 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e, + 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, - 0x16, 0xfe, 0x64, 0x1a, - 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, - 0x61, 0x07, 0x44, 0x02, - 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, - 0x13, 0x0a, 0x9d, 0x01, + 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, + 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18, + 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, - 0xfe, 0x80, 0xe7, 0x1a, - 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, - 0x0a, 0x5a, 0x01, 0x18, - 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, - 0x7e, 0x1e, 0xfe, 0x80, + 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, + 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01, + 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, - 0xfe, 0x80, 0x4c, 0x0a, - 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, - 0xfe, 0x19, 0xde, 0xfe, - 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, - 0x2a, 0x1c, 0xfa, 0xb3, + 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, + 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d, + 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3, 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, - 0xf4, 0x1a, 0xfe, 0xfa, - 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, - 0xfe, 0x18, 0x58, 0x03, - 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, - 0xfe, 0x30, 0xf4, 0x07, + 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, + 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe, + 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07, 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, - 0xf7, 0x24, 0xb1, 0xfe, - 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, - 0xfe, 0xba, 0x10, 0x1c, - 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, - 0x1d, 0xf7, 0x54, 0xb1, + 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, + 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83, + 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1, 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, - 0xaf, 0x19, 0xfe, 0x98, - 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, - 0x1a, 0x87, 0x8b, 0x0f, - 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, - 0xfe, 0x32, 0x90, 0x04, + 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, + 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04, + 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04, 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, - 0x7c, 0x12, 0xfe, 0x0f, - 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, - 0x31, 0x02, 0xc9, 0x2b, - 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, - 0x6a, 0xfe, 0x19, 0xfe, + 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, + 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c, + 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe, 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, - 0x1b, 0xfe, 0x36, 0x14, - 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, - 0xfe, 0x80, 0xe7, 0x1a, - 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, - 0x30, 0xfe, 0x12, 0x45, + 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, + 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a, + 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45, 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, - 0x39, 0xf0, 0x75, 0x26, - 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, - 0xe3, 0x23, 0x07, 0xfe, - 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, - 0x56, 0xfe, 0x3c, 0x13, + 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, + 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1, + 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, - 0x01, 0x18, 0xcb, 0xfe, - 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, - 0xfe, 0x00, 0xcc, 0xcb, - 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, - 0xfe, 0x80, 0x4c, 0x01, + 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, + 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, + 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01, 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, - 0x12, 0xfe, 0x14, 0x56, - 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, - 0x0d, 0x19, 0xfe, 0x15, - 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, - 0x83, 0xfe, 0x18, 0x80, + 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, + 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30, + 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80, 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, - 0x90, 0xfe, 0xba, 0x90, - 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, - 0x21, 0xb9, 0x88, 0x20, - 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, - 0x18, 0xfe, 0x49, 0x44, + 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, + 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba, + 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44, 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, - 0x1a, 0xa4, 0x0a, 0x67, - 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, - 0x1d, 0x7b, 0xfe, 0x52, - 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, - 0x4e, 0xe4, 0xdd, 0x7b, + 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, + 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90, + 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b, 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, - 0xfe, 0x4e, 0xe4, 0xfe, - 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, - 0xfe, 0x08, 0x10, 0x03, - 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, - 0x68, 0x54, 0xfe, 0xf1, + 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, + 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1, + 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, - 0xfe, 0x1a, 0xf4, 0xfe, - 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, - 0x09, 0x92, 0xfe, 0x5a, - 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, - 0x5a, 0xf0, 0xfe, 0xc8, + 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, + 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d, + 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8, 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, - 0x1a, 0x10, 0x09, 0x0d, - 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, - 0x1f, 0x93, 0x01, 0x42, - 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, - 0xfe, 0x14, 0xf0, 0x08, + 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, + 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99, + 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08, 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, - 0xfe, 0x82, 0xf0, 0xfe, - 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, - 0x02, 0x0f, 0xfe, 0x18, - 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, - 0x80, 0x04, 0xfe, 0x82, + 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, + 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98, + 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, - 0x83, 0x33, 0x0b, 0x0e, - 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, - 0x02, 0x0f, 0xfe, 0x04, - 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, - 0x80, 0x04, 0xfe, 0x80, + 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, + 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84, + 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, - 0xfe, 0x99, 0x83, 0xfe, - 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, - 0x83, 0xfe, 0xce, 0x47, - 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, - 0x0b, 0x0e, 0x02, 0x0f, + 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, + 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f, + 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, - 0xfe, 0x08, 0x90, 0x04, - 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, - 0xfe, 0x8a, 0x93, 0x79, - 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, - 0x0b, 0x0e, 0x02, 0x0f, + 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, + 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, + 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, - 0xfe, 0x3c, 0x90, 0x04, - 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, - 0x04, 0xfe, 0x83, 0x83, - 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, + 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, + 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e, + 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, }; static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ -- cgit v1.1 From c2dce2fabc7f0b559e920890d13e7b8ecfc91e13 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:30 -0600 Subject: [SCSI] advansys: Shrink advansys_board_found a little more Move the error reporting into AscInitGetConfig, AdvInitGetConfig and AscInitSetConfig. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 230 +++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 118 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 5649bf4..fe289b1 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -9321,13 +9321,14 @@ static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) } #endif /* CONFIG_ISA */ -static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) +static int __devinit AscInitGetConfig(asc_board_t *boardp) { + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; unsigned short warn_code = 0; asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; if (asc_dvc->err_code != 0) - return (UW_ERR); + return asc_dvc->err_code; if (AscFindSignature(asc_dvc->iop_base)) { warn_code |= AscInitAscDvcVar(asc_dvc); @@ -9338,27 +9339,63 @@ static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc) } else { asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; } - return warn_code; + + switch (warn_code) { + case 0: /* No error */ + break; + case ASC_WARN_IO_PORT_ROTATE: + ASC_PRINT1("AscInitGetConfig: board %d: I/O port address " + "modified\n", boardp->id); + break; + case ASC_WARN_AUTO_CONFIG: + ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment " + "switch enabled\n", boardp->id); + break; + case ASC_WARN_EEPROM_CHKSUM: + ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum " + "error\n", boardp->id); + break; + case ASC_WARN_IRQ_MODIFIED: + ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n", + boardp->id); + break; + case ASC_WARN_CMD_QNG_CONFLICT: + ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled " + "w/o disconnects\n", boardp->id); + break; + default: + ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: " + "0x%x\n", boardp->id, warn_code); + break; + } + + if (asc_dvc->err_code != 0) { + ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, " + "err_code 0x%x\n", boardp->id, asc_dvc->init_state, + asc_dvc->err_code); + } + + return asc_dvc->err_code; } -static unsigned short __devinit -AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc) +static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp) { + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; PortAddr iop_base = asc_dvc->iop_base; unsigned short cfg_msw; unsigned short warn_code = 0; asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; if (asc_dvc->err_code != 0) - return UW_ERR; + return asc_dvc->err_code; if (!AscFindSignature(asc_dvc->iop_base)) { asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; - return 0; + return asc_dvc->err_code; } cfg_msw = AscGetChipCfgMsw(iop_base); if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { - cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); + cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; warn_code |= ASC_WARN_CFG_MSW_RECOVER; AscSetChipCfgMsw(iop_base, cfg_msw); } @@ -9409,7 +9446,44 @@ AscInitSetConfig(struct pci_dev *pdev, ASC_DVC_VAR *asc_dvc) #endif /* CONFIG_ISA */ asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; - return warn_code; + + switch (warn_code) { + case 0: /* No error. */ + break; + case ASC_WARN_IO_PORT_ROTATE: + ASC_PRINT1("AscInitSetConfig: board %d: I/O port address " + "modified\n", boardp->id); + break; + case ASC_WARN_AUTO_CONFIG: + ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment " + "switch enabled\n", boardp->id); + break; + case ASC_WARN_EEPROM_CHKSUM: + ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum " + "error\n", boardp->id); + break; + case ASC_WARN_IRQ_MODIFIED: + ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n", + boardp->id); + break; + case ASC_WARN_CMD_QNG_CONFLICT: + ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o " + "disconnects\n", + boardp->id); + break; + default: + ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: " + "0x%x\n", boardp->id, warn_code); + break; + } + + if (asc_dvc->err_code != 0) { + ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, " + "err_code 0x%x\n", boardp->id, asc_dvc->init_state, + asc_dvc->err_code); + } + + return asc_dvc->err_code; } static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) @@ -9596,7 +9670,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) cfg_msw = AscGetChipCfgMsw(iop_base); cfg_lsw = AscGetChipCfgLsw(iop_base); if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { - cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); + cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; warn_code |= ASC_WARN_CFG_MSW_RECOVER; AscSetChipCfgMsw(iop_base, cfg_msw); } @@ -12009,6 +12083,7 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = 0 /* 63 reserved */ }; +#ifdef CONFIG_PCI /* * Initialize the ADV_DVC_VAR structure. * @@ -12018,8 +12093,9 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = * then 0 is returned. */ static int __devinit -AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc) +AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp) { + ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; unsigned short warn_code = 0; AdvPortAddr iop_base = asc_dvc->iop_base; u16 cmd; @@ -12087,8 +12163,19 @@ AdvInitGetConfig(struct pci_dev *pdev, ADV_DVC_VAR *asc_dvc) warn_code |= status; } - return warn_code; + if (warn_code != 0) { + ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", + boardp->id, warn_code); + } + + if (asc_dvc->err_code) { + ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n", + boardp->id, asc_dvc->err_code); + } + + return asc_dvc->err_code; } +#endif static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) { @@ -15316,22 +15403,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) share_irq = 0; break; } - } else { - /* - * For Wide boards set PCI information before calling - * AdvInitGetConfig(). - */ -#ifdef CONFIG_PCI - shost->irq = adv_dvc_varp->irq_no = pdev->irq; - shost->unchecked_isa_dma = FALSE; - share_irq = IRQF_SHARED; -#endif /* CONFIG_PCI */ - } - /* - * Read the board configuration. - */ - if (ASC_NARROW_BOARD(boardp)) { /* * NOTE: AscInitGetConfig() may change the board's * bus_type value. The bus_type value should no @@ -15339,60 +15411,20 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * referenced only use the bit-wise AND operator "&". */ ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n"); - switch (ret = AscInitGetConfig(asc_dvc_varp)) { - case 0: /* No error */ - break; - case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1 - ("AscInitGetConfig: board %d: I/O port address modified\n", - boardp->id); - break; - case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1 - ("AscInitGetConfig: board %d: I/O port increment switch enabled\n", - boardp->id); - break; - case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1 - ("AscInitGetConfig: board %d: EEPROM checksum error\n", - boardp->id); - break; - case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1 - ("AscInitGetConfig: board %d: IRQ modified\n", - boardp->id); - break; - case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1 - ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n", - boardp->id); - break; - default: - ASC_PRINT2 - ("AscInitGetConfig: board %d: unknown warning: 0x%x\n", - boardp->id, ret); - break; - } - if ((err_code = asc_dvc_varp->err_code) != 0) { - ASC_PRINT3 - ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", - boardp->id, - asc_dvc_varp->init_state, asc_dvc_varp->err_code); - } + err_code = AscInitGetConfig(boardp); } else { +#ifdef CONFIG_PCI + /* + * For Wide boards set PCI information before calling + * AdvInitGetConfig(). + */ + shost->irq = adv_dvc_varp->irq_no = pdev->irq; + shost->unchecked_isa_dma = FALSE; + share_irq = IRQF_SHARED; ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); - ret = AdvInitGetConfig(pdev, adv_dvc_varp); - if (ret != 0) { - ASC_PRINT2 - ("AdvInitGetConfig: board %d: warning: 0x%x\n", - boardp->id, ret); - } - if ((err_code = adv_dvc_varp->err_code) != 0) { - ASC_PRINT2 - ("AdvInitGetConfig: board %d error: err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); - } + err_code = AdvInitGetConfig(pdev, boardp); +#endif /* CONFIG_PCI */ } if (err_code != 0) @@ -15439,47 +15471,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Modify board configuration. */ ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); - switch (ret = AscInitSetConfig(pdev, asc_dvc_varp)) { - case 0: /* No error. */ - break; - case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1 - ("AscInitSetConfig: board %d: I/O port address modified\n", - boardp->id); - break; - case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1 - ("AscInitSetConfig: board %d: I/O port increment switch enabled\n", - boardp->id); - break; - case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1 - ("AscInitSetConfig: board %d: EEPROM checksum error\n", - boardp->id); - break; - case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1 - ("AscInitSetConfig: board %d: IRQ modified\n", - boardp->id); - break; - case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1 - ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n", - boardp->id); - break; - default: - ASC_PRINT2 - ("AscInitSetConfig: board %d: unknown warning: 0x%x\n", - boardp->id, ret); - break; - } - if (asc_dvc_varp->err_code != 0) { - ASC_PRINT3 - ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", - boardp->id, - asc_dvc_varp->init_state, asc_dvc_varp->err_code); + err_code = AscInitSetConfig(pdev, boardp); + if (err_code) goto err_free_proc; - } /* * Finish initializing the 'Scsi_Host' structure. -- cgit v1.1 From b66229258f88a06ecdb8998066861b3ad8ad6a2a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:31 -0600 Subject: [SCSI] advansys: Remove `waiting' queue If the adapter is busy, return the request to the midlayer rather than queueing it in the driver. asc_execute_queue() and asc_dequeue() become unused, and we don't need to print out stats on the waiting queue any more. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 186 +++--------------------------------------------- 1 file changed, 9 insertions(+), 177 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index fe289b1..526239a 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2852,7 +2852,6 @@ typedef struct asc_board { } dvc_cfg; ushort asc_n_io_port; /* Number I/O ports. */ asc_queue_t active; /* Active command queue */ - asc_queue_t waiting; /* Waiting command queue */ asc_queue_t done; /* Done command queue */ ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ @@ -2922,10 +2921,8 @@ static int asc_build_req(asc_board_t *, struct scsi_cmnd *); static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); static void asc_enqueue(asc_queue_t *, REQP, int); -static REQP asc_dequeue(asc_queue_t *, int); static REQP asc_dequeue_list(asc_queue_t *, REQP *, int); static int asc_rmqueue(asc_queue_t *, REQP); -static void asc_execute_queue(asc_queue_t *); #ifdef CONFIG_PROC_FS static int asc_proc_copy(off_t, off_t, char *, int, char *, int); static int asc_prt_board_devices(struct Scsi_Host *, char *, int); @@ -3274,6 +3271,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) asc_board_t *boardp; ulong flags; struct scsi_cmnd *done_scp; + int asc_res, result = 0; shost = scp->device->host; boardp = ASC_BOARDP(shost); @@ -3302,37 +3300,13 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) return 0; } - /* - * Attempt to execute any waiting commands for the board. - */ - if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { - ASC_DBG(1, - "advansys_queuecommand: before asc_execute_queue() waiting\n"); - asc_execute_queue(&boardp->waiting); - } - - /* - * Save the function pointer to Linux mid-level 'done' function - * and attempt to execute the command. - * - * If ASC_NOERROR is returned the request has been added to the - * board's 'active' queue and will be completed by the interrupt - * handler. - * - * If ASC_BUSY is returned add the request to the board's per - * target waiting list. This is the first time the request has - * been tried. Add it to the back of the waiting list. It will be - * retried later. - * - * If an error occurred, the request will have been placed on the - * board's 'done' queue and must be completed before returning. - */ scp->scsi_done = done; - switch (asc_execute_scsi_cmnd(scp)) { + asc_res = asc_execute_scsi_cmnd(scp); + switch (asc_res) { case ASC_NOERROR: break; case ASC_BUSY: - asc_enqueue(&boardp->waiting, scp, ASC_BACK); + result = SCSI_MLQUEUE_HOST_BUSY; break; case ASC_ERROR: default: @@ -3343,7 +3317,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) } spin_unlock_irqrestore(&boardp->lock, flags); - return 0; + return result; } /* @@ -3488,33 +3462,6 @@ static int advansys_reset(struct scsi_cmnd *scp) } } - /* - * Dequeue all 'waiting' requests and set the request status - * to DID_RESET. - */ - if (done_scp == NULL) { - done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, - ASC_TID_ALL); - for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { - tscp->result = HOST_BYTE(DID_RESET); - } - } else { - /* Append to 'done_scp' at the end with 'last_scp'. */ - ASC_ASSERT(last_scp != NULL); - last_scp->host_scribble = - (unsigned char *)asc_dequeue_list(&boardp->waiting, - &new_last_scp, - ASC_TID_ALL); - if (new_last_scp != NULL) { - ASC_ASSERT(REQPNEXT(last_scp) != NULL); - for (tscp = REQPNEXT(last_scp); tscp; - tscp = REQPNEXT(tscp)) { - tscp->result = HOST_BYTE(DID_RESET); - } - last_scp = new_last_scp; - } - } - /* Save the time of the most recently completed reset. */ boardp->last_reset = jiffies; @@ -3650,7 +3597,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) } /* - * Start waiting requests and create a list of completed requests. + * Create a list of completed requests. * * If a reset request is being performed for the board, the reset * handler will complete pending requests after it has completed. @@ -3659,13 +3606,6 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, " "last_scp 0x%p\n", done_scp, last_scp); - /* Start any waiting commands for the board. */ - if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { - ASC_DBG(1, "advansys_interrupt: before " - "asc_execute_queue()\n"); - asc_execute_queue(&boardp->waiting); - } - /* * Add to the list of requests that must be completed. * @@ -3986,8 +3926,8 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) * If this function returns ASC_NOERROR the request has been enqueued * on the board's 'done' queue and must be completed by the caller. * - * If ASC_BUSY is returned the request will be enqueued by the - * caller on the target's waiting queue and re-tried later. + * If ASC_BUSY is returned the request will be returned to the midlayer + * and re-tried later. */ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) { @@ -4043,10 +3983,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) "ASC_NOERROR\n"); break; case ASC_BUSY: - /* - * Caller will enqueue request on the target's waiting - * queue and retry later. - */ ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: @@ -4087,10 +4023,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " "ASC_BUSY\n"); /* - * If busy is returned the request has not been - * enqueued. It will be enqueued by the caller on the - * target's waiting queue and retried later. - * * The asc_stats fields 'adv_build_noreq' and * 'adv_build_nosg' count wide board busy conditions. * They are updated in adv_build_req and @@ -4127,10 +4059,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) "ASC_NOERROR\n"); break; case ASC_BUSY: - /* - * Caller will enqueue request on the target's waiting - * queue and retry later. - */ ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: @@ -5005,39 +4933,6 @@ static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag) } /* - * Return first queued 'REQP' on the specified queue for - * the specified target device. Clear the 'tidmask' bit for - * the device if no more commands are left queued for it. - * - * 'REQPNEXT(reqp)' returns reqp's next pointer. - */ -static REQP asc_dequeue(asc_queue_t *ascq, int tid) -{ - REQP reqp; - - ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid); - ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); - if ((reqp = ascq->q_first[tid]) != NULL) { - ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)); - ascq->q_first[tid] = REQPNEXT(reqp); - /* If the queue is empty, clear its bit and the last pointer. */ - if (ascq->q_first[tid] == NULL) { - ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); - ASC_ASSERT(ascq->q_last[tid] == reqp); - ascq->q_last[tid] = NULL; - } -#ifdef ADVANSYS_STATS - /* Maintain request queue statistics. */ - ascq->q_cur_cnt[tid]--; - ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); - REQTIMESTAT("asc_dequeue", ascq, reqp, tid); -#endif /* ADVANSYS_STATS */ - } - ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp); - return reqp; -} - -/* * Return a pointer to a singly linked list of all the requests queued * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. * @@ -5202,45 +5097,6 @@ static int asc_rmqueue(asc_queue_t *ascq, REQP reqp) return ret; } -/* - * Execute as many queued requests as possible for the specified queue. - * - * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd. - */ -static void asc_execute_queue(asc_queue_t *ascq) -{ - ADV_SCSI_BIT_ID_TYPE scan_tidmask; - REQP reqp; - int i; - - ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq); - /* - * Execute queued commands for devices attached to - * the current board in round-robin fashion. - */ - scan_tidmask = ascq->q_tidmask; - do { - for (i = 0; i <= ADV_MAX_TID; i++) { - if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) { - if ((reqp = asc_dequeue(ascq, i)) == NULL) { - scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); - } else - if (asc_execute_scsi_cmnd - ((struct scsi_cmnd *)reqp) - == ASC_BUSY) { - scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); - /* - * The request returned ASC_BUSY. Enqueue at the front of - * target's waiting list to maintain correct ordering. - */ - asc_enqueue(ascq, reqp, ASC_FRONT); - } - } - } - } while (scan_tidmask); - return; -} - #ifdef CONFIG_PROC_FS /* * asc_prt_board_devices() @@ -6723,7 +6579,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) ushort chip_scsi_id; asc_board_t *boardp; asc_queue_t *active; - asc_queue_t *waiting; leftlen = cplen; totlen = len = 0; @@ -6732,7 +6587,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) s = &boardp->asc_stats; active = &ASC_BOARDP(shost)->active; - waiting = &ASC_BOARDP(shost)->waiting; if (ASC_NARROW_BOARD(boardp)) { chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; @@ -6746,8 +6600,7 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) } do { - if (active->q_tot_cnt[tgt_id] > 0 - || waiting->q_tot_cnt[tgt_id] > 0) { + if (active->q_tot_cnt[tgt_id] > 0) { len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id); ASC_PRT_NEXT(); @@ -6771,27 +6624,6 @@ asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) q_tot_cnt [tgt_id])); ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n", - waiting->q_cur_cnt[tgt_id], - waiting->q_max_cnt[tgt_id], - waiting->q_tot_cnt[tgt_id], - waiting->q_min_tim[tgt_id], - waiting->q_max_tim[tgt_id], - (waiting->q_tot_cnt[tgt_id] == - 0) ? 0 : (waiting-> - q_tot_tim[tgt_id] / - waiting-> - q_tot_cnt[tgt_id]), - (waiting->q_tot_cnt[tgt_id] == - 0) ? 0 : ASC_TENTHS(waiting-> - q_tot_tim - [tgt_id], - waiting-> - q_tot_cnt - [tgt_id])); - ASC_PRT_NEXT(); } } while (0); -- cgit v1.1 From 7686f02aa8a380b3b0322179090f3c83ee4df977 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:32 -0600 Subject: [SCSI] advansys: Remove a check for an impossible condition The midlayer guarantees it won't call ->queuecommand for a host which is handling a reset condition. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 526239a..cd17f28 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3281,25 +3281,6 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) /* against own ISR */ spin_lock_irqsave(&boardp->lock, flags); - /* - * Block new commands while handling a reset or abort request. - */ - if (boardp->flags & ASC_HOST_IN_RESET) { - ASC_DBG1(1, - "advansys_queuecommand: scp 0x%lx blocked for reset request\n", - (ulong)scp); - scp->result = HOST_BYTE(DID_RESET); - - /* - * Add blocked requests to the board's 'done' queue. The queued - * requests will be completed at the end of the abort or reset - * handling. - */ - asc_enqueue(&boardp->done, scp, ASC_BACK); - spin_unlock_irqrestore(&boardp->lock, flags); - return 0; - } - scp->scsi_done = done; asc_res = asc_execute_scsi_cmnd(scp); switch (asc_res) { -- cgit v1.1 From 6ed1ef0786094f06d2462aeeb6ad7bf9f5f9fc18 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:33 -0600 Subject: [SCSI] advansys: Remove `done' queue - Move the guts of asc_scsi_done_list() into a new function, asc_scsi_done. - Call asc_scsi_done() in asc_isr_callback() and adv_isr_callback(). The comment was wrong; scsi_done cannot enable interrupts. - All other places which queued an scp on the done list are error paths for queuecommand, and so we can just call asc_scsi_done() in queuecommand if we receive an error. - We no longer need to keep a list of done requests in advansys_interrupt Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 120 ++++++++++-------------------------------------- 1 file changed, 24 insertions(+), 96 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index cd17f28..90f05c5 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2852,7 +2852,6 @@ typedef struct asc_board { } dvc_cfg; ushort asc_n_io_port; /* Number I/O ports. */ asc_queue_t active; /* Active command queue */ - asc_queue_t done; /* Done command queue */ ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ @@ -3258,6 +3257,23 @@ static const char *advansys_info(struct Scsi_Host *shost) return info; } +static void asc_scsi_done(struct scsi_cmnd *scp) +{ + struct asc_board *boardp = ASC_BOARDP(scp->device->host); + + if (scp->use_sg) + dma_unmap_sg(boardp->dev, + (struct scatterlist *)scp->request_buffer, + scp->use_sg, scp->sc_data_direction); + else if (scp->request_bufflen) + dma_unmap_single(boardp->dev, scp->SCp.dma_handle, + scp->request_bufflen, scp->sc_data_direction); + + ASC_STATS(scp->device->host, done); + + scp->scsi_done(scp); +} + /* * advansys_queuecommand() - interrupt-driven I/O entrypoint. * @@ -3270,7 +3286,6 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) struct Scsi_Host *shost; asc_board_t *boardp; ulong flags; - struct scsi_cmnd *done_scp; int asc_res, result = 0; shost = scp->device->host; @@ -3291,9 +3306,8 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) break; case ASC_ERROR: default: - done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); /* Interrupts could be enabled here. */ - asc_scsi_done_list(done_scp); + asc_scsi_done(scp); break; } spin_unlock_irqrestore(&boardp->lock, flags); @@ -3410,12 +3424,6 @@ static int advansys_reset(struct scsi_cmnd *scp) /* Board lock is held. */ /* - * Dequeue all board 'done' requests. A pointer to the last request - * is returned in 'last_scp'. - */ - done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL); - - /* * Dequeue all board 'active' requests for all devices and set * the request status to DID_RESET. A pointer to the last request * is returned in 'last_scp'. @@ -3548,8 +3556,6 @@ static struct scsi_host_template advansys_template = { static irqreturn_t advansys_interrupt(int irq, void *dev_id) { unsigned long flags; - struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; - struct scsi_cmnd *new_last_scp; struct Scsi_Host *shost = dev_id; asc_board_t *boardp = ASC_BOARDP(shost); irqreturn_t result = IRQ_NONE; @@ -3577,49 +3583,13 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) } } - /* - * Create a list of completed requests. - * - * If a reset request is being performed for the board, the reset - * handler will complete pending requests after it has completed. - */ - if ((boardp->flags & ASC_HOST_IN_RESET) == 0) { - ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, " - "last_scp 0x%p\n", done_scp, last_scp); - - /* - * Add to the list of requests that must be completed. - * - * 'done_scp' will always be NULL on the first iteration of - * this loop. 'last_scp' is set at the same time as 'done_scp'. - */ - if (done_scp == NULL) { - done_scp = asc_dequeue_list(&boardp->done, - &last_scp, ASC_TID_ALL); - } else { - ASC_ASSERT(last_scp != NULL); - last_scp->host_scribble = - (unsigned char *)asc_dequeue_list(&boardp-> - done, - &new_last_scp, - ASC_TID_ALL); - if (new_last_scp != NULL) { - ASC_ASSERT(REQPNEXT(last_scp) != NULL); - last_scp = new_last_scp; - } - } - } spin_unlock_irqrestore(&boardp->lock, flags); /* * If interrupts were enabled on entry, then they * are now enabled here. - * - * Complete all requests on the done list. */ - asc_scsi_done_list(done_scp); - ASC_DBG(1, "advansys_interrupt: end\n"); return result; } @@ -3836,27 +3806,11 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) ASC_DBG(2, "asc_scsi_done_list: begin\n"); while (scp != NULL) { - asc_board_t *boardp; - ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp); tscp = REQPNEXT(scp); scp->host_scribble = NULL; - boardp = ASC_BOARDP(scp->device->host); - - if (scp->use_sg) - dma_unmap_sg(boardp->dev, - (struct scatterlist *)scp->request_buffer, - scp->use_sg, scp->sc_data_direction); - else if (scp->request_bufflen) - dma_unmap_single(boardp->dev, scp->SCp.dma_handle, - scp->request_bufflen, - scp->sc_data_direction); - - ASC_STATS(scp->device->host, done); - ASC_ASSERT(scp->scsi_done != NULL); - - scp->scsi_done(scp); + asc_scsi_done(scp); scp = tscp; } @@ -3904,8 +3858,8 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) * on the board's 'active' queue and will be completed from the * interrupt handler. * - * If this function returns ASC_NOERROR the request has been enqueued - * on the board's 'done' queue and must be completed by the caller. + * If this function returns ASC_ERROR the host error code has been set, + * and the called must call asc_scsi_done. * * If ASC_BUSY is returned the request will be returned to the midlayer * and re-tried later. @@ -3972,7 +3926,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) boardp->id, asc_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); break; default: ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " @@ -3980,7 +3933,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) boardp->id, asc_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); break; } } else { @@ -4011,11 +3963,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) */ return ASC_BUSY; case ASC_ERROR: - /* - * If an error is returned, then the request has been - * queued on the board done queue. It will be completed - * by the caller. - */ default: ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " "ASC_ERROR\n"); @@ -4048,7 +3995,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) boardp->id, adv_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); break; default: ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " @@ -4056,7 +4002,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) boardp->id, adv_dvc_varp->err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); break; } } @@ -4071,8 +4016,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * The global structures 'asc_scsi_q' and 'asc_sg_head' are * used to build the request. * - * If an error occurs, then queue the request on the board done - * queue and return ASC_ERROR. + * If an error occurs, then return ASC_ERROR. */ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) { @@ -4098,7 +4042,6 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; } asc_scsi_q.cdbptr = &scp->cmnd[0]; @@ -4167,7 +4110,6 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; } @@ -4274,7 +4216,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; } scsiqp->cdb_len = scp->cmd_len; @@ -4342,7 +4283,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); - asc_enqueue(&boardp->done, scp, ASC_BACK); /* * Free the 'adv_req_t' structure by adding it back @@ -4628,13 +4568,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); } - /* - * Because interrupts may be enabled by the 'struct scsi_cmnd' done - * function, add the command to the end of the board's done queue. - * The done function for the command will be called from - * advansys_interrupt(). - */ - asc_enqueue(&boardp->done, scp, ASC_BACK); + asc_scsi_done(scp); return; } @@ -4790,13 +4724,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); } - /* - * Because interrupts may be enabled by the 'struct scsi_cmnd' done - * function, add the command to the end of the board's done queue. - * The done function for the command will be called from - * advansys_interrupt(). - */ - asc_enqueue(&boardp->done, scp, ASC_BACK); + asc_scsi_done(scp); /* * Free all 'adv_sgblk_t' structures allocated for the request. -- cgit v1.1 From 349d2c44291d922614a273e9a4e6b43ee17c103d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:34 -0600 Subject: [SCSI] advansys: Remove `active' queue and all remaining internal queueing code The `active' list was used in the reset handler -- but the midlayer guarantees that list is empty by the time the reset handler is invoked. It was also checked in the interrupt routines to be sure that this command belonged to this board, but we don't need to check that either. We can then delete the asc_prt_target_stats() function as it will never print anything, along with asc_enqueue(), asc_dequeue_list(), asc_rmqueue(), asc_scsi_done_list(), struct asc_queue, ASC_QUEUE_EMPTY, ASC_TID_ALL, ASC_FRONT, ASC_BACK, and all the REQ* macros. Also remove this item from the todo list. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 504 +----------------------------------------------- 1 file changed, 6 insertions(+), 498 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 90f05c5..67cdfe6 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -63,11 +63,10 @@ * has not occurred then print a message and run in polled mode. * 4. Need to add support for target mode commands, cf. CAM XPT. * 5. check DMA mapping functions for failure - * 6. Remove internal queueing - * 7. Use scsi_transport_spi - * 8. advansys_info is not safe against multiple simultaneous callers - * 9. Kill boardp->id - * 10. Add module_param to override ISA/VLB ioport array + * 6. Use scsi_transport_spi + * 7. advansys_info is not safe against multiple simultaneous callers + * 8. Kill boardp->id + * 9. Add module_param to override ISA/VLB ioport array */ #warning this driver is still not properly converted to the DMA API @@ -2514,64 +2513,6 @@ do { \ #define HOST_BYTE(byte) ((byte) << 16) #define DRIVER_BYTE(byte) ((byte) << 24) -/* - * The following definitions and macros are OS independent interfaces to - * the queue functions: - * REQ - SCSI request structure - * REQP - pointer to SCSI request structure - * REQPTID(reqp) - reqp's target id - * REQPNEXT(reqp) - reqp's next pointer - * REQPNEXTP(reqp) - pointer to reqp's next pointer - * REQPTIME(reqp) - reqp's time stamp value - * REQTIMESTAMP() - system time stamp value - */ -typedef struct scsi_cmnd REQ, *REQP; -#define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble)) -#define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble)) -#define REQPTID(reqp) ((reqp)->device->id) -#define REQPTIME(reqp) ((reqp)->SCp.this_residual) -#define REQTIMESTAMP() (jiffies) - -#define REQTIMESTAT(function, ascq, reqp, tid) \ -{ \ - /* - * If the request time stamp is less than the system time stamp, then \ - * maybe the system time stamp wrapped. Set the request time to zero.\ - */ \ - if (REQPTIME(reqp) <= REQTIMESTAMP()) { \ - REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \ - } else { \ - /* Indicate an error occurred with the assertion. */ \ - ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \ - REQPTIME(reqp) = 0; \ - } \ - /* Handle first minimum time case without external initialization. */ \ - if (((ascq)->q_tot_cnt[tid] == 1) || \ - (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \ - (ascq)->q_min_tim[tid] = REQPTIME(reqp); \ - ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \ - (function), (tid), (ascq)->q_min_tim[tid]); \ - } \ - if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \ - (ascq)->q_max_tim[tid] = REQPTIME(reqp); \ - ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \ - (function), tid, (ascq)->q_max_tim[tid]); \ - } \ - (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \ - /* Reset the time stamp field. */ \ - REQPTIME(reqp) = 0; \ -} - -/* asc_enqueue() flags */ -#define ASC_FRONT 1 -#define ASC_BACK 2 - -/* asc_dequeue_list() argument */ -#define ASC_TID_ALL (-1) - -/* Return non-zero, if the queue is empty. */ -#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) - #ifndef ADVANSYS_STATS #define ASC_STATS(shost, counter) #define ASC_STATS_ADD(shost, counter, count) @@ -2784,23 +2725,6 @@ struct asc_stats { #endif /* ADVANSYS_STATS */ /* - * Request queuing structure - */ -typedef struct asc_queue { - ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */ - REQP q_first[ADV_MAX_TID + 1]; /* first queued request */ - REQP q_last[ADV_MAX_TID + 1]; /* last queued request */ -#ifdef ADVANSYS_STATS - short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */ - short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */ - ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */ - ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */ - ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */ - ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */ -#endif /* ADVANSYS_STATS */ -} asc_queue_t; - -/* * Adv Library Request Structures * * The following two structures are used to process Wide Board requests. @@ -2851,7 +2775,6 @@ typedef struct asc_board { ADV_DVC_CFG adv_dvc_cfg; /* Wide board */ } dvc_cfg; ushort asc_n_io_port; /* Number I/O ports. */ - asc_queue_t active; /* Active command queue */ ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ @@ -2914,14 +2837,10 @@ static int asc_dbglvl = 3; */ static int advansys_slave_configure(struct scsi_device *); -static void asc_scsi_done_list(struct scsi_cmnd *); static int asc_execute_scsi_cmnd(struct scsi_cmnd *); static int asc_build_req(asc_board_t *, struct scsi_cmnd *); static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); -static void asc_enqueue(asc_queue_t *, REQP, int); -static REQP asc_dequeue_list(asc_queue_t *, REQP *, int); -static int asc_rmqueue(asc_queue_t *, REQP); #ifdef CONFIG_PROC_FS static int asc_proc_copy(off_t, off_t, char *, int, char *, int); static int asc_prt_board_devices(struct Scsi_Host *, char *, int); @@ -2939,7 +2858,6 @@ static int asc_prt_line(char *, int, char *fmt, ...); #ifdef ADVANSYS_STATS #ifdef CONFIG_PROC_FS static int asc_prt_board_stats(struct Scsi_Host *, char *, int); -static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int); #endif /* CONFIG_PROC_FS */ #endif /* ADVANSYS_STATS */ @@ -2991,9 +2909,6 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, int leftlen; char *curbuf; off_t advoffset; -#ifdef ADVANSYS_STATS - int tgt_id; -#endif /* ADVANSYS_STATS */ ASC_DBG(1, "advansys_proc_info: begin\n"); @@ -3123,26 +3038,6 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, } advoffset += cplen; curbuf += cnt; - - /* - * Display driver statistics for each target. - */ - for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) { - cp = boardp->prtbuf; - cplen = asc_prt_target_stats(shost, tgt_id, cp, - ASC_PRTBUF_SIZE); - ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, - cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; - } #endif /* ADVANSYS_STATS */ /* @@ -3331,8 +3226,6 @@ static int advansys_reset(struct scsi_cmnd *scp) ASC_DVC_VAR *asc_dvc_varp; ADV_DVC_VAR *adv_dvc_varp; ulong flags; - struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; - struct scsi_cmnd *tscp, *new_last_scp; int status; int ret = SUCCESS; @@ -3423,34 +3316,6 @@ static int advansys_reset(struct scsi_cmnd *scp) } /* Board lock is held. */ - /* - * Dequeue all board 'active' requests for all devices and set - * the request status to DID_RESET. A pointer to the last request - * is returned in 'last_scp'. - */ - if (done_scp == NULL) { - done_scp = asc_dequeue_list(&boardp->active, &last_scp, - ASC_TID_ALL); - for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { - tscp->result = HOST_BYTE(DID_RESET); - } - } else { - /* Append to 'done_scp' at the end with 'last_scp'. */ - ASC_ASSERT(last_scp != NULL); - last_scp->host_scribble = - (unsigned char *)asc_dequeue_list(&boardp->active, - &new_last_scp, - ASC_TID_ALL); - if (new_last_scp != NULL) { - ASC_ASSERT(REQPNEXT(last_scp) != NULL); - for (tscp = REQPNEXT(last_scp); tscp; - tscp = REQPNEXT(tscp)) { - tscp->result = HOST_BYTE(DID_RESET); - } - last_scp = new_last_scp; - } - } - /* Save the time of the most recently completed reset. */ boardp->last_reset = jiffies; @@ -3458,12 +3323,6 @@ static int advansys_reset(struct scsi_cmnd *scp) boardp->flags &= ~ASC_HOST_IN_RESET; spin_unlock_irqrestore(&boardp->lock, flags); - /* - * Complete all the 'done_scp' requests. - */ - if (done_scp) - asc_scsi_done_list(done_scp); - ASC_DBG1(1, "advansys_reset: ret %d\n", ret); return ret; @@ -3795,30 +3654,6 @@ static int advansys_slave_configure(struct scsi_device *sdev) } /* - * Complete all requests on the singly linked list pointed - * to by 'scp'. - * - * Interrupts can be enabled on entry. - */ -static void asc_scsi_done_list(struct scsi_cmnd *scp) -{ - struct scsi_cmnd *tscp; - - ASC_DBG(2, "asc_scsi_done_list: begin\n"); - while (scp != NULL) { - ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp); - tscp = REQPNEXT(scp); - scp->host_scribble = NULL; - - asc_scsi_done(scp); - - scp = tscp; - } - ASC_DBG(2, "asc_scsi_done_list: done\n"); - return; -} - -/* * Execute a single 'Scsi_Cmnd'. * * The function 'done' is called when the request has been completed. @@ -3854,9 +3689,8 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp) * scsi_done - used to save caller's done function * host_scribble - used for pointer to another struct scsi_cmnd * - * If this function returns ASC_NOERROR the request has been enqueued - * on the board's 'active' queue and will be completed from the - * interrupt handler. + * If this function returns ASC_NOERROR the request will be completed + * from the interrupt handler. * * If this function returns ASC_ERROR the host error code has been set, * and the called must call asc_scsi_done. @@ -3901,10 +3735,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) return ASC_ERROR; } - /* - * Execute the command. If there is no error, add the command - * to the active queue. - */ switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { case ASC_NOERROR: ASC_STATS(scp->device->host, exe_noerror); @@ -3913,7 +3743,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * successful request counter. Wrapping doesn't matter. */ boardp->reqcnt[scp->device->id]++; - asc_enqueue(&boardp->active, scp, ASC_BACK); ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), " "ASC_NOERROR\n"); break; @@ -3970,10 +3799,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) return ASC_ERROR; } - /* - * Execute the command. If there is no error, add the command - * to the active queue. - */ switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { case ASC_NOERROR: ASC_STATS(scp->device->host, exe_noerror); @@ -3982,7 +3807,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * successful request counter. Wrapping doesn't matter. */ boardp->reqcnt[scp->device->id]++; - asc_enqueue(&boardp->active, scp, ASC_BACK); ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), " "ASC_NOERROR\n"); break; @@ -4467,19 +4291,8 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) ASC_STATS(shost, callback); ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); - /* - * If the request isn't found on the active queue, it may - * have been removed to handle a reset request. - * Display a message and return. - */ boardp = ASC_BOARDP(shost); ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var); - if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { - ASC_PRINT2 - ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n", - boardp->id, (ulong)scp); - return; - } /* * 'qdonep' contains the command's ending status. @@ -4624,21 +4437,8 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) ASC_STATS(shost, callback); ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); - /* - * If the request isn't found on the active queue, it may have been - * removed to handle a reset request. Display a message and return. - * - * Note: Because the structure may still be in use don't attempt - * to free the adv_req_t and adv_sgblk_t, if any, structures. - */ boardp = ASC_BOARDP(shost); ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var); - if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { - ASC_PRINT2 - ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n", - boardp->id, (ulong)scp); - return; - } /* * 'done_status' contains the command's ending status. @@ -4787,225 +4587,6 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) } } -/* - * Add a 'REQP' to the end of specified queue. Set 'tidmask' - * to indicate a command is queued for the device. - * - * 'flag' may be either ASC_FRONT or ASC_BACK. - * - * 'REQPNEXT(reqp)' returns reqp's next pointer. - */ -static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag) -{ - int tid; - - ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n", - (ulong)ascq, (ulong)reqp, flag); - ASC_ASSERT(reqp != NULL); - ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK); - tid = REQPTID(reqp); - ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); - if (flag == ASC_FRONT) { - reqp->host_scribble = (unsigned char *)ascq->q_first[tid]; - ascq->q_first[tid] = reqp; - /* If the queue was empty, set the last pointer. */ - if (ascq->q_last[tid] == NULL) { - ascq->q_last[tid] = reqp; - } - } else { /* ASC_BACK */ - if (ascq->q_last[tid] != NULL) { - ascq->q_last[tid]->host_scribble = - (unsigned char *)reqp; - } - ascq->q_last[tid] = reqp; - reqp->host_scribble = NULL; - /* If the queue was empty, set the first pointer. */ - if (ascq->q_first[tid] == NULL) { - ascq->q_first[tid] = reqp; - } - } - /* The queue has at least one entry, set its bit. */ - ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid); -#ifdef ADVANSYS_STATS - /* Maintain request queue statistics. */ - ascq->q_tot_cnt[tid]++; - ascq->q_cur_cnt[tid]++; - if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) { - ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid]; - ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n", - tid, ascq->q_max_cnt[tid]); - } - REQPTIME(reqp) = REQTIMESTAMP(); -#endif /* ADVANSYS_STATS */ - ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp); - return; -} - -/* - * Return a pointer to a singly linked list of all the requests queued - * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. - * - * If 'lastpp' is not NULL, '*lastpp' will be set to point to the - * the last request returned in the singly linked list. - * - * 'tid' should either be a valid target id or if it is ASC_TID_ALL, - * then all queued requests are concatenated into one list and - * returned. - * - * Note: If 'lastpp' is used to append a new list to the end of - * an old list, only change the old list last pointer if '*lastpp' - * (or the function return value) is not NULL, i.e. use a temporary - * variable for 'lastpp' and check its value after the function return - * before assigning it to the list last pointer. - * - * Unfortunately collecting queuing time statistics adds overhead to - * the function that isn't inherent to the function's algorithm. - */ -static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid) -{ - REQP firstp, lastp; - int i; - - ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid); - ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID)); - - /* - * If 'tid' is not ASC_TID_ALL, return requests only for - * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all - * requests for all tids. - */ - if (tid != ASC_TID_ALL) { - /* Return all requests for the specified 'tid'. */ - if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) { - /* List is empty; Set first and last return pointers to NULL. */ - firstp = lastp = NULL; - } else { - firstp = ascq->q_first[tid]; - lastp = ascq->q_last[tid]; - ascq->q_first[tid] = ascq->q_last[tid] = NULL; - ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); -#ifdef ADVANSYS_STATS - { - REQP reqp; - ascq->q_cur_cnt[tid] = 0; - for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { - REQTIMESTAT("asc_dequeue_list", ascq, - reqp, tid); - } - } -#endif /* ADVANSYS_STATS */ - } - } else { - /* Return all requests for all tids. */ - firstp = lastp = NULL; - for (i = 0; i <= ADV_MAX_TID; i++) { - if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) { - if (firstp == NULL) { - firstp = ascq->q_first[i]; - lastp = ascq->q_last[i]; - } else { - ASC_ASSERT(lastp != NULL); - lastp->host_scribble = - (unsigned char *)ascq->q_first[i]; - lastp = ascq->q_last[i]; - } - ascq->q_first[i] = ascq->q_last[i] = NULL; - ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i); -#ifdef ADVANSYS_STATS - ascq->q_cur_cnt[i] = 0; -#endif /* ADVANSYS_STATS */ - } - } -#ifdef ADVANSYS_STATS - { - REQP reqp; - for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { - REQTIMESTAT("asc_dequeue_list", ascq, reqp, - reqp->device->id); - } - } -#endif /* ADVANSYS_STATS */ - } - if (lastpp) { - *lastpp = lastp; - } - ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp); - return firstp; -} - -/* - * Remove the specified 'REQP' from the specified queue for - * the specified target device. Clear the 'tidmask' bit for the - * device if no more commands are left queued for it. - * - * 'REQPNEXT(reqp)' returns reqp's the next pointer. - * - * Return ASC_TRUE if the command was found and removed, - * otherwise return ASC_FALSE. - */ -static int asc_rmqueue(asc_queue_t *ascq, REQP reqp) -{ - REQP currp, prevp; - int tid; - int ret = ASC_FALSE; - - ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n", - (ulong)ascq, (ulong)reqp); - ASC_ASSERT(reqp != NULL); - - tid = REQPTID(reqp); - ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); - - /* - * Handle the common case of 'reqp' being the first - * entry on the queue. - */ - if (reqp == ascq->q_first[tid]) { - ret = ASC_TRUE; - ascq->q_first[tid] = REQPNEXT(reqp); - /* If the queue is now empty, clear its bit and the last pointer. */ - if (ascq->q_first[tid] == NULL) { - ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); - ASC_ASSERT(ascq->q_last[tid] == reqp); - ascq->q_last[tid] = NULL; - } - } else if (ascq->q_first[tid] != NULL) { - ASC_ASSERT(ascq->q_last[tid] != NULL); - /* - * Because the case of 'reqp' being the first entry has been - * handled above and it is known the queue is not empty, if - * 'reqp' is found on the queue it is guaranteed the queue will - * not become empty and that 'q_first[tid]' will not be changed. - * - * Set 'prevp' to the first entry, 'currp' to the second entry, - * and search for 'reqp'. - */ - for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp); - currp; prevp = currp, currp = REQPNEXT(currp)) { - if (currp == reqp) { - ret = ASC_TRUE; - prevp->host_scribble = - (unsigned char *)REQPNEXT(currp); - reqp->host_scribble = NULL; - if (ascq->q_last[tid] == reqp) { - ascq->q_last[tid] = prevp; - } - break; - } - } - } -#ifdef ADVANSYS_STATS - /* Maintain request queue statistics. */ - if (ret == ASC_TRUE) { - ascq->q_cur_cnt[tid]--; - REQTIMESTAT("asc_rmqueue", ascq, reqp, tid); - } - ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); -#endif /* ADVANSYS_STATS */ - ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret); - return ret; -} - #ifdef CONFIG_PROC_FS /* * asc_prt_board_devices() @@ -6465,79 +6046,6 @@ static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) return totlen; } - -/* - * asc_prt_target_stats() - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * This is separated from asc_prt_board_stats because a full set - * of targets will overflow ASC_PRTBUF_SIZE. - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. - */ -static int -asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) -{ - int leftlen; - int totlen; - int len; - struct asc_stats *s; - ushort chip_scsi_id; - asc_board_t *boardp; - asc_queue_t *active; - - leftlen = cplen; - totlen = len = 0; - - boardp = ASC_BOARDP(shost); - s = &boardp->asc_stats; - - active = &ASC_BOARDP(shost)->active; - - if (ASC_NARROW_BOARD(boardp)) { - chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; - } else { - chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; - } - - if ((chip_scsi_id == tgt_id) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) { - return 0; - } - - do { - if (active->q_tot_cnt[tgt_id] > 0) { - len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n", - active->q_cur_cnt[tgt_id], - active->q_max_cnt[tgt_id], - active->q_tot_cnt[tgt_id], - active->q_min_tim[tgt_id], - active->q_max_tim[tgt_id], - (active->q_tot_cnt[tgt_id] == - 0) ? 0 : (active-> - q_tot_tim[tgt_id] / - active-> - q_tot_cnt[tgt_id]), - (active->q_tot_cnt[tgt_id] == - 0) ? 0 : ASC_TENTHS(active-> - q_tot_tim - [tgt_id], - active-> - q_tot_cnt - [tgt_id])); - ASC_PRT_NEXT(); - } - } while (0); - - return totlen; -} #endif /* CONFIG_PROC_FS */ #endif /* ADVANSYS_STATS */ -- cgit v1.1 From b2a7a4ba0497f73295e3f4d20a8cedb1e3d2b1a7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:35 -0600 Subject: [SCSI] advansys: Enable interrupts earlier in queuecommand Move as much as possible outside the critical section in queuecommand, eg: - Set the scsi_done field before acquiring the lock - Call asc_scsi_done after dropping the lock Also remove a comment suggesting we should enable interrupts (now we do) and do some minor reformatting for readability. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 67cdfe6..d7bc0cf 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3176,23 +3176,24 @@ static void asc_scsi_done(struct scsi_cmnd *scp) * in the 'scp' result field. */ static int -advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) +advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { - struct Scsi_Host *shost; - asc_board_t *boardp; - ulong flags; + struct Scsi_Host *shost = scp->device->host; + asc_board_t *boardp = ASC_BOARDP(shost); + unsigned long flags; int asc_res, result = 0; - shost = scp->device->host; - boardp = ASC_BOARDP(shost); ASC_STATS(shost, queuecommand); + scp->scsi_done = done; - /* host_lock taken by mid-level prior to call but need to protect */ - /* against own ISR */ + /* + * host_lock taken by mid-level prior to call, but need + * to protect against own ISR + */ spin_lock_irqsave(&boardp->lock, flags); - - scp->scsi_done = done; asc_res = asc_execute_scsi_cmnd(scp); + spin_unlock_irqrestore(&boardp->lock, flags); + switch (asc_res) { case ASC_NOERROR: break; @@ -3201,11 +3202,9 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) break; case ASC_ERROR: default: - /* Interrupts could be enabled here. */ asc_scsi_done(scp); break; } - spin_unlock_irqrestore(&boardp->lock, flags); return result; } -- cgit v1.1 From f05ec594fed6890d38bb8767676f626a4035ba55 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:36 -0600 Subject: [SCSI] advansys: Support 16-byte commands properly The SCSI midlayer won't send commands greater than ->max_cmd_len. So the checks on length in asc_build_req and adv_build_req are obsolete and can be deleted, but also we have to set the max_cmd_len in advansys_board_found(). Also move the length definitions together, and write a helpful comment. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index d7bc0cf..ef4f679 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -210,10 +210,16 @@ typedef unsigned char uchar; #define ASC_SCSI_WIDTH_BIT_SET 0xFF #define ASC_MAX_SENSE_LEN 32 #define ASC_MIN_SENSE_LEN 14 -#define ASC_MAX_CDB_LEN 12 #define ASC_SCSI_RESET_HOLD_TIME_US 60 /* + * Narrow boards only support 12-byte commands, while wide boards + * extend to 16-byte commands. + */ +#define ASC_MAX_CDB_LEN 12 +#define ADV_MAX_CDB_LEN 16 + +/* * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data) * and CmdDt (Command Support Data) field bit definitions. */ @@ -1190,12 +1196,6 @@ static const char *advansys_info(struct Scsi_Host *shost); #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15) /* - * For wide boards a CDB length maximum of 16 bytes - * is supported. - */ -#define ADV_MAX_CDB_LEN 16 - -/* * Define total number of simultaneous maximum element scatter-gather * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the * maximum number of outstanding commands per wide host adapter. Each @@ -3856,17 +3856,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) /* * Build the ASC_SCSI_Q request. - * - * For narrow boards a CDB length maximum of 12 bytes - * is supported. */ - if (scp->cmd_len > ASC_MAX_CDB_LEN) { - ASC_PRINT3("asc_build_req: board %d: cmd_len %d > " - "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len, - ASC_MAX_CDB_LEN); - scp->result = HOST_BYTE(DID_ERROR); - return ASC_ERROR; - } asc_scsi_q.cdbptr = &scp->cmnd[0]; asc_scsi_q.q2.cdb_len = scp->cmd_len; asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); @@ -4029,18 +4019,7 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, * Build the ADV_SCSI_REQ_Q request. */ - /* - * Set CDB length and copy it to the request structure. - * For wide boards a CDB length maximum of 16 bytes - * is supported. - */ - if (scp->cmd_len > ADV_MAX_CDB_LEN) { - ASC_PRINT3 - ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n", - boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN); - scp->result = HOST_BYTE(DID_ERROR); - return ASC_ERROR; - } + /* Set CDB length and copy it to the request structure. */ scsiqp->cdb_len = scp->cmd_len; /* Copy first 12 CDB bytes to cdb[]. */ for (i = 0; i < scp->cmd_len && i < 12; i++) { @@ -14834,6 +14813,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (ASC_NARROW_BOARD(boardp)) { shost->max_id = ASC_MAX_TID + 1; shost->max_lun = ASC_MAX_LUN + 1; + shost->max_cmd_len = ASC_MAX_CDB_LEN; shost->io_port = asc_dvc_varp->iop_base; boardp->asc_n_io_port = ASC_IOADR_GAP; @@ -14844,6 +14824,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) } else { shost->max_id = ADV_MAX_TID + 1; shost->max_lun = ADV_MAX_LUN + 1; + shost->max_cmd_len = ADV_MAX_CDB_LEN; /* * Save the I/O Port address and length even though -- cgit v1.1 From faac48ecf475c8e214190dabe600585e0bd4f455 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:37 -0600 Subject: [SCSI] advansys: Remove a check for an impossible condition AscExeScsiQueue() has one caller, and it passes the address of a variable; this cannot ever be NULL. This is the only place that ever sets ASCQ_ERR_SCSIQ_NULL_PTR, so delete that error code too, as well as several other unused ASCQ_ERR codes. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ef4f679..60a9188 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -520,14 +520,6 @@ typedef struct asc_risc_sg_list_q { #define ASCQ_ERR_ISR_RE_ENTRY 0x1A #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C -#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D -#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E -#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F -#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20 -#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21 -#define ASCQ_ERR_SEND_SCSI_Q 0x22 -#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23 -#define ASCQ_ERR_RESET_SDTR 0x24 /* * Warning code values are set in ASC_DVC_VAR 'warn_code'. @@ -7578,10 +7570,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) sg_head = scsiq->sg_head; if (asc_dvc->err_code != 0) return (ERR); - if (scsiq == (ASC_SCSI_Q *)0L) { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR); - return (ERR); - } scsiq->q1.q_no = 0; if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { scsiq->q1.extra_bytes = 0; -- cgit v1.1 From b009bef6cd2c6c2b870088d9ae67dbc4ec2ca317 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:38 -0600 Subject: [SCSI] advansys: Remove some custom wrappers - Replace ASC_ASSERT() with BUG_ON(). In a few places, get rid of the assertion altogether -- the ensuing crash will tell us all we need to know. Use BUG() where it fits better than BUG_ON(). Also fix a fencepost error in advansys_proc_info(). - Replace DvcSleepMilliSecond with mdelay. Despite its name using 'sleep', the implementation was a delay. I've marked some places with XXX where we should probably be using msleep instead. They need to be audited to be sure we can sleep in that context. - Replace DvcDelayMicroSecond with udelay. - Replace DvcDelayNanoSecond with udelay too. All callers were multiples of 1000. - Remove DvcEnterCritical and DvcLeaveCritical. These functions are no-ops, and as the comments said, the spinlock protects the critical sections. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 213 +++++++++++------------------------------------- 1 file changed, 49 insertions(+), 164 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 60a9188..9c5d37d 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -70,9 +70,6 @@ */ #warning this driver is still not properly converted to the DMA API -/* Enable driver assertions. */ -#define ADVANSYS_ASSERT - /* Enable driver /proc statistics. */ #define ADVANSYS_STATS @@ -1121,10 +1118,6 @@ static uchar AscGetChipScsiCtrl(PortAddr); static uchar AscGetChipVersion(PortAddr, ushort); static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort); static void AscToggleIRQAct(PortAddr); -static inline ulong DvcEnterCritical(void); -static inline void DvcLeaveCritical(ulong); -static void DvcSleepMilliSecond(ASC_DCNT); -static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); static void DvcGetQinfo(PortAddr, ushort, uchar *, int); static ushort AscInitAsc1000Driver(ASC_DVC_VAR *); @@ -2226,15 +2219,8 @@ typedef struct adv_scsi_req_q { #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ -/* - * Device drivers must define the following functions. - */ -static inline ulong DvcEnterCritical(void); -static inline void DvcLeaveCritical(ulong); -static void DvcSleepMilliSecond(ADV_DCNT); static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, uchar *, ASC_SDCNT *, int); -static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); /* * Adv Library functions available to drivers. @@ -2670,24 +2656,6 @@ do { \ ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len)); #endif /* ADVANSYS_DEBUG */ -#ifndef ADVANSYS_ASSERT -#define ASC_ASSERT(a) -#else /* ADVANSYS_ASSERT */ - -#define ASC_ASSERT(a) \ - { \ - if (!(a)) { \ - printk("ASC_ASSERT() Failure: file %s, line %d\n", \ - __FILE__, __LINE__); \ - } \ - } - -#endif /* ADVANSYS_ASSERT */ - -/* - * --- Driver Structures - */ - #ifdef ADVANSYS_STATS /* Per board statistics structure */ @@ -2949,7 +2917,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, if (ASC_WIDE_BOARD(boardp)) { cp = boardp->prtbuf; cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); - ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; @@ -2967,7 +2935,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ cp = boardp->prtbuf; cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); - ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -2987,7 +2955,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, } else { cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); } - ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -3003,7 +2971,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ cp = boardp->prtbuf; cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); - ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -3020,7 +2988,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, */ cp = boardp->prtbuf; cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); - ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -3042,7 +3010,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, } else { cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); } - ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); totcnt += cnt; leftlen -= cnt; @@ -3139,7 +3107,7 @@ static const char *advansys_info(struct Scsi_Host *shost) ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); } - ASC_ASSERT(strlen(info) < ASC_INFO_SIZE); + BUG_ON(strlen(info) >= ASC_INFO_SIZE); ASC_DBG(1, "advansys_info: end\n"); return info; } @@ -4201,7 +4169,6 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, * Point the previous ADV_SG_BLOCK structure to * the newly allocated ADV_SG_BLOCK structure. */ - ASC_ASSERT(prev_sg_block != NULL); prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); } @@ -4262,7 +4229,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); boardp = ASC_BOARDP(shost); - ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var); + BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); /* * 'qdonep' contains the command's ending status. @@ -4408,7 +4375,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); boardp = ASC_BOARDP(shost); - ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var); + BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); /* * 'done_status' contains the command's ending status. @@ -5738,7 +5705,7 @@ static int asc_prt_line(char *buf, int buflen, char *fmt, ...) va_start(args, fmt); ret = vsprintf(s, fmt, args); - ASC_ASSERT(ret < ASC_PRTLINE_SIZE); + BUG_ON(ret >= ASC_PRTLINE_SIZE); if (buf == NULL) { (void)printk(s); ret = 0; @@ -5756,36 +5723,6 @@ static int asc_prt_line(char *buf, int buflen, char *fmt, ...) */ /* - * Delay for 'n' milliseconds. Don't use the 'jiffies' - * global variable which is incremented once every 5 ms - * from a timer interrupt, because this function may be - * called when interrupts are disabled. - */ -static void DvcSleepMilliSecond(ADV_DCNT n) -{ - ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n); - mdelay(n); -} - -/* - * Currently and inline noop but leave as a placeholder. - * Leave DvcEnterCritical() as a noop placeholder. - */ -static inline ulong DvcEnterCritical(void) -{ - return 0; -} - -/* - * Critical sections are all protected by the board spinlock. - * Leave DvcLeaveCritical() as a noop placeholder. - */ -static inline void DvcLeaveCritical(ulong flags) -{ - return; -} - -/* * void * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) * @@ -6317,10 +6254,9 @@ static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) (ulong)b, sgblockno); printk(" sg_cnt %u, sg_ptr 0x%lx\n", b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); - ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK); - if (b->sg_ptr != 0) { - ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK); - } + BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); + if (b->sg_ptr != 0) + BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); for (i = 0; i < b->sg_cnt; i++) { printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", i, (ulong)b->sg_list[i].sg_addr, @@ -6590,7 +6526,7 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) uchar scsi_status; asc_board_t *boardp; - ASC_ASSERT(asc_dvc->drv_ptr != NULL); + BUG_ON(!asc_dvc->drv_ptr); boardp = asc_dvc->drv_ptr; iop_base = asc_dvc->iop_base; @@ -7199,7 +7135,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) AscSetChipControl(iop_base, (uchar)(CC_SCSI_RESET | CC_HALT)); - DvcDelayNanoSecond(asc_dvc, 60000); + udelay(60); AscSetChipControl(iop_base, CC_HALT); AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); @@ -7276,7 +7212,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) saved_ctrl_reg &= (uchar)(~CC_HALT); while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { - DvcSleepMilliSecond(100); + mdelay(100); } AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); AscSetChipControl(iop_base, CC_HALT); @@ -7549,7 +7485,6 @@ static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) { PortAddr iop_base; - ulong last_int_level; int sta; int n_q_required; int disable_syn_offset_one_fix; @@ -7593,9 +7528,7 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); } } - last_int_level = DvcEnterCritical(); if (asc_dvc->in_critical_cnt != 0) { - DvcLeaveCritical(last_int_level); AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); return (ERR); } @@ -7603,13 +7536,11 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { asc_dvc->in_critical_cnt--; - DvcLeaveCritical(last_int_level); return (ERR); } #if !CC_VERY_LONG_SG_LIST if (sg_entry_cnt > ASC_MAX_SG_LIST) { asc_dvc->in_critical_cnt--; - DvcLeaveCritical(last_int_level); return (ERR); } #endif /* !CC_VERY_LONG_SG_LIST */ @@ -7724,7 +7655,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) AscSendScsiQueue(asc_dvc, scsiq, n_q_required)) == 1) { asc_dvc->in_critical_cnt--; - DvcLeaveCritical(last_int_level); return (sta); } } @@ -7769,13 +7699,11 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) if ((sta = AscSendScsiQueue(asc_dvc, scsiq, n_q_required)) == 1) { asc_dvc->in_critical_cnt--; - DvcLeaveCritical(last_int_level); return (sta); } } } asc_dvc->in_critical_cnt--; - DvcLeaveCritical(last_int_level); return (sta); } @@ -8308,7 +8236,7 @@ static int AscHostReqRiscHalt(PortAddr iop_base) sta = 1; break; } - DvcSleepMilliSecond(100); + mdelay(100); } while (count++ < 20); AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); return (sta); @@ -8326,22 +8254,12 @@ static int AscStopQueueExe(PortAddr iop_base) ASC_STOP_ACK_RISC_STOP) { return (1); } - DvcSleepMilliSecond(100); + mdelay(100); } while (count++ < 20); } return (0); } -static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec) -{ - udelay(micro_sec); -} - -static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec) -{ - udelay((nano_sec + 999) / 1000); -} - static int AscStartChip(PortAddr iop_base) { AscSetChipControl(iop_base, 0); @@ -8460,16 +8378,16 @@ static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) iop_base = asc_dvc->iop_base; while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { - DvcSleepMilliSecond(100); + mdelay(100); } AscStopChip(iop_base); AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); - DvcDelayNanoSecond(asc_dvc, 60000); + udelay(60); AscSetChipIH(iop_base, INS_RFLAG_WTM); AscSetChipIH(iop_base, INS_HALT); AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); AscSetChipControl(iop_base, CC_HALT); - DvcSleepMilliSecond(200); + mdelay(200); AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); AscSetChipStatus(iop_base, 0); return (AscIsChipHalted(iop_base)); @@ -8711,8 +8629,7 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { AscResetChipAndScsiBus(asc_dvc); - DvcSleepMilliSecond((ASC_DCNT) - ((ushort)asc_dvc->scsi_reset_wait * 1000)); + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ } asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; if (asc_dvc->err_code != 0) @@ -8869,8 +8786,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) (AscGetChipScsiCtrl(iop_base) != 0)) { asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; AscResetChipAndScsiBus(asc_dvc); - DvcSleepMilliSecond((ASC_DCNT) - ((ushort)asc_dvc->scsi_reset_wait * 1000)); + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ } if (AscIsChipHalted(iop_base) == FALSE) { asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; @@ -9084,7 +9000,7 @@ static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) saved_word = AscReadLramWord(iop_base, q_addr); AscSetChipLramAddr(iop_base, q_addr); AscSetChipLramData(iop_base, 0x55AA); - DvcSleepMilliSecond(10); + mdelay(10); AscSetChipLramAddr(iop_base, q_addr); if (AscGetChipLramData(iop_base) == 0x55AA) { sta = 1; @@ -9101,7 +9017,7 @@ static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) retry = 0; while (TRUE) { AscSetChipEEPCmd(iop_base, cmd_reg); - DvcSleepMilliSecond(1); + mdelay(1); read_back = AscGetChipEEPCmd(iop_base); if (read_back == cmd_reg) { return (1); @@ -9120,7 +9036,7 @@ static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) retry = 0; while (TRUE) { AscSetChipEEPData(iop_base, data_reg); - DvcSleepMilliSecond(1); + mdelay(1); read_back = AscGetChipEEPData(iop_base); if (read_back == data_reg) { return (1); @@ -9133,13 +9049,13 @@ static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) static void __devinit AscWaitEEPRead(void) { - DvcSleepMilliSecond(1); + mdelay(1); return; } static void __devinit AscWaitEEPWrite(void) { - DvcSleepMilliSecond(20); + mdelay(20); return; } @@ -11364,7 +11280,7 @@ AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp) */ AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); - DvcSleepMilliSecond(100); + mdelay(100); AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG); @@ -12048,7 +11964,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) */ for (i = 0; i < 2; i++) { AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + mdelay(10); /* Wait for 10ms before reading back. */ byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { @@ -12057,7 +11973,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) } AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + mdelay(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; @@ -12073,7 +11989,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) * err_code, and return an error. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ + mdelay(10); /* Wait for 10ms before checking status. */ byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { @@ -12529,7 +12445,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) */ for (i = 0; i < 2; i++) { AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + mdelay(10); /* Wait for 10ms before reading back. */ byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { @@ -12538,7 +12454,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) } AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + mdelay(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; @@ -12554,7 +12470,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) * err_code, and return an error. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); - DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ + mdelay(10); /* Wait for 10ms before checking status. */ byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { @@ -13645,12 +13561,11 @@ static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base) ASC_EEP_CMD_DONE) { break; } - DvcSleepMilliSecond(1); + mdelay(1); } if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == - 0) { - ASC_ASSERT(0); - } + 0) + BUG(); return; } @@ -13688,7 +13603,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iop_base); - DvcSleepMilliSecond(ADV_EEP_DELAY_MS); + mdelay(ADV_EEP_DELAY_MS); } /* @@ -13756,7 +13671,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iop_base); - DvcSleepMilliSecond(ADV_EEP_DELAY_MS); + mdelay(ADV_EEP_DELAY_MS); } /* @@ -13824,7 +13739,7 @@ AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iop_base); - DvcSleepMilliSecond(ADV_EEP_DELAY_MS); + mdelay(ADV_EEP_DELAY_MS); } /* @@ -13882,14 +13797,11 @@ AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) */ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) { - ulong last_int_level; AdvPortAddr iop_base; ADV_DCNT req_size; ADV_PADDR req_paddr; ADV_CARR_T *new_carrp; - ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */ - /* * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. */ @@ -13901,14 +13813,11 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) iop_base = asc_dvc->iop_base; - last_int_level = DvcEnterCritical(); - /* * Allocate a carrier ensuring at least one carrier always * remains on the freelist and initialize fields. */ if ((new_carrp = asc_dvc->carr_freelist) == NULL) { - DvcLeaveCritical(last_int_level); return ADV_BUSY; } asc_dvc->carr_freelist = (ADV_CARR_T *) @@ -13931,8 +13840,8 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq, (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG); - ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr); - ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q)); + BUG_ON(req_paddr & 31); + BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q)); /* Wait for assertion before making little-endian */ req_paddr = cpu_to_le32(req_paddr); @@ -13991,8 +13900,6 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) le32_to_cpu(new_carrp->carr_pa)); } - DvcLeaveCritical(last_int_level); - return ADV_SUCCESS; } @@ -14024,7 +13931,7 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc) * The hold time delay is done on the host because the RISC has no * microsecond accurate timer. */ - DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US); + udelay(ASC_SCSI_RESET_HOLD_TIME_US); /* * Send the SCSI Bus Reset end idle command which de-asserts @@ -14035,7 +13942,7 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc) return status; } - DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000); + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ return status; } @@ -14086,7 +13993,7 @@ static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) */ AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); - DvcSleepMilliSecond(100); + mdelay(100); AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG); @@ -14158,11 +14065,8 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) ushort target_bit; ADV_CARR_T *free_carrp; ADV_VADDR irq_next_vpa; - int flags; ADV_SCSI_REQ_Q *scsiq; - flags = DvcEnterCritical(); - iop_base = asc_dvc->iop_base; /* Reading the register clears the interrupt. */ @@ -14170,7 +14074,6 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | ADV_INTR_STATUS_INTRC)) == 0) { - DvcLeaveCritical(flags); return ADV_FALSE; } @@ -14243,7 +14146,6 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) asc_dvc->carr_freelist = free_carrp; asc_dvc->carr_pending_cnt--; - ASC_ASSERT(scsiq != NULL); target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); /* @@ -14264,18 +14166,7 @@ static int AdvISR(ADV_DVC_VAR *asc_dvc) * Fall through and continue processing other completed * requests... */ - - /* - * Disable interrupts again in case the driver inadvertently - * enabled interrupts in its callback function. - * - * The DvcEnterCritical() return value is ignored, because - * the 'flags' saved when AdvISR() was first entered will be - * used to restore the interrupt flag on exit. - */ - (void)DvcEnterCritical(); } - DvcLeaveCritical(flags); return ADV_TRUE; } @@ -14297,13 +14188,10 @@ static int AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, ushort idle_cmd, ADV_DCNT idle_cmd_parameter) { - ulong last_int_level; int result; ADV_DCNT i, j; AdvPortAddr iop_base; - last_int_level = DvcEnterCritical(); - iop_base = asc_dvc->iop_base; /* @@ -14343,16 +14231,13 @@ AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, for (j = 0; j < SCSI_US_PER_MSEC; j++) { AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result); - if (result != 0) { - DvcLeaveCritical(last_int_level); + if (result != 0) return result; - } - DvcDelayMicroSecond(asc_dvc, (ushort)1); + udelay(1); } } - ASC_ASSERT(0); /* The idle command should never timeout. */ - DvcLeaveCritical(last_int_level); + BUG(); /* The idle command should never timeout. */ return ADV_ERROR; } -- cgit v1.1 From 95c9f16284960f579205d7da8b5d90e2f3bf44a7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:39 -0600 Subject: [SCSI] advansys: Comment/indentation/macro cleanup - Delete comments relating to the previous structure of the driver. I have no intention of honouring them ;-) - Reformat comments > 80 columns - Remove now-obsolete comments from advansys_interrupt - Change adv_get_sglist() from do {} while (1) to for (;;) - Return void from AscInitQLinkVar() - Take out a level of indentation in adv_get_sglist() - Reduce indentation level of AscAsyncFix() - Remove unused macros - Refactor AscSendScsiQueue slightly Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 379 +++++++++++++----------------------------------- 1 file changed, 101 insertions(+), 278 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 9c5d37d..e5b26a1 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -76,10 +76,6 @@ /* Enable driver tracing. */ /* #define ADVANSYS_DEBUG */ -/* - * --- Asc Library Constants and Macros - */ - #define ASC_LIB_VERSION_MAJOR 1 #define ASC_LIB_VERSION_MINOR 24 #define ASC_LIB_SERIAL_NUMBER 123 @@ -118,15 +114,10 @@ typedef unsigned char uchar; #define FALSE (0) #endif -#define EOF (-1) #define ERR (-1) #define UW_ERR (uint)(0xFFFF) #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) -#define ASC_DVCLIB_CALL_DONE (1) -#define ASC_DVCLIB_CALL_FAILED (0) -#define ASC_DVCLIB_CALL_ERROR (-1) - #define PCI_VENDOR_ID_ASP 0x10cd #define PCI_DEVICE_ID_ASP_1200A 0x1100 #define PCI_DEVICE_ID_ASP_ABP940 0x1200 @@ -164,11 +155,10 @@ typedef unsigned char uchar; #define ASC_IS_PCMCIA (0x0008) #define ASC_IS_MCA (0x0020) #define ASC_IS_VL (0x0040) -#define ASC_ISA_PNP_PORT_ADDR (0x279) -#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800) #define ASC_IS_WIDESCSI_16 (0x0100) #define ASC_IS_WIDESCSI_32 (0x0200) #define ASC_IS_BIG_ENDIAN (0x8000) + #define ASC_CHIP_MIN_VER_VL (0x01) #define ASC_CHIP_MAX_VER_VL (0x07) #define ASC_CHIP_MIN_VER_PCI (0x09) @@ -187,16 +177,9 @@ typedef unsigned char uchar; #define ASC_CHIP_MAX_VER_EISA (0x47) #define ASC_CHIP_VER_EISA_BIT (0x40) #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3) -#define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21 -#define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A -#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL) #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL) -#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL) #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL) -#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL) #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL) -#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL) -#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL) #define ASC_SCSI_ID_BITS 3 #define ASC_SCSI_TIX_TYPE uchar @@ -216,24 +199,6 @@ typedef unsigned char uchar; #define ASC_MAX_CDB_LEN 12 #define ADV_MAX_CDB_LEN 16 -/* - * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data) - * and CmdDt (Command Support Data) field bit definitions. - */ -#define ADV_INQ_RTN_VPD_AND_CMDDT 0x3 -#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2 -#define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1 -#define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0 - -#define ASC_SCSIDIR_NOCHK 0x00 -#define ASC_SCSIDIR_T2H 0x08 -#define ASC_SCSIDIR_H2T 0x10 -#define ASC_SCSIDIR_NODATA 0x18 -#define SCSI_ASC_NOMEDIA 0x3A -#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4)) -#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) -#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) -#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) #define MS_SDTR_LEN 0x03 #define MS_WDTR_LEN 0x02 @@ -417,19 +382,6 @@ typedef struct asc_sg_head { ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; } ASC_SG_HEAD; -#define ASC_MIN_SG_LIST 2 - -typedef struct asc_min_sg_head { - ushort entry_cnt; - ushort queue_cnt; - ushort entry_to_copy; - ushort res; - ASC_SG_LIST sg_list[ASC_MIN_SG_LIST]; -} ASC_MIN_SG_HEAD; - -#define QCX_SORT (0x0001) -#define QCX_COALEASE (0x0002) - typedef struct asc_scsi_q { ASC_SCSIQ_1 q1; ASC_SCSIQ_2 q2; @@ -486,34 +438,9 @@ typedef struct asc_risc_sg_list_q { ASC_SG_LIST sg_list[7]; } ASC_RISC_SG_LIST_Q; -#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL -#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024 -#define ASCQ_ERR_NO_ERROR 0 -#define ASCQ_ERR_IO_NOT_FOUND 1 -#define ASCQ_ERR_LOCAL_MEM 2 -#define ASCQ_ERR_CHKSUM 3 -#define ASCQ_ERR_START_CHIP 4 -#define ASCQ_ERR_INT_TARGET_ID 5 -#define ASCQ_ERR_INT_LOCAL_MEM 6 -#define ASCQ_ERR_HALT_RISC 7 -#define ASCQ_ERR_GET_ASPI_ENTRY 8 -#define ASCQ_ERR_CLOSE_ASPI 9 -#define ASCQ_ERR_HOST_INQUIRY 0x0A -#define ASCQ_ERR_SAVED_SRB_BAD 0x0B -#define ASCQ_ERR_QCNTL_SG_LIST 0x0C #define ASCQ_ERR_Q_STATUS 0x0D -#define ASCQ_ERR_WR_SCSIQ 0x0E -#define ASCQ_ERR_PC_ADDR 0x0F -#define ASCQ_ERR_SYN_OFFSET 0x10 -#define ASCQ_ERR_SYN_XFER_TIME 0x11 -#define ASCQ_ERR_LOCK_DMA 0x12 -#define ASCQ_ERR_UNLOCK_DMA 0x13 -#define ASCQ_ERR_VDS_CHK_INSTALL 0x14 -#define ASCQ_ERR_MICRO_CODE_HALT 0x15 -#define ASCQ_ERR_SET_LRAM_ADDR 0x16 #define ASCQ_ERR_CUR_QNG 0x17 #define ASCQ_ERR_SG_Q_LINKS 0x18 -#define ASCQ_ERR_SCSIQ_PTR 0x19 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C @@ -529,7 +456,6 @@ typedef struct asc_risc_sg_list_q { #define ASC_WARN_CMD_QNG_CONFLICT 0x0010 #define ASC_WARN_EEPROM_RECOVER 0x0020 #define ASC_WARN_CFG_MSW_RECOVER 0x0040 -#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* * Error code values are set in ASC_DVC_VAR 'err_code'. @@ -549,27 +475,21 @@ typedef struct asc_risc_sg_list_q { #define ASC_IERR_SET_SDTR 0x1000 #define ASC_IERR_RW_LRAM 0x8000 -#define ASC_DEF_IRQ_NO 10 #define ASC_MAX_IRQ_NO 15 #define ASC_MIN_IRQ_NO 10 -#define ASC_MIN_REMAIN_Q (0x02) #define ASC_DEF_MAX_TOTAL_QNG (0xF0) #define ASC_MIN_TAG_Q_PER_DVC (0x04) -#define ASC_DEF_TAG_Q_PER_DVC (0x04) -#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q +#define ASC_MIN_FREE_Q (0x02) #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q)) #define ASC_MAX_TOTAL_QNG 240 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 #define ASC_MAX_INRAM_TAG_QNG 16 -#define ASC_IOADR_TABLE_MAX_IX 11 #define ASC_IOADR_GAP 0x10 -#define ASC_LIB_SCSIQ_WK_SP 256 #define ASC_MAX_SYN_XFER_NO 16 #define ASC_SYN_MAX_OFFSET 0x0F #define ASC_DEF_SDTR_OFFSET 0x0F -#define ASC_DEF_SDTR_INDEX 0x00 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 #define SYN_XFER_NS_0 25 #define SYN_XFER_NS_1 30 @@ -648,7 +568,6 @@ typedef struct asc_dvc_cfg { #define ASC_DEF_DVC_CNTL 0xFFFF #define ASC_DEF_CHIP_SCSI_ID 7 #define ASC_DEF_ISA_DMA_SPEED 4 -#define ASC_INIT_STATE_NULL 0x0000 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001 #define ASC_INIT_STATE_END_GET_CFG 0x0002 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004 @@ -740,12 +659,7 @@ typedef struct asc_cap_info_array { #define ASC_EEP_MAX_DVC_ADDR_VL 15 #define ASC_EEP_DVC_CFG_BEG 32 #define ASC_EEP_MAX_DVC_ADDR 45 -#define ASC_EEP_DEFINED_WORDS 10 -#define ASC_EEP_MAX_ADDR 63 -#define ASC_EEP_RES_WORDS 0 #define ASC_EEP_MAX_RETRY 20 -#define ASC_MAX_INIT_BUSY_RETRY 8 -#define ASC_EEP_ISA_PNP_WSIZE 16 /* * These macros keep the chip SCSI id and ISA DMA speed @@ -781,17 +695,11 @@ typedef struct asceep_config { ushort chksum; } ASCEEP_CONFIG; -#define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800 -#define ASC_PCI_CFG_LSW_BURST_MODE 0x0080 -#define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020 - #define ASC_EEP_CMD_READ 0x80 #define ASC_EEP_CMD_WRITE 0x40 #define ASC_EEP_CMD_WRITE_ABLE 0x30 #define ASC_EEP_CMD_WRITE_DISABLE 0x00 #define ASC_OVERRUN_BSIZE 0x00000048UL -#define ASC_CTRL_BREAK_ONCE 0x0001 -#define ASC_CTRL_BREAK_STAY_IDLE 0x0002 #define ASCV_MSGOUT_BEG 0x0000 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) @@ -1105,7 +1013,6 @@ static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar); static int AscSetChipSynRegAtID(PortAddr, uchar, uchar); static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar); static ushort AscInitLram(ASC_DVC_VAR *); -static ushort AscInitQLinkVar(ASC_DVC_VAR *); static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort); static int AscIsrChipHalted(ASC_DVC_VAR *); static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, @@ -1131,10 +1038,6 @@ static void AscEnableIsaDma(uchar); #endif /* CONFIG_ISA */ static const char *advansys_info(struct Scsi_Host *shost); -/* - * --- Adv Library Constants and Macros - */ - #define ADV_LIB_VERSION_MAJOR 5 #define ADV_LIB_VERSION_MINOR 14 @@ -1515,10 +1418,6 @@ typedef struct adveep_38C1600_config { * EEPROM Commands */ #define ASC_EEP_CMD_DONE 0x0200 -#define ASC_EEP_CMD_DONE_ERR 0x0001 - -/* cfg_word */ -#define EEP_CFG_WORD_BIG_ENDIAN 0x8000 /* bios_ctrl */ #define BIOS_CTRL_BIOS 0x0001 @@ -1675,8 +1574,6 @@ typedef struct adveep_38C1600_config { #define ADV_CHIP_ID_BYTE 0x25 #define ADV_CHIP_ID_WORD 0x04C1 -#define ADV_SC_SCSI_BUS_RESET 0x2000 - #define ADV_INTR_ENABLE_HOST_INTR 0x01 #define ADV_INTR_ENABLE_SEL_INTR 0x02 #define ADV_INTR_ENABLE_DPR_INTR 0x04 @@ -1716,8 +1613,6 @@ typedef struct adveep_38C1600_config { #define ADV_TICKLE_B 0x02 #define ADV_TICKLE_C 0x03 -#define ADV_SCSI_CTRL_RSTOUT 0x2000 - #define AdvIsIntPending(port) \ (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR) @@ -1870,14 +1765,11 @@ typedef struct adveep_38C1600_config { */ #define INTAB 0x01 -/* a_advlib.h */ - /* * Adv Library Status Definitions */ #define ADV_TRUE 1 #define ADV_FALSE 0 -#define ADV_NOERROR 1 #define ADV_SUCCESS 1 #define ADV_BUSY 0 #define ADV_ERROR (-1) @@ -1888,7 +1780,6 @@ typedef struct adveep_38C1600_config { #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */ #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ -#define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */ #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */ #define ADV_MAX_TID 15 /* max. target identifier */ @@ -2206,10 +2097,8 @@ typedef struct adv_scsi_req_q { /* * Wait loop time out values. */ -#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */ #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */ #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */ -#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */ #define SCSI_MAX_RETRY 10 /* retry count */ #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */ @@ -2443,10 +2332,6 @@ do { \ (sizeof(ADV_SG_BLOCK) * \ ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) -/* - * --- Driver Constants and Macros - */ - /* Reference Scsi_Host hostdata */ #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) @@ -2792,10 +2677,6 @@ static ASC_SG_HEAD asc_sg_head = { 0 }; static int asc_dbglvl = 3; #endif /* ADVANSYS_DEBUG */ -/* - * --- Driver Function Prototypes - */ - static int advansys_slave_configure(struct scsi_device *); static int asc_execute_scsi_cmnd(struct scsi_cmnd *); static int asc_build_req(asc_board_t *, struct scsi_cmnd *); @@ -3359,17 +3240,9 @@ static struct scsi_host_template advansys_template = { }; /* - * --- Miscellaneous Driver Functions - */ - -/* * First-level interrupt handler. * - * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because - * all boards are currently checked for interrupts on each interrupt, 'dev_id' - * is not referenced. 'dev_id' could be used to identify an interrupt passed - * to the AdvanSys driver which is for a device sharing an interrupt with - * an AdvanSys adapter. + * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host. */ static irqreturn_t advansys_interrupt(int irq, void *dev_id) { @@ -3381,9 +3254,6 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); spin_lock_irqsave(&boardp->lock, flags); if (ASC_NARROW_BOARD(boardp)) { - /* - * Narrow Board - */ if (AscIsIntPending(shost->io_port)) { result = IRQ_HANDLED; ASC_STATS(shost, interrupt); @@ -3391,23 +3261,14 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) AscISR(&boardp->dvc_var.asc_dvc_var); } } else { - /* - * Wide Board - */ ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { result = IRQ_HANDLED; ASC_STATS(shost, interrupt); } } - spin_unlock_irqrestore(&boardp->lock, flags); - /* - * If interrupts were enabled on entry, then they - * are now enabled here. - */ - ASC_DBG(1, "advansys_interrupt: end\n"); return result; } @@ -4110,7 +3971,7 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, prev_sg_block = NULL; reqp->sgblkp = NULL; - do { + for (;;) { /* * Allocate a 'adv_sgblk_t' structure from the board free * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK @@ -4121,8 +3982,8 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, ASC_STATS(scp->device->host, adv_build_nosg); /* - * Allocation failed. Free 'adv_sgblk_t' structures already - * allocated for the request. + * Allocation failed. Free 'adv_sgblk_t' structures + * already allocated for the request. */ while ((sgblkp = reqp->sgblkp) != NULL) { /* Remove 'sgblkp' from the request list. */ @@ -4133,52 +3994,50 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, boardp->adv_sgblkp = sgblkp; } return ASC_BUSY; - } else { - /* Complete 'adv_sgblk_t' board allocation. */ - boardp->adv_sgblkp = sgblkp->next_sgblkp; - sgblkp->next_sgblkp = NULL; + } + + /* Complete 'adv_sgblk_t' board allocation. */ + boardp->adv_sgblkp = sgblkp->next_sgblkp; + sgblkp->next_sgblkp = NULL; + + /* + * Get 8 byte aligned virtual and physical addresses + * for the allocated ADV_SG_BLOCK structure. + */ + sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); + sg_block_paddr = virt_to_bus(sg_block); + + /* + * Check if this is the first 'adv_sgblk_t' for the + * request. + */ + if (reqp->sgblkp == NULL) { + /* Request's first scatter-gather block. */ + reqp->sgblkp = sgblkp; /* - * Get 8 byte aligned virtual and physical addresses for - * the allocated ADV_SG_BLOCK structure. + * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical + * address pointers. */ - sg_block = - (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); - sg_block_paddr = virt_to_bus(sg_block); + scsiqp->sg_list_ptr = sg_block; + scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr); + } else { + /* Request's second or later scatter-gather block. */ + sgblkp->next_sgblkp = reqp->sgblkp; + reqp->sgblkp = sgblkp; /* - * Check if this is the first 'adv_sgblk_t' for the request. + * Point the previous ADV_SG_BLOCK structure to + * the newly allocated ADV_SG_BLOCK structure. */ - if (reqp->sgblkp == NULL) { - /* Request's first scatter-gather block. */ - reqp->sgblkp = sgblkp; - - /* - * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical - * address pointers. - */ - scsiqp->sg_list_ptr = sg_block; - scsiqp->sg_real_addr = - cpu_to_le32(sg_block_paddr); - } else { - /* Request's second or later scatter-gather block. */ - sgblkp->next_sgblkp = reqp->sgblkp; - reqp->sgblkp = sgblkp; - - /* - * Point the previous ADV_SG_BLOCK structure to - * the newly allocated ADV_SG_BLOCK structure. - */ - prev_sg_block->sg_ptr = - cpu_to_le32(sg_block_paddr); - } + prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); } for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { sg_block->sg_list[i].sg_addr = - cpu_to_le32(sg_dma_address(slp)); + cpu_to_le32(sg_dma_address(slp)); sg_block->sg_list[i].sg_count = - cpu_to_le32(sg_dma_len(slp)); + cpu_to_le32(sg_dma_len(slp)); ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); @@ -4192,8 +4051,6 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; prev_sg_block = sg_block; } - while (1); - /* NOTREACHED */ } /* @@ -4264,14 +4121,16 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* - * Note: The 'status_byte()' macro used by target drivers - * defined in scsi.h shifts the status byte returned by - * host drivers right by 1 bit. This is why target drivers - * also use right shifted status byte definitions. For - * instance target drivers use CHECK_CONDITION, defined to - * 0x1, instead of the SCSI defined check condition value - * of 0x2. Host drivers are supposed to return the status - * byte as it is defined by SCSI. + * Note: The 'status_byte()' macro used by + * target drivers defined in scsi.h shifts the + * status byte returned by host drivers right + * by 1 bit. This is why target drivers also + * use right shifted status byte definitions. + * For instance target drivers use + * CHECK_CONDITION, defined to 0x1, instead of + * the SCSI defined check condition value of + * 0x2. Host drivers are supposed to return + * the status byte as it is defined by SCSI. */ scp->result = DRIVER_BYTE(DRIVER_SENSE) | STATUS_BYTE(qdonep->d3.scsi_stat); @@ -4411,14 +4270,16 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* - * Note: The 'status_byte()' macro used by target drivers - * defined in scsi.h shifts the status byte returned by - * host drivers right by 1 bit. This is why target drivers - * also use right shifted status byte definitions. For - * instance target drivers use CHECK_CONDITION, defined to - * 0x1, instead of the SCSI defined check condition value - * of 0x2. Host drivers are supposed to return the status - * byte as it is defined by SCSI. + * Note: The 'status_byte()' macro used by + * target drivers defined in scsi.h shifts the + * status byte returned by host drivers right + * by 1 bit. This is why target drivers also + * use right shifted status byte definitions. + * For instance target drivers use + * CHECK_CONDITION, defined to 0x1, instead of + * the SCSI defined check condition value of + * 0x2. Host drivers are supposed to return + * the status byte as it is defined by SCSI. */ scp->result = DRIVER_BYTE(DRIVER_SENSE) | STATUS_BYTE(scsiqp->scsi_status); @@ -5719,10 +5580,6 @@ static int asc_prt_line(char *buf, int buflen, char *fmt, ...) #endif /* CONFIG_PROC_FS */ /* - * --- Functions Required by the Asc Library - */ - -/* * void * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) * @@ -5815,10 +5672,6 @@ AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type) } /* - * --- Functions Required by the Adv Library - */ - -/* * DvcGetPhyAddr() * * Return the physical address of 'vaddr' and set '*lenp' to the @@ -5845,10 +5698,6 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, return paddr; } -/* - * --- Tracing and Debugging Functions - */ - #ifdef ADVANSYS_STATS #ifdef CONFIG_PROC_FS /* @@ -6322,10 +6171,6 @@ static void asc_prt_hex(char *f, uchar *s, int l) } #endif /* ADVANSYS_DEBUG */ -/* - * --- Asc Library Functions - */ - static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base) { PortAddr eisa_cfg_iop; @@ -6537,8 +6382,7 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) target_ix = AscReadLramByte(iop_base, (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_TARGET_IX)); - q_cntl = - AscReadLramByte(iop_base, + q_cntl = AscReadLramByte(iop_base, (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL)); tid_no = ASC_TIX_TO_TID(target_ix); target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no); @@ -6562,7 +6406,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); return (0); } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { - AscMemWordCopyPtrFromLram(iop_base, ASCV_MSGIN_BEG, (uchar *)&ext_msg, @@ -6793,9 +6636,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) cur_dvc_qng); /* - * Set the device queue depth to the number of - * active requests when the QUEUE FULL condition - * was encountered. + * Set the device queue depth to the + * number of active requests when the + * QUEUE FULL condition was encountered. */ boardp->queue_full |= target_id; boardp->queue_full_cnt[tid_no] = @@ -6821,9 +6664,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) int i; q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP); - if (q_no == ASC_QLINK_END) { - return (0); - } + if (q_no == ASC_QLINK_END) + return 0; q_addr = ASC_QNO_TO_QADDR(q_no); @@ -6875,8 +6717,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) sg_entry_cnt = ASC_MAX_SG_LIST - 1; /* - * Keep track of remaining number of SG elements that will - * need to be handled on the next interrupt. + * Keep track of remaining number of SG elements that + * will need to be handled on the next interrupt. */ scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); } else { @@ -7723,36 +7565,28 @@ AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required) sta = 0; free_q_head = (uchar)AscGetVarFreeQHead(iop_base); if (n_q_required > 1) { - if ((next_qp = AscAllocMultipleFreeQueue(iop_base, - free_q_head, (uchar) - (n_q_required))) - != (uchar)ASC_QLINK_END) { + next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head, + (uchar)n_q_required); + if (next_qp != ASC_QLINK_END) { asc_dvc->last_q_shortage = 0; scsiq->sg_head->queue_cnt = n_q_required - 1; scsiq->q1.q_no = free_q_head; - if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq, - free_q_head)) == 1) { - AscPutVarFreeQHead(iop_base, next_qp); - asc_dvc->cur_total_qng += (uchar)(n_q_required); - asc_dvc->cur_dvc_qng[tid_no]++; - } - return (sta); + sta = AscPutReadySgListQueue(asc_dvc, scsiq, + free_q_head); } } else if (n_q_required == 1) { - if ((next_qp = AscAllocFreeQueue(iop_base, - free_q_head)) != - ASC_QLINK_END) { + next_qp = AscAllocFreeQueue(iop_base, free_q_head); + if (next_qp != ASC_QLINK_END) { scsiq->q1.q_no = free_q_head; - if ((sta = AscPutReadyQueue(asc_dvc, scsiq, - free_q_head)) == 1) { - AscPutVarFreeQHead(iop_base, next_qp); - asc_dvc->cur_total_qng++; - asc_dvc->cur_dvc_qng[tid_no]++; - } - return (sta); + sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head); } } - return (sta); + if (sta == 1) { + AscPutVarFreeQHead(iop_base, next_qp); + asc_dvc->cur_total_qng += (uchar)(n_q_required); + asc_dvc->cur_dvc_qng[tid_no]++; + } + return sta; } static int AscSgListToQueue(int sg_list) @@ -8072,7 +7906,7 @@ static ushort AscInitLram(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) +static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) { PortAddr iop_base; int i; @@ -8099,7 +7933,6 @@ static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) for (i = 0; i < 32; i++, lram_addr += 2) { AscWriteLramWord(iop_base, lram_addr, 0); } - return (0); } static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code) @@ -8396,10 +8229,10 @@ static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type) { if (bus_type & ASC_IS_ISA) - return (ASC_MAX_ISA_DMA_COUNT); + return ASC_MAX_ISA_DMA_COUNT; else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) - return (ASC_MAX_VL_DMA_COUNT); - return (ASC_MAX_PCI_DMA_COUNT); + return ASC_MAX_VL_DMA_COUNT; + return ASC_MAX_PCI_DMA_COUNT; } #ifdef CONFIG_ISA @@ -9262,26 +9095,22 @@ static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev) char type = sdev->type; ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id; - if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) { - if (!(asc_dvc->init_sdtr & tid_bits)) { - if ((type == TYPE_ROM) && - (strncmp(sdev->vendor, "HP ", 3) == 0)) { - asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; - } - asc_dvc->pci_fix_asyn_xfer |= tid_bits; - if ((type == TYPE_PROCESSOR) || - (type == TYPE_SCANNER) || (type == TYPE_ROM) || - (type == TYPE_TAPE)) { - asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; - } + if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)) + return; + if (asc_dvc->init_sdtr & tid_bits) + return; + + if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0)) + asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; + + asc_dvc->pci_fix_asyn_xfer |= tid_bits; + if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) || + (type == TYPE_ROM) || (type == TYPE_TAPE)) + asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; - if (asc_dvc->pci_fix_asyn_xfer & tid_bits) { - AscSetRunChipSynRegAtID(asc_dvc->iop_base, - sdev->id, + if (asc_dvc->pci_fix_asyn_xfer & tid_bits) + AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id, ASYN_SDTR_DATA_FIX_PCI_REV_AB); - } - } - } } static uchar AscReadLramByte(PortAddr iop_base, ushort addr) @@ -9443,12 +9272,6 @@ AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) return; } -/* - * --- Adv Library Functions - */ - -/* a_mcode.h */ - /* Microcode buffer is kept after initialization for error recovery. */ static unsigned char _adv_asc3550_buf[] = { 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, @@ -13773,7 +13596,6 @@ AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) return; } -/* a_advlib.c */ /* * AdvExeScsiQueue() - Send a request to the RISC microcode program. * @@ -14198,7 +14020,6 @@ AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, * Clear the idle command status which is set by the microcode * to a non-zero value to indicate when the command is completed. * The non-zero result is one of the IDLE_CMD_STATUS_* values - * defined in a_advlib.h. */ AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0); @@ -14921,6 +14742,8 @@ static int advansys_release(struct Scsi_Host *shost) return 0; } +#define ASC_IOADR_TABLE_MAX_IX 11 + static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = { 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190, 0x0210, 0x0230, 0x0250, 0x0330 -- cgit v1.1 From 01fbfe0b8359695a3ff7f4b79ab1e0a777f10ae4 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 9 Sep 2007 08:56:40 -0600 Subject: [SCSI] advansys: Use DRV_NAME Follow the example of some other drivers by defining DRV_NAME to be "advansys". Prevents spelling mistakes. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e5b26a1..0303fc7 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1,3 +1,4 @@ +#define DRV_NAME "advansys" #define ASC_VERSION "3.4" /* AdvanSys Driver Version */ /* @@ -3213,11 +3214,11 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, } static struct scsi_host_template advansys_template = { - .proc_name = "advansys", + .proc_name = DRV_NAME, #ifdef CONFIG_PROC_FS .proc_info = advansys_proc_info, #endif - .name = "advansys", + .name = DRV_NAME, .info = advansys_info, .queuecommand = advansys_queuecommand, .eh_bus_reset_handler = advansys_reset, @@ -14634,7 +14635,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) /* Register DMA channel for ISA bus. */ if (asc_dvc_varp->bus_type & ASC_IS_ISA) { shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; - ret = request_dma(shost->dma_channel, "advansys"); + ret = request_dma(shost->dma_channel, DRV_NAME); if (ret) { ASC_PRINT3 ("advansys_board_found: board %d: request_dma() %d failed %d\n", @@ -14650,7 +14651,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq); ret = request_irq(shost->irq, advansys_interrupt, share_irq, - "advansys", shost); + DRV_NAME, shost); if (ret) { if (ret == -EBUSY) { @@ -14754,7 +14755,7 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) PortAddr iop_base = _asc_def_iop_base[id]; struct Scsi_Host *shost; - if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { + if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n", iop_base); return -ENODEV; @@ -14790,7 +14791,7 @@ static struct isa_driver advansys_isa_driver = { .remove = __devexit_p(advansys_isa_remove), .driver = { .owner = THIS_MODULE, - .name = "advansys", + .name = DRV_NAME, }, }; @@ -14799,7 +14800,7 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) PortAddr iop_base = _asc_def_iop_base[id]; struct Scsi_Host *shost; - if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { + if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n", iop_base); return -ENODEV; @@ -14867,7 +14868,7 @@ static int __devinit advansys_eisa_probe(struct device *dev) err = -ENODEV; for (i = 0; i < 2; i++, ioport += 0x20) { - if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) { + if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) { printk(KERN_WARNING "Region %x-%x busy\n", ioport, ioport + ASC_IOADR_GAP - 1); continue; @@ -14925,7 +14926,7 @@ static __devexit int advansys_eisa_remove(struct device *dev) static struct eisa_driver advansys_eisa_driver = { .id_table = advansys_eisa_table, .driver = { - .name = "advansys", + .name = DRV_NAME, .probe = advansys_eisa_probe, .remove = __devexit_p(advansys_eisa_remove), } @@ -14972,7 +14973,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_enable_device(pdev); if (err) goto fail; - err = pci_request_regions(pdev, "advansys"); + err = pci_request_regions(pdev, DRV_NAME); if (err) goto disable_device; pci_set_master(pdev); @@ -15007,7 +15008,7 @@ static void __devexit advansys_pci_remove(struct pci_dev *pdev) } static struct pci_driver advansys_pci_driver = { - .name = "advansys", + .name = DRV_NAME, .id_table = advansys_pci_tbl, .probe = advansys_pci_probe, .remove = __devexit_p(advansys_pci_remove), -- cgit v1.1 From bfd129445f23c037d9a440ebfa4109e11c220301 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 11 Sep 2007 17:00:14 +0200 Subject: [SCSI] switch sdev sysfs attributes to default attributes This removes the unused sysfs attribute overwriting logic for most of the attributes, and plugs them into the driver core default attribute creation. Without this patch, at the time of the events for the SCSI LUN's, there will be no sysfs files, because their creation is delayed until the sd driver has spun up the disks, which might take several seconds. It is the last WAIT_FOR_SYSFS rule in the default udev setup which can be removed with this change. Signed-off-by: Kay Sievers Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi_sysfs.c | 136 ++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 84 deletions(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a3d227f..0088c4d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -618,24 +618,31 @@ sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); /* Default template for device attributes. May NOT be modified */ -static struct device_attribute *scsi_sysfs_sdev_attrs[] = { - &dev_attr_device_blocked, - &dev_attr_queue_depth, - &dev_attr_queue_type, - &dev_attr_type, - &dev_attr_scsi_level, - &dev_attr_vendor, - &dev_attr_model, - &dev_attr_rev, - &dev_attr_rescan, - &dev_attr_delete, - &dev_attr_state, - &dev_attr_timeout, - &dev_attr_iocounterbits, - &dev_attr_iorequest_cnt, - &dev_attr_iodone_cnt, - &dev_attr_ioerr_cnt, - &dev_attr_modalias, +static struct attribute *scsi_sdev_attrs[] = { + &dev_attr_device_blocked.attr, + &dev_attr_type.attr, + &dev_attr_scsi_level.attr, + &dev_attr_vendor.attr, + &dev_attr_model.attr, + &dev_attr_rev.attr, + &dev_attr_rescan.attr, + &dev_attr_delete.attr, + &dev_attr_state.attr, + &dev_attr_timeout.attr, + &dev_attr_iocounterbits.attr, + &dev_attr_iorequest_cnt.attr, + &dev_attr_iodone_cnt.attr, + &dev_attr_ioerr_cnt.attr, + &dev_attr_modalias.attr, + NULL +}; + +static struct attribute_group scsi_sdev_attr_group = { + .attrs = scsi_sdev_attrs, +}; + +static struct attribute_group *scsi_sdev_attr_groups[] = { + &scsi_sdev_attr_group, NULL }; @@ -697,56 +704,6 @@ static struct device_attribute sdev_attr_queue_type_rw = __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, sdev_store_queue_type_rw); -static struct device_attribute *attr_changed_internally( - struct Scsi_Host *shost, - struct device_attribute * attr) -{ - if (!strcmp("queue_depth", attr->attr.name) - && shost->hostt->change_queue_depth) - return &sdev_attr_queue_depth_rw; - else if (!strcmp("queue_type", attr->attr.name) - && shost->hostt->change_queue_type) - return &sdev_attr_queue_type_rw; - return attr; -} - - -static struct device_attribute *attr_overridden( - struct device_attribute **attrs, - struct device_attribute *attr) -{ - int i; - - if (!attrs) - return NULL; - for (i = 0; attrs[i]; i++) - if (!strcmp(attrs[i]->attr.name, attr->attr.name)) - return attrs[i]; - return NULL; -} - -static int attr_add(struct device *dev, struct device_attribute *attr) -{ - struct device_attribute *base_attr; - - /* - * Spare the caller from having to copy things it's not interested in. - */ - base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr); - if (base_attr) { - /* extend permissions */ - attr->attr.mode |= base_attr->attr.mode; - - /* override null show/store with default */ - if (!attr->show) - attr->show = base_attr->show; - if (!attr->store) - attr->store = base_attr->store; - } - - return device_create_file(dev, attr); -} - /** * scsi_sysfs_add_sdev - add scsi device to sysfs * @sdev: scsi_device to add @@ -778,6 +735,24 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) * released by the sdev_class .release */ get_device(&sdev->sdev_gendev); + /* create queue files, which may be writable, depending on the host */ + if (sdev->host->hostt->change_queue_depth) + error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); + else + error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); + if (error) { + __scsi_remove_device(sdev); + goto out; + } + if (sdev->host->hostt->change_queue_type) + error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); + else + error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); + if (error) { + __scsi_remove_device(sdev); + goto out; + } + error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL); if (error) @@ -788,9 +763,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) * nothing went wrong */ error = 0; + /* add additional host specific attributes */ if (sdev->host->hostt->sdev_attrs) { for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { - error = attr_add(&sdev->sdev_gendev, + error = device_create_file(&sdev->sdev_gendev, sdev->host->hostt->sdev_attrs[i]); if (error) { __scsi_remove_device(sdev); @@ -798,20 +774,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } } } - - for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) { - if (!attr_overridden(sdev->host->hostt->sdev_attrs, - scsi_sysfs_sdev_attrs[i])) { - struct device_attribute * attr = - attr_changed_internally(sdev->host, - scsi_sysfs_sdev_attrs[i]); - error = device_create_file(&sdev->sdev_gendev, attr); - if (error) { - __scsi_remove_device(sdev); - goto out; - } - } - } transport_add_device(&sdev->sdev_gendev); out: @@ -998,6 +960,12 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost) return 0; } +static struct device_type scsi_dev_type = { + .name = "scsi_device", + .release = scsi_device_dev_release, + .groups = scsi_sdev_attr_groups, +}; + void scsi_sysfs_device_initialize(struct scsi_device *sdev) { unsigned long flags; @@ -1006,7 +974,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) device_initialize(&sdev->sdev_gendev); sdev->sdev_gendev.bus = &scsi_bus_type; - sdev->sdev_gendev.release = scsi_device_dev_release; + sdev->sdev_gendev.type = &scsi_dev_type; sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); -- cgit v1.1 From 1a4f550a09f89e3a15eff1971bc9db977571b9f6 Mon Sep 17 00:00:00 2001 From: Nick Cheng Date: Thu, 13 Sep 2007 17:26:40 +0800 Subject: [SCSI] arcmsr: 1.20.00.15: add SATA RAID plus other fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: ** support ARC1200/1201/1202 SATA RAID adapter, which is named ACB_ADAPTER_TYPE_B ** modify the arcmsr_pci_slot_reset function ** modify the arcmsr_pci_ers_disconnect_forepart function ** modify the arcmsr_pci_ers_need_reset_forepart function  Signed-off-by: Nick Cheng Signed-off-by: James Bottomley --- Documentation/scsi/ChangeLog.arcmsr | 17 +- drivers/scsi/Kconfig | 23 +- drivers/scsi/arcmsr/arcmsr.h | 192 ++- drivers/scsi/arcmsr/arcmsr_attr.c | 64 +- drivers/scsi/arcmsr/arcmsr_hba.c | 2263 +++++++++++++++++++++-------------- include/linux/pci_ids.h | 3 + 6 files changed, 1571 insertions(+), 991 deletions(-) diff --git a/Documentation/scsi/ChangeLog.arcmsr b/Documentation/scsi/ChangeLog.arcmsr index 162c47f..cd8403a 100644 --- a/Documentation/scsi/ChangeLog.arcmsr +++ b/Documentation/scsi/ChangeLog.arcmsr @@ -53,4 +53,19 @@ ** for linux standard list ** enable usage of pci message signal interrupt ** follow Randy.Danlup kindness suggestion cleanup this code -************************************************************************** \ No newline at end of file +** 1.20.00.14 05/02/2007 Erich Chen & Nick Cheng +** 1.implement PCI-Express error recovery function and AER capability +** 2.implement the selection of ARCMSR_MAX_XFER_SECTORS_B=4096 +** if firmware version is newer than 1.42 +** 3.modify arcmsr_iop_reset to improve the ability +** 4.modify the ISR, arcmsr_interrupt routine,to prevent the +** inconsistency with sg_mod driver if application directly calls +** the arcmsr driver w/o passing through scsi mid layer +** specially thanks to Yanmin Zhang's openhanded help about AER +** 1.20.00.15 08/30/2007 Erich Chen & Nick Cheng +** 1. support ARC1200/1201/1202 SATA RAID adapter, which is named +** ACB_ADAPTER_TYPE_B +** 2. modify the arcmsr_pci_slot_reset function +** 3. modify the arcmsr_pci_ers_disconnect_forepart function +** 4. modify the arcmsr_pci_ers_need_reset_forepart function +************************************************************************** diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index e1efa0e..69b2fac 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -543,19 +543,32 @@ config SCSI_IN2000 module will be called in2000. config SCSI_ARCMSR - tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" + tristate "ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID Host Adapter" depends on PCI && SCSI help - This driver supports all of ARECA's SATA RAID controller cards. + This driver supports all of ARECA's SATA/SAS RAID controller cards. This is an ARECA-maintained driver by Erich Chen. - If you have any problems, please mail to: < erich@areca.com.tw > + If you have any problems, please mail to: . Areca supports Linux RAID config tools. - - < http://www.areca.com.tw > + Please link To compile this driver as a module, choose M here: the module will be called arcmsr (modprobe arcmsr). +config SCSI_ARCMSR_AER + bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)" + depends on SCSI_ARCMSR && PCIEAER + default n + help + The advanced error reporting(AER) capability is "NOT" provided by + ARC1200/1201/1202 SATA RAID controllers cards. + If your card is one of ARC1200/1201/1202, please use the default setting, n. + If your card is other models, you could pick it + on condition that the kernel version is greater than 2.6.19. + This function is maintained driver by Nick Cheng. If you have any + problems or suggestion, you are welcome to contact with . + To enable this function, choose Y here. + source "drivers/scsi/megaraid/Kconfig.megaraid" config SCSI_HPTIOP diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index f0b8bf4..ace7a15 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -9,7 +9,7 @@ ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. ** ** Web site: www.areca.com.tw -** E-mail: erich@areca.com.tw +** E-mail: support@areca.com.tw ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2 as @@ -45,19 +45,26 @@ #include struct class_device_attribute; - -#define ARCMSR_MAX_OUTSTANDING_CMD 256 -#define ARCMSR_MAX_FREECCB_NUM 288 -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.14" +/*The limit of outstanding scsi command that firmware can handle*/ +#define ARCMSR_MAX_OUTSTANDING_CMD 256 +#define ARCMSR_MAX_FREECCB_NUM 320 +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/08/30" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 -#define ARCMSR_MAX_XFER_SECTORS_B 4096 -#define ARCMSR_MAX_TARGETID 17 -#define ARCMSR_MAX_TARGETLUN 8 -#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD -#define ARCMSR_MAX_QBUFFER 4096 -#define ARCMSR_MAX_SG_ENTRIES 38 - +#define ARCMSR_MAX_XFER_SECTORS_B 4096 +#define ARCMSR_MAX_TARGETID 17 +#define ARCMSR_MAX_TARGETLUN 8 +#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD +#define ARCMSR_MAX_QBUFFER 4096 +#define ARCMSR_MAX_SG_ENTRIES 38 +#define ARCMSR_MAX_HBB_POSTQUEUE 264 +/* +********************************************************************************** +** +********************************************************************************** +*/ +#define ARC_SUCCESS 0 +#define ARC_FAILURE 1 /* ******************************************************************************* ** split 64bits dma addressing @@ -90,7 +97,7 @@ struct CMD_MESSAGE_FIELD uint8_t messagedatabuffer[1032]; }; /* IOP message transfer */ -#define ARCMSR_MESSAGE_FAIL 0x0001 +#define ARCMSR_MESSAGE_FAIL 0x0001 /* DeviceType */ #define ARECA_SATA_RAID 0x90000000 /* FunctionCode */ @@ -163,27 +170,27 @@ struct QBUFFER }; /* ******************************************************************************* -** FIRMWARE INFO +** FIRMWARE INFO for Intel IOP R 80331 processor (Type A) ******************************************************************************* */ struct FIRMWARE_INFO { - uint32_t signature; /*0, 00-03*/ - uint32_t request_len; /*1, 04-07*/ - uint32_t numbers_queue; /*2, 08-11*/ + uint32_t signature; /*0, 00-03*/ + uint32_t request_len; /*1, 04-07*/ + uint32_t numbers_queue; /*2, 08-11*/ uint32_t sdram_size; /*3, 12-15*/ - uint32_t ide_channels; /*4, 16-19*/ - char vendor[40]; /*5, 20-59*/ - char model[8]; /*15, 60-67*/ - char firmware_ver[16]; /*17, 68-83*/ - char device_map[16]; /*21, 84-99*/ + uint32_t ide_channels; /*4, 16-19*/ + char vendor[40]; /*5, 20-59*/ + char model[8]; /*15, 60-67*/ + char firmware_ver[16]; /*17, 68-83*/ + char device_map[16]; /*21, 84-99*/ }; /* signature of set and get firmware config */ -#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 -#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 +#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 +#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 /* message code of inbound message register */ -#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 -#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 +#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 +#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 #define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 #define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 #define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 @@ -203,6 +210,60 @@ struct FIRMWARE_INFO #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 /* outbound firmware ok */ #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 + +/* +************************************************************************ +** SPEC. for Areca Type B adapter +************************************************************************ +*/ +/* ARECA HBB COMMAND for its FIRMWARE */ +/* window of "instruction flags" from driver to iop */ +#define ARCMSR_DRV2IOP_DOORBELL 0x00020400 +#define ARCMSR_DRV2IOP_DOORBELL_MASK 0x00020404 +/* window of "instruction flags" from iop to driver */ +#define ARCMSR_IOP2DRV_DOORBELL 0x00020408 +#define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C +/* ARECA FLAG LANGUAGE */ +/* ioctl transfer */ +#define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001 +/* ioctl transfer */ +#define ARCMSR_IOP2DRV_DATA_READ_OK 0x00000002 +#define ARCMSR_IOP2DRV_CDB_DONE 0x00000004 +#define ARCMSR_IOP2DRV_MESSAGE_CMD_DONE 0x00000008 + +#define ARCMSR_DOORBELL_HANDLE_INT 0x0000000F +#define ARCMSR_DOORBELL_INT_CLEAR_PATTERN 0xFF00FFF0 +#define ARCMSR_MESSAGE_INT_CLEAR_PATTERN 0xFF00FFF7 +/* (ARCMSR_INBOUND_MESG0_GET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_GET_CONFIG 0x00010008 +/* (ARCMSR_INBOUND_MESG0_SET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_SET_CONFIG 0x00020008 +/* (ARCMSR_INBOUND_MESG0_ABORT_CMD<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_ABORT_CMD 0x00030008 +/* (ARCMSR_INBOUND_MESG0_STOP_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_STOP_BGRB 0x00040008 +/* (ARCMSR_INBOUND_MESG0_FLUSH_CACHE<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_FLUSH_CACHE 0x00050008 +/* (ARCMSR_INBOUND_MESG0_START_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ +#define ARCMSR_MESSAGE_START_BGRB 0x00060008 +#define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008 +#define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008 +/* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */ +#define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000 +/* ioctl transfer */ +#define ARCMSR_DRV2IOP_DATA_WRITE_OK 0x00000001 +/* ioctl transfer */ +#define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002 +#define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004 +#define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008 + +/* data tunnel buffer between user space program and its firmware */ +/* user space data to iop 128bytes */ +#define ARCMSR_IOCTL_WBUFFER 0x0000fe00 +/* iop data to user space 128bytes */ +#define ARCMSR_IOCTL_RBUFFER 0x0000ff00 +/* iop message_rwbuffer for message command */ +#define ARCMSR_MSGCODE_RWBUFFER 0x0000fa00 /* ******************************************************************************* ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) @@ -214,7 +275,6 @@ struct ARCMSR_CDB uint8_t TargetID; uint8_t LUN; uint8_t Function; - uint8_t CdbLength; uint8_t sgcount; uint8_t Flags; @@ -224,20 +284,18 @@ struct ARCMSR_CDB #define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 #define ARCMSR_CDB_FLAG_HEADQ 0x08 #define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 - uint8_t Reserved1; + uint8_t Reserved1; uint32_t Context; uint32_t DataLength; - uint8_t Cdb[16]; - uint8_t DeviceStatus; -#define ARCMSR_DEV_CHECK_CONDITION 0x02 -#define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 -#define ARCMSR_DEV_ABORTED 0xF1 -#define ARCMSR_DEV_INIT_FAIL 0xF2 - uint8_t SenseData[15]; +#define ARCMSR_DEV_CHECK_CONDITION 0x02 +#define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 +#define ARCMSR_DEV_ABORTED 0xF1 +#define ARCMSR_DEV_INIT_FAIL 0xF2 + uint8_t SenseData[15]; union { struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; @@ -246,10 +304,10 @@ struct ARCMSR_CDB }; /* ******************************************************************************* -** Messaging Unit (MU) of the Intel R 80331 I/O processor (80331) +** Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor ******************************************************************************* */ -struct MessageUnit +struct MessageUnit_A { uint32_t resrved0[4]; /*0000 000F*/ uint32_t inbound_msgaddr0; /*0010 0013*/ @@ -274,6 +332,30 @@ struct MessageUnit uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ uint32_t reserved6[32]; /*0F80 0FFF 32*/ }; + +struct MessageUnit_B +{ + uint32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; + uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; + uint32_t postq_index; + uint32_t doneq_index; + uint32_t *drv2iop_doorbell_reg; + uint32_t *drv2iop_doorbell_mask_reg; + uint32_t *iop2drv_doorbell_reg; + uint32_t *iop2drv_doorbell_mask_reg; + uint32_t *msgcode_rwbuffer_reg; + uint32_t *ioctl_wbuffer_reg; + uint32_t *ioctl_rbuffer_reg; +}; + +struct MessageUnit +{ + union + { + struct MessageUnit_A pmu_A; + struct MessageUnit_B pmu_B; + } u; +}; /* ******************************************************************************* ** Adapter Control Block @@ -281,37 +363,45 @@ struct MessageUnit */ struct AdapterControlBlock { + uint32_t adapter_type; /* adapter A,B..... */ + #define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */ + #define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */ + #define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc P IOP */ + #define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */ struct pci_dev * pdev; struct Scsi_Host * host; unsigned long vir2phy_offset; /* Offset is used in making arc cdb physical to virtual calculations */ uint32_t outbound_int_enable; - struct MessageUnit __iomem * pmu; + struct MessageUnit * pmu; /* message unit ATU inbound base address0 */ uint32_t acb_flags; -#define ACB_F_SCSISTOPADAPTER 0x0001 -#define ACB_F_MSG_STOP_BGRB 0x0002 + #define ACB_F_SCSISTOPADAPTER 0x0001 + #define ACB_F_MSG_STOP_BGRB 0x0002 /* stop RAID background rebuild */ -#define ACB_F_MSG_START_BGRB 0x0004 + #define ACB_F_MSG_START_BGRB 0x0004 /* stop RAID background rebuild */ -#define ACB_F_IOPDATA_OVERFLOW 0x0008 + #define ACB_F_IOPDATA_OVERFLOW 0x0008 /* iop message data rqbuffer overflow */ -#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 + #define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 /* message clear wqbuffer */ -#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 + #define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 /* message clear rqbuffer */ -#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 -#define ACB_F_BUS_RESET 0x0080 -#define ACB_F_IOP_INITED 0x0100 + #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 + #define ACB_F_BUS_RESET 0x0080 + #define ACB_F_IOP_INITED 0x0100 /* iop init */ struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_head ccb_free_list; /* head of free ccb list */ + atomic_t ccboutstandingcount; + /*The present outstanding command number that in the IOP that + waiting for being handled by FW*/ void * dma_coherent; /* dma_coherent used for memory free */ @@ -353,7 +443,7 @@ struct CommandControlBlock { struct ARCMSR_CDB arcmsr_cdb; /* - ** 0-503 (size of CDB=504): + ** 0-503 (size of CDB = 504): ** arcmsr messenger scsi command descriptor size 504 bytes */ uint32_t cdb_shifted_phyaddr; @@ -466,7 +556,9 @@ struct SENSE_DATA #define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 #define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F -extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb); +extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *); +extern void arcmsr_iop_message_read(struct AdapterControlBlock *); +extern struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *); extern struct class_device_attribute *arcmsr_host_attrs[]; -extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); +extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *); void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 06c0dce..0f0a1ae 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -8,7 +8,7 @@ ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved ** ** Web site: www.areca.com.tw -** E-mail: erich@areca.com.tw +** E-mail: support@areca.com.tw ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2 as @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -58,15 +59,11 @@ struct class_device_attribute *arcmsr_host_attrs[]; -static ssize_t -arcmsr_sysfs_iop_message_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - struct MessageUnit __iomem *reg = acb->pmu; uint8_t *pQbuffer,*ptmpQbuffer; int32_t allxfer_len = 0; @@ -85,12 +82,13 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, allxfer_len++; } if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) - ®->message_rbuffer; - uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; + struct QBUFFER *prbuffer; + uint8_t *iop_data; int32_t iop_len; acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; + prbuffer = arcmsr_get_iop_rqbuffer(acb); + iop_data = (uint8_t *)prbuffer->data; iop_len = readl(&prbuffer->data_len); while (iop_len > 0) { acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); @@ -99,16 +97,12 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, iop_data++; iop_len--; } - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, - ®->inbound_doorbell); + arcmsr_iop_message_read(acb); } return (allxfer_len); } -static ssize_t -arcmsr_sysfs_iop_message_write(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); @@ -126,7 +120,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, wqbuf_lastindex = acb->wqbuf_lastindex; wqbuf_firstindex = acb->wqbuf_firstindex; if (wqbuf_lastindex != wqbuf_firstindex) { - arcmsr_post_Qbuffer(acb); + arcmsr_post_ioctldata2iop(acb); return 0; /*need retry*/ } else { my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) @@ -144,7 +138,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { acb->acb_flags &= ~ACB_F_MESSAGE_WQBUFFER_CLEARED; - arcmsr_post_Qbuffer(acb); + arcmsr_post_ioctldata2iop(acb); } return count; } else { @@ -153,15 +147,11 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, } } -static ssize_t -arcmsr_sysfs_iop_message_clear(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - struct MessageUnit __iomem *reg = acb->pmu; uint8_t *pQbuffer; if (!capable(CAP_SYS_ADMIN)) @@ -169,8 +159,7 @@ arcmsr_sysfs_iop_message_clear(struct kobject *kobj, if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK - , ®->inbound_doorbell); + arcmsr_iop_message_read(acb); } acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED @@ -191,6 +180,7 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { .attr = { .name = "mu_read", .mode = S_IRUSR , + .owner = THIS_MODULE, }, .size = 1032, .read = arcmsr_sysfs_iop_message_read, @@ -200,6 +190,7 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { .attr = { .name = "mu_write", .mode = S_IWUSR, + .owner = THIS_MODULE, }, .size = 1032, .write = arcmsr_sysfs_iop_message_write, @@ -209,6 +200,7 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { .attr = { .name = "mu_clear", .mode = S_IWUSR, + .owner = THIS_MODULE, }, .size = 1, .write = arcmsr_sysfs_iop_message_clear, @@ -219,31 +211,26 @@ int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb) struct Scsi_Host *host = acb->host; int error; - error = sysfs_create_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_read_attr); + error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); if (error) { printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); goto error_bin_file_message_read; } - error = sysfs_create_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_write_attr); + error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); if (error) { printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); goto error_bin_file_message_write; } - error = sysfs_create_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_clear_attr); + error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); if (error) { printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); goto error_bin_file_message_clear; } return 0; error_bin_file_message_clear: - sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_write_attr); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); error_bin_file_message_write: - sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_read_attr); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); error_bin_file_message_read: return error; } @@ -252,12 +239,9 @@ void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { struct Scsi_Host *host = acb->host; - sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_clear_attr); - sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_write_attr); - sysfs_remove_bin_file(&host->shost_classdev.kobj, - &arcmsr_sysfs_message_read_attr); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); } diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 0ddfc21..d70398a 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -9,7 +9,7 @@ ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved ** ** Web site: www.areca.com.tw -** E-mail: erich@areca.com.tw +** E-mail: support@areca.com.tw ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2 as @@ -71,33 +71,37 @@ #include #include "arcmsr.h" -MODULE_AUTHOR("Erich Chen "); +MODULE_AUTHOR("Erich Chen "); MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, + struct scsi_cmnd *cmd); +static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); static int arcmsr_abort(struct scsi_cmnd *); static int arcmsr_bus_reset(struct scsi_cmnd *); static int arcmsr_bios_param(struct scsi_device *sdev, - struct block_device *bdev, sector_t capacity, int *info); -static int arcmsr_queue_command(struct scsi_cmnd * cmd, - void (*done) (struct scsi_cmnd *)); + struct block_device *bdev, sector_t capacity, int *info); +static int arcmsr_queue_command(struct scsi_cmnd *cmd, + void (*done) (struct scsi_cmnd *)); static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void arcmsr_remove(struct pci_dev *pdev); static void arcmsr_shutdown(struct pci_dev *pdev); static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); +static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); -static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb); -static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb); +static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb); +static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state); static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); -static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) +static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, + int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) queue_depth = ARCMSR_MAX_CMD_PERLUN; @@ -123,17 +127,21 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = arcmsr_host_attrs, }; +#ifdef CONFIG_SCSI_ARCMSR_AER static struct pci_error_handlers arcmsr_pci_error_handlers = { .error_detected = arcmsr_pci_error_detected, .slot_reset = arcmsr_pci_slot_reset, }; - +#endif static struct pci_device_id arcmsr_device_id_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1200)}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1201)}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)}, @@ -153,20 +161,20 @@ static struct pci_driver arcmsr_pci_driver = { .probe = arcmsr_probe, .remove = arcmsr_remove, .shutdown = arcmsr_shutdown, + #ifdef CONFIG_SCSI_ARCMSR_AER .err_handler = &arcmsr_pci_error_handlers, + #endif }; static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) { irqreturn_t handle_state; - struct AdapterControlBlock *acb; - unsigned long flags; - - acb = (struct AdapterControlBlock *)dev_id; + struct AdapterControlBlock *acb = dev_id; - spin_lock_irqsave(acb->host->host_lock, flags); + spin_lock(acb->host->host_lock); handle_state = arcmsr_interrupt(acb); - spin_unlock_irqrestore(acb->host->host_lock, flags); + spin_unlock(acb->host->host_lock); + return handle_state; } @@ -198,68 +206,159 @@ static int arcmsr_bios_param(struct scsi_device *sdev, return 0; } -static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) +static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb) { struct pci_dev *pdev = acb->pdev; - struct MessageUnit __iomem *reg = acb->pmu; - u32 ccb_phyaddr_hi32; - void *dma_coherent; - dma_addr_t dma_coherent_handle, dma_addr; - struct CommandControlBlock *ccb_tmp; - int i, j; + u16 dev_id; + pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); + switch (dev_id) { + case 0x1201 : { + acb->adapter_type = ACB_ADAPTER_TYPE_B; + } + break; + + default : acb->adapter_type = ACB_ADAPTER_TYPE_A; + } +} + +static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) +{ + + switch (acb->adapter_type) { - dma_coherent = dma_alloc_coherent(&pdev->dev, + case ACB_ADAPTER_TYPE_A: { + struct pci_dev *pdev = acb->pdev; + void *dma_coherent; + dma_addr_t dma_coherent_handle, dma_addr; + struct CommandControlBlock *ccb_tmp; + uint32_t intmask_org; + int i, j; + + acb->pmu = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); + if (!acb->pmu) { + printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", + acb->host->host_no); + } + + dma_coherent = dma_alloc_coherent(&pdev->dev, ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20, &dma_coherent_handle, GFP_KERNEL); - if (!dma_coherent) - return -ENOMEM; + if (!dma_coherent) + return -ENOMEM; - acb->dma_coherent = dma_coherent; - acb->dma_coherent_handle = dma_coherent_handle; + acb->dma_coherent = dma_coherent; + acb->dma_coherent_handle = dma_coherent_handle; - if (((unsigned long)dma_coherent & 0x1F)) { - dma_coherent = dma_coherent + - (0x20 - ((unsigned long)dma_coherent & 0x1F)); - dma_coherent_handle = dma_coherent_handle + - (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); - } + if (((unsigned long)dma_coherent & 0x1F)) { + dma_coherent = dma_coherent + + (0x20 - ((unsigned long)dma_coherent & 0x1F)); + dma_coherent_handle = dma_coherent_handle + + (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); + } - dma_addr = dma_coherent_handle; - ccb_tmp = (struct CommandControlBlock *)dma_coherent; - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { - ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; - ccb_tmp->acb = acb; - acb->pccb_pool[i] = ccb_tmp; - list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); - dma_addr = dma_addr + sizeof (struct CommandControlBlock); - ccb_tmp++; - } + dma_addr = dma_coherent_handle; + ccb_tmp = (struct CommandControlBlock *)dma_coherent; + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; + ccb_tmp->acb = acb; + acb->pccb_pool[i] = ccb_tmp; + list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); + dma_addr = dma_addr + sizeof(struct CommandControlBlock); + ccb_tmp++; + } - acb->vir2phy_offset = (unsigned long)ccb_tmp - - (unsigned long)dma_addr; - for (i = 0; i < ARCMSR_MAX_TARGETID; i++) - for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) - acb->devstate[i][j] = ARECA_RAID_GOOD; + acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr; + for (i = 0; i < ARCMSR_MAX_TARGETID; i++) + for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) + acb->devstate[i][j] = ARECA_RAID_GONE; - /* - ** here we need to tell iop 331 our ccb_tmp.HighPart - ** if ccb_tmp.HighPart is not zero - */ - ccb_phyaddr_hi32 = (uint32_t) ((dma_coherent_handle >> 16) >> 16); - if (ccb_phyaddr_hi32 != 0) { - writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->message_rwbuffer[0]); - writel(ccb_phyaddr_hi32, ®->message_rwbuffer[1]); - writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) - printk(KERN_NOTICE "arcmsr%d: " - "'set ccb high part physical address' timeout\n", - acb->host->host_no); - } + /* + ** here we need to tell iop 331 our ccb_tmp.HighPart + ** if ccb_tmp.HighPart is not zero + */ + intmask_org = arcmsr_disable_outbound_ints(acb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + + struct pci_dev *pdev = acb->pdev; + struct MessageUnit_B *reg; + void *mem_base0, *mem_base1; + void *dma_coherent; + dma_addr_t dma_coherent_handle, dma_addr; + uint32_t intmask_org; + struct CommandControlBlock *ccb_tmp; + int i, j; + + dma_coherent = dma_alloc_coherent(&pdev->dev, + ((ARCMSR_MAX_FREECCB_NUM * + sizeof(struct CommandControlBlock) + 0x20) + + sizeof(struct MessageUnit_B)), + &dma_coherent_handle, GFP_KERNEL); + if (!dma_coherent) + return -ENOMEM; + + acb->dma_coherent = dma_coherent; + acb->dma_coherent_handle = dma_coherent_handle; + + if (((unsigned long)dma_coherent & 0x1F)) { + dma_coherent = dma_coherent + + (0x20 - ((unsigned long)dma_coherent & 0x1F)); + dma_coherent_handle = dma_coherent_handle + + (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); + } + + reg = (struct MessageUnit_B *)(dma_coherent + + ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); + + dma_addr = dma_coherent_handle; + ccb_tmp = (struct CommandControlBlock *)dma_coherent; + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; + ccb_tmp->acb = acb; + acb->pccb_pool[i] = ccb_tmp; + list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); + dma_addr = dma_addr + sizeof(struct CommandControlBlock); + ccb_tmp++; + } + + reg = (struct MessageUnit_B *)(dma_coherent + + ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); + acb->pmu = (struct MessageUnit_B *)reg; + mem_base0 = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + mem_base1 = ioremap(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); + reg->drv2iop_doorbell_reg = (uint32_t *)((char *)mem_base0 + + ARCMSR_DRV2IOP_DOORBELL); + reg->drv2iop_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 + + ARCMSR_DRV2IOP_DOORBELL_MASK); + reg->iop2drv_doorbell_reg = (uint32_t *)((char *)mem_base0 + + ARCMSR_IOP2DRV_DOORBELL); + reg->iop2drv_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 + + ARCMSR_IOP2DRV_DOORBELL_MASK); + reg->ioctl_wbuffer_reg = (uint32_t *)((char *)mem_base1 + + ARCMSR_IOCTL_WBUFFER); + reg->ioctl_rbuffer_reg = (uint32_t *)((char *)mem_base1 + + ARCMSR_IOCTL_RBUFFER); + reg->msgcode_rwbuffer_reg = (uint32_t *)((char *)mem_base1 + + ARCMSR_MSGCODE_RWBUFFER); + + acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr; + for (i = 0; i < ARCMSR_MAX_TARGETID; i++) + for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) + acb->devstate[i][j] = ARECA_RAID_GOOD; - writel(readl(®->outbound_intmask) | - ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, - ®->outbound_intmask); + /* + ** here we need to tell iop 331 our ccb_tmp.HighPart + ** if ccb_tmp.HighPart is not zero + */ + intmask_org = arcmsr_disable_outbound_ints(acb); + } + break; + } return 0; } @@ -310,16 +409,11 @@ static int arcmsr_probe(struct pci_dev *pdev, host->unique_id = (bus << 8) | dev_fun; host->irq = pdev->irq; error = pci_request_regions(pdev, "arcmsr"); - if (error) + if (error) { goto out_host_put; - - acb->pmu = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!acb->pmu) { - printk(KERN_NOTICE "arcmsr%d: memory" - " mapping region fail \n", acb->host->host_no); - goto out_release_regions; } + arcmsr_define_adapter_type(acb); + acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | ACB_F_MESSAGE_RQBUFFER_CLEARED | ACB_F_MESSAGE_WQBUFFER_READED); @@ -328,10 +422,10 @@ static int arcmsr_probe(struct pci_dev *pdev, error = arcmsr_alloc_ccb_pool(acb); if (error) - goto out_iounmap; + goto out_release_regions; error = request_irq(pdev->irq, arcmsr_do_interrupt, - IRQF_DISABLED | IRQF_SHARED, "arcmsr", acb); + IRQF_SHARED, "arcmsr", acb); if (error) goto out_free_ccb_pool; @@ -349,14 +443,15 @@ static int arcmsr_probe(struct pci_dev *pdev, goto out_free_sysfs; scsi_scan_host(host); + #ifdef CONFIG_SCSI_ARCMSR_AER pci_enable_pcie_error_reporting(pdev); + #endif return 0; out_free_sysfs: out_free_irq: free_irq(pdev->irq, acb); out_free_ccb_pool: arcmsr_free_ccb_pool(acb); - out_iounmap: iounmap(acb->pmu); out_release_regions: pci_release_regions(pdev); @@ -368,17 +463,84 @@ static int arcmsr_probe(struct pci_dev *pdev, return error; } -static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) +static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + uint32_t Index; + uint8_t Retries = 0x00; + + do { + for (Index = 0; Index < 100; Index++) { + if (readl(®->outbound_intstatus) & + ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { + writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, + ®->outbound_intstatus); + return 0x00; + } + msleep(10); + }/*max 1 seconds*/ + + } while (Retries++ < 20);/*max 20 sec*/ + return 0xff; +} + +static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + uint32_t Index; + uint8_t Retries = 0x00; + + do { + for (Index = 0; Index < 100; Index++) { + if (readl(reg->iop2drv_doorbell_reg) + & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { + writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN + , reg->iop2drv_doorbell_reg); + return 0x00; + } + msleep(10); + }/*max 1 seconds*/ + + } while (Retries++ < 20);/*max 20 sec*/ + return 0xff; +} + +static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) { - struct MessageUnit __iomem *reg = acb->pmu; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) + if (arcmsr_hba_wait_msgint_ready(acb)) + printk(KERN_NOTICE + "arcmsr%d: wait 'abort all outstanding command' timeout \n" + , acb->host->host_no); +} + +static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + + writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) printk(KERN_NOTICE "arcmsr%d: wait 'abort all outstanding command' timeout \n" , acb->host->host_no); } +static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + arcmsr_abort_hba_allcmd(acb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + arcmsr_abort_hbb_allcmd(acb); + } + } +} + static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) { struct scsi_cmnd *pcmd = ccb->pcmd; @@ -400,28 +562,239 @@ static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag) pcmd->scsi_done(pcmd); } +static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + int retry_count = 30; + + writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); + do { + if (!arcmsr_hba_wait_msgint_ready(acb)) + break; + else { + retry_count--; + printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \ + timeout, retry count down = %d \n", acb->host->host_no, retry_count); + } + } while (retry_count != 0); +} + +static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + int retry_count = 30; + + writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell_reg); + do { + if (!arcmsr_hbb_wait_msgint_ready(acb)) + break; + else { + retry_count--; + printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \ + timeout,retry count down = %d \n", acb->host->host_no, retry_count); + } + } while (retry_count != 0); +} + +static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + arcmsr_flush_hba_cache(acb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + arcmsr_flush_hbb_cache(acb); + } + } +} + +static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) +{ + + struct scsi_cmnd *pcmd = ccb->pcmd; + struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; + + pcmd->result = DID_OK << 16; + if (sensebuffer) { + int sense_data_length = + sizeof(struct SENSE_DATA) < sizeof(pcmd->sense_buffer) + ? sizeof(struct SENSE_DATA) : sizeof(pcmd->sense_buffer); + memset(sensebuffer, 0, sizeof(pcmd->sense_buffer)); + memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); + sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; + sensebuffer->Valid = 1; + } +} + +static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) +{ + u32 orig_mask = 0; + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A : { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + orig_mask = readl(®->outbound_intmask)|\ + ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; + writel(orig_mask|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, \ + ®->outbound_intmask); + } + break; + + case ACB_ADAPTER_TYPE_B : { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + orig_mask = readl(reg->iop2drv_doorbell_mask_reg) & \ + (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); + writel(0, reg->iop2drv_doorbell_mask_reg); + } + break; + } + return orig_mask; +} + +static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, \ + struct CommandControlBlock *ccb, uint32_t flag_ccb) +{ + + uint8_t id, lun; + id = ccb->pcmd->device->id; + lun = ccb->pcmd->device->lun; + if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { + if (acb->devstate[id][lun] == ARECA_RAID_GONE) + acb->devstate[id][lun] = ARECA_RAID_GOOD; + ccb->pcmd->result = DID_OK << 16; + arcmsr_ccb_complete(ccb, 1); + } else { + switch (ccb->arcmsr_cdb.DeviceStatus) { + case ARCMSR_DEV_SELECT_TIMEOUT: { + acb->devstate[id][lun] = ARECA_RAID_GONE; + ccb->pcmd->result = DID_NO_CONNECT << 16; + arcmsr_ccb_complete(ccb, 1); + } + break; + + case ARCMSR_DEV_ABORTED: + + case ARCMSR_DEV_INIT_FAIL: { + acb->devstate[id][lun] = ARECA_RAID_GONE; + ccb->pcmd->result = DID_BAD_TARGET << 16; + arcmsr_ccb_complete(ccb, 1); + } + break; + + case ARCMSR_DEV_CHECK_CONDITION: { + acb->devstate[id][lun] = ARECA_RAID_GOOD; + arcmsr_report_sense_info(ccb); + arcmsr_ccb_complete(ccb, 1); + } + break; + + default: + printk(KERN_NOTICE + "arcmsr%d: scsi id = %d lun = %d" + " isr get command error done, " + "but got unknown DeviceStatus = 0x%x \n" + , acb->host->host_no + , id + , lun + , ccb->arcmsr_cdb.DeviceStatus); + acb->devstate[id][lun] = ARECA_RAID_GONE; + ccb->pcmd->result = DID_NO_CONNECT << 16; + arcmsr_ccb_complete(ccb, 1); + break; + } + } +} + +static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t flag_ccb) + +{ + struct CommandControlBlock *ccb; + + ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5)); + if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { + if (ccb->startdone == ARCMSR_CCB_ABORTED) { + struct scsi_cmnd *abortcmd = ccb->pcmd; + if (abortcmd) { + abortcmd->result |= DID_ABORT << 16; + arcmsr_ccb_complete(ccb, 1); + printk(KERN_NOTICE "arcmsr%d: ccb ='0x%p' \ + isr got aborted command \n", acb->host->host_no, ccb); + } + } + printk(KERN_NOTICE "arcmsr%d: isr get an illegal ccb command \ + done acb = '0x%p'" + "ccb = '0x%p' ccbacb = '0x%p' startdone = 0x%x" + " ccboutstandingcount = %d \n" + , acb->host->host_no + , acb + , ccb + , ccb->acb + , ccb->startdone + , atomic_read(&acb->ccboutstandingcount)); + } + arcmsr_report_ccb_state(acb, ccb, flag_ccb); +} + +static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) +{ + int i = 0; + uint32_t flag_ccb; + + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = \ + (struct MessageUnit_A *)acb->pmu; + uint32_t outbound_intstatus; + outbound_intstatus = readl(®->outbound_intstatus) & \ + acb->outbound_int_enable; + /*clear and abort all outbound posted Q*/ + writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ + while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) \ + && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { + arcmsr_drain_donequeue(acb, flag_ccb); + } + } + break; + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + /*clear all outbound posted Q*/ + for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { + if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { + writel(0, ®->done_qbuffer[i]); + arcmsr_drain_donequeue(acb, flag_ccb); + } + writel(0, ®->post_qbuffer[i]); + } + reg->doneq_index = 0; + reg->postq_index = 0; + } + break; + } +} static void arcmsr_remove(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - struct MessageUnit __iomem *reg = acb->pmu; int poll_count = 0; arcmsr_free_sysfs_attr(acb); scsi_remove_host(host); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); - writel(readl(®->outbound_intmask) | - ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, - ®->outbound_intmask); + arcmsr_disable_outbound_ints(acb); acb->acb_flags |= ACB_F_SCSISTOPADAPTER; acb->acb_flags &= ~ACB_F_IOP_INITED; - for (poll_count = 0; poll_count < 256; poll_count++) { + for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++) { if (!atomic_read(&acb->ccboutstandingcount)) break; - arcmsr_interrupt(acb); + arcmsr_interrupt(acb);/* FIXME: need spinlock */ msleep(25); } @@ -429,8 +802,7 @@ static void arcmsr_remove(struct pci_dev *pdev) int i; arcmsr_abort_allcmd(acb); - for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) - readl(®->outbound_queueport); + arcmsr_done4abort_postqueue(acb); for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { struct CommandControlBlock *ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { @@ -477,86 +849,43 @@ static void arcmsr_module_exit(void) module_init(arcmsr_module_init); module_exit(arcmsr_module_exit); -static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) -{ - struct MessageUnit __iomem *reg = acb->pmu; - u32 orig_mask = readl(®->outbound_intmask); - - writel(orig_mask | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, - ®->outbound_intmask); - return orig_mask; -} - -static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, - u32 orig_mask) +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \ + u32 intmask_org) { - struct MessageUnit __iomem *reg = acb->pmu; u32 mask; - mask = orig_mask & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | - ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); - writel(mask, ®->outbound_intmask); -} - -static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) -{ - struct MessageUnit __iomem *reg = acb->pmu; - - writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) - printk(KERN_NOTICE - "arcmsr%d: wait 'flush adapter cache' timeout \n" - , acb->host->host_no); -} + switch (acb->adapter_type) { -static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) -{ - struct scsi_cmnd *pcmd = ccb->pcmd; - struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; + case ACB_ADAPTER_TYPE_A : { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | + ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); + writel(mask, ®->outbound_intmask); + acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; + } + break; - pcmd->result = DID_OK << 16; - if (sensebuffer) { - int sense_data_length = - sizeof (struct SENSE_DATA) < sizeof (pcmd->sense_buffer) - ? sizeof (struct SENSE_DATA) : sizeof (pcmd->sense_buffer); - memset(sensebuffer, 0, sizeof (pcmd->sense_buffer)); - memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); - sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; - sensebuffer->Valid = 1; + case ACB_ADAPTER_TYPE_B : { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | \ + ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE); + writel(mask, reg->iop2drv_doorbell_mask_reg); + acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; + } } } -static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb) +static void arcmsr_build_ccb(struct AdapterControlBlock *acb, + struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) { - struct MessageUnit __iomem *reg = acb->pmu; - uint32_t Index; - uint8_t Retries = 0x00; - - do { - for (Index = 0; Index < 100; Index++) { - if (readl(®->outbound_intstatus) - & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { - writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT - , ®->outbound_intstatus); - return 0x00; - } - msleep_interruptible(10); - }/*max 1 seconds*/ - } while (Retries++ < 20);/*max 20 sec*/ - return 0xff; -} - -static void arcmsr_build_ccb(struct AdapterControlBlock *acb, - struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) -{ - struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; - int8_t *psge = (int8_t *)&arcmsr_cdb->u; - uint32_t address_lo, address_hi; - int arccdbsize = 0x30; - int nseg; + struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; + int8_t *psge = (int8_t *)&arcmsr_cdb->u; + uint32_t address_lo, address_hi; + int arccdbsize = 0x30; + int nseg; ccb->pcmd = pcmd; - memset(arcmsr_cdb, 0, sizeof (struct ARCMSR_CDB)); + memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB)); arcmsr_cdb->Bus = 0; arcmsr_cdb->TargetID = pcmd->device->id; arcmsr_cdb->LUN = pcmd->device->lun; @@ -609,52 +938,85 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb, static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) { - struct MessageUnit __iomem *reg = acb->pmu; uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr; struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; - atomic_inc(&acb->ccboutstandingcount); ccb->startdone = ARCMSR_CCB_START; - if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) - writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, + + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu; + + if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) + writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, ®->inbound_queueport); - else - writel(cdb_shifted_phyaddr, ®->inbound_queueport); -} + else { + writel(cdb_shifted_phyaddr, ®->inbound_queueport); + } + } + break; -void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb) -{ - struct MessageUnit __iomem *reg = acb->pmu; - struct QBUFFER __iomem *pwbuffer = (struct QBUFFER __iomem *) ®->message_wbuffer; - uint8_t __iomem *iop_data = (uint8_t __iomem *) pwbuffer->data; - int32_t allxfer_len = 0; + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + uint32_t ending_index, index = reg->postq_index; - if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { - acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); - while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) - && (allxfer_len < 124)) { - writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; - iop_data++; - allxfer_len++; + ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE); + writel(0, ®->post_qbuffer[ending_index]); + if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { + writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\ + ®->post_qbuffer[index]); + } + else { + writel(cdb_shifted_phyaddr, ®->post_qbuffer[index]); + } + index++; + index %= ARCMSR_MAX_HBB_POSTQUEUE;/*if last index number set it to 0 */ + reg->postq_index = index; + writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell_reg); } - writel(allxfer_len, &pwbuffer->data_len); - writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK - , ®->inbound_doorbell); + break; } } -static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) +static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb) { - struct MessageUnit __iomem *reg = acb->pmu; - + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; acb->acb_flags &= ~ACB_F_MSG_START_BGRB; writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) + + if (arcmsr_hba_wait_msgint_ready(acb)) { + printk(KERN_NOTICE + "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" + , acb->host->host_no); + } +} + +static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; + writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell_reg); + + if (arcmsr_hbb_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" , acb->host->host_no); + } +} + +static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + arcmsr_stop_hba_bgrb(acb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + arcmsr_stop_hbb_bgrb(acb); + } + break; + } } static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) @@ -665,151 +1027,260 @@ static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) acb->dma_coherent_handle); } -static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) +void arcmsr_iop_message_read(struct AdapterControlBlock *acb) { - struct MessageUnit __iomem *reg = acb->pmu; - struct CommandControlBlock *ccb; - uint32_t flag_ccb, outbound_intstatus, outbound_doorbell; + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); + } + break; - outbound_intstatus = readl(®->outbound_intstatus) - & acb->outbound_int_enable; - writel(outbound_intstatus, ®->outbound_intstatus); - if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { - outbound_doorbell = readl(®->outbound_doorbell); - writel(outbound_doorbell, ®->outbound_doorbell); - if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { - struct QBUFFER __iomem * prbuffer = - (struct QBUFFER __iomem *) ®->message_rbuffer; - uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; - int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; - - rqbuf_lastindex = acb->rqbuf_lastindex; - rqbuf_firstindex = acb->rqbuf_firstindex; - iop_len = readl(&prbuffer->data_len); - my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) - &(ARCMSR_MAX_QBUFFER - 1); - if (my_empty_len >= iop_len) { - while (iop_len > 0) { - acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); - acb->rqbuf_lastindex++; - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; - iop_data++; - iop_len--; - } - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, - ®->inbound_doorbell); - } else - acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; - } - if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { - acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { - struct QBUFFER __iomem * pwbuffer = - (struct QBUFFER __iomem *) ®->message_wbuffer; - uint8_t __iomem * iop_data = (uint8_t __iomem *) pwbuffer->data; - int32_t allxfer_len = 0; - - acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); - while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) - && (allxfer_len < 124)) { - writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; - iop_data++; - allxfer_len++; - } - writel(allxfer_len, &pwbuffer->data_len); - writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, - ®->inbound_doorbell); - } - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) - acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg); } + break; } - if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { - int id, lun; +} + +static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; /* - **************************************************************** - ** areca cdb command done - **************************************************************** + ** push inbound doorbell tell iop, driver data write ok + ** and wait reply on next hwinterrupt for next Qbuffer post */ - while (1) { - if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) - break;/*chip FIFO no ccb for completion already*/ - /* check if command done with no error*/ - ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + - (flag_ccb << 5)); - if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { - if (ccb->startdone == ARCMSR_CCB_ABORTED) { - struct scsi_cmnd *abortcmd = ccb->pcmd; - if (abortcmd) { - abortcmd->result |= DID_ABORT >> 16; - arcmsr_ccb_complete(ccb, 1); - printk(KERN_NOTICE - "arcmsr%d: ccb ='0x%p' isr got aborted command \n" - , acb->host->host_no, ccb); - } - continue; - } - printk(KERN_NOTICE - "arcmsr%d: isr get an illegal ccb command done acb = '0x%p'" - "ccb = '0x%p' ccbacb = '0x%p' startdone = 0x%x" - " ccboutstandingcount = %d \n" - , acb->host->host_no - , acb - , ccb - , ccb->acb - , ccb->startdone - , atomic_read(&acb->ccboutstandingcount)); - continue; - } - id = ccb->pcmd->device->id; - lun = ccb->pcmd->device->lun; - if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { - if (acb->devstate[id][lun] == ARECA_RAID_GONE) - acb->devstate[id][lun] = ARECA_RAID_GOOD; - ccb->pcmd->result = DID_OK << 16; - arcmsr_ccb_complete(ccb, 1); - } else { - switch(ccb->arcmsr_cdb.DeviceStatus) { - case ARCMSR_DEV_SELECT_TIMEOUT: { - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - case ARCMSR_DEV_ABORTED: - case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - case ARCMSR_DEV_CHECK_CONDITION: { - acb->devstate[id][lun] = ARECA_RAID_GOOD; - arcmsr_report_sense_info(ccb); - arcmsr_ccb_complete(ccb, 1); - } - break; - default: - printk(KERN_NOTICE - "arcmsr%d: scsi id = %d lun = %d" - " isr get command error done, " - "but got unknown DeviceStatus = 0x%x \n" - , acb->host->host_no - , id - , lun - , ccb->arcmsr_cdb.DeviceStatus); - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - break; - } - } - }/*drain reply FIFO*/ + writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, ®->inbound_doorbell); + } + break; + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + /* + ** push inbound doorbell tell iop, driver data write ok + ** and wait reply on next hwinterrupt for next Qbuffer post + */ + writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell_reg); + } + break; + } +} + +struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) +{ + static struct QBUFFER *qbuffer; + + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + qbuffer = (struct QBUFFER __iomem *) ®->message_rbuffer; + } + break; + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + qbuffer = (struct QBUFFER __iomem *) reg->ioctl_rbuffer_reg; + } + break; + } + return qbuffer; +} + +static struct QBUFFER *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb) +{ + static struct QBUFFER *pqbuffer; + + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + pqbuffer = (struct QBUFFER *) ®->message_wbuffer; + } + break; + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + pqbuffer = (struct QBUFFER __iomem *)reg->ioctl_wbuffer_reg; + } + break; + } + return pqbuffer; +} + +static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) +{ + struct QBUFFER *prbuffer; + struct QBUFFER *pQbuffer; + uint8_t *iop_data; + int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; + + rqbuf_lastindex = acb->rqbuf_lastindex; + rqbuf_firstindex = acb->rqbuf_firstindex; + prbuffer = arcmsr_get_iop_rqbuffer(acb); + iop_data = (uint8_t *)prbuffer->data; + iop_len = prbuffer->data_len; + my_empty_len = (rqbuf_firstindex - rqbuf_lastindex -1)&(ARCMSR_MAX_QBUFFER -1); + + if (my_empty_len >= iop_len) + { + while (iop_len > 0) { + pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex]; + memcpy(pQbuffer, iop_data,1); + rqbuf_lastindex++; + rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + iop_data++; + iop_len--; + } + acb->rqbuf_lastindex = rqbuf_lastindex; + arcmsr_iop_message_read(acb); + } + + else { + acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; + } +} + +static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb) +{ + acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; + if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { + uint8_t *pQbuffer; + struct QBUFFER *pwbuffer; + uint8_t *iop_data; + int32_t allxfer_len = 0; + + acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); + pwbuffer = arcmsr_get_iop_wqbuffer(acb); + iop_data = (uint8_t __iomem *)pwbuffer->data; + + while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) && \ + (allxfer_len < 124)) { + pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; + memcpy(iop_data, pQbuffer, 1); + acb->wqbuf_firstindex++; + acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; + iop_data++; + allxfer_len++; + } + pwbuffer->data_len = allxfer_len; + + arcmsr_iop_message_wrote(acb); + } + + if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) { + acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; + } +} + +static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) +{ + uint32_t outbound_doorbell; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + + outbound_doorbell = readl(®->outbound_doorbell); + writel(outbound_doorbell, ®->outbound_doorbell); + if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { + arcmsr_iop2drv_data_wrote_handle(acb); + } + + if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { + arcmsr_iop2drv_data_read_handle(acb); + } +} + +static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) +{ + uint32_t flag_ccb; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + + while ((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) { + arcmsr_drain_donequeue(acb, flag_ccb); + } +} + +static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) +{ + uint32_t index; + uint32_t flag_ccb; + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + + index = reg->doneq_index; + + while ((flag_ccb = readl(®->done_qbuffer[index])) != 0) { + writel(0, ®->done_qbuffer[index]); + arcmsr_drain_donequeue(acb, flag_ccb); + index++; + index %= ARCMSR_MAX_HBB_POSTQUEUE; + reg->doneq_index = index; + } +} + +static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) +{ + uint32_t outbound_intstatus; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + + outbound_intstatus = readl(®->outbound_intstatus) & \ + acb->outbound_int_enable; + if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { + return 1; + } + writel(outbound_intstatus, ®->outbound_intstatus); + if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { + arcmsr_hba_doorbell_isr(acb); + } + if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { + arcmsr_hba_postqueue_isr(acb); + } + return 0; +} + +static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) +{ + uint32_t outbound_doorbell; + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + + outbound_doorbell = readl(reg->iop2drv_doorbell_reg) & \ + acb->outbound_int_enable; + if (!outbound_doorbell) + return 1; + + writel(~outbound_doorbell, reg->iop2drv_doorbell_reg); + + if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { + arcmsr_iop2drv_data_wrote_handle(acb); + } + if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) { + arcmsr_iop2drv_data_read_handle(acb); + } + if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) { + arcmsr_hbb_postqueue_isr(acb); + } + + return 0; +} + +static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + if (arcmsr_handle_hba_isr(acb)) { + return IRQ_NONE; + } + } + break; + + case ACB_ADAPTER_TYPE_B: { + if (arcmsr_handle_hbb_isr(acb)) { + return IRQ_NONE; + } + } + break; } - if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) - return IRQ_NONE; return IRQ_HANDLED; } @@ -818,16 +1289,47 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb) if (acb) { /* stop adapter background rebuild */ if (acb->acb_flags & ACB_F_MSG_START_BGRB) { + uint32_t intmask_org; acb->acb_flags &= ~ACB_F_MSG_START_BGRB; + intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); + arcmsr_enable_outbound_ints(acb, intmask_org); + } + } +} + +void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) +{ + int32_t wqbuf_firstindex, wqbuf_lastindex; + uint8_t *pQbuffer; + struct QBUFFER *pwbuffer; + uint8_t *iop_data; + int32_t allxfer_len = 0; + + pwbuffer = arcmsr_get_iop_wqbuffer(acb); + iop_data = (uint8_t __iomem *)pwbuffer->data; + if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { + acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); + wqbuf_firstindex = acb->wqbuf_firstindex; + wqbuf_lastindex = acb->wqbuf_lastindex; + while ((wqbuf_firstindex != wqbuf_lastindex) && (allxfer_len < 124)) { + pQbuffer = &acb->wqbuffer[wqbuf_firstindex]; + memcpy(iop_data, pQbuffer, 1); + wqbuf_firstindex++; + wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; + iop_data++; + allxfer_len++; } + acb->wqbuf_firstindex = wqbuf_firstindex; + pwbuffer->data_len = allxfer_len; + arcmsr_iop_message_wrote(acb); } } -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd) +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ + struct scsi_cmnd *cmd) { - struct MessageUnit __iomem *reg = acb->pmu; struct CMD_MESSAGE_FIELD *pcmdmessagefld; int retvalue = 0, transfer_len = 0; char *buffer; @@ -836,7 +1338,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_ (uint32_t ) cmd->cmnd[6] << 16 | (uint32_t ) cmd->cmnd[7] << 8 | (uint32_t ) cmd->cmnd[8]; - /* 4 bytes: Areca io control code */ + /* 4 bytes: Areca io control code */ sg = scsi_sglist(cmd); buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; @@ -852,194 +1354,199 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_ } pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; switch(controlcode) { + case ARCMSR_MESSAGE_READ_RQBUFFER: { - unsigned long *ver_addr; - dma_addr_t buf_handle; - uint8_t *pQbuffer, *ptmpQbuffer; - int32_t allxfer_len = 0; + unsigned long *ver_addr; + dma_addr_t buf_handle; + uint8_t *pQbuffer, *ptmpQbuffer; + int32_t allxfer_len = 0; + + ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); + if (!ver_addr) { + retvalue = ARCMSR_MESSAGE_FAIL; + goto message_out; + } + ptmpQbuffer = (uint8_t *) ver_addr; + while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) + && (allxfer_len < 1031)) { + pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; + memcpy(ptmpQbuffer, pQbuffer, 1); + acb->rqbuf_firstindex++; + acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; + ptmpQbuffer++; + allxfer_len++; + } + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); - if (!ver_addr) { - retvalue = ARCMSR_MESSAGE_FAIL; - goto message_out; - } - ptmpQbuffer = (uint8_t *) ver_addr; - while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) - && (allxfer_len < 1031)) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - memcpy(ptmpQbuffer, pQbuffer, 1); - acb->rqbuf_firstindex++; - acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; - ptmpQbuffer++; - allxfer_len++; - } - if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) - ®->message_rbuffer; - uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; - int32_t iop_len; - - acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - iop_len = readl(&prbuffer->data_len); - while (iop_len > 0) { - acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); - acb->rqbuf_lastindex++; - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; - iop_data++; - iop_len--; - } - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, - ®->inbound_doorbell); + struct QBUFFER *prbuffer; + uint8_t *iop_data; + int32_t iop_len; + + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; + prbuffer = arcmsr_get_iop_rqbuffer(acb); + iop_data = (uint8_t *)prbuffer->data; + iop_len = readl(&prbuffer->data_len); + while (iop_len > 0) { + acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); + acb->rqbuf_lastindex++; + acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + iop_data++; + iop_len--; } - memcpy(pcmdmessagefld->messagedatabuffer, - (uint8_t *)ver_addr, allxfer_len); - pcmdmessagefld->cmdmessage.Length = allxfer_len; - pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; - pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); + arcmsr_iop_message_read(acb); + } + memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len); + pcmdmessagefld->cmdmessage.Length = allxfer_len; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); } break; - case ARCMSR_MESSAGE_WRITE_WQBUFFER: { - unsigned long *ver_addr; - dma_addr_t buf_handle; - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; - uint8_t *pQbuffer, *ptmpuserbuffer; - ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); - if (!ver_addr) { - retvalue = ARCMSR_MESSAGE_FAIL; - goto message_out; - } - ptmpuserbuffer = (uint8_t *)ver_addr; - user_len = pcmdmessagefld->cmdmessage.Length; - memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); - wqbuf_lastindex = acb->wqbuf_lastindex; - wqbuf_firstindex = acb->wqbuf_firstindex; - if (wqbuf_lastindex != wqbuf_firstindex) { + case ARCMSR_MESSAGE_WRITE_WQBUFFER: { + unsigned long *ver_addr; + dma_addr_t buf_handle; + int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; + uint8_t *pQbuffer, *ptmpuserbuffer; + + ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); + if (!ver_addr) { + retvalue = ARCMSR_MESSAGE_FAIL; + goto message_out; + } + ptmpuserbuffer = (uint8_t *)ver_addr; + user_len = pcmdmessagefld->cmdmessage.Length; + memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); + wqbuf_lastindex = acb->wqbuf_lastindex; + wqbuf_firstindex = acb->wqbuf_firstindex; + if (wqbuf_lastindex != wqbuf_firstindex) { + struct SENSE_DATA *sensebuffer = + (struct SENSE_DATA *)cmd->sense_buffer; + arcmsr_post_ioctldata2iop(acb); + /* has error report sensedata */ + sensebuffer->ErrorCode = 0x70; + sensebuffer->SenseKey = ILLEGAL_REQUEST; + sensebuffer->AdditionalSenseLength = 0x0A; + sensebuffer->AdditionalSenseCode = 0x20; + sensebuffer->Valid = 1; + retvalue = ARCMSR_MESSAGE_FAIL; + } else { + my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) + &(ARCMSR_MAX_QBUFFER - 1); + if (my_empty_len >= user_len) { + while (user_len > 0) { + pQbuffer = + &acb->wqbuffer[acb->wqbuf_lastindex]; + memcpy(pQbuffer, ptmpuserbuffer, 1); + acb->wqbuf_lastindex++; + acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + ptmpuserbuffer++; + user_len--; + } + if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { + acb->acb_flags &= + ~ACB_F_MESSAGE_WQBUFFER_CLEARED; + arcmsr_post_ioctldata2iop(acb); + } + } else { + /* has error report sensedata */ struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)cmd->sense_buffer; - arcmsr_post_Qbuffer(acb); - /* has error report sensedata */ sensebuffer->ErrorCode = 0x70; sensebuffer->SenseKey = ILLEGAL_REQUEST; sensebuffer->AdditionalSenseLength = 0x0A; sensebuffer->AdditionalSenseCode = 0x20; sensebuffer->Valid = 1; retvalue = ARCMSR_MESSAGE_FAIL; - } else { - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) - &(ARCMSR_MAX_QBUFFER - 1); - if (my_empty_len >= user_len) { - while (user_len > 0) { - pQbuffer = - &acb->wqbuffer[acb->wqbuf_lastindex]; - memcpy(pQbuffer, ptmpuserbuffer, 1); - acb->wqbuf_lastindex++; - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; - ptmpuserbuffer++; - user_len--; - } - if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { - acb->acb_flags &= - ~ACB_F_MESSAGE_WQBUFFER_CLEARED; - arcmsr_post_Qbuffer(acb); - } - } else { - /* has error report sensedata */ - struct SENSE_DATA *sensebuffer = - (struct SENSE_DATA *)cmd->sense_buffer; - sensebuffer->ErrorCode = 0x70; - sensebuffer->SenseKey = ILLEGAL_REQUEST; - sensebuffer->AdditionalSenseLength = 0x0A; - sensebuffer->AdditionalSenseCode = 0x20; - sensebuffer->Valid = 1; - retvalue = ARCMSR_MESSAGE_FAIL; - } + } } pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); } break; + case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { - uint8_t *pQbuffer = acb->rqbuffer; + uint8_t *pQbuffer = acb->rqbuffer; - if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, - ®->inbound_doorbell); - } - acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; - acb->rqbuf_firstindex = 0; - acb->rqbuf_lastindex = 0; - memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); - pcmdmessagefld->cmdmessage.ReturnCode = - ARCMSR_MESSAGE_RETURNCODE_OK; + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; + arcmsr_iop_message_read(acb); + } + acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; + acb->rqbuf_firstindex = 0; + acb->rqbuf_lastindex = 0; + memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; } break; + case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { - uint8_t *pQbuffer = acb->wqbuffer; + uint8_t *pQbuffer = acb->wqbuffer; - if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK - , ®->inbound_doorbell); - } - acb->acb_flags |= - (ACB_F_MESSAGE_WQBUFFER_CLEARED | - ACB_F_MESSAGE_WQBUFFER_READED); - acb->wqbuf_firstindex = 0; - acb->wqbuf_lastindex = 0; - memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); - pcmdmessagefld->cmdmessage.ReturnCode = - ARCMSR_MESSAGE_RETURNCODE_OK; + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; + arcmsr_iop_message_read(acb); + } + acb->acb_flags |= + (ACB_F_MESSAGE_WQBUFFER_CLEARED | + ACB_F_MESSAGE_WQBUFFER_READED); + acb->wqbuf_firstindex = 0; + acb->wqbuf_lastindex = 0; + memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_OK; } break; + case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { - uint8_t *pQbuffer; + uint8_t *pQbuffer; - if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { - acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK - , ®->inbound_doorbell); - } - acb->acb_flags |= - (ACB_F_MESSAGE_WQBUFFER_CLEARED - | ACB_F_MESSAGE_RQBUFFER_CLEARED - | ACB_F_MESSAGE_WQBUFFER_READED); - acb->rqbuf_firstindex = 0; - acb->rqbuf_lastindex = 0; - acb->wqbuf_firstindex = 0; - acb->wqbuf_lastindex = 0; - pQbuffer = acb->rqbuffer; - memset(pQbuffer, 0, sizeof (struct QBUFFER)); - pQbuffer = acb->wqbuffer; - memset(pQbuffer, 0, sizeof (struct QBUFFER)); - pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; + arcmsr_iop_message_read(acb); + } + acb->acb_flags |= + (ACB_F_MESSAGE_WQBUFFER_CLEARED + | ACB_F_MESSAGE_RQBUFFER_CLEARED + | ACB_F_MESSAGE_WQBUFFER_READED); + acb->rqbuf_firstindex = 0; + acb->rqbuf_lastindex = 0; + acb->wqbuf_firstindex = 0; + acb->wqbuf_lastindex = 0; + pQbuffer = acb->rqbuffer; + memset(pQbuffer, 0, sizeof(struct QBUFFER)); + pQbuffer = acb->wqbuffer; + memset(pQbuffer, 0, sizeof(struct QBUFFER)); + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; } break; + case ARCMSR_MESSAGE_RETURN_CODE_3F: { - pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; } break; + case ARCMSR_MESSAGE_SAY_HELLO: { - int8_t * hello_string = "Hello! I am ARCMSR"; + int8_t *hello_string = "Hello! I am ARCMSR"; - memcpy(pcmdmessagefld->messagedatabuffer, hello_string - , (int16_t)strlen(hello_string)); - pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; + memcpy(pcmdmessagefld->messagedatabuffer, hello_string + , (int16_t)strlen(hello_string)); + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; } break; + case ARCMSR_MESSAGE_SAY_GOODBYE: arcmsr_iop_parking(acb); break; + case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: arcmsr_flush_adapter_cache(acb); break; + default: retvalue = ARCMSR_MESSAGE_FAIL; } - message_out: + message_out: sg = scsi_sglist(cmd); kunmap_atomic(buffer - sg->offset, KM_IRQ0); - return retvalue; } @@ -1109,8 +1616,7 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) { struct Scsi_Host *host = cmd->device->host; - struct AdapterControlBlock *acb = - (struct AdapterControlBlock *) host->hostdata; + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; struct CommandControlBlock *ccb; int target = cmd->device->id; int lun = cmd->device->lun; @@ -1153,26 +1659,27 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, ccb = arcmsr_get_freeccb(acb); if (!ccb) return SCSI_MLQUEUE_HOST_BUSY; + arcmsr_build_ccb(acb, ccb, cmd); arcmsr_post_ccb(acb, ccb); return 0; } -static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) +static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) { - struct MessageUnit __iomem *reg = acb->pmu; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; char *acb_firm_model = acb->firm_model; char *acb_firm_version = acb->firm_version; - char __iomem *iop_firm_model = (char __iomem *) ®->message_rwbuffer[15]; - char __iomem *iop_firm_version = (char __iomem *) ®->message_rwbuffer[17]; + char *iop_firm_model = (char *) (®->message_rwbuffer[15]); + char *iop_firm_version = (char *) (®->message_rwbuffer[17]); int count; writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) - printk(KERN_NOTICE - "arcmsr%d: wait " - "'get adapter firmware miscellaneous data' timeout \n" - , acb->host->host_no); + if (arcmsr_hba_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ + miscellaneous data' timeout \n", acb->host->host_no); + } + count = 8; while (count) { *acb_firm_model = readb(iop_firm_model); @@ -1180,6 +1687,7 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) iop_firm_model++; count--; } + count = 16; while (count) { *acb_firm_version = readb(iop_firm_version); @@ -1187,28 +1695,93 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) iop_firm_version++; count--; } - printk(KERN_INFO - "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" + + printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" , acb->host->host_no , acb->firm_version); + acb->firm_request_len = readl(®->message_rwbuffer[1]); acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); acb->firm_sdram_size = readl(®->message_rwbuffer[3]); acb->firm_hd_channels = readl(®->message_rwbuffer[4]); } -static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, +static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + uint32_t *lrwbuffer = reg->msgcode_rwbuffer_reg; + char *acb_firm_model = acb->firm_model; + char *acb_firm_version = acb->firm_version; + char *iop_firm_model = (char *) (&lrwbuffer[15]); + /*firm_model,15,60-67*/ + char *iop_firm_version = (char *) (&lrwbuffer[17]); + /*firm_version,17,68-83*/ + int count; + + writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ + miscellaneous data' timeout \n", acb->host->host_no); + } + + count = 8; + while (count) + { + *acb_firm_model = readb(iop_firm_model); + acb_firm_model++; + iop_firm_model++; + count--; + } + + count = 16; + while (count) + { + *acb_firm_version = readb(iop_firm_version); + acb_firm_version++; + iop_firm_version++; + count--; + } + + printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", + acb->host->host_no, + acb->firm_version); + + lrwbuffer++; + acb->firm_request_len = readl(lrwbuffer++); + /*firm_request_len,1,04-07*/ + acb->firm_numbers_queue = readl(lrwbuffer++); + /*firm_numbers_queue,2,08-11*/ + acb->firm_sdram_size = readl(lrwbuffer++); + /*firm_sdram_size,3,12-15*/ + acb->firm_hd_channels = readl(lrwbuffer); + /*firm_ide_channels,4,16-19*/ +} + +static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + arcmsr_get_hba_config(acb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + arcmsr_get_hbb_config(acb); + } + break; + } +} + +static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_ccb) { - struct MessageUnit __iomem *reg = acb->pmu; + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; struct CommandControlBlock *ccb; uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; - int id, lun; - polling_ccb_retry: + polling_hba_ccb_retry: poll_count++; - outbound_intstatus = readl(®->outbound_intstatus) - & acb->outbound_int_enable; + outbound_intstatus = readl(®->outbound_intstatus) & acb->outbound_int_enable; writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ while (1) { if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { @@ -1218,17 +1791,14 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, msleep(25); if (poll_count > 100) break; - goto polling_ccb_retry; + goto polling_hba_ccb_retry; } } - ccb = (struct CommandControlBlock *) - (acb->vir2phy_offset + (flag_ccb << 5)); - if ((ccb->acb != acb) || - (ccb->startdone != ARCMSR_CCB_START)) { - if ((ccb->startdone == ARCMSR_CCB_ABORTED) || - (ccb == poll_ccb)) { - printk(KERN_NOTICE - "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" + ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5)); + poll_ccb_done = (ccb == poll_ccb) ? 1:0; + if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { + if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) { + printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" " poll command abort successfully \n" , acb->host->host_no , ccb->pcmd->device->id @@ -1239,176 +1809,280 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, poll_ccb_done = 1; continue; } - printk(KERN_NOTICE - "arcmsr%d: polling get an illegal ccb" - " command done ccb ='0x%p'" + printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" + " command done ccb = '0x%p'" "ccboutstandingcount = %d \n" , acb->host->host_no , ccb , atomic_read(&acb->ccboutstandingcount)); continue; } - id = ccb->pcmd->device->id; - lun = ccb->pcmd->device->lun; - if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { - if (acb->devstate[id][lun] == ARECA_RAID_GONE) - acb->devstate[id][lun] = ARECA_RAID_GOOD; - ccb->pcmd->result = DID_OK << 16; - arcmsr_ccb_complete(ccb, 1); - } else { - switch(ccb->arcmsr_cdb.DeviceStatus) { - case ARCMSR_DEV_SELECT_TIMEOUT: { - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - case ARCMSR_DEV_ABORTED: - case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); + arcmsr_report_ccb_state(acb, ccb, flag_ccb); + } +} + +static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \ + struct CommandControlBlock *poll_ccb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + struct CommandControlBlock *ccb; + uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0; + int index; + + polling_hbb_ccb_retry: + poll_count++; + /* clear doorbell interrupt */ + writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg); + while (1) { + index = reg->doneq_index; + if ((flag_ccb = readl(®->done_qbuffer[index])) == 0) { + if (poll_ccb_done) + break; + else { + msleep(25); + if (poll_count > 100) + break; + goto polling_hbb_ccb_retry; } - break; - case ARCMSR_DEV_CHECK_CONDITION: { - acb->devstate[id][lun] = ARECA_RAID_GOOD; - arcmsr_report_sense_info(ccb); + } + writel(0, ®->done_qbuffer[index]); + index++; + /*if last index number set it to 0 */ + index %= ARCMSR_MAX_HBB_POSTQUEUE; + reg->doneq_index = index; + /* check ifcommand done with no error*/ + ccb = (struct CommandControlBlock *)\ + (acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/ + poll_ccb_done = (ccb == poll_ccb) ? 1:0; + if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { + if (ccb->startdone == ARCMSR_CCB_ABORTED) { + printk(KERN_NOTICE "arcmsr%d: \ + scsi id = %d lun = %d ccb = '0x%p' poll command abort successfully \n" + ,acb->host->host_no + ,ccb->pcmd->device->id + ,ccb->pcmd->device->lun + ,ccb); + ccb->pcmd->result = DID_ABORT << 16; arcmsr_ccb_complete(ccb, 1); + continue; } - break; - default: - printk(KERN_NOTICE - "arcmsr%d: scsi id = %d lun = %d" - " polling and getting command error done" - "but got unknown DeviceStatus = 0x%x \n" + printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" + " command done ccb = '0x%p'" + "ccboutstandingcount = %d \n" , acb->host->host_no - , id - , lun - , ccb->arcmsr_cdb.DeviceStatus); - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - break; + , ccb + , atomic_read(&acb->ccboutstandingcount)); + continue; } + arcmsr_report_ccb_state(acb, ccb, flag_ccb); + } /*drain reply FIFO*/ +} + +static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, \ + struct CommandControlBlock *poll_ccb) +{ + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + arcmsr_polling_hba_ccbdone(acb,poll_ccb); + } + break; + + case ACB_ADAPTER_TYPE_B: { + arcmsr_polling_hbb_ccbdone(acb,poll_ccb); } } } -static void arcmsr_done4_abort_postqueue(struct AdapterControlBlock *acb) + +static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) { - int i = 0, found = 0; - int id, lun; - uint32_t flag_ccb, outbound_intstatus; - struct MessageUnit __iomem *reg = acb->pmu; - struct CommandControlBlock *ccb; - /*clear and abort all outbound posted Q*/ - - while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && -(i++ < 256)){ - ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + -(flag_ccb << 5)); - if (ccb){ - if ((ccb->acb != acb)||(ccb->startdone != \ -ARCMSR_CCB_START)){ - printk(KERN_NOTICE "arcmsr%d: polling get \ -an illegal ccb" "command done ccb = '0x%p'""ccboutstandingcount = %d \n", - acb->host->host_no, ccb, - atomic_read(&acb->ccboutstandingcount)); - continue; + uint32_t cdb_phyaddr, ccb_phyaddr_hi32; + dma_addr_t dma_coherent_handle; + /* + ******************************************************************** + ** here we need to tell iop 331 our freeccb.HighPart + ** if freeccb.HighPart is not zero + ******************************************************************** + */ + dma_coherent_handle = acb->dma_coherent_handle; + cdb_phyaddr = (uint32_t)(dma_coherent_handle); + ccb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); + /* + *********************************************************************** + ** if adapter type B, set window of "post command Q" + *********************************************************************** + */ + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + if (ccb_phyaddr_hi32 != 0) { + struct MessageUnit_A __iomem *reg = \ + (struct MessageUnit_A *)acb->pmu; + uint32_t intmask_org; + intmask_org = arcmsr_disable_outbound_ints(acb); + writel(ARCMSR_SIGNATURE_SET_CONFIG, \ + ®->message_rwbuffer[0]); + writel(ccb_phyaddr_hi32, ®->message_rwbuffer[1]); + writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, \ + ®->inbound_msgaddr0); + if (arcmsr_hba_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: ""set ccb high \ + part physical address timeout\n", + acb->host->host_no); + return 1; } + arcmsr_enable_outbound_ints(acb, intmask_org); + } + } + break; - id = ccb->pcmd->device->id; - lun = ccb->pcmd->device->lun; - if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)){ - if (acb->devstate[id][lun] == ARECA_RAID_GONE) - acb->devstate[id][lun] = ARECA_RAID_GOOD; - ccb->pcmd->result = DID_OK << 16; - arcmsr_ccb_complete(ccb, 1); - } - else { - switch(ccb->arcmsr_cdb.DeviceStatus) { - case ARCMSR_DEV_SELECT_TIMEOUT: { - acb->devstate[id][lun] = ARECA_RAID_GONE; - ccb->pcmd->result = DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; + case ACB_ADAPTER_TYPE_B: { + unsigned long post_queue_phyaddr; + uint32_t *rwbuffer; - case ARCMSR_DEV_ABORTED: + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + uint32_t intmask_org; + intmask_org = arcmsr_disable_outbound_ints(acb); + reg->postq_index = 0; + reg->doneq_index = 0; + writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \ + acb->host->host_no); + return 1; + } + post_queue_phyaddr = cdb_phyaddr + ARCMSR_MAX_FREECCB_NUM * \ + sizeof(struct CommandControlBlock) + offsetof(struct MessageUnit_B, post_qbuffer) ; + rwbuffer = reg->msgcode_rwbuffer_reg; + /* driver "set config" signature */ + writel(ARCMSR_SIGNATURE_SET_CONFIG, rwbuffer++); + /* normal should be zero */ + writel(ccb_phyaddr_hi32, rwbuffer++); + /* postQ size (256 + 8)*4 */ + writel(post_queue_phyaddr, rwbuffer++); + /* doneQ size (256 + 8)*4 */ + writel(post_queue_phyaddr + 1056, rwbuffer++); + /* ccb maxQ size must be --> [(256 + 8)*4]*/ + writel(1056, rwbuffer); + + writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \ + timeout \n",acb->host->host_no); + return 1; + } - case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; + writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: 'can not set diver mode \n"\ + ,acb->host->host_no); + return 1; + } + arcmsr_enable_outbound_ints(acb, intmask_org); + } + break; + } + return 0; +} - case ARCMSR_DEV_CHECK_CONDITION: { - acb->devstate[id][lun] = - ARECA_RAID_GOOD; - arcmsr_report_sense_info(ccb); - arcmsr_ccb_complete(ccb, 1); - } - break; +static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) +{ + uint32_t firmware_state = 0; - default: - printk(KERN_NOTICE - "arcmsr%d: scsi id = %d \ - lun = %d""polling and \ - getting command error \ - done""but got unknown \ - DeviceStatus = 0x%x \n", - acb->host->host_no, id, - lun, ccb->arcmsr_cdb.DeviceStatus); - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - break; - } - } - found = 1; - } + switch (acb->adapter_type) { + + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + do { + firmware_state = readl(®->outbound_msgaddr1); + } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); + } + break; + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + do { + firmware_state = readl(reg->iop2drv_doorbell_reg); + } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); + } + break; } - if (found){ - outbound_intstatus = readl(®->outbound_intstatus) & \ - acb->outbound_int_enable; - writel(outbound_intstatus, ®->outbound_intstatus); - /*clear interrupt*/ +} + +static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; + acb->acb_flags |= ACB_F_MSG_START_BGRB; + writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); + if (arcmsr_hba_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ + rebulid' timeout \n", acb->host->host_no); } - return; } +static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + acb->acb_flags |= ACB_F_MSG_START_BGRB; + writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell_reg); + if (arcmsr_hbb_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ + rebulid' timeout \n",acb->host->host_no); + } +} -static void arcmsr_iop_init(struct AdapterControlBlock *acb) +static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) { - struct MessageUnit __iomem *reg = acb->pmu; - uint32_t intmask_org, mask, outbound_doorbell, firmware_state = 0; + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: + arcmsr_start_hba_bgrb(acb); + break; + case ACB_ADAPTER_TYPE_B: + arcmsr_start_hbb_bgrb(acb); + break; + } +} - do { - firmware_state = readl(®->outbound_msgaddr1); - } while (!(firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)); - intmask_org = readl(®->outbound_intmask) - | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; - arcmsr_get_firmware_spec(acb); +static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb) +{ + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu; + uint32_t outbound_doorbell; + /* empty doorbell Qbuffer if door bell ringed */ + outbound_doorbell = readl(®->outbound_doorbell); + /*clear doorbell interrupt */ + writel(outbound_doorbell, ®->outbound_doorbell); + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); + } + break; - acb->acb_flags |= ACB_F_MSG_START_BGRB; - writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); - if (arcmsr_wait_msgint_ready(acb)) { - printk(KERN_NOTICE "arcmsr%d: " - "wait 'start adapter background rebulid' timeout\n", - acb->host->host_no); + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; + /*clear interrupt and message state*/ + writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg); + writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg); + /* let IOP know data has been read */ + } + break; } +} - outbound_doorbell = readl(®->outbound_doorbell); - writel(outbound_doorbell, ®->outbound_doorbell); - writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); - mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE - | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); - writel(intmask_org & mask, ®->outbound_intmask); - acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; +static void arcmsr_iop_init(struct AdapterControlBlock *acb) +{ + uint32_t intmask_org; + + arcmsr_wait_firmware_ready(acb); + arcmsr_iop_confirm(acb); + /* disable all outbound interrupt */ + intmask_org = arcmsr_disable_outbound_ints(acb); + arcmsr_get_firmware_spec(acb); + /*start background rebuild*/ + arcmsr_start_adapter_bgrb(acb); + /* empty doorbell Qbuffer if door bell ringed */ + arcmsr_clear_doorbell_queue_buffer(acb); + /* enable outbound Post Queue,outbound doorbell Interrupt */ + arcmsr_enable_outbound_ints(acb, intmask_org); acb->acb_flags |= ACB_F_IOP_INITED; } @@ -1422,21 +2096,21 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) /* talk to iop 331 outstanding command aborted */ arcmsr_abort_allcmd(acb); /* wait for 3 sec for all command aborted*/ - msleep_interruptible(3000); + ssleep(3); /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); /* clear all outbound posted Q */ - arcmsr_done4_abort_postqueue(acb); + arcmsr_done4abort_postqueue(acb); for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { ccb->startdone = ARCMSR_CCB_ABORTED; + arcmsr_ccb_complete(ccb, 1); } } /* enable all outbound interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); } - } static int arcmsr_bus_reset(struct scsi_cmnd *cmd) @@ -1450,7 +2124,7 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) for (i = 0; i < 400; i++) { if (!atomic_read(&acb->ccboutstandingcount)) break; - arcmsr_interrupt(acb); + arcmsr_interrupt(acb);/* FIXME: need spinlock */ msleep(25); } arcmsr_iop_reset(acb); @@ -1468,7 +2142,7 @@ static void arcmsr_abort_one_cmd(struct AdapterControlBlock *acb, /* ** Wait for 3 sec for all command done. */ - msleep_interruptible(3000); + ssleep(3); intmask = arcmsr_disable_outbound_ints(acb); arcmsr_polling_ccbdone(acb, ccb); @@ -1515,6 +2189,8 @@ static const char *arcmsr_info(struct Scsi_Host *host) switch (acb->pdev->device) { case PCI_DEVICE_ID_ARECA_1110: + case PCI_DEVICE_ID_ARECA_1200: + case PCI_DEVICE_ID_ARECA_1202: case PCI_DEVICE_ID_ARECA_1210: raid6 = 0; /*FALLTHRU*/ @@ -1522,6 +2198,7 @@ static const char *arcmsr_info(struct Scsi_Host *host) case PCI_DEVICE_ID_ARECA_1130: case PCI_DEVICE_ID_ARECA_1160: case PCI_DEVICE_ID_ARECA_1170: + case PCI_DEVICE_ID_ARECA_1201: case PCI_DEVICE_ID_ARECA_1220: case PCI_DEVICE_ID_ARECA_1230: case PCI_DEVICE_ID_ARECA_1260: @@ -1544,287 +2221,82 @@ static const char *arcmsr_info(struct Scsi_Host *host) ARCMSR_DRIVER_VERSION); return buf; } - +#ifdef CONFIG_SCSI_ARCMSR_AER static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev) { - struct Scsi_Host *host; - struct AdapterControlBlock *acb; - uint8_t bus, dev_fun; - int error; - - error = pci_enable_device(pdev); - if (error) - return PCI_ERS_RESULT_DISCONNECT; - pci_set_master(pdev); - - host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof \ -(struct AdapterControlBlock)); - if (!host) - return PCI_ERS_RESULT_DISCONNECT; - acb = (struct AdapterControlBlock *)host->hostdata; - memset(acb, 0, sizeof (struct AdapterControlBlock)); - - error = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (error) { - error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (error) { - printk(KERN_WARNING - "scsi%d: No suitable DMA mask available\n", - host->host_no); - return PCI_ERS_RESULT_DISCONNECT; - } - } - bus = pdev->bus->number; - dev_fun = pdev->devfn; - acb = (struct AdapterControlBlock *) host->hostdata; - memset(acb, 0, sizeof(struct AdapterControlBlock)); - acb->pdev = pdev; - acb->host = host; - host->max_sectors = ARCMSR_MAX_XFER_SECTORS; - host->max_lun = ARCMSR_MAX_TARGETLUN; - host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/ - host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/ - host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; - host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ - host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; - host->this_id = ARCMSR_SCSI_INITIATOR_ID; - host->unique_id = (bus << 8) | dev_fun; - host->irq = pdev->irq; - error = pci_request_regions(pdev, "arcmsr"); - if (error) - return PCI_ERS_RESULT_DISCONNECT; + struct Scsi_Host *host = pci_get_drvdata(pdev); + struct AdapterControlBlock *acb = + (struct AdapterControlBlock *) host->hostdata; + uint32_t intmask_org; + int i, j; - acb->pmu = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!acb->pmu) { - printk(KERN_NOTICE "arcmsr%d: memory" - " mapping region fail \n", acb->host->host_no); + if (pci_enable_device(pdev)) { return PCI_ERS_RESULT_DISCONNECT; } + pci_set_master(pdev); + intmask_org = arcmsr_disable_outbound_ints(acb); acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | ACB_F_MESSAGE_RQBUFFER_CLEARED | ACB_F_MESSAGE_WQBUFFER_READED); acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; - INIT_LIST_HEAD(&acb->ccb_free_list); - - error = arcmsr_alloc_ccb_pool(acb); - if (error) - return PCI_ERS_RESULT_DISCONNECT; - - error = request_irq(pdev->irq, arcmsr_do_interrupt, - IRQF_DISABLED | IRQF_SHARED, "arcmsr", acb); - if (error) - return PCI_ERS_RESULT_DISCONNECT; - - arcmsr_iop_init(acb); - if (strncmp(acb->firm_version, "V1.42", 5) >= 0) - host->max_sectors = ARCMSR_MAX_XFER_SECTORS_B; - - pci_set_drvdata(pdev, host); - - error = scsi_add_host(host, &pdev->dev); - if (error) - return PCI_ERS_RESULT_DISCONNECT; + for (i = 0; i < ARCMSR_MAX_TARGETID; i++) + for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) + acb->devstate[i][j] = ARECA_RAID_GONE; - error = arcmsr_alloc_sysfs_attr(acb); - if (error) - return PCI_ERS_RESULT_DISCONNECT; + arcmsr_wait_firmware_ready(acb); + arcmsr_iop_confirm(acb); + /* disable all outbound interrupt */ + arcmsr_get_firmware_spec(acb); + /*start background rebuild*/ + arcmsr_start_adapter_bgrb(acb); + /* empty doorbell Qbuffer if door bell ringed */ + arcmsr_clear_doorbell_queue_buffer(acb); + /* enable outbound Post Queue,outbound doorbell Interrupt */ + arcmsr_enable_outbound_ints(acb, intmask_org); + acb->acb_flags |= ACB_F_IOP_INITED; - scsi_scan_host(host); + pci_enable_pcie_error_reporting(pdev); return PCI_ERS_RESULT_RECOVERED; } static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - struct MessageUnit __iomem *reg = acb->pmu; + struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata; struct CommandControlBlock *ccb; - /*clear and abort all outbound posted Q*/ - int i = 0, found = 0; - int id, lun; - uint32_t flag_ccb, outbound_intstatus; - - while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && - (i++ < 256)){ - ccb = (struct CommandControlBlock *)(acb->vir2phy_offset - + (flag_ccb << 5)); - if (ccb){ - if ((ccb->acb != acb)||(ccb->startdone != - ARCMSR_CCB_START)){ - printk(KERN_NOTICE "arcmsr%d: polling \ - get an illegal ccb"" command done ccb = '0x%p'" - "ccboutstandingcount = %d \n", - acb->host->host_no, ccb, - atomic_read(&acb->ccboutstandingcount)); - continue; - } - - id = ccb->pcmd->device->id; - lun = ccb->pcmd->device->lun; - if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { - if (acb->devstate[id][lun] == - ARECA_RAID_GONE) - acb->devstate[id][lun] = - ARECA_RAID_GOOD; - ccb->pcmd->result = DID_OK << 16; - arcmsr_ccb_complete(ccb, 1); - } - else { - switch(ccb->arcmsr_cdb.DeviceStatus) { - case ARCMSR_DEV_SELECT_TIMEOUT: { - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - - case ARCMSR_DEV_ABORTED: - - case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - - case ARCMSR_DEV_CHECK_CONDITION: { - acb->devstate[id][lun] = - ARECA_RAID_GOOD; - arcmsr_report_sense_info(ccb); - arcmsr_ccb_complete(ccb, 1); - } - break; + uint32_t intmask_org; + int i = 0; - default: - printk(KERN_NOTICE - "arcmsr%d: scsi \ - id = %d lun = %d" - " polling and \ - getting command \ - error done" - "but got unknown \ - DeviceStatus = 0x%x \n" - , acb->host->host_no, - id, lun, - ccb->arcmsr_cdb.DeviceStatus); - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - break; - } - } - found = 1; + if (atomic_read(&acb->ccboutstandingcount) != 0) { + /* talk to iop 331 outstanding command aborted */ + arcmsr_abort_allcmd(acb); + /* wait for 3 sec for all command aborted*/ + ssleep(3); + /* disable all outbound interrupt */ + intmask_org = arcmsr_disable_outbound_ints(acb); + /* clear all outbound posted Q */ + arcmsr_done4abort_postqueue(acb); + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + ccb = acb->pccb_pool[i]; + if (ccb->startdone == ARCMSR_CCB_START) { + ccb->startdone = ARCMSR_CCB_ABORTED; + arcmsr_ccb_complete(ccb, 1); } } - if (found){ - outbound_intstatus = readl(®->outbound_intstatus) & - acb->outbound_int_enable; - writel(outbound_intstatus, ®->outbound_intstatus); - /*clear interrupt*/ - } - return; + /* enable all outbound interrupt */ + arcmsr_enable_outbound_ints(acb, intmask_org); + } + pci_disable_device(pdev); } - static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - struct MessageUnit __iomem *reg = acb->pmu; - struct CommandControlBlock *ccb; - /*clear and abort all outbound posted Q*/ - int i = 0, found = 0; - int id, lun; - uint32_t flag_ccb, outbound_intstatus; - - while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && - (i++ < 256)){ - ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + - (flag_ccb << 5)); - if (ccb){ - if ((ccb->acb != acb)||(ccb->startdone != - ARCMSR_CCB_START)){ - printk(KERN_NOTICE - "arcmsr%d: polling get an illegal ccb" - " command done ccb = '0x%p'" - "ccboutstandingcount = %d \n", - acb->host->host_no, ccb, - atomic_read(&acb->ccboutstandingcount)); - continue; - } - - id = ccb->pcmd->device->id; - lun = ccb->pcmd->device->lun; - if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { - if (acb->devstate[id][lun] == ARECA_RAID_GONE) - acb->devstate[id][lun] = ARECA_RAID_GOOD; - ccb->pcmd->result = DID_OK << 16; - arcmsr_ccb_complete(ccb, 1); - } - else { - switch(ccb->arcmsr_cdb.DeviceStatus) { - case ARCMSR_DEV_SELECT_TIMEOUT: { - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_NO_CONNECT << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - - case ARCMSR_DEV_ABORTED: - - case ARCMSR_DEV_INIT_FAIL: { - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - } - break; - - case ARCMSR_DEV_CHECK_CONDITION: { - acb->devstate[id][lun] = - ARECA_RAID_GOOD; - arcmsr_report_sense_info(ccb); - arcmsr_ccb_complete(ccb, 1); - } - break; + struct Scsi_Host *host = pci_get_drvdata(pdev); + struct AdapterControlBlock *acb = \ + (struct AdapterControlBlock *)host->hostdata; - default: - printk(KERN_NOTICE "arcmsr%d: \ - scsi id = %d lun = %d" - " polling and \ - getting command error done" - "but got unknown \ - DeviceStatus = 0x%x \n" - , acb->host->host_no, - id, lun, ccb->arcmsr_cdb.DeviceStatus); - acb->devstate[id][lun] = - ARECA_RAID_GONE; - ccb->pcmd->result = - DID_BAD_TARGET << 16; - arcmsr_ccb_complete(ccb, 1); - break; - } - } - found = 1; - } - } - if (found){ - outbound_intstatus = readl(®->outbound_intstatus) & - acb->outbound_int_enable; - writel(outbound_intstatus, ®->outbound_intstatus); - /*clear interrupt*/ - } - return; + arcmsr_stop_adapter_bgrb(acb); + arcmsr_flush_adapter_cache(acb); } static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, @@ -1840,5 +2312,6 @@ static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, break; default: return PCI_ERS_RESULT_NEED_RESET; - } + } } +#endif diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 715a23e..92dc6ca 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2057,6 +2057,9 @@ #define PCI_DEVICE_ID_ARECA_1130 0x1130 #define PCI_DEVICE_ID_ARECA_1160 0x1160 #define PCI_DEVICE_ID_ARECA_1170 0x1170 +#define PCI_DEVICE_ID_ARECA_1200 0x1200 +#define PCI_DEVICE_ID_ARECA_1201 0x1201 +#define PCI_DEVICE_ID_ARECA_1202 0x1202 #define PCI_DEVICE_ID_ARECA_1210 0x1210 #define PCI_DEVICE_ID_ARECA_1220 0x1220 #define PCI_DEVICE_ID_ARECA_1230 0x1230 -- cgit v1.1 From 685b9e02fb77c6f33319ca59c52ae67e92fb750c Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 15 Sep 2007 11:41:53 -0500 Subject: [SCSI] arcmsr: fix compile problems CC [M] drivers/scsi/arcmsr/arcmsr_hba.o drivers/scsi/arcmsr/arcmsr_attr.c:186: warning: initialization from incompatible pointer type drivers/scsi/arcmsr/arcmsr_attr.c:196: warning: initialization from incompatible pointer type drivers/scsi/arcmsr/arcmsr_attr.c:206: warning: initialization from incompatible pointer type drivers/scsi/arcmsr/arcmsr_hba.c: In function 'arcmsr_alloc_ccb_pool': drivers/scsi/arcmsr/arcmsr_hba.c:329: warning: assignment from incompatible pointer type drivers/scsi/arcmsr/arcmsr_hba.c: At top level: drivers/scsi/arcmsr/arcmsr_hba.c:101: warning: 'arcmsr_pci_error_detected' declared 'static' but never defined drivers/scsi/arcmsr/arcmsr_hba.c:102: warning: 'arcmsr_pci_slot_reset' declared 'static' but never defined The majority being incorrect casting or the fact that binary attributes now take an additional argument. Cc: Nick Cheng Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr_attr.c | 15 ++++++++++++--- drivers/scsi/arcmsr/arcmsr_hba.c | 5 +---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 0f0a1ae..d04d1aa 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -59,7 +59,10 @@ struct class_device_attribute *arcmsr_host_attrs[]; -static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, + struct bin_attribute *bin, + char *buf, loff_t off, + size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); @@ -102,7 +105,10 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, lo return (allxfer_len); } -static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, + struct bin_attribute *bin, + char *buf, loff_t off, + size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); @@ -147,7 +153,10 @@ static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, l } } -static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, size_t count) +static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, + struct bin_attribute *bin, + char *buf, loff_t off, + size_t count) { struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct Scsi_Host *host = class_to_shost(cdev); diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index d70398a..50e1310 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -97,9 +97,6 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb); static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); -static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state); -static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { @@ -326,7 +323,7 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) reg = (struct MessageUnit_B *)(dma_coherent + ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); - acb->pmu = (struct MessageUnit_B *)reg; + acb->pmu = (struct MessageUnit *)reg; mem_base0 = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); mem_base1 = ioremap(pci_resource_start(pdev, 2), -- cgit v1.1 From 29dd3609f2fc70e02ce48123485b14d9417b834f Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:46:51 -0600 Subject: [SCSI] mpt fusion: standardize printks and debug info Standardize all prints using common MYIOC_s_XXX_FMT macro defined in mptbase.h. Currently the driver uses several different methods to display info, where in some cases the "controller name" generating the printk is not provided. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 279 +++++++++++++++++++------------------- drivers/message/fusion/mptctl.c | 233 +++++++++++++++---------------- drivers/message/fusion/mptfc.c | 10 +- drivers/message/fusion/mptsas.c | 253 +++++++++++++++++++--------------- drivers/message/fusion/mptscsih.c | 140 +++++++++---------- drivers/message/fusion/mptspi.c | 54 ++++---- 6 files changed, 505 insertions(+), 464 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 635defd..2c90453 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -349,7 +349,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n", ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function)); - DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr) + DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr); /* Check/log IOC log info */ @@ -451,8 +451,9 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) #ifdef CONFIG_FUSION_LOGGING if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) && !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { - dmfprintk(ioc, printk(KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf)); - DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf) + dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n", + ioc->name, mf)); + DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf); } #endif @@ -517,8 +518,8 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) u16 status; status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; - dcprintk(ioc, printk(KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n", - status, le32_to_cpu(pReply->IOCLogInfo))); + dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n", + ioc->name, status, le32_to_cpu(pReply->IOCLogInfo))); pCfg->status = status; if (status == MPI_IOCSTATUS_SUCCESS) { @@ -783,7 +784,8 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) #ifdef MFCNT if (!ioc->active) - printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n"); + printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame " + "returning NULL!\n", ioc->name); #endif /* If interrupts are not attached, do not return a request frame */ @@ -804,7 +806,8 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) req_idx = req_offset / ioc->req_sz; mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; - ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */ + /* Default, will be changed if necessary in SG generation */ + ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; #ifdef MFCNT ioc->mfcnt++; #endif @@ -815,14 +818,17 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) #ifdef MFCNT if (mf == NULL) - printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth); + printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! " + "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt, + ioc->req_depth); mfcounter++; if (mfcounter == PRINT_MF_COUNT) - printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth); + printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name, + ioc->mfcnt, ioc->req_depth); #endif - dmfprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n", - ioc->name, cb_idx, ioc->id, mf)); + dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n", + ioc->name, cb_idx, ioc->id, mf)); return mf; } @@ -855,7 +861,9 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; - dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx])); + dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d " + "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, + ioc->RequestNB[req_idx])); CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); } @@ -1002,7 +1010,7 @@ mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) return -5; - dhsprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n", + dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n", ioc->name, ii)); CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); @@ -1470,24 +1478,27 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; } ioc->debug_level = mpt_debug_level; + ioc->id = mpt_ids++; + sprintf(ioc->name, "ioc%d", ioc->id); - dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n")); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { - dprintk(ioc, printk(KERN_INFO MYNAM - ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); + dprintk(ioc, printk(MYIOC_s_INFO_FMT + ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name)); } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n"); + printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n", + ioc->name); kfree(ioc); return r; } if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { - dprintk(ioc, printk(KERN_INFO MYNAM - ": Using 64 bit consistent mask\n")); + dprintk(ioc, printk(MYIOC_s_INFO_FMT + ": Using 64 bit consistent mask\n", ioc->name)); } else { - dprintk(ioc, printk(KERN_INFO MYNAM - ": Not using 64 bit consistent mask\n")); + dprintk(ioc, printk(MYIOC_s_INFO_FMT + ": Not using 64 bit consistent mask\n", ioc->name)); } ioc->alloc_total = sizeof(MPT_ADAPTER); @@ -1526,7 +1537,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) /* Find lookup slot. */ INIT_LIST_HEAD(&ioc->list); - ioc->id = mpt_ids++; mem_phys = msize = 0; port = psize = 0; @@ -1552,15 +1562,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) /*mem = ioremap(mem_phys, msize);*/ mem = ioremap(mem_phys, msize); if (mem == NULL) { - printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n"); + printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name); kfree(ioc); return -EINVAL; } ioc->memmap = mem; - dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys)); - dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n", - &ioc->facts, &ioc->pfacts[0])); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", + ioc->name, &ioc->facts, &ioc->pfacts[0])); ioc->mem_phys = mem_phys; ioc->chip = (SYSIF_REGS __iomem *)mem; @@ -1642,8 +1652,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) if (ioc->errata_flag_1064) pci_disable_io_access(pdev); - sprintf(ioc->name, "ioc%d", ioc->id); - spin_lock_init(&ioc->FreeQlock); /* Disable all! */ @@ -1660,9 +1668,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0){ - printk(KERN_WARNING MYNAM - ": WARNING - %s did not initialize properly! (%d)\n", - ioc->name, r); + printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", + ioc->name, r); list_del(&ioc->list); if (ioc->alt_ioc) @@ -1888,8 +1895,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) int irq_allocated = 0; u8 *a; - printk(KERN_INFO MYNAM ": Initiating %s %s\n", - ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); + printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name, + reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); /* Disable reply interrupts (also blocks FreeQ) */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); @@ -1910,21 +1917,19 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { if (hard_reset_done == -4) { - printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n", - ioc->name); + printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n", + ioc->name); if (reset_alt_ioc_active && ioc->alt_ioc) { /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ - dprintk(ioc, printk(KERN_INFO MYNAM - ": alt-%s reply irq re-enabled\n", - ioc->alt_ioc->name)); + dprintk(ioc, printk(MYIOC_s_INFO_FMT + "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name)); CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); ioc->alt_ioc->active = 1; } } else { - printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n", - ioc->name); + printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name); } return -1; } @@ -1936,9 +1941,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) alt_ioc_ready = 1; else - printk(KERN_WARNING MYNAM - ": alt-%s: Not ready WARNING!\n", - ioc->alt_ioc->name); + printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name); } for (ii=0; ii<5; ii++) { @@ -1949,7 +1952,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if (ii == 5) { - dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc)); + dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Retry IocFacts failed rc=%x\n", ioc->name, rc)); ret = -2; } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc); @@ -1958,14 +1962,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if (alt_ioc_ready) { if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); + "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); /* Retry - alt IOC was initialized once */ rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); } if (rc) { dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc)); + "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc)); alt_ioc_ready = 0; reset_alt_ioc_active = 0; } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { @@ -1983,13 +1987,12 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if (ioc->pcidev->irq) { if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev)) printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", - ioc->name); + ioc->name); rc = request_irq(ioc->pcidev->irq, mpt_interrupt, - IRQF_SHARED, ioc->name, ioc); + IRQF_SHARED, ioc->name, ioc); if (rc < 0) { printk(MYIOC_s_ERR_FMT "Unable to allocate " - "interrupt %d!\n", ioc->name, - ioc->pcidev->irq); + "interrupt %d!\n", ioc->name, ioc->pcidev->irq); if (mpt_msi_enable) pci_disable_msi(ioc->pcidev); return -EBUSY; @@ -1998,8 +2001,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ioc->pci_irq = ioc->pcidev->irq; pci_set_master(ioc->pcidev); /* ?? */ pci_set_drvdata(ioc->pcidev, ioc); - dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt " - "%d\n", ioc->name, ioc->pcidev->irq)); + dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " + "%d\n", ioc->name, ioc->pcidev->irq)); } } @@ -2018,8 +2021,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ret = -4; // NEW! if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { - printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n", - ioc->alt_ioc->name, rc); + printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n", + ioc->alt_ioc->name, rc); alt_ioc_ready = 0; reset_alt_ioc_active = 0; } @@ -2028,16 +2031,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { alt_ioc_ready = 0; reset_alt_ioc_active = 0; - printk(KERN_WARNING MYNAM - ": alt-%s: (%d) init failure WARNING!\n", - ioc->alt_ioc->name, rc); + printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n", + ioc->alt_ioc->name, rc); } } if (reason == MPT_HOSTEVENT_IOC_BRINGUP){ if (ioc->upload_fw) { ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "firmware upload required!\n", ioc->name)); + "firmware upload required!\n", ioc->name)); /* Controller is not operational, cannot do upload */ @@ -2053,12 +2055,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) * mpt_diag_reset) */ ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT - ": mpt_upload: alt_%s has cached_fw=%p \n", - ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); + "mpt_upload: alt_%s has cached_fw=%p \n", + ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); ioc->alt_ioc->cached_fw = NULL; } } else { - printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); + printk(MYIOC_s_WARN_FMT + "firmware upload failure!\n", ioc->name); ret = -5; } } @@ -2073,8 +2076,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if (reset_alt_ioc_active && ioc->alt_ioc) { /* (re)Enable alt-IOC! (reply interrupt) */ - dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", - ioc->alt_ioc->name)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n", + ioc->alt_ioc->name)); CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); ioc->alt_ioc->active = 1; } @@ -2127,10 +2130,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) (void) GetLanConfigPages(ioc); a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; dprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "LanAddr = %02X:%02X:%02X:" - "%02X:%02X:%02X\n", - ioc->name, a[5], a[4], - a[3], a[2], a[1], a[0] )); + "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", + ioc->name, a[5], a[4], a[3], a[2], a[1], a[0])); } } else { @@ -2169,16 +2170,16 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { if ((ret == 0) && MptResetHandlers[cb_idx]) { dprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "Calling IOC post_reset handler #%d\n", - ioc->name, cb_idx)); + "Calling IOC post_reset handler #%d\n", + ioc->name, cb_idx)); rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET); handlers++; } if (alt_ioc_ready && MptResetHandlers[cb_idx]) { drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "Calling alt-%s post_reset handler #%d\n", - ioc->name, ioc->alt_ioc->name, cb_idx)); + "Calling IOC post_reset handler #%d\n", + ioc->alt_ioc->name, cb_idx)); rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET); handlers++; } @@ -2218,8 +2219,8 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x," " searching for devfn match on %x or %x\n", - ioc->name, pci_name(pdev), pdev->bus->number, - pdev->devfn, func-1, func+1)); + ioc->name, pci_name(pdev), pdev->bus->number, + pdev->devfn, func-1, func+1)); peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1)); if (!peer) { @@ -2233,15 +2234,15 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) if (_pcidev == peer) { /* Paranoia checks */ if (ioc->alt_ioc != NULL) { - printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n", + printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", ioc->name, ioc->alt_ioc->name); break; } else if (ioc_srch->alt_ioc != NULL) { - printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n", + printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", ioc_srch->name, ioc_srch->alt_ioc->name); break; } - dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n", + dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n", ioc->name, ioc_srch->name)); ioc_srch->alt_ioc = ioc; ioc->alt_ioc = ioc_srch; @@ -2262,10 +2263,11 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) int ret; if (ioc->cached_fw != NULL) { - ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n")); + ddlprintk(ioc, printk(MYIOC_s_INFO_FMT + "mpt_adapter_disable: Pushing FW onto adapter\n", ioc->name)); if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) { - printk(KERN_WARNING MYNAM - ": firmware downloadboot failure (%d)!\n", ret); + printk(MYIOC_s_WARN_FMT "firmware downloadboot failure (%d)!\n", + ioc->name, ret); } } @@ -2277,8 +2279,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) if (ioc->alloc != NULL) { sz = ioc->alloc_sz; - dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n", - ioc->name, ioc->alloc, ioc->alloc_sz)); + dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", + ioc->name, ioc->alloc, ioc->alloc_sz)); pci_free_consistent(ioc->pcidev, sz, ioc->alloc, ioc->alloc_dma); ioc->reply_frames = NULL; @@ -2338,15 +2340,14 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) if (ioc->HostPageBuffer != NULL) { if((ret = mpt_host_page_access_control(ioc, MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { - printk(KERN_ERR MYNAM - ": %s: host page buffers free failed (%d)!\n", - __FUNCTION__, ret); + printk(MYIOC_s_ERR_FMT + "host page buffers free failed (%d)!\n", + ioc->name, ret); } - dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n", + dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n", ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz)); pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, - ioc->HostPageBuffer, - ioc->HostPageBuffer_dma); + ioc->HostPageBuffer, ioc->HostPageBuffer_dma); ioc->HostPageBuffer = NULL; ioc->HostPageBuffer_sz = 0; ioc->alloc_total -= ioc->HostPageBuffer_sz; @@ -2388,7 +2389,7 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) #if defined(CONFIG_MTRR) && 0 if (ioc->mtrr_reg > 0) { mtrr_del(ioc->mtrr_reg, 0, 0); - dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name)); + dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name)); } #endif @@ -2396,8 +2397,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) list_del(&ioc->list); sz_last = ioc->alloc_total; - dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", - ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); + dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n", + ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); if (ioc->alt_ioc) ioc->alt_ioc->alt_ioc = NULL; @@ -2476,7 +2477,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) /* Get current [raw] IOC state */ ioc_state = mpt_GetIocState(ioc, 0); - dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state)); + dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state)); /* * Check to see if IOC got left/stuck in doorbell handshake @@ -2498,9 +2499,9 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { statefault = 2; printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n", - ioc->name); - printk(KERN_WARNING " FAULT code = %04xh\n", - ioc_state & MPI_DOORBELL_DATA_MASK); + ioc->name); + printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n", + ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK); } /* @@ -2516,9 +2517,9 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) * Else, fall through to KickStart case */ whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT; - dinitprintk(ioc, printk(KERN_INFO MYNAM - ": whoinit 0x%x statefault %d force %d\n", - whoinit, statefault, force)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT + "whoinit 0x%x statefault %d force %d\n", + ioc->name, whoinit, statefault, force)); if (whoinit == MPI_WHOINIT_PCI_PEER) return -4; else { @@ -2601,7 +2602,6 @@ mpt_GetIocState(MPT_ADAPTER *ioc, int cooked) /* Get! */ s = CHIPREG_READ32(&ioc->chip->Doorbell); -// dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s)); sc = s & MPI_IOC_STATE_MASK; /* Save! */ @@ -2633,9 +2633,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) /* IOC *must* NOT be in RESET state! */ if (ioc->last_state == MPI_IOC_STATE_RESET) { - printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n", - ioc->name, - ioc->last_state ); + printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n", + ioc->name, ioc->last_state ); return -44; } @@ -2755,8 +2754,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) } ioc->NBShiftFactor = shiftFactor; dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT - "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", - ioc->name, vv, shiftFactor, r)); + "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", + ioc->name, vv, shiftFactor, r)); if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { /* @@ -2809,9 +2808,8 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) /* IOC *must* NOT be in RESET state! */ if (ioc->last_state == MPI_IOC_STATE_RESET) { - printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n", - ioc->name, - ioc->last_state ); + printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n", + ioc->name, ioc->last_state ); return -4; } @@ -2986,7 +2984,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) state = mpt_GetIocState(ioc, 1); count++; } - dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", + dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n", ioc->name, count)); ioc->aen_event_read_flag=0; @@ -3079,10 +3077,9 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc) int sz; sz = ioc->facts.FWImageSize; - dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", - ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); - pci_free_consistent(ioc->pcidev, sz, - ioc->cached_fw, ioc->cached_fw_dma); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", + ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); + pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma); ioc->cached_fw = NULL; return; @@ -3123,8 +3120,8 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) mpt_alloc_fw_memory(ioc, sz); - dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n", - ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n", + ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); if (ioc->cached_fw == NULL) { /* Major Failure. @@ -3155,14 +3152,14 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma); sgeoffset += sizeof(u32) + sizeof(dma_addr_t); - dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n", - prequest, sgeoffset)); - DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest) + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n", + ioc->name, prequest, sgeoffset)); + DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); - dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii)); cmdStatus = -EFAULT; if (ii == 0) { @@ -3433,7 +3430,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) u32 ioc_state=0; int cnt,cntdn; - dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name)); + dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name)); if (ioc->bus_type == SPI) { /* Always issue a Msg Unit Reset first. This will clear some * SCSI bus hang conditions. @@ -3452,7 +3449,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) return hard_reset_done; dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n", - ioc->name)); + ioc->name)); cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */ for (cnt=0; cntname, ioc_state); + dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n", + ioc->name, mpt_GetIocState(ioc, 0))); return -1; } @@ -3658,8 +3655,8 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) } if ((count = mpt_downloadboot(ioc, (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) { - printk(KERN_WARNING MYNAM - ": firmware downloadboot failure (%d)!\n", count); + printk(MYIOC_s_WARN_FMT + "firmware downloadboot failure (%d)!\n", ioc->name, count); } } else { @@ -3802,8 +3799,8 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) if (sleepFlag != CAN_SLEEP) count *= 10; - printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n", - ioc->name, (int)((count+5)/HZ)); + printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", + ioc->name, (int)((count+5)/HZ)); return -ETIME; } @@ -4196,7 +4193,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, } dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req)); - DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req) + DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req); dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n", ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : "")); @@ -4401,7 +4398,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) #endif dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name)); - DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply) + DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply); dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n", ioc->name, t, u16cnt/2)); @@ -4876,8 +4873,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; - ddvprintk(ioc, printk(KERN_INFO MYNAM - " :%s noQas due to Capabilities=%x\n", + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "noQas due to Capabilities=%x\n", ioc->name, pPP0->Capabilities)); } ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; @@ -5785,10 +5782,10 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) CONFIGPARMS *pCfg; unsigned long flags; - dprintk(ioc, printk(KERN_DEBUG MYNAM - ": IOC %s_reset routed to MPT base driver!\n", - reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT + ": IOC %s_reset routed to MPT base driver!\n", + ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); if (reset_phase == MPT_IOC_SETUP_RESET) { ; @@ -6201,8 +6198,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) } if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { - printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n", - rc, ioc->name); + printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc); } ioc->reload_fw = 0; if (ioc->alt_ioc) @@ -6622,12 +6618,12 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply evStr)); #ifdef CONFIG_FUSION_LOGGING - devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM - ": Event data:\n")); + devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT + ": Event data:\n", ioc->name)); for (ii = 0; ii < evDataLen; ii++) devtverboseprintk(ioc, printk(" %08x", le32_to_cpu(pEventReply->Data[ii]))); - devtverboseprintk(ioc, printk(KERN_DEBUG "\n")); + devtverboseprintk(ioc, printk("\n")); #endif /* @@ -7119,8 +7115,8 @@ mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) if (!desc) return; - printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n", - ioc->name, ioc_status, desc, extend_desc); + dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n", + ioc->name, ioc_status, desc, extend_desc)); } /** @@ -7346,7 +7342,8 @@ mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) if (!desc) return; - printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc); + dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n", + ioc->name, status, desc)); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 12dfa2e..5d137a8 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -181,7 +181,6 @@ static inline int mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) { int rc = 0; -// dctlprintk(ioc, printk(KERN_DEBUG MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock)); if (nonblock) { if (!mutex_trylock(&ioc->ioctl->ioctl_mutex)) @@ -190,7 +189,6 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex)) rc = -ERESTARTSYS; } -// dctlprintk(ioc, printk(KERN_DEBUG MYNAM "::mptctl_syscall_down return %d\n", rc)); return rc; } @@ -475,7 +473,7 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { MPT_IOCTL *ioctl = ioc->ioctl; - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": IOC %s_reset routed to IOCTL driver!\n",ioc->name, + dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC %s_reset routed to IOCTL driver!\n", ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); @@ -581,7 +579,7 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) MPT_ADAPTER *iocp = NULL; if (copy_from_user(&khdr, uhdr, sizeof(khdr))) { - printk(KERN_ERR "%s::mptctl_ioctl() @%d - " + printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - " "Unable to copy mpt_ioctl_header data @ %p\n", __FILE__, __LINE__, uhdr); return -EFAULT; @@ -594,13 +592,13 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) iocnumX = khdr.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { - printk(KERN_DEBUG "%s::mptctl_ioctl() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnumX); return -ENODEV; } if (!iocp->active) { - printk(KERN_DEBUG "%s::mptctl_ioctl() @%d - Controller disabled.\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n", __FILE__, __LINE__); return -EFAULT; } @@ -667,14 +665,14 @@ static int mptctl_do_reset(unsigned long arg) MPT_ADAPTER *iocp; if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) { - printk(KERN_ERR "%s@%d::mptctl_do_reset - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - " "Unable to copy mpt_ioctl_diag_reset struct @ %p\n", __FILE__, __LINE__, urinfo); return -EFAULT; } if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) { - printk(KERN_DEBUG "%s@%d::mptctl_do_reset - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n", __FILE__, __LINE__, krinfo.hdr.iocnum); return -ENODEV; /* (-6) No such device or address */ } @@ -683,8 +681,8 @@ static int mptctl_do_reset(unsigned long arg) iocp->name)); if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) { - printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n", - __FILE__, __LINE__); + printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n", + iocp->name, __FILE__, __LINE__); return -1; } @@ -715,7 +713,7 @@ mptctl_fw_download(unsigned long arg) struct mpt_fw_xfer kfwdl; if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) { - printk(KERN_ERR "%s@%d::_ioctl_fwdl - " + printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - " "Unable to copy mpt_fw_xfer struct @ %p\n", __FILE__, __LINE__, ufwdl); return -EFAULT; @@ -763,7 +761,8 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) pFWDownloadReply_t ReplyMsg = NULL; if (mpt_verify_adapter(ioc, &iocp) < 0) { - printk(KERN_DEBUG "ioctl_fwdl - ioc%d not found!\n", ioc); + printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n", + ioc); return -ENODEV; /* (-6) No such device or address */ } else { @@ -875,9 +874,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address); n++; if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { - printk(KERN_ERR "%s@%d::_ioctl_fwdl - " - "Unable to copy f/w buffer hunk#%d @ %p\n", - __FILE__, __LINE__, n, ufwbuf); + printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - " + "Unable to copy f/w buffer hunk#%d @ %p\n", + iocp->name, __FILE__, __LINE__, n, ufwbuf); goto fwdl_out; } fw_bytes_copied += bl->len; @@ -913,21 +912,22 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) ReplyMsg = (pFWDownloadReply_t)iocp->ioctl->ReplyFrame; iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK; if (iocstat == MPI_IOCSTATUS_SUCCESS) { - printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name); + printk(MYIOC_s_INFO_FMT "F/W update successfull!\n", iocp->name); return 0; } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) { - printk(KERN_WARNING MYNAM ": ?Hmmm... %s says it doesn't support F/W download!?!\n", - iocp->name); - printk(KERN_WARNING MYNAM ": (time to go bang on somebodies door)\n"); + printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n", + iocp->name); + printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n", + iocp->name); return -EBADRQC; } else if (iocstat == MPI_IOCSTATUS_BUSY) { - printk(KERN_WARNING MYNAM ": Warning! %s says: IOC_BUSY!\n", iocp->name); - printk(KERN_WARNING MYNAM ": (try again later?)\n"); + printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name); + printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name); return -EBUSY; } else { - printk(KERN_WARNING MYNAM "::ioctl_fwdl() ERROR! %s returned [bad] status = %04xh\n", - iocp->name, iocstat); - printk(KERN_WARNING MYNAM ": (bad VooDoo)\n"); + printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n", + iocp->name, iocstat); + printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name); return -ENOMSG; } return 0; @@ -1014,10 +1014,10 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags, if (buflist[buflist_ent].kptr == NULL) { alloc_sz = alloc_sz / 2; if (alloc_sz == 0) { - printk(KERN_WARNING MYNAM "-SG: No can do - " - "not enough memory! :-(\n"); - printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n", - numfrags); + printk(MYIOC_s_WARN_FMT "-SG: No can do - " + "not enough memory! :-(\n", ioc->name); + printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n", + ioc->name, numfrags); goto free_and_fail; } continue; @@ -1040,18 +1040,19 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags, /* Need to chain? */ if (fragcnt == sg_spill) { - printk(KERN_WARNING MYNAM "-SG: No can do - " "Chain required! :-(\n"); - printk(KERN_WARNING MYNAM "(freeing %d frags)\n", numfrags); + printk(MYIOC_s_WARN_FMT + "-SG: No can do - " "Chain required! :-(\n", ioc->name); + printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags); goto free_and_fail; } /* overflow check... */ if (numfrags*8 > MAX_SGL_BYTES){ /* GRRRRR... */ - printk(KERN_WARNING MYNAM "-SG: No can do - " - "too many SG frags! :-(\n"); - printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n", - numfrags); + printk(MYIOC_s_WARN_FMT "-SG: No can do - " + "too many SG frags! :-(\n", ioc->name); + printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n", + ioc->name, numfrags); goto free_and_fail; } } @@ -1072,8 +1073,6 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags, free_and_fail: if (sglbuf != NULL) { - int i; - for (i = 0; i < numfrags; i++) { dma_addr_t dma_addr; u8 *kptr; @@ -1195,13 +1194,13 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) karg = kmalloc(data_size, GFP_KERNEL); if (karg == NULL) { - printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n", + printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n", __FILE__, __LINE__); return -ENOMEM; } if (copy_from_user(karg, uarg, data_size)) { - printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - " "Unable to read in mpt_ioctl_iocinfo struct @ %p\n", __FILE__, __LINE__, uarg); kfree(karg); @@ -1210,7 +1209,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); kfree(karg); return -ENODEV; @@ -1218,9 +1217,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) /* Verify the data transfer size is correct. */ if (karg->hdr.maxDataSize != data_size) { - printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - " "Structure size mismatch. Command not completed.\n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); kfree(karg); return -EFAULT; } @@ -1296,9 +1295,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, karg, data_size)) { - printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - " "Unable to write out mpt_ioctl_iocinfo struct @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); kfree(karg); return -EFAULT; } @@ -1335,7 +1334,7 @@ mptctl_gettargetinfo (unsigned long arg) struct scsi_device *sdev; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { - printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - " "Unable to read in mpt_ioctl_targetinfo struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1343,7 +1342,7 @@ mptctl_gettargetinfo (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1359,8 +1358,8 @@ mptctl_gettargetinfo (unsigned long arg) port = karg.hdr.port; if (maxWordsLeft <= 0) { - printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n", - __FILE__, __LINE__); + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n", + ioc->name, __FILE__, __LINE__); return -ENOMEM; } @@ -1380,8 +1379,8 @@ mptctl_gettargetinfo (unsigned long arg) */ pmem = kzalloc(numBytes, GFP_KERNEL); if (!pmem) { - printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n", - __FILE__, __LINE__); + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n", + ioc->name, __FILE__, __LINE__); return -ENOMEM; } pdata = (int *) pmem; @@ -1410,9 +1409,9 @@ mptctl_gettargetinfo (unsigned long arg) */ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_targetinfo))) { - printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); kfree(pmem); return -EFAULT; } @@ -1420,9 +1419,9 @@ mptctl_gettargetinfo (unsigned long arg) /* Copy the remaining data from kernel memory to user memory */ if (copy_to_user(uarg->targetInfo, pmem, numBytes)) { - printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, pdata); + ioc->name, __FILE__, __LINE__, pdata); kfree(pmem); return -EFAULT; } @@ -1449,7 +1448,7 @@ mptctl_readtest (unsigned long arg) int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) { - printk(KERN_ERR "%s@%d::mptctl_readtest - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - " "Unable to read in mpt_ioctl_test struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1457,7 +1456,7 @@ mptctl_readtest (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_readtest() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1481,9 +1480,9 @@ mptctl_readtest (unsigned long arg) /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) { - printk(KERN_ERR "%s@%d::mptctl_readtest - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - " "Unable to write out mpt_ioctl_test struct @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); return -EFAULT; } @@ -1510,7 +1509,7 @@ mptctl_eventquery (unsigned long arg) int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) { - printk(KERN_ERR "%s@%d::mptctl_eventquery - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - " "Unable to read in mpt_ioctl_eventquery struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1518,7 +1517,7 @@ mptctl_eventquery (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_eventquery() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1531,9 +1530,9 @@ mptctl_eventquery (unsigned long arg) /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) { - printk(KERN_ERR "%s@%d::mptctl_eventquery - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - " "Unable to write out mpt_ioctl_eventquery struct @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); return -EFAULT; } return 0; @@ -1549,7 +1548,7 @@ mptctl_eventenable (unsigned long arg) int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) { - printk(KERN_ERR "%s@%d::mptctl_eventenable - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - " "Unable to read in mpt_ioctl_eventenable struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1557,7 +1556,7 @@ mptctl_eventenable (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_eventenable() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1570,7 +1569,9 @@ mptctl_eventenable (unsigned long arg) int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); ioc->events = kzalloc(sz, GFP_KERNEL); if (!ioc->events) { - printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); + printk(MYIOC_s_ERR_FMT + ": ERROR - Insufficient memory to add adapter!\n", + ioc->name); return -ENOMEM; } ioc->alloc_total += sz; @@ -1596,7 +1597,7 @@ mptctl_eventreport (unsigned long arg) int numBytes, maxEvents, max; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) { - printk(KERN_ERR "%s@%d::mptctl_eventreport - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - " "Unable to read in mpt_ioctl_eventreport struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1604,7 +1605,7 @@ mptctl_eventreport (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_eventreport() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1630,9 +1631,9 @@ mptctl_eventreport (unsigned long arg) */ numBytes = max * sizeof(MPT_IOCTL_EVENTS); if (copy_to_user(uarg->eventData, ioc->events, numBytes)) { - printk(KERN_ERR "%s@%d::mptctl_eventreport - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - " "Unable to write out mpt_ioctl_eventreport struct @ %p\n", - __FILE__, __LINE__, ioc->events); + ioc->name, __FILE__, __LINE__, ioc->events); return -EFAULT; } @@ -1650,7 +1651,7 @@ mptctl_replace_fw (unsigned long arg) int newFwSize; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) { - printk(KERN_ERR "%s@%d::mptctl_replace_fw - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1658,7 +1659,7 @@ mptctl_replace_fw (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1688,9 +1689,9 @@ mptctl_replace_fw (unsigned long arg) /* Copy the data from user memory to kernel space */ if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) { - printk(KERN_ERR "%s@%d::mptctl_replace_fw - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw image " - "@ %p\n", __FILE__, __LINE__, uarg); + "@ %p\n", ioc->name, __FILE__, __LINE__, uarg); mpt_free_fw_memory(ioc); return -EFAULT; } @@ -1724,7 +1725,7 @@ mptctl_mpt_command (unsigned long arg) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) { - printk(KERN_ERR "%s@%d::mptctl_mpt_command - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - " "Unable to read in mpt_ioctl_command struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -1732,7 +1733,7 @@ mptctl_mpt_command (unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -1777,17 +1778,17 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } if (!ioc->ioctl) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - " "No memory available during driver init.\n", __FILE__, __LINE__); return -ENOMEM; } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - " "Busy with IOC Reset \n", __FILE__, __LINE__); return -EBUSY; } @@ -1801,9 +1802,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) sz += sizeof(dma_addr_t) + sizeof(u32); if (sz > ioc->req_sz) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Request frame too large (%d) maximum (%d)\n", - __FILE__, __LINE__, sz, ioc->req_sz); + ioc->name, __FILE__, __LINE__, sz, ioc->req_sz); return -EFAULT; } @@ -1821,9 +1822,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) * Request frame in user space */ if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to read MF from mpt_ioctl_command struct @ %p\n", - __FILE__, __LINE__, mfPtr); + ioc->name, __FILE__, __LINE__, mfPtr); rc = -EFAULT; goto done_free_mem; } @@ -1874,17 +1875,17 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; if (pScsiReq->TargetID > id) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Target ID out of bounds. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -ENODEV; goto done_free_mem; } if (pScsiReq->Bus >= ioc->number_of_buses) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Target Bus out of bounds. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -ENODEV; goto done_free_mem; } @@ -1936,9 +1937,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ioc->ioctl->id = pScsiReq->TargetID; } else { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver is not loaded. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; } @@ -1955,9 +1956,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) case MPI_FUNCTION_SATA_PASSTHROUGH: if (!ioc->sh) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver is not loaded. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; } @@ -2014,9 +2015,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ioc->ioctl->reset = MPTCTL_RESET_OK; ioc->ioctl->id = pScsiReq->TargetID; } else { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver is not loaded. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; } @@ -2026,9 +2027,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) { MPT_SCSI_HOST *hd = NULL; if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver not loaded or SCSI host not found. \n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; } else if (mptctl_set_tm_flags(hd) != 0) { @@ -2059,9 +2060,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) || (pInit->HostMfaHighAddr != high_addr) || (pInit->SenseBufferHighAddr != sense_high)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n", - __FILE__, __LINE__); + ioc->name, __FILE__, __LINE__); rc = -EFAULT; goto done_free_mem; } @@ -2092,9 +2093,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) MPI_FUNCTION_LAN_RESET */ - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Illegal request (function 0x%x) \n", - __FILE__, __LINE__, hdr->Function); + ioc->name, __FILE__, __LINE__, hdr->Function); rc = -EFAULT; goto done_free_mem; } @@ -2151,11 +2152,11 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) if (copy_from_user(bufOut.kptr, karg.dataOutBufPtr, bufOut.len)) { - printk(KERN_ERR + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - Unable " "to read user data " "struct @ %p\n", - __FILE__, __LINE__,karg.dataOutBufPtr); + ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr); rc = -EFAULT; goto done_free_mem; } @@ -2242,10 +2243,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) if (sz > 0) { if (copy_to_user(karg.replyFrameBufPtr, &ioc->ioctl->ReplyFrame, sz)){ - printk(KERN_ERR + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write out reply frame %p\n", - __FILE__, __LINE__, karg.replyFrameBufPtr); + ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr); rc = -ENODATA; goto done_free_mem; } @@ -2258,9 +2259,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE); if (sz > 0) { if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write sense data to user %p\n", - __FILE__, __LINE__, + ioc->name, __FILE__, __LINE__, karg.senseDataPtr); rc = -ENODATA; goto done_free_mem; @@ -2276,9 +2277,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) if (copy_to_user(karg.dataInBufPtr, bufIn.kptr, karg.dataInSize)) { - printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write data to user %p\n", - __FILE__, __LINE__, + ioc->name, __FILE__, __LINE__, karg.dataInBufPtr); rc = -ENODATA; } @@ -2349,7 +2350,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) return -EFAULT; if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) { - printk(KERN_ERR "%s@%d::mptctl_hp_host_info - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - " "Unable to read in hp_host_info struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -2357,7 +2358,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } @@ -2538,9 +2539,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { - printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - " "Unable to write out hp_host_info @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2576,7 +2577,7 @@ mptctl_hp_targetinfo(unsigned long arg) int tmp, np, rc = 0; if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) { - printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - " + printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - " "Unable to read in hp_host_targetinfo struct @ %p\n", __FILE__, __LINE__, uarg); return -EFAULT; @@ -2584,11 +2585,11 @@ mptctl_hp_targetinfo(unsigned long arg) if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { - printk(KERN_DEBUG "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", + printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", __FILE__, __LINE__, iocnum); return -ENODEV; } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_targetinfo called.\n", + dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n", ioc->name)); /* There is nothing to do for FCP parts. @@ -2689,9 +2690,9 @@ mptctl_hp_targetinfo(unsigned long arg) /* Copy the data from kernel memory to user memory */ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) { - printk(KERN_ERR "%s@%d::mptctl_hp_target_info - " + printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n", - __FILE__, __LINE__, uarg); + ioc->name, __FILE__, __LINE__, uarg); return -EFAULT; } @@ -2741,7 +2742,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd, if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n", - __LINE__, iocnumX); + __LINE__, iocnumX); return -ENODEV; } @@ -2781,7 +2782,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd, if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n", - __LINE__, iocnumX); + __LINE__, iocnumX); return -ENODEV; } diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 0586f87..6c62994 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -204,7 +204,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, "DID_IMM_RETRY, deferring %s recovery.\n", ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun,caller)); + SCpnt->device->id, SCpnt->device->lun, caller)); msleep(1000); spin_lock_irqsave(shost->host_lock, flags); } @@ -216,7 +216,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, "port state %d, vdev %p.\n", caller, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun,ready, + SCpnt->device->id, SCpnt->device->lun, ready, SCpnt->device->hostdata)); return FAILED; } @@ -224,7 +224,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, "%s.%d: %d:%d, executing recovery.\n", caller, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun)); + SCpnt->device->id, SCpnt->device->lun)); return (*func)(SCpnt); } @@ -1320,8 +1320,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->transportt = mptfc_transport_template; error = scsi_add_host (sh, &ioc->pcidev->dev); if(error) { - dprintk(ioc, printk(KERN_ERR MYNAM - "scsi_add_host failed\n")); + dprintk(ioc, printk(MYIOC_s_ERR_FMT + "scsi_add_host failed\n", ioc->name)); goto out_mptfc_probe; } diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 4333449..ecaa1d6 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -100,19 +100,25 @@ static void mptsas_hotplug_work(struct work_struct *work); static void mptsas_print_phy_data(MPT_ADAPTER *ioc, MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) { - dsasprintk(ioc, printk(KERN_DEBUG "---- IO UNIT PAGE 0 ------------\n")); - dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n", - le16_to_cpu(phy_data->AttachedDeviceHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Controller Handle=0x%X\n", - le16_to_cpu(phy_data->ControllerDevHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Port=0x%X\n", phy_data->Port)); - dsasprintk(ioc, printk(KERN_DEBUG "Port Flags=0x%X\n", phy_data->PortFlags)); - dsasprintk(ioc, printk(KERN_DEBUG "PHY Flags=0x%X\n", phy_data->PhyFlags)); - dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate)); - dsasprintk(ioc, printk(KERN_DEBUG "Controller PHY Device Info=0x%X\n", - le32_to_cpu(phy_data->ControllerPhyDeviceInfo))); - dsasprintk(ioc, printk(KERN_DEBUG "DiscoveryStatus=0x%X\n\n", - le32_to_cpu(phy_data->DiscoveryStatus))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "---- IO UNIT PAGE 0 ------------\n", ioc->name)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n", + ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n", + ioc->name, le16_to_cpu(phy_data->ControllerDevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n", + ioc->name, phy_data->Port)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n", + ioc->name, phy_data->PortFlags)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n", + ioc->name, phy_data->PhyFlags)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n", + ioc->name, phy_data->NegotiatedLinkRate)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Controller PHY Device Info=0x%X\n", ioc->name, + le32_to_cpu(phy_data->ControllerPhyDeviceInfo))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n", + ioc->name, le32_to_cpu(phy_data->DiscoveryStatus))); } static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0) @@ -121,27 +127,41 @@ static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0) memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); - dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 0 ------------\n")); - dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n", - le16_to_cpu(pg0->AttachedDevHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", - (unsigned long long)le64_to_cpu(sas_address))); - dsasprintk(ioc, printk(KERN_DEBUG "Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier)); - dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Info=0x%X\n", - le32_to_cpu(pg0->AttachedDeviceInfo))); - dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate)); - dsasprintk(ioc, printk(KERN_DEBUG "Change Count=0x%X\n", pg0->ChangeCount)); - dsasprintk(ioc, printk(KERN_DEBUG "PHY Info=0x%X\n\n", le32_to_cpu(pg0->PhyInfo))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "---- SAS PHY PAGE 0 ------------\n", ioc->name)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Attached Device Handle=0x%X\n", ioc->name, + le16_to_cpu(pg0->AttachedDevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n", + ioc->name, (unsigned long long)le64_to_cpu(sas_address))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Attached PHY Identifier=0x%X\n", ioc->name, + pg0->AttachedPhyIdentifier)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n", + ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n", + ioc->name, pg0->ProgrammedLinkRate)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n", + ioc->name, pg0->ChangeCount)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n", + ioc->name, le32_to_cpu(pg0->PhyInfo))); } static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1) { - dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 1 ------------\n")); - dsasprintk(ioc, printk(KERN_DEBUG "Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount)); - dsasprintk(ioc, printk(KERN_DEBUG "Running Disparity Error Count=0x%x\n", - pg1->RunningDisparityErrorCount)); - dsasprintk(ioc, printk(KERN_DEBUG "Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount)); - dsasprintk(ioc, printk(KERN_DEBUG "PHY Reset Problem Count=0x%x\n\n", pg1->PhyResetProblemCount)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "---- SAS PHY PAGE 1 ------------\n", ioc->name)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n", + ioc->name, pg1->InvalidDwordCount)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Running Disparity Error Count=0x%x\n", ioc->name, + pg1->RunningDisparityErrorCount)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Loss Dword Synch Count=0x%x\n", ioc->name, + pg1->LossDwordSynchCount)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "PHY Reset Problem Count=0x%x\n\n", ioc->name, + pg1->PhyResetProblemCount)); } static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0) @@ -150,37 +170,53 @@ static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0) memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); - dsasprintk(ioc, printk(KERN_DEBUG "---- SAS DEVICE PAGE 0 ---------\n")); - dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Slot=0x%X\n", le16_to_cpu(pg0->Slot))); - dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", (unsigned long long) - le64_to_cpu(sas_address))); - dsasprintk(ioc, printk(KERN_DEBUG "Target ID=0x%X\n", pg0->TargetID)); - dsasprintk(ioc, printk(KERN_DEBUG "Bus=0x%X\n", pg0->Bus)); - /* The PhyNum field specifies the PHY number of the parent - * device this device is linked to - */ - dsasprintk(ioc, printk(KERN_DEBUG "Parent Phy Num=0x%X\n", pg0->PhyNum)); - dsasprintk(ioc, printk(KERN_DEBUG "Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus))); - dsasprintk(ioc, printk(KERN_DEBUG "Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo))); - dsasprintk(ioc, printk(KERN_DEBUG "Flags=0x%X\n", le16_to_cpu(pg0->Flags))); - dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n\n", pg0->PhysicalPort)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "---- SAS DEVICE PAGE 0 ---------\n", ioc->name)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n", + ioc->name, le16_to_cpu(pg0->DevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n", + ioc->name, le16_to_cpu(pg0->ParentDevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n", + ioc->name, le16_to_cpu(pg0->EnclosureHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n", + ioc->name, le16_to_cpu(pg0->Slot))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n", + ioc->name, (unsigned long long)le64_to_cpu(sas_address))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n", + ioc->name, pg0->TargetID)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n", + ioc->name, pg0->Bus)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n", + ioc->name, pg0->PhyNum)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n", + ioc->name, le16_to_cpu(pg0->AccessStatus))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n", + ioc->name, le32_to_cpu(pg0->DeviceInfo))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n", + ioc->name, le16_to_cpu(pg0->Flags))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n", + ioc->name, pg0->PhysicalPort)); } static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1) { - dsasprintk(ioc, printk(KERN_DEBUG "---- SAS EXPANDER PAGE 1 ------------\n")); - dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n", pg1->PhysicalPort)); - dsasprintk(ioc, printk(KERN_DEBUG "PHY Identifier=0x%X\n", pg1->PhyIdentifier)); - dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate)); - dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate)); - dsasprintk(ioc, printk(KERN_DEBUG "Hardware Link Rate=0x%X\n", pg1->HwLinkRate)); - dsasprintk(ioc, printk(KERN_DEBUG "Owner Device Handle=0x%X\n", - le16_to_cpu(pg1->OwnerDevHandle))); - dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n\n", - le16_to_cpu(pg1->AttachedDevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n", + ioc->name, pg1->PhysicalPort)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n", + ioc->name, pg1->PhyIdentifier)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n", + ioc->name, pg1->NegotiatedLinkRate)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n", + ioc->name, pg1->ProgrammedLinkRate)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n", + ioc->name, pg1->HwLinkRate)); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n", + ioc->name, le16_to_cpu(pg1->OwnerDevHandle))); + dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Attached Device Handle=0x%X\n\n", ioc->name, + le16_to_cpu(pg1->AttachedDevHandle))); } static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy) @@ -250,8 +286,8 @@ mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_detai port_info = port_details->port_info; phy_info = port_info->phy_info; - dsaswideprintk(ioc, printk(KERN_DEBUG "%s: [%p]: num_phys=%02d " - "bitmask=0x%016llX\n", __FUNCTION__, port_details, + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d " + "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, port_details->num_phys, (unsigned long long) port_details->phy_bitmask)); @@ -278,14 +314,15 @@ mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rp { if (phy_info->port_details) { phy_info->port_details->rphy = rphy; - dsaswideprintk(ioc, printk(KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n", + ioc->name, rphy)); } if (rphy) { - dsaswideprintk(ioc, dev_printk(KERN_DEBUG, - &rphy->dev, "add:")); - dsaswideprintk(ioc, printk(KERN_DEBUG "rphy=%p release=%p\n", - rphy, rphy->dev.release)); + dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT, + &rphy->dev, "add:", ioc->name)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n", + ioc->name, rphy, rphy->dev.release)); } } @@ -305,10 +342,10 @@ mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_po phy_info->port_details->port = port; if (port) { - dsaswideprintk(ioc, dev_printk(KERN_DEBUG, - &port->dev, "add:")); - dsaswideprintk(ioc, printk(KERN_DEBUG "port=%p release=%p\n", - port, port->dev.release)); + dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT, + &port->dev, "add:", ioc->name)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n", + ioc->name, port, port->dev.release)); } } @@ -359,9 +396,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) * Removing a phy from a port, letting the last * phy be removed by firmware events. */ - dsaswideprintk(ioc, printk(KERN_DEBUG - "%s: [%p]: deleting phy = %d\n", - __FUNCTION__, port_details, i)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "%s: [%p]: deleting phy = %d\n", + ioc->name, __FUNCTION__, port_details, i)); port_details->num_phys--; port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); @@ -375,8 +412,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) phy_info = port_info->phy_info; for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { sas_address = phy_info->attached.sas_address; - dsaswideprintk(ioc, printk(KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", - i, (unsigned long long)sas_address)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n", + ioc->name, i, (unsigned long long)sas_address)); if (!sas_address) continue; port_details = phy_info->port_details; @@ -394,9 +431,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) port_details->phy_bitmask |= (1 << phy_info->phy_id); phy_info->sas_port_add_phy=1; - dsaswideprintk(ioc, printk(KERN_DEBUG "\t\tForming port\n\t\t" + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t" "phy_id=%d sas_address=0x%018llX\n", - i, (unsigned long long)sas_address)); + ioc->name, i, (unsigned long long)sas_address)); phy_info->port_details = port_details; } @@ -411,9 +448,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) continue; if (phy_info_cmp->port_details == port_details ) continue; - dsaswideprintk(ioc, printk(KERN_DEBUG + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tphy_id=%d sas_address=0x%018llX\n", - j, (unsigned long long) + ioc->name, j, (unsigned long long) phy_info_cmp->attached.sas_address)); if (phy_info_cmp->port_details) { port_details->rphy = @@ -445,15 +482,15 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) port_details = port_info->phy_info[i].port_details; if (!port_details) continue; - dsaswideprintk(ioc, printk(KERN_DEBUG + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: phy_id=%02d num_phys=%02d " - "bitmask=0x%016llX\n", __FUNCTION__, + "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details, i, port_details->num_phys, (unsigned long long)port_details->phy_bitmask)); - dsaswideprintk(ioc, printk(KERN_DEBUG"\t\tport = %p rphy=%p\n", - port_details->port, port_details->rphy)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n", + ioc->name, port_details->port, port_details->rphy)); } - dsaswideprintk(ioc, printk(KERN_DEBUG"\n")); + dsaswideprintk(ioc, printk("\n")); mutex_unlock(&ioc->sas_topology_mutex); } @@ -1129,10 +1166,8 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) /* process the completed Reply Message Frame */ reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { - printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", - __FUNCTION__, - reply->IOCStatus, - reply->IOCLogInfo); + printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", + ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo); error = -ENXIO; goto out_unlock; } @@ -1218,16 +1253,16 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, u64 sas_address = 0; if (!rsp) { - printk(KERN_ERR "%s: the smp response space is missing\n", - __FUNCTION__); + printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", + ioc->name, __FUNCTION__); return -EINVAL; } /* do we need to support multiple segments? */ if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { - printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n", - __FUNCTION__, req->bio->bi_vcnt, req->data_len, - rsp->bio->bi_vcnt, rsp->data_len); + printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n", + ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len, + rsp->bio->bi_vcnt, rsp->data_len); return -EINVAL; } @@ -1292,7 +1327,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); if (!timeleft) { - printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__); + printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__); /* On timeout reset the board */ mpt_HardResetHandler(ioc, CAN_SLEEP); ret = -ETIMEDOUT; @@ -1307,8 +1342,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, memcpy(req->sense, smprep, sizeof(*smprep)); req->sense_len = sizeof(*smprep); } else { - printk(KERN_ERR "%s: smp passthru reply failed to be returned\n", - __FUNCTION__); + printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", + ioc->name, __FUNCTION__); ret = -ENXIO; } unmap: @@ -1952,12 +1987,12 @@ static int mptsas_probe_one_phy(struct device *dev, goto out; } mptsas_set_port(ioc, phy_info, port); - dsaswideprintk(ioc, printk(KERN_DEBUG + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_alloc: port=%p dev=%p port_id=%d\n", - port, dev, port->port_identifier)); + ioc->name, port, dev, port->port_identifier)); } - dsaswideprintk(ioc, printk(KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", - phy_info->phy_id)); + dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n", + ioc->name, phy_info->phy_id)); sas_port_add_phy(port, phy_info->phy); phy_info->sas_port_add_phy = 0; } @@ -2259,8 +2294,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) expander_sas_address) continue; dsaswideprintk(ioc, - dev_printk(KERN_DEBUG, &port->dev, - "delete port (%d)\n", port->port_identifier)); + dev_printk(MYIOC_s_DEBUG_FMT, &port->dev, + "delete port (%d)\n", ioc->name, port->port_identifier)); sas_port_delete(port); mptsas_port_delete(ioc, phy_info->port_details); } @@ -2503,7 +2538,7 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id) ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) { - printk(KERN_WARNING "mptsas: lost hotplug event\n"); + printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name); goto out; } @@ -2644,8 +2679,8 @@ mptsas_hotplug_work(struct work_struct *work) printk(MYIOC_s_INFO_FMT "removing %s device, channel %d, id %d, phy %d\n", ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); - dev_printk(KERN_DEBUG, &port->dev, - "delete port (%d)\n", port->port_identifier); + dev_printk(MYIOC_s_DEBUG_FMT, &port->dev, + "delete port (%d)\n", ioc->name, port->port_identifier); sas_port_delete(port); mptsas_port_delete(ioc, phy_info->port_details); break; @@ -2686,8 +2721,8 @@ mptsas_hotplug_work(struct work_struct *work) if (!vtarget) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT - "%s: exit at line=%d\n", ioc->name, - __FUNCTION__, __LINE__)); + "%s: exit at line=%d\n", ioc->name, + __FUNCTION__, __LINE__)); break; } /* @@ -2820,7 +2855,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) { - printk(KERN_WARNING "mptsas: lost hotplug event\n"); + printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name); break; } @@ -2879,7 +2914,7 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc, ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) { - printk(KERN_WARNING "mptsas: lost hotplug event\n"); + printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name); return; } @@ -3230,8 +3265,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) error = scsi_add_host(sh, &ioc->pcidev->dev); if (error) { - dprintk(ioc, printk(KERN_ERR MYNAM - "scsi_add_host failed\n")); + dprintk(ioc, printk(MYIOC_s_ERR_FMT + "scsi_add_host failed\n", ioc->name)); goto out_mptsas_probe; } diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index f00c100..8081fe7 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -192,7 +192,7 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex) int chain_idx; dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n", - ioc->name)); + ioc->name)); spin_lock_irqsave(&ioc->FreeQlock, flags); if (!list_empty(&ioc->FreeChainQ)) { int offset; @@ -203,13 +203,14 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex) offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer; chain_idx = offset / ioc->req_sz; rc = SUCCESS; - dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n", - ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx)); + dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n", + ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx)); } else { rc = FAILED; chain_idx = MPT_HOST_NO_CHAIN; - dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer failed\n", - ioc->name)); + dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n", + ioc->name)); } spin_unlock_irqrestore(&ioc->FreeQlock, flags); @@ -419,8 +420,8 @@ nextSGEset: * out the Address and Flags fields. */ chainSge = (char *) psge; - dsgprintk(ioc, printk(KERN_DEBUG " Current buff @ %p (index 0x%x)", - psge, req_idx)); + dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Current buff @ %p (index 0x%x)", + ioc->name, psge, req_idx)); /* Start the SGE for the next buffer */ @@ -428,8 +429,8 @@ nextSGEset: sgeOffset = 0; sg_done = 0; - dsgprintk(ioc, printk(KERN_DEBUG " Chain buff @ %p (index 0x%x)\n", - psge, chain_idx)); + dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Chain buff @ %p (index 0x%x)\n", + ioc->name, psge, chain_idx)); /* Start the SGE for the next buffer */ @@ -588,18 +589,17 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc } scsi_print_command(sc); - printk(KERN_DEBUG "\tfw_channel = %d, fw_id = %d\n", - pScsiReply->Bus, pScsiReply->TargetID); - printk(KERN_DEBUG "\trequest_len = %d, underflow = %d, resid = %d\n", - scsi_bufflen(sc), sc->underflow, scsi_get_resid(sc)); - printk(KERN_DEBUG "\ttag = %d, transfer_count = %d, sc->result = %08X\n", - le16_to_cpu(pScsiReply->TaskTag), + printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d\n", + ioc->name, pScsiReply->Bus, pScsiReply->TargetID); + printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, " + "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow, + scsi_get_resid(sc)); + printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, " + "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag), le32_to_cpu(pScsiReply->TransferCount), sc->result); - - printk(KERN_DEBUG "\tiocstatus = %s (0x%04x), " + printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), " "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n", - desc, ioc_status, - desc1, pScsiReply->SCSIStatus, + ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus, pScsiReply->SCSIState); if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { @@ -607,9 +607,8 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc asc = sc->sense_buffer[12]; ascq = sc->sense_buffer[13]; - printk(KERN_DEBUG "\t[sense_key,asc,ascq]: " - "[0x%02x,0x%02x,0x%02x]\n", - skey, asc, ascq); + printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: " + "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq); } /* @@ -617,8 +616,8 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc */ if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID && pScsiReply->ResponseInfo) - printk(KERN_DEBUG "response_info = %08xh\n", - le32_to_cpu(pScsiReply->ResponseInfo)); + printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n", + ioc->name, le32_to_cpu(pScsiReply->ResponseInfo)); } #endif @@ -738,8 +737,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) */ if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && pScsiReply->ResponseInfo) { - printk(KERN_NOTICE "[%d:%d:%d:%d] " - "FCP_ResponseInfo=%08xh\n", + printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] " + "FCP_ResponseInfo=%08xh\n", ioc->name, sc->device->host->host_no, sc->device->channel, sc->device->id, sc->device->lun, le32_to_cpu(pScsiReply->ResponseInfo)); @@ -824,9 +823,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->result=DID_SOFT_ERROR << 16; else /* Sufficient data transfer occurred */ sc->result = (DID_OK << 16) | scsi_status; - dreplyprintk(ioc, printk(KERN_DEBUG + dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n", - sc->result, sc->device->channel, sc->device->id)); + ioc->name, sc->result, sc->device->channel, sc->device->id)); break; case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ @@ -858,9 +857,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) } - dreplyprintk(ioc, printk(KERN_DEBUG " sc->underflow={report ERR if < %02xh bytes xfer'd}\n", - sc->underflow)); - dreplyprintk(ioc, printk(KERN_DEBUG " ActBytesXferd=%02xh\n", xfer_cnt)); + dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT + " sc->underflow={report ERR if < %02xh bytes xfer'd}\n", + ioc->name, sc->underflow)); + dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT + " ActBytesXferd=%02xh\n", ioc->name, xfer_cnt)); /* Report Queue Full */ @@ -974,7 +975,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) int ii; int max = ioc->req_depth; - dprintk(ioc, printk(KERN_DEBUG MYNAM ": flush_ScsiLookup called\n")); + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush_ScsiLookup called\n", ioc->name)); for (ii= 0; ii < max; ii++) { if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { @@ -986,8 +987,8 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) hd->ScsiLookup[ii] = NULL; mf = MPT_INDEX_2_MFPTR(ioc, ii); - dmfprintk(ioc, printk(KERN_DEBUG MYNAM ": flush: ScsiDone (mf=%p,sc=%p)\n", - mf, SCpnt)); + dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush: ScsiDone (mf=%p,sc=%p)\n", + ioc->name, mf, SCpnt)); /* Free Chain buffers */ mptscsih_freeChainBuffers(ioc, ii); @@ -1036,8 +1037,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) struct scsi_cmnd *sc; struct scsi_lun lun; - dsprintk(hd->ioc, printk(KERN_DEBUG MYNAM ": search_running channel %d id %d lun %d max %d\n", - vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); + dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n", + hd->ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); for (ii=0; ii < max; ii++) { if ((sc = hd->ScsiLookup[ii]) != NULL) { @@ -1069,8 +1070,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) scsi_dma_unmap(sc); sc->host_scribble = NULL; sc->result = DID_NO_CONNECT << 16; - sdev_printk(KERN_INFO, sc->device, "completing cmds: fw_channel %d," - "fw_id %d, sc=%p, mf = %p, idx=%x\n", vdevice->vtarget->channel, + sdev_printk(MYIOC_s_INFO_FMT, sc->device, "completing cmds: fw_channel %d," + "fw_id %d, sc=%p, mf = %p, idx=%x\n", hd->ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, sc, mf, ii); sc->scsi_done(sc); } @@ -1475,7 +1476,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", ioc->name, SCpnt, mf, my_idx)); - DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf) + DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf); return 0; fail: @@ -1590,18 +1591,18 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c */ if (mptscsih_tm_pending_wait(hd) == FAILED) { if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { - dtmprintk(ioc, printk(KERN_DEBUG MYNAM ": %s: TMHandler abort: " + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler abort: " "Timed out waiting for last TM (%d) to complete! \n", ioc->name, hd->tmPending)); return FAILED; } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { - dtmprintk(ioc, printk(KERN_DEBUG MYNAM ": %s: TMHandler target " + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler target " "reset: Timed out waiting for last TM (%d) " "to complete! \n", ioc->name, hd->tmPending)); return FAILED; } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { - dtmprintk(ioc, printk(KERN_DEBUG MYNAM ": %s: TMHandler bus reset: " + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler bus reset: " "Timed out waiting for last TM (%d) to complete! \n", ioc->name, hd->tmPending)); return FAILED; @@ -1618,10 +1619,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c printk(MYIOC_s_WARN_FMT "TM Handler for type=%x: IOC Not operational (0x%x)!\n", ioc->name, type, ioc_raw_state); - printk(KERN_WARNING " Issuing HardReset!!\n"); + printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name); if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) - printk((KERN_WARNING "TMHandler: HardReset " - "FAILED!!\n")); + printk(MYIOC_s_WARN_FMT "TMHandler: HardReset " + "FAILED!!\n", ioc->name); return FAILED; } @@ -1806,8 +1807,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { SCpnt->result = DID_RESET << 16; SCpnt->scsi_done(SCpnt); - printk(KERN_DEBUG MYNAM ": mptscsih_abort: Can't locate " - "host! (sc=%p)\n", SCpnt); + printk(KERN_ERR MYNAM ": task abort: " + "can't locate host! (sc=%p)\n", SCpnt); return FAILED; } @@ -1818,8 +1819,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdevice = SCpnt->device->hostdata; if (!vdevice || !vdevice->vtarget) { - dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: device has been " - "deleted (sc=%p)\n", ioc->name, SCpnt)); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "task abort: device has been deleted (sc=%p)\n", + ioc->name, SCpnt)); SCpnt->result = DID_NO_CONNECT << 16; SCpnt->scsi_done(SCpnt); retval = 0; @@ -1829,8 +1831,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) /* Task aborts are not supported for hidden raid components. */ if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { - dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: hidden raid " - "component (sc=%p)\n", ioc->name, SCpnt)); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "task abort: hidden raid component (sc=%p)\n", + ioc->name, SCpnt)); SCpnt->result = DID_RESET << 16; retval = FAILED; goto out; @@ -1843,7 +1846,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) * Do OS callback. */ SCpnt->result = DID_RESET << 16; - dtmprintk(ioc, printk(KERN_DEBUG MYNAM ": %s: mptscsih_abort: " + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " "Command not in the active list! (sc=%p)\n", ioc->name, SCpnt)); retval = 0; @@ -1908,8 +1911,8 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) /* If we can't locate our host adapter structure, return FAILED status. */ if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ - printk(KERN_DEBUG MYNAM ": mptscsih_dev_reset: Can't " - "locate host! (sc=%p)\n", SCpnt); + printk(KERN_ERR MYNAM ": target reset: " + "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; } @@ -1971,8 +1974,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) /* If we can't locate our host adapter structure, return FAILED status. */ if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ - printk(KERN_DEBUG MYNAM ": mptscsih_bus_reset: Can't " - "locate host! (sc=%p)\n", SCpnt ); + printk(KERN_ERR MYNAM ": bus reset: " + "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; } @@ -2015,8 +2018,8 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) /* If we can't locate the host to reset, then we failed. */ if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ - printk( KERN_DEBUG MYNAM ": mptscsih_host_reset: Can't " - "locate host! (sc=%p)\n", SCpnt); + printk(KERN_ERR MYNAM ": host reset: " + "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; } @@ -2229,7 +2232,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED || hd->cmdPtr) if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) - printk((KERN_WARNING " Firmware Reload FAILED!!\n")); + printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name); break; case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET: @@ -2576,10 +2579,10 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) unsigned long flags; int ii; - dtmprintk(ioc, printk(KERN_DEBUG MYNAM - ": IOC %s_reset routed to SCSI host driver!\n", - reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT + ": IOC %s_reset routed to SCSI host driver!\n", + ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( + reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); /* If a FW reload request arrives after base installed but * before all scsi hosts have been attached, then an alt_ioc @@ -2719,7 +2722,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) case MPI_EVENT_STATE_CHANGE: /* 02 */ case MPI_EVENT_EVENT_CHANGE: /* 0A */ default: - dprintk(ioc, printk(KERN_DEBUG MYNAM ": Ignoring event (=%02Xh)\n", event)); + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": Ignoring event (=%02Xh)\n", + ioc->name, event)); break; } @@ -2852,8 +2856,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) SCSI_STD_SENSE_BYTES); memcpy(hd->pLocal->sense, sense_data, sz); - ddvprintk(ioc, printk(KERN_DEBUG " Check Condition, sense ptr %p\n", - sense_data)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Check Condition, sense ptr %p\n", + ioc->name, sense_data)); } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) { if (pReq->CDB[0] == INQUIRY) completionCode = MPT_SCANDV_ISSUE_SENSE; @@ -3085,8 +3089,8 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) /* Get and Populate a free Frame */ if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "No msg frames!\n", - hd->ioc->name)); + dfailprintk(hd->ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n", + hd->ioc->name)); return -EBUSY; } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3108788..0e1cf5d 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -139,8 +139,9 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, factor = MPT_ULTRA320; if (scsi_device_qas(sdev)) { ddvprintk(hd->ioc, - printk(KERN_DEBUG "Enabling QAS due to " - "byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); + printk(MYIOC_s_DEBUG_FMT "Enabling QAS due to " + "byte56=%02x on id=%d!\n", hd->ioc->name, + scsi_device_qas(sdev), id)); noQas = 0; } if (sdev->type == TYPE_TAPE && @@ -227,8 +228,8 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, /* Disable QAS in a mixed configuration case */ - ddvprintk(hd->ioc, printk(KERN_DEBUG - "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); + ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + "Disabling QAS due to noQas=%02x on id=%d!\n", hd->ioc->name, noQas, id)); } } @@ -302,7 +303,7 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id) ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", - ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel)); + ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel)); mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); @@ -425,8 +426,8 @@ static int mptspi_target_alloc(struct scsi_target *starget) if (starget->channel == 0 && mptspi_is_raid(hd, starget->id)) { vtarget->raidVolume = 1; - ddvprintk(hd->ioc, printk(KERN_DEBUG - "RAID Volume @ channel=%d id=%d\n", starget->channel, + ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + "RAID Volume @ channel=%d id=%d\n", hd->ioc->name, starget->channel, starget->id)); } @@ -532,7 +533,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL); if (pg0 == NULL) { - starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); + starget_printk(MYIOC_s_ERR_FMT, starget, + "dma_alloc_coherent for parameters failed\n", ioc->name); return -EINVAL; } @@ -552,7 +554,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, cfg.pageAddr = starget->id; if (mpt_config(ioc, &cfg)) { - starget_printk(KERN_ERR, starget, "mpt_config failed\n"); + starget_printk(MYIOC_s_ERR_FMT, starget, "mpt_config failed\n", ioc->name); goto out_free; } err = 0; @@ -673,8 +675,8 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, /* If this is a piece of a RAID, then quiesce first */ if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { - starget_printk(KERN_ERR, scsi_target(sdev), - "Integrated RAID quiesce failed\n"); + starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), + "Integrated RAID quiesce failed\n", hd->ioc->name); return; } @@ -684,8 +686,8 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) - starget_printk(KERN_ERR, scsi_target(sdev), - "Integrated RAID resume failed\n"); + starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), + "Integrated RAID resume failed\n", hd->ioc->name); mptspi_read_parameters(sdev->sdev_target); spi_display_xfer_agreement(sdev->sdev_target); @@ -847,7 +849,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL); if (pg1 == NULL) { - starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); + starget_printk(MYIOC_s_ERR_FMT, starget, + "dma_alloc_coherent for parameters failed\n", ioc->name); return -EINVAL; } @@ -876,7 +879,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters)); if (mpt_config(ioc, &cfg)) { - starget_printk(KERN_ERR, starget, "mpt_config failed\n"); + starget_printk(MYIOC_s_ERR_FMT, starget, + "mpt_config failed\n", ioc->name); goto out_free; } err = 0; @@ -1092,12 +1096,12 @@ static void mpt_work_wrapper(struct work_struct *work) if(vtarget->id != disk) continue; - starget_printk(KERN_INFO, vtarget->starget, - "Integrated RAID requests DV of new device\n"); + starget_printk(MYIOC_s_INFO_FMT, vtarget->starget, + "Integrated RAID requests DV of new device\n", hd->ioc->name); mptspi_dv_device(hd, sdev); } - shost_printk(KERN_INFO, shost, - "Integrated RAID detects new device %d\n", disk); + shost_printk(MYIOC_s_INFO_FMT, shost, + "Integrated RAID detects new device %d\n", hd->ioc->name, disk); scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1); } @@ -1107,9 +1111,9 @@ static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); if (!wqw) { - shost_printk(KERN_ERR, hd->ioc->sh, - "Failed to act on RAID event for physical disk %d\n", - disk); + shost_printk(MYIOC_s_ERR_FMT, hd->ioc->sh, + "Failed to act on RAID event for physical disk %d\n", + hd->ioc->name, disk); return; } INIT_WORK(&wqw->work, mpt_work_wrapper); @@ -1418,7 +1422,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (numSGE < sh->sg_tablesize) { /* Reset this value */ - dprintk(ioc, printk(MYIOC_s_INFO_FMT + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Resetting sg_tablesize to %d from %d\n", ioc->name, numSGE, sh->sg_tablesize)); sh->sg_tablesize = numSGE; @@ -1484,8 +1488,8 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) error = scsi_add_host (sh, &ioc->pcidev->dev); if(error) { - dprintk(ioc, printk(KERN_ERR MYNAM - "scsi_add_host failed\n")); + dprintk(ioc, printk(MYIOC_s_ERR_FMT + "scsi_add_host failed\n", ioc->name)); goto out_mptspi_probe; } -- cgit v1.1 From 8d6d83e90b874b0d6027d2bbf1d8c76dbf26e931 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:47:40 -0600 Subject: [SCSI] mpt fusion: adding/removing white space cleaning up some white space that was introduce in a recent "cb_idx int to u8" patch. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 2c90453..5987f8b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -305,7 +305,7 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) /* Check for (valid) IO callback! */ if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || - MptCallbacks[cb_idx] == NULL) { + MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", __FUNCTION__, ioc->name, cb_idx); goto out; @@ -369,7 +369,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) /* Check for (valid) IO callback! */ if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || - MptCallbacks[cb_idx] == NULL) { + MptCallbacks[cb_idx] == NULL) { printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", __FUNCTION__, ioc->name, cb_idx); freeme = 0; @@ -621,7 +621,7 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) void mpt_deregister(u8 cb_idx) { - if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { + if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { MptCallbacks[cb_idx] = NULL; MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; MptEvHandlers[cb_idx] = NULL; @@ -645,7 +645,7 @@ mpt_deregister(u8 cb_idx) int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) { - if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -1; MptEvHandlers[cb_idx] = ev_cbfunc; @@ -665,7 +665,7 @@ mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) void mpt_event_deregister(u8 cb_idx) { - if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return; MptEvHandlers[cb_idx] = NULL; @@ -722,7 +722,7 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx) MPT_ADAPTER *ioc; const struct pci_device_id *id; - if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return -EINVAL; MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; @@ -749,7 +749,7 @@ mpt_device_driver_deregister(u8 cb_idx) struct mpt_pci_driver *dd_cbfunc; MPT_ADAPTER *ioc; - if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) + if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) return; dd_cbfunc = MptDeviceDriverHandlers[cb_idx]; @@ -1681,7 +1681,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) } /* call per device driver probe entry point */ - for(cb_idx=0; cb_idxprobe) { MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); @@ -1731,7 +1731,7 @@ mpt_detach(struct pci_dev *pdev) remove_proc_entry(pname, NULL); /* call per device driver remove entry point */ - for(cb_idx=0; cb_idxremove) { MptDeviceDriverHandlers[cb_idx]->remove(pdev); @@ -5933,7 +5933,7 @@ procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eo len += sprintf(buf+len, " Fusion MPT base driver\n"); scsi = fc = sas = lan = ctl = targ = dmp = 0; - for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { drvname = NULL; if (MptCallbacks[cb_idx]) { switch (MptDriverClass[cb_idx]) { @@ -6676,7 +6676,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply /* * Call each currently registered protocol event handler. */ - for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { + for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { if (MptEvHandlers[cb_idx]) { devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n", ioc->name, cb_idx)); -- cgit v1.1 From a69de507aae293e32d22e873f34f25f49b2db3b2 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:48:19 -0600 Subject: [SCSI] mpt fusion: rename vdev to vdevice common naming of vdevice through out driver Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 18 +++++++++--------- drivers/message/fusion/mptfc.c | 20 ++++++++++---------- drivers/message/fusion/mptsas.c | 30 +++++++++++++++--------------- drivers/message/fusion/mptscsih.c | 36 ++++++++++++++++++------------------ drivers/message/fusion/mptspi.c | 16 ++++++++-------- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 5d137a8..b7d1159 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1175,7 +1175,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) int cim_rev; u8 revision; struct scsi_device *sdev; - VirtDevice *vdev; + VirtDevice *vdevice; /* Add of PCI INFO results in unaligned access for * IA64 and Sparc. Reset long to int. Return no PCI @@ -1270,8 +1270,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) karg->numDevices = 0; if (ioc->sh) { shost_for_each_device(sdev, ioc->sh) { - vdev = sdev->hostdata; - if (vdev->vtarget->tflags & + vdevice = sdev->hostdata; + if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) continue; karg->numDevices++; @@ -1322,7 +1322,7 @@ mptctl_gettargetinfo (unsigned long arg) struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo karg; MPT_ADAPTER *ioc; - VirtDevice *vdev; + VirtDevice *vdevice; char *pmem; int *pdata; int iocnum; @@ -1391,13 +1391,13 @@ mptctl_gettargetinfo (unsigned long arg) shost_for_each_device(sdev, ioc->sh) { if (!maxWordsLeft) continue; - vdev = sdev->hostdata; - if (vdev->vtarget->tflags & + vdevice = sdev->hostdata; + if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) continue; - lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun; - *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) + - (vdev->vtarget->id )); + lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun; + *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) + + (vdevice->vtarget->id )); pdata++; numDevices++; --maxWordsLeft; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 6c62994..061702d 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -213,7 +213,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT "%s.%d: %d:%d, failing recovery, " - "port state %d, vdev %p.\n", caller, + "port state %d, vdevice %p.\n", caller, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun, ready, @@ -470,7 +470,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) /* * if already mapped, remap here. If not mapped, * target_alloc will allocate vtarget and map, - * slave_alloc will fill in vdev from vtarget. + * slave_alloc will fill in vdevice from vtarget. */ if (ri->starget) { vtarget = ri->starget->hostdata; @@ -602,7 +602,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) { MPT_SCSI_HOST *hd; VirtTarget *vtarget; - VirtDevice *vdev; + VirtDevice *vdevice; struct scsi_target *starget; struct fc_rport *rport; @@ -615,15 +615,15 @@ mptfc_slave_alloc(struct scsi_device *sdev) hd = (MPT_SCSI_HOST *)sdev->host->hostdata; - vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); - if (!vdev) { + vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", hd->ioc->name, sizeof(VirtDevice)); return -ENOMEM; } - sdev->hostdata = vdev; + sdev->hostdata = vdevice; vtarget = starget->hostdata; if (vtarget->num_luns == 0) { @@ -631,8 +631,8 @@ mptfc_slave_alloc(struct scsi_device *sdev) vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; } - vdev->vtarget = vtarget; - vdev->lun = sdev->lun; + vdevice->vtarget = vtarget; + vdevice->lun = sdev->lun; vtarget->num_luns++; @@ -648,9 +648,9 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) struct mptfc_rport_info *ri; struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); int err; - VirtDevice *vdev = SCpnt->device->hostdata; + VirtDevice *vdevice = SCpnt->device->hostdata; - if (!vdev || !vdev->vtarget) { + if (!vdevice || !vdevice->vtarget) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index ecaa1d6..1dfe7d7 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -506,15 +506,15 @@ static VirtTarget * mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id) { struct scsi_device *sdev; - VirtDevice *vdev; + VirtDevice *vdevice; VirtTarget *vtarget = NULL; shost_for_each_device(sdev, ioc->sh) { - if ((vdev = sdev->hostdata) == NULL) + if ((vdevice = sdev->hostdata) == NULL) continue; - if (vdev->vtarget->id == id && - vdev->vtarget->channel == channel) - vtarget = vdev->vtarget; + if (vdevice->vtarget->id == id && + vdevice->vtarget->channel == channel) + vtarget = vdevice->vtarget; } return vtarget; } @@ -943,18 +943,18 @@ mptsas_slave_alloc(struct scsi_device *sdev) MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; struct sas_rphy *rphy; struct mptsas_portinfo *p; - VirtDevice *vdev; + VirtDevice *vdevice; struct scsi_target *starget; int i; - vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); - if (!vdev) { + vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n", hd->ioc->name, sizeof(VirtDevice)); return -ENOMEM; } starget = scsi_target(sdev); - vdev->vtarget = starget->hostdata; + vdevice->vtarget = starget->hostdata; if (sdev->channel == MPTSAS_RAID_CHANNEL) goto out; @@ -966,7 +966,7 @@ mptsas_slave_alloc(struct scsi_device *sdev) if (p->phy_info[i].attached.sas_address != rphy->identify.sas_address) continue; - vdev->lun = sdev->lun; + vdevice->lun = sdev->lun; /* * Exposing hidden raid components */ @@ -980,21 +980,21 @@ mptsas_slave_alloc(struct scsi_device *sdev) } mutex_unlock(&hd->ioc->sas_topology_mutex); - kfree(vdev); + kfree(vdevice); return -ENXIO; out: - vdev->vtarget->num_luns++; - sdev->hostdata = vdev; + vdevice->vtarget->num_luns++; + sdev->hostdata = vdevice; return 0; } static int mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - VirtDevice *vdev = SCpnt->device->hostdata; + VirtDevice *vdevice = SCpnt->device->hostdata; - if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) { + if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 8081fe7..02f9590 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -644,7 +644,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) SCSIIORequest_t *pScsiReq; SCSIIOReply_t *pScsiReply; u16 req_idx, req_idx_MR; - VirtDevice *vdev; + VirtDevice *vdevice; VirtTarget *vtarget; hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; @@ -770,10 +770,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) hd->sel_timeout[pScsiReq->TargetID]++; - vdev = sc->device->hostdata; - if (!vdev) + vdevice = sc->device->hostdata; + if (!vdevice) break; - vtarget = vdev->vtarget; + vtarget = vdevice->vtarget; if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) { mptscsih_issue_sep_command(ioc, vtarget, MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED); @@ -1359,7 +1359,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) MPT_SCSI_HOST *hd; MPT_FRAME_HDR *mf; SCSIIORequest_t *pScsiReq; - VirtDevice *vdev = SCpnt->device->hostdata; + VirtDevice *vdevice = SCpnt->device->hostdata; int lun; u32 datalen; u32 scsictl; @@ -1416,8 +1416,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* Default to untagged. Once a target structure has been allocated, * use the Inquiry data to determine if device supports tagged. */ - if (vdev - && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) + if (vdevice + && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) && (SCpnt->device->tagged_supported)) { scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; } else { @@ -1426,10 +1426,10 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* Use the above information to set up the message frame */ - pScsiReq->TargetID = (u8) vdev->vtarget->id; - pScsiReq->Bus = vdev->vtarget->channel; + pScsiReq->TargetID = (u8) vdevice->vtarget->id; + pScsiReq->Bus = vdevice->vtarget->channel; pScsiReq->ChainOffset = 0; - if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) + if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; else pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; @@ -1968,7 +1968,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) { MPT_SCSI_HOST *hd; int retval; - VirtDevice *vdev; + VirtDevice *vdevice; MPT_ADAPTER *ioc; /* If we can't locate our host adapter structure, return FAILED status. @@ -1987,9 +1987,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) if (hd->timeouts < -1) hd->timeouts++; - vdev = SCpnt->device->hostdata; + vdevice = SCpnt->device->hostdata; retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, - vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc)); + vdevice->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc)); printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n", ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); @@ -2503,14 +2503,14 @@ slave_configure_exit: static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) { - VirtDevice *vdev; + VirtDevice *vdevice; SCSIIORequest_t *pReq; u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); /* Get target structure */ pReq = (SCSIIORequest_t *) mf; - vdev = sc->device->hostdata; + vdevice = sc->device->hostdata; if (sense_count) { u8 *sense_data; @@ -2524,7 +2524,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR /* Log SMART data (asc = 0x5D, non-IM case only) if required. */ if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { - if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) { + if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) { int idx; MPT_ADAPTER *ioc = hd->ioc; @@ -2542,8 +2542,8 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR if (hd->ioc->pcidev->vendor == PCI_VENDOR_ID_IBM) { mptscsih_issue_sep_command(hd->ioc, - vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); - vdev->vtarget->tflags |= + vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); + vdevice->vtarget->tflags |= MPT_TARGET_FLAGS_LED_ON; } } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 0e1cf5d..4248bf3 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -698,26 +698,26 @@ static int mptspi_slave_alloc(struct scsi_device *sdev) { MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; VirtTarget *vtarget; - VirtDevice *vdev; + VirtDevice *vdevice; struct scsi_target *starget; if (sdev->channel == 1 && mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0) return -ENXIO; - vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); - if (!vdev) { + vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", hd->ioc->name, sizeof(VirtDevice)); return -ENOMEM; } - vdev->lun = sdev->lun; - sdev->hostdata = vdev; + vdevice->lun = sdev->lun; + sdev->hostdata = vdevice; starget = scsi_target(sdev); vtarget = starget->hostdata; - vdev->vtarget = vtarget; + vdevice->vtarget = vtarget; vtarget->num_luns++; if (sdev->channel == 1) @@ -758,9 +758,9 @@ static int mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; - VirtDevice *vdev = SCpnt->device->hostdata; + VirtDevice *vdevice = SCpnt->device->hostdata; - if (!vdev || !vdev->vtarget) { + if (!vdevice || !vdevice->vtarget) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; -- cgit v1.1 From e80b002bfd38263117da93feb4f67f5cf7d9221b Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:49:03 -0600 Subject: [SCSI] mpt fusion: removing references to hd->ioc Cleaning up code by accesing the ioc pointer directly instead of via hd->ioc. In the future, most data members of struct MPT_SCSI_HOST will be either deleted or moved to struct MPT_ADAPTER. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptfc.c | 17 ++-- drivers/message/fusion/mptsas.c | 37 +++---- drivers/message/fusion/mptscsih.c | 199 ++++++++++++++++++++------------------ drivers/message/fusion/mptspi.c | 97 +++++++++++-------- 4 files changed, 188 insertions(+), 162 deletions(-) diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 061702d..19438ec 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -194,12 +194,14 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); unsigned long flags; int ready; + MPT_ADAPTER *ioc; hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; + ioc = hd->ioc; spin_lock_irqsave(shost->host_lock, flags); while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { spin_unlock_irqrestore(shost->host_lock, flags); - dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT + dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "mptfc_block_error_handler.%d: %d:%d, port status is " "DID_IMM_RETRY, deferring %s recovery.\n", ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, @@ -211,7 +213,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, spin_unlock_irqrestore(shost->host_lock, flags); if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { - dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT + dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "%s.%d: %d:%d, failing recovery, " "port state %d, vdevice %p.\n", caller, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, @@ -220,7 +222,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, SCpnt->device->hostdata)); return FAILED; } - dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT + dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "%s.%d: %d:%d, executing recovery.\n", caller, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, @@ -605,7 +607,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) VirtDevice *vdevice; struct scsi_target *starget; struct fc_rport *rport; - + MPT_ADAPTER *ioc; starget = scsi_target(sdev); rport = starget_to_rport(starget); @@ -614,11 +616,12 @@ mptfc_slave_alloc(struct scsi_device *sdev) return -ENXIO; hd = (MPT_SCSI_HOST *)sdev->host->hostdata; + ioc = hd->ioc; vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", - hd->ioc->name, sizeof(VirtDevice)); + ioc->name, sizeof(VirtDevice)); return -ENOMEM; } @@ -627,7 +630,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) vtarget = starget->hostdata; if (vtarget->num_luns == 0) { - vtarget->ioc_id = hd->ioc->id; + vtarget->ioc_id = ioc->id; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; } @@ -637,7 +640,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) vtarget->num_luns++; - mptfc_dump_lun_info(hd->ioc, rport, sdev, vtarget); + mptfc_dump_lun_info(ioc, rport, sdev, vtarget); return 0; } diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 1dfe7d7..ee03c3f 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -846,13 +846,14 @@ mptsas_target_alloc(struct scsi_target *starget) struct sas_rphy *rphy; struct mptsas_portinfo *p; int i; + MPT_ADAPTER *ioc = hd->ioc; vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); if (!vtarget) return -ENOMEM; vtarget->starget = starget; - vtarget->ioc_id = hd->ioc->id; + vtarget->ioc_id = ioc->id; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; id = starget->id; channel = 0; @@ -861,15 +862,15 @@ mptsas_target_alloc(struct scsi_target *starget) * RAID volumes placed beyond the last expected port. */ if (starget->channel == MPTSAS_RAID_CHANNEL) { - for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) - if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) - channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; + for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) + if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) + channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; goto out; } rphy = dev_to_rphy(starget->dev.parent); - mutex_lock(&hd->ioc->sas_topology_mutex); - list_for_each_entry(p, &hd->ioc->sas_topology, list) { + mutex_lock(&ioc->sas_topology_mutex); + list_for_each_entry(p, &ioc->sas_topology, list) { for (i = 0; i < p->num_phys; i++) { if (p->phy_info[i].attached.sas_address != rphy->identify.sas_address) @@ -881,18 +882,18 @@ mptsas_target_alloc(struct scsi_target *starget) /* * Exposing hidden raid components */ - if (mptscsih_is_phys_disk(hd->ioc, channel, id)) { - id = mptscsih_raid_id_to_num(hd->ioc, + if (mptscsih_is_phys_disk(ioc, channel, id)) { + id = mptscsih_raid_id_to_num(ioc, channel, id); vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; p->phy_info[i].attached.phys_disk_num = id; } - mutex_unlock(&hd->ioc->sas_topology_mutex); + mutex_unlock(&ioc->sas_topology_mutex); goto out; } } - mutex_unlock(&hd->ioc->sas_topology_mutex); + mutex_unlock(&ioc->sas_topology_mutex); kfree(vtarget); return -ENXIO; @@ -912,6 +913,7 @@ mptsas_target_destroy(struct scsi_target *starget) struct sas_rphy *rphy; struct mptsas_portinfo *p; int i; + MPT_ADAPTER *ioc = hd->ioc; if (!starget->hostdata) return; @@ -920,7 +922,7 @@ mptsas_target_destroy(struct scsi_target *starget) goto out; rphy = dev_to_rphy(starget->dev.parent); - list_for_each_entry(p, &hd->ioc->sas_topology, list) { + list_for_each_entry(p, &ioc->sas_topology, list) { for (i = 0; i < p->num_phys; i++) { if (p->phy_info[i].attached.sas_address != rphy->identify.sas_address) @@ -946,11 +948,12 @@ mptsas_slave_alloc(struct scsi_device *sdev) VirtDevice *vdevice; struct scsi_target *starget; int i; + MPT_ADAPTER *ioc = hd->ioc; vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n", - hd->ioc->name, sizeof(VirtDevice)); + ioc->name, sizeof(VirtDevice)); return -ENOMEM; } starget = scsi_target(sdev); @@ -960,8 +963,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) goto out; rphy = dev_to_rphy(sdev->sdev_target->dev.parent); - mutex_lock(&hd->ioc->sas_topology_mutex); - list_for_each_entry(p, &hd->ioc->sas_topology, list) { + mutex_lock(&ioc->sas_topology_mutex); + list_for_each_entry(p, &ioc->sas_topology, list) { for (i = 0; i < p->num_phys; i++) { if (p->phy_info[i].attached.sas_address != rphy->identify.sas_address) @@ -970,15 +973,15 @@ mptsas_slave_alloc(struct scsi_device *sdev) /* * Exposing hidden raid components */ - if (mptscsih_is_phys_disk(hd->ioc, + if (mptscsih_is_phys_disk(ioc, p->phy_info[i].attached.channel, p->phy_info[i].attached.id)) sdev->no_uld_attach = 1; - mutex_unlock(&hd->ioc->sas_topology_mutex); + mutex_unlock(&ioc->sas_topology_mutex); goto out; } } - mutex_unlock(&hd->ioc->sas_topology_mutex); + mutex_unlock(&ioc->sas_topology_mutex); kfree(vdevice); return -ENXIO; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 02f9590..17369f8 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1036,14 +1036,15 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) int max = hd->ioc->req_depth; struct scsi_cmnd *sc; struct scsi_lun lun; + MPT_ADAPTER *ioc = hd->ioc; - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n", - hd->ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n", + ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); for (ii=0; ii < max; ii++) { if ((sc = hd->ScsiLookup[ii]) != NULL) { - mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); + mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii); if (mf == NULL) continue; /* If the device is a hidden raid component, then its @@ -1063,15 +1064,15 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) /* Cleanup */ hd->ScsiLookup[ii] = NULL; - mptscsih_freeChainBuffers(hd->ioc, ii); - mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); + mptscsih_freeChainBuffers(ioc, ii); + mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf); if ((unsigned char *)mf != sc->host_scribble) continue; scsi_dma_unmap(sc); sc->host_scribble = NULL; sc->result = DID_NO_CONNECT << 16; sdev_printk(MYIOC_s_INFO_FMT, sc->device, "completing cmds: fw_channel %d," - "fw_id %d, sc=%p, mf = %p, idx=%x\n", hd->ioc->name, vdevice->vtarget->channel, + "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, sc, mf, ii); sc->scsi_done(sc); } @@ -1098,6 +1099,7 @@ mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSI { long time = jiffies; MPT_SCSI_HOST *hd; + MPT_ADAPTER *ioc; if (sc->device == NULL) return; @@ -1105,10 +1107,10 @@ mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSI return; if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL) return; - + ioc = hd->ioc; if (time - hd->last_queue_full > 10 * HZ) { - dprintk(hd->ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n", - hd->ioc->name, 0, sc->device->id, sc->device->lun)); + dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n", + ioc->name, 0, sc->device->id, sc->device->lun)); hd->last_queue_full = time; } } @@ -1143,20 +1145,20 @@ mptscsih_remove(struct pci_dev *pdev) sz1=0; if (hd->ScsiLookup != NULL) { - sz1 = hd->ioc->req_depth * sizeof(void *); + sz1 = ioc->req_depth * sizeof(void *); kfree(hd->ScsiLookup); hd->ScsiLookup = NULL; } - dprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Free'd ScsiLookup (%d) memory\n", - hd->ioc->name, sz1)); + ioc->name, sz1)); kfree(hd->info_kbuf); /* NULL the Scsi_Host pointer */ - hd->ioc->sh = NULL; + ioc->sh = NULL; scsi_host_put(host); @@ -1386,7 +1388,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) /* * Put together a MPT SCSI request... */ - if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) { + if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n", ioc->name)); return SCSI_MLQUEUE_HOST_BUSY; @@ -1454,7 +1456,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) pScsiReq->DataLength = cpu_to_le32(datalen); /* SenseBuffer low address */ - pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma + pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma + (my_idx * MPT_SENSE_BUFFER_ALLOC)); /* Now add the SG list @@ -1466,14 +1468,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) (dma_addr_t) -1); } else { /* Add a 32 or 64 bit SGE */ - if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS) + if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS) goto fail; } SCpnt->host_scribble = (unsigned char *)mf; hd->ScsiLookup[my_idx] = SCpnt; - mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); + mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", ioc->name, SCpnt, mf, my_idx)); DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf); @@ -1481,8 +1483,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) fail: hd->ScsiLookup[my_idx] = NULL; - mptscsih_freeChainBuffers(hd->ioc, my_idx); - mpt_free_msg_frame(hd->ioc, mf); + mptscsih_freeChainBuffers(ioc, my_idx); + mpt_free_msg_frame(ioc, mf); return SCSI_MLQUEUE_HOST_BUSY; } @@ -1608,12 +1610,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c return FAILED; } } else { - spin_lock_irqsave(&hd->ioc->FreeQlock, flags); + spin_lock_irqsave(&ioc->FreeQlock, flags); hd->tmPending |= (1 << type); - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); } - ioc_raw_state = mpt_GetIocState(hd->ioc, 0); + ioc_raw_state = mpt_GetIocState(ioc, 0); if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { printk(MYIOC_s_WARN_FMT @@ -1681,16 +1683,17 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i SCSITaskMgmt_t *pScsiTm; int ii; int retval; + MPT_ADAPTER *ioc = hd->ioc; /* Return Fail to calling function if no message frames available. */ - if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) { - dfailprintk(hd->ioc, printk(MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", - hd->ioc->name)); + if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { + dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", + ioc->name)); return FAILED; } - dtmprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt request @ %p\n", - hd->ioc->name, mf)); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt request @ %p\n", + ioc->name, mf)); /* Format the Request */ @@ -1713,34 +1716,34 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i pScsiTm->TaskMsgContext = ctx2abort; - dtmprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " - "type=%d\n", hd->ioc->name, ctx2abort, type)); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " + "type=%d\n", ioc->name, ctx2abort, type)); DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm); - if ((hd->ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && - (hd->ioc->facts.MsgVersion >= MPI_VERSION_01_05)) - mpt_put_msg_frame_hi_pri(hd->ioc->TaskCtx, hd->ioc, mf); + if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && + (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) + mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf); else { - retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, + retval = mpt_send_handshake_request(ioc->TaskCtx, ioc, sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP); if (retval) { - dfailprintk(hd->ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!" - " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd, - hd->ioc, mf, retval)); + dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!" + " (hd %p, ioc %p, mf %p, rc=%d) \n", ioc->name, hd, + ioc, mf, retval)); goto fail_out; } } if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { - dfailprintk(hd->ioc, printk(MYIOC_s_ERR_FMT "task management request TIMED OUT!" - " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, - hd->ioc, mf)); - dtmprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n", - hd->ioc->name)); - retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); - dtmprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n", - hd->ioc->name, retval)); + dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "task management request TIMED OUT!" + " (hd %p, ioc %p, mf %p) \n", ioc->name, hd, + ioc, mf)); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n", + ioc->name)); + retval = mpt_HardResetHandler(ioc, CAN_SLEEP); + dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n", + ioc->name, retval)); goto fail_out; } @@ -1761,7 +1764,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i /* * Free task managment mf, and corresponding tm flags */ - mpt_free_msg_frame(hd->ioc, mf); + mpt_free_msg_frame(ioc, mf); hd->tmPending = 0; hd->tmState = TM_STATE_NONE; return FAILED; @@ -1868,7 +1871,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) * swap it here either. It is an opaque cookie to * the controller, so it does not matter. -DaveM */ - mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); + mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx); ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext; hd->abortSCpnt = SCpnt; @@ -2030,7 +2033,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) /* If our attempts to reset the host failed, then return a failed * status. The host will be taken off line by the SCSI mid-layer. */ - if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) { + if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) { retval = FAILED; } else { /* Make sure TM pending is cleared and TM state is set to @@ -2060,17 +2063,18 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) unsigned long flags; int loop_count = 4 * 10; /* Wait 10 seconds */ int status = FAILED; + MPT_ADAPTER *ioc = hd->ioc; do { - spin_lock_irqsave(&hd->ioc->FreeQlock, flags); + spin_lock_irqsave(&ioc->FreeQlock, flags); if (hd->tmState == TM_STATE_NONE) { hd->tmState = TM_STATE_IN_PROGRESS; hd->tmPending = 1; - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); status = SUCCESS; break; } - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); msleep(250); } while (--loop_count); @@ -2091,15 +2095,16 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) unsigned long flags; int loop_count = 4 * timeout; int status = FAILED; + MPT_ADAPTER *ioc = hd->ioc; do { - spin_lock_irqsave(&hd->ioc->FreeQlock, flags); + spin_lock_irqsave(&ioc->FreeQlock, flags); if(hd->tmPending == 0) { status = SUCCESS; - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); break; } - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&ioc->FreeQlock, flags); msleep(250); } while (--loop_count); @@ -2407,11 +2412,12 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) struct scsi_target *starget; int max_depth; int tagged; + MPT_ADAPTER *ioc = hd->ioc; starget = scsi_target(sdev); vtarget = starget->hostdata; - if (hd->ioc->bus_type == SPI) { + if (ioc->bus_type == SPI) { if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) max_depth = 1; else if (sdev->type == TYPE_DISK && @@ -2447,18 +2453,19 @@ mptscsih_slave_configure(struct scsi_device *sdev) VirtDevice *vdevice; struct scsi_target *starget; MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; + MPT_ADAPTER *ioc = hd->ioc; starget = scsi_target(sdev); vtarget = starget->hostdata; vdevice = sdev->hostdata; - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "device @ %p, channel=%d, id=%d, lun=%d\n", - hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun)); - if (hd->ioc->bus_type == SPI) - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + ioc->name, sdev, sdev->channel, sdev->id, sdev->lun)); + if (ioc->bus_type == SPI) + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sdtr %d wdtr %d ppr %d inq length=%d\n", - hd->ioc->name, sdev->sdtr, sdev->wdtr, + ioc->name, sdev->sdtr, sdev->wdtr, sdev->ppr, sdev->inquiry_len)); if (sdev->id > sh->max_id) { @@ -2470,21 +2477,21 @@ mptscsih_slave_configure(struct scsi_device *sdev) vdevice->configured_lun = 1; mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Queue depth=%d, tflags=%x\n", - hd->ioc->name, sdev->queue_depth, vtarget->tflags)); + ioc->name, sdev->queue_depth, vtarget->tflags)); - if (hd->ioc->bus_type == SPI) - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + if (ioc->bus_type == SPI) + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", - hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset, + ioc->name, vtarget->negoFlags, vtarget->maxOffset, vtarget->minSyncFactor)); slave_configure_exit: - dsprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "tagged %d, simple %d, ordered %d\n", - hd->ioc->name,sdev->tagged_supported, sdev->simple_tags, + ioc->name,sdev->tagged_supported, sdev->simple_tags, sdev->ordered_tags)); return 0; @@ -2506,6 +2513,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR VirtDevice *vdevice; SCSIIORequest_t *pReq; u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); + MPT_ADAPTER *ioc = hd->ioc; /* Get target structure */ @@ -2518,15 +2526,14 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR /* Copy the sense received into the scsi command block. */ req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); - sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); + sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); /* Log SMART data (asc = 0x5D, non-IM case only) if required. */ - if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { + if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) { int idx; - MPT_ADAPTER *ioc = hd->ioc; idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; @@ -2539,9 +2546,9 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12]; ioc->eventContext++; - if (hd->ioc->pcidev->vendor == + if (ioc->pcidev->vendor == PCI_VENDOR_ID_IBM) { - mptscsih_issue_sep_command(hd->ioc, + mptscsih_issue_sep_command(ioc, vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); vdevice->vtarget->tflags |= MPT_TARGET_FLAGS_LED_ON; @@ -2549,8 +2556,8 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR } } } else { - dprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n", - hd->ioc->name)); + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n", + ioc->name)); } } @@ -2635,7 +2642,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) /* ScsiLookup initialization */ - for (ii=0; ii < hd->ioc->req_depth; ii++) + for (ii=0; ii < ioc->req_depth; ii++) hd->ScsiLookup[ii] = NULL; /* 2. Chain Buffer initialization @@ -2780,12 +2787,12 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) if (mf != hd->cmdPtr) { printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n", - hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx); + ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx); } hd->cmdPtr = NULL; ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n", - hd->ioc->name, mf, mr, req_idx)); + ioc->name, mf, mr, req_idx)); hd->pLocal = &hd->localReply; hd->pLocal->scsiStatus = 0; @@ -2849,7 +2856,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) */ completionCode = MPT_SCANDV_SENSE; hd->pLocal->scsiStatus = scsi_status; - sense_data = ((u8 *)hd->ioc->sense_buf_pool + + sense_data = ((u8 *)ioc->sense_buf_pool + (req_idx * MPT_SENSE_BUFFER_ALLOC)); sz = min_t(int, pReq->SenseBufferLength, @@ -2916,8 +2923,9 @@ void mptscsih_timer_expired(unsigned long data) { MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data; + MPT_ADAPTER *ioc = hd->ioc; - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr)); if (hd->cmdPtr) { MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr; @@ -2931,13 +2939,13 @@ mptscsih_timer_expired(unsigned long data) */ } else { /* Perform a FW reload */ - if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) { - printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name); + if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { + printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name); } } } else { /* This should NEVER happen */ - printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name); + printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name); } /* No more processing. @@ -2945,7 +2953,7 @@ mptscsih_timer_expired(unsigned long data) * The FW will reply to all outstanding commands, callback will finish cleanup. * Hard reset clean-up will free all resources. */ - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", hd->ioc->name)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name)); return; } @@ -2983,11 +2991,12 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) char cmdLen; char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char cmd = io->cmd; + MPT_ADAPTER *ioc = hd->ioc; in_isr = in_interrupt(); if (in_isr) { - dprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n", - hd->ioc->name)); + dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n", + ioc->name)); return -EPERM; } @@ -3088,9 +3097,9 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) /* Get and Populate a free Frame */ - if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { - dfailprintk(hd->ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n", - hd->ioc->name)); + if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { + dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n", + ioc->name)); return -EBUSY; } @@ -3129,19 +3138,19 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) if (cmd == REQUEST_SENSE) { pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED); - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n", - hd->ioc->name, cmd)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n", + ioc->name, cmd)); } for (ii=0; ii < 16; ii++) pScsiReq->CDB[ii] = CDB[ii]; pScsiReq->DataLength = cpu_to_le32(io->size); - pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma + pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma + (my_idx * MPT_SENSE_BUFFER_ALLOC)); - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n", - hd->ioc->name, cmd, io->channel, io->id, io->lun)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n", + ioc->name, cmd, io->channel, io->id, io->lun)); if (dir == MPI_SCSIIO_CONTROL_READ) { mpt_add_sge((char *) &pScsiReq->SGL, @@ -3176,7 +3185,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) hd->cmdPtr = mf; add_timer(&hd->timer); - mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); + mpt_put_msg_frame(ioc->InternalCtx, ioc, mf); wait_event(hd->scandv_waitq, hd->scandv_wait_done); if (hd->pLocal) { @@ -3192,8 +3201,8 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) } else { rc = -EFAULT; /* This should never happen. */ - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n", - hd->ioc->name)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n", + ioc->name)); } return rc; diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 4248bf3..02062f1 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -107,7 +107,8 @@ static void mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, struct scsi_device *sdev) { - SpiCfgData *pspi_data = &hd->ioc->spi_data; + MPT_ADAPTER *ioc = hd->ioc; + SpiCfgData *pspi_data = &ioc->spi_data; int id = (int) target->id; int nvram; u8 width = MPT_NARROW; @@ -138,9 +139,9 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, else { factor = MPT_ULTRA320; if (scsi_device_qas(sdev)) { - ddvprintk(hd->ioc, + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enabling QAS due to " - "byte56=%02x on id=%d!\n", hd->ioc->name, + "byte56=%02x on id=%d!\n", ioc->name, scsi_device_qas(sdev), id)); noQas = 0; } @@ -228,8 +229,8 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, /* Disable QAS in a mixed configuration case */ - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT - "Disabling QAS due to noQas=%02x on id=%d!\n", hd->ioc->name, noQas, id)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "Disabling QAS due to noQas=%02x on id=%d!\n", ioc->name, noQas, id)); } } @@ -375,14 +376,15 @@ static int mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id) { int i, rc = 0; + MPT_ADAPTER *ioc = hd->ioc; - if (!hd->ioc->raid_data.pIocPg2) + if (!ioc->raid_data.pIocPg2) goto out; - if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes) + if (!ioc->raid_data.pIocPg2->NumActiveVolumes) goto out; - for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { - if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) { + for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { + if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) { rc = 1; goto out; } @@ -397,15 +399,17 @@ static int mptspi_target_alloc(struct scsi_target *starget) struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; VirtTarget *vtarget; + MPT_ADAPTER *ioc; if (hd == NULL) return -ENODEV; + ioc = hd->ioc; vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); if (!vtarget) return -ENOMEM; - vtarget->ioc_id = hd->ioc->id; + vtarget->ioc_id = ioc->id; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; vtarget->id = (u8)starget->id; vtarget->channel = (u8)starget->channel; @@ -413,34 +417,34 @@ static int mptspi_target_alloc(struct scsi_target *starget) starget->hostdata = vtarget; if (starget->channel == 1) { - if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0) + if (mptscsih_is_phys_disk(ioc, 0, starget->id) == 0) return 0; vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; /* The real channel for this device is zero */ vtarget->channel = 0; /* The actual physdisknum (for RAID passthrough) */ - vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0, + vtarget->id = mptscsih_raid_id_to_num(ioc, 0, starget->id); } if (starget->channel == 0 && mptspi_is_raid(hd, starget->id)) { vtarget->raidVolume = 1; - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT - "RAID Volume @ channel=%d id=%d\n", hd->ioc->name, starget->channel, + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT + "RAID Volume @ channel=%d id=%d\n", ioc->name, starget->channel, starget->id)); } - if (hd->ioc->spi_data.nvram && - hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { - u32 nvram = hd->ioc->spi_data.nvram[starget->id]; + if (ioc->spi_data.nvram && + ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { + u32 nvram = ioc->spi_data.nvram[starget->id]; spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; } else { - spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor; - spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth; + spi_min_period(starget) = ioc->spi_data.minSyncFactor; + spi_max_width(starget) = ioc->spi_data.maxBusWidth; } - spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset; + spi_max_offset(starget) = ioc->spi_data.maxSyncOffset; spi_offset(starget) = 0; mptspi_write_width(starget, 0); @@ -614,12 +618,13 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) { MpiRaidActionRequest_t *pReq; MPT_FRAME_HDR *mf; + MPT_ADAPTER *ioc = hd->ioc; /* Get and Populate a free Frame */ - if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { - ddvprintk(hd->ioc, printk(MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", - hd->ioc->name)); + if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { + ddvprintk(ioc, printk(MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", + ioc->name)); return -EAGAIN; } pReq = (MpiRaidActionRequest_t *)mf; @@ -640,8 +645,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) mpt_add_sge((char *)&pReq->ActionDataSGE, MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); - ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n", - hd->ioc->name, pReq->Action, channel, id)); + ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n", + ioc->name, pReq->Action, channel, id)); hd->pLocal = NULL; hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ @@ -653,7 +658,7 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) hd->cmdPtr = mf; add_timer(&hd->timer); - mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); + mpt_put_msg_frame(ioc->InternalCtx, ioc, mf); wait_event(hd->scandv_waitq, hd->scandv_wait_done); if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0)) @@ -666,6 +671,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, struct scsi_device *sdev) { VirtTarget *vtarget = scsi_target(sdev)->hostdata; + MPT_ADAPTER *ioc = hd->ioc; /* no DV on RAID devices */ if (sdev->channel == 0 && @@ -676,7 +682,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), - "Integrated RAID quiesce failed\n", hd->ioc->name); + "Integrated RAID quiesce failed\n", ioc->name); return; } @@ -687,7 +693,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), - "Integrated RAID resume failed\n", hd->ioc->name); + "Integrated RAID resume failed\n", ioc->name); mptspi_read_parameters(sdev->sdev_target); spi_display_xfer_agreement(sdev->sdev_target); @@ -700,15 +706,16 @@ static int mptspi_slave_alloc(struct scsi_device *sdev) VirtTarget *vtarget; VirtDevice *vdevice; struct scsi_target *starget; + MPT_ADAPTER *ioc = hd->ioc; if (sdev->channel == 1 && - mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0) + mptscsih_is_phys_disk(ioc, 0, sdev->id) == 0) return -ENXIO; vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); if (!vdevice) { printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", - hd->ioc->name, sizeof(VirtDevice)); + ioc->name, sizeof(VirtDevice)); return -ENOMEM; } @@ -759,6 +766,7 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; VirtDevice *vdevice = SCpnt->device->hostdata; + MPT_ADAPTER *ioc = hd->ioc; if (!vdevice || !vdevice->vtarget) { SCpnt->result = DID_NO_CONNECT << 16; @@ -767,14 +775,14 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) } if (SCpnt->device->channel == 1 && - mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) { + mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) { SCpnt->result = DID_NO_CONNECT << 16; done(SCpnt); return 0; } if (spi_dv_pending(scsi_target(SCpnt->device))) - ddvprintk(hd->ioc, scsi_print_command(SCpnt)); + ddvprintk(ioc, scsi_print_command(SCpnt)); return mptscsih_qcmd(SCpnt,done); } @@ -1071,15 +1079,16 @@ static void mpt_work_wrapper(struct work_struct *work) struct work_queue_wrapper *wqw = container_of(work, struct work_queue_wrapper, work); struct _MPT_SCSI_HOST *hd = wqw->hd; - struct Scsi_Host *shost = hd->ioc->sh; + MPT_ADAPTER *ioc = hd->ioc; + struct Scsi_Host *shost = ioc->sh; struct scsi_device *sdev; int disk = wqw->disk; struct _CONFIG_PAGE_IOC_3 *pg3; kfree(wqw); - mpt_findImVolumes(hd->ioc); - pg3 = hd->ioc->raid_data.pIocPg3; + mpt_findImVolumes(ioc); + pg3 = ioc->raid_data.pIocPg3; if (!pg3) return; @@ -1097,23 +1106,24 @@ static void mpt_work_wrapper(struct work_struct *work) continue; starget_printk(MYIOC_s_INFO_FMT, vtarget->starget, - "Integrated RAID requests DV of new device\n", hd->ioc->name); + "Integrated RAID requests DV of new device\n", ioc->name); mptspi_dv_device(hd, sdev); } shost_printk(MYIOC_s_INFO_FMT, shost, - "Integrated RAID detects new device %d\n", hd->ioc->name, disk); - scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1); + "Integrated RAID detects new device %d\n", ioc->name, disk); + scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1); } static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) { struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); + MPT_ADAPTER *ioc = hd->ioc; if (!wqw) { - shost_printk(MYIOC_s_ERR_FMT, hd->ioc->sh, + shost_printk(MYIOC_s_ERR_FMT, ioc->sh, "Failed to act on RAID event for physical disk %d\n", - hd->ioc->name, disk); + ioc->name, disk); return; } INIT_WORK(&wqw->work, mpt_work_wrapper); @@ -1216,11 +1226,12 @@ mptspi_dv_renegotiate_work(struct work_struct *work) struct scsi_target *starget; struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; u32 nego; + MPT_ADAPTER *ioc = hd->ioc; kfree(wqw); if (hd->spi_pending) { - shost_for_each_device(sdev, hd->ioc->sh) { + shost_for_each_device(sdev, ioc->sh) { if (hd->spi_pending & (1 << sdev->id)) continue; starget = scsi_target(sdev); @@ -1231,7 +1242,7 @@ mptspi_dv_renegotiate_work(struct work_struct *work) mptspi_write_spi_device_pg1(starget, &pg1); } } else { - shost_for_each_device(sdev, hd->ioc->sh) + shost_for_each_device(sdev, ioc->sh) mptspi_dv_device(hd, sdev); } } @@ -1483,7 +1494,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Some versions of the firmware don't support page 0; without * that we can't get the parameters */ - if (hd->ioc->spi_data.sdp0length != 0) + if (ioc->spi_data.sdp0length != 0) sh->transportt = mptspi_transport_template; error = scsi_add_host (sh, &ioc->pcidev->dev); -- cgit v1.1 From 50847ed8bc3d108d923bb8b6793f453a15af3c3f Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:49:53 -0600 Subject: [SCSI] mpt fusion: removing Dell copyright Some other vender has concerns over this copyright, and Dell has approved removing it. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptsas.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index ee03c3f..d2f1b8e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -5,7 +5,6 @@ * * Copyright (c) 1999-2007 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) - * Copyright (c) 2005-2007 Dell */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* -- cgit v1.1 From 448f09e618ab82ad90f01a04eae7f04f2985138f Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:50:49 -0600 Subject: [SCSI] mpt fusion: Kconfig cleanup Adding 949X, 949E, and 1078 to Kconfig. Adding "depends on FUSION" required in the FUSION_LOGGING section, and fixing a spelling error. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index 9b87c2f..a34a11d 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig @@ -41,6 +41,8 @@ config FUSION_FC LSIFC929 LSIFC929X LSIFC929XL + LSIFC949X + LSIFC949E Brocade FC 410/420 config FUSION_SAS @@ -56,6 +58,7 @@ config FUSION_SAS LSISAS1068 LSISAS1064E LSISAS1068E + LSISAS1078 config FUSION_MAX_SGE int "Maximum number of scatter gather entries (16 - 128)" @@ -106,7 +109,6 @@ config FUSION_LAN config FUSION_LOGGING bool "Fusion MPT logging facility" - depends on FUSION ---help--- This turns on a logging facility that can be used to debug a number of Fusion MPT related problems. @@ -115,7 +117,7 @@ config FUSION_LOGGING echo [level] > /sys/class/scsi_host/host#/debug_level - There are various debug levels that an be found in the source: + There are various debug levels that can be found in the source: file:drivers/message/fusion/mptdebug.h endif # FUSION -- cgit v1.1 From 2b83224749e5851469b639d27e13e70621d958a4 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 18:52:28 -0600 Subject: [SCSI] mpt fusion: bump version to 3.04.06 bump version Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 53f7e38..9456564 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -75,8 +75,8 @@ #define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.05" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.05" +#define MPT_LINUX_VERSION_COMMON "3.04.06" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.06" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ -- cgit v1.1 From cec744fb2b78e9dcd377a6740f2de05227c7faef Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Fri, 14 Sep 2007 19:08:08 -0600 Subject: [SCSI] MAINTAINERS : mpt fusion mailing list change Mailing list changed. The former list at mpt_linux_developer@lsi.com is no longer in service. Please use the new email provided listed in this patch. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index fa35397..01480f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2375,7 +2375,7 @@ LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) P: Eric Moore M: Eric.Moore@lsi.com M: support@lsi.com -L: mpt_linux_developer@lsi.com +L: DL-MPTFusionLinux@lsi.com L: linux-scsi@vger.kernel.org W: http://www.lsilogic.com/support S: Supported -- cgit v1.1 From 52aeeca9001d1b4037a8e5d0c001ebb5fdc61b37 Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Mon, 17 Sep 2007 15:11:39 -0700 Subject: [SCSI] stale residual returned on write following BUSY retry A BUSY status returned on a write request results in a stale residual being returned when the write ultimately successfully completes. This can be reproduced as follows: 1) issue immediate mode rewind to scsi tape drive 2) issue write request The tape drive returns busy. The low level driver detects underrun and sets the residual into the scsi command. The low level driver responds with (DID_OK << 16) | scsi_status. scsi_status is 8, hence status_byte(result) == 4, i.e., BUSY. scsi_softirq_done() calls scsi_decide_disposition() which returns ADD_TO_MLQUEUE. scsi_softirq_done() then calls scsi_queue_insert() which, on the way to resubmitting the request to the driver, calls scsi_init_cmd_errh(). The attached patch modifies scsi_init_cmd_errh() to clear the resid field. This prevents a "stale" residual from being returned when the scsi command finally completes without a BUSY status. Signed-off-by: Michael Reed Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 277f1b6..47d3cdd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -449,6 +449,7 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) { cmd->serial_number = 0; + cmd->resid = 0; memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); if (cmd->cmd_len == 0) cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); -- cgit v1.1 From 427d0bd4fde60f40e9518817d826e48c05262a98 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 18 Sep 2007 12:27:43 +0200 Subject: [SCSI] ide-scsi.: convert to data accessors and !use_sg cleanup - Convert ide-scsi to the new data accessors and cleanup the !use_sg code paths. In old code the driver was trying to translate narrow commands, if received, to wide commands. This code path still assumed scsi_cmnd->request_buffer is a linear char pointer. This means that this driver was broken since 2.6.17. As suggested by Christoph Hellwig I set use_10_for_rw = 1; and use_10_for_ms = 1; for this device and completely killed the translation. Signed-off-by: Boaz Harrosh Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: James Bottomley --- drivers/scsi/ide-scsi.c | 138 +++++------------------------------------------- 1 file changed, 13 insertions(+), 125 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 1cc01ac..3b55a6c 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -82,14 +82,12 @@ typedef struct idescsi_pc_s { */ #define PC_DMA_IN_PROGRESS 0 /* 1 while DMA in progress */ #define PC_WRITING 1 /* Data direction */ -#define PC_TRANSFORM 2 /* transform SCSI commands */ #define PC_TIMEDOUT 3 /* command timed out */ #define PC_DMA_OK 4 /* Use DMA */ /* * SCSI command transformation layer */ -#define IDESCSI_TRANSFORM 0 /* Enable/Disable transformation */ #define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ /* @@ -175,7 +173,8 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne char *buf; while (bcount) { - if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { + if (pc->sg - scsi_sglist(pc->scsi_cmd) > + scsi_sg_count(pc->scsi_cmd)) { printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); idescsi_discard_data (drive, bcount); return; @@ -210,7 +209,8 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign char *buf; while (bcount) { - if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { + if (pc->sg - scsi_sglist(pc->scsi_cmd) > + scsi_sg_count(pc->scsi_cmd)) { printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); idescsi_output_zeros (drive, bcount); return; @@ -239,77 +239,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign } } -/* - * Most of the SCSI commands are supported directly by ATAPI devices. - * idescsi_transform_pc handles the few exceptions. - */ -static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc) -{ - u8 *c = pc->c, *scsi_buf = pc->buffer, *sc = pc->scsi_cmd->cmnd; - char *atapi_buf; - - if (!test_bit(PC_TRANSFORM, &pc->flags)) - return; - if (drive->media == ide_cdrom || drive->media == ide_optical) { - if (c[0] == READ_6 || c[0] == WRITE_6) { - c[8] = c[4]; c[5] = c[3]; c[4] = c[2]; - c[3] = c[1] & 0x1f; c[2] = 0; c[1] &= 0xe0; - c[0] += (READ_10 - READ_6); - } - if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { - unsigned short new_len; - if (!scsi_buf) - return; - if ((atapi_buf = kmalloc(pc->buffer_size + 4, GFP_ATOMIC)) == NULL) - return; - memset(atapi_buf, 0, pc->buffer_size + 4); - memset (c, 0, 12); - c[0] = sc[0] | 0x40; - c[1] = sc[1]; - c[2] = sc[2]; - new_len = sc[4] + 4; - c[8] = new_len; - c[7] = new_len >> 8; - c[9] = sc[5]; - if (c[0] == MODE_SELECT_10) { - atapi_buf[1] = scsi_buf[0]; /* Mode data length */ - atapi_buf[2] = scsi_buf[1]; /* Medium type */ - atapi_buf[3] = scsi_buf[2]; /* Device specific parameter */ - atapi_buf[7] = scsi_buf[3]; /* Block descriptor length */ - memcpy(atapi_buf + 8, scsi_buf + 4, pc->buffer_size - 4); - } - pc->buffer = atapi_buf; - pc->request_transfer += 4; - pc->buffer_size += 4; - } - } -} - -static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc) -{ - u8 *atapi_buf = pc->buffer; - u8 *sc = pc->scsi_cmd->cmnd; - u8 *scsi_buf = pc->scsi_cmd->request_buffer; - - if (!test_bit(PC_TRANSFORM, &pc->flags)) - return; - if (drive->media == ide_cdrom || drive->media == ide_optical) { - if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) { - scsi_buf[0] = atapi_buf[1]; /* Mode data length */ - scsi_buf[1] = atapi_buf[2]; /* Medium type */ - scsi_buf[2] = atapi_buf[3]; /* Device specific parameter */ - scsi_buf[3] = atapi_buf[7]; /* Block descriptor length */ - memcpy(scsi_buf + 4, atapi_buf + 8, pc->request_transfer - 8); - } - if (pc->c[0] == INQUIRY) { - scsi_buf[2] |= 2; /* ansi_revision */ - scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; /* response data format */ - } - } - if (atapi_buf && atapi_buf != scsi_buf) - kfree(atapi_buf); -} - static void hexdump(u8 *x, int len) { int i; @@ -393,7 +322,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); struct Scsi_Host *host; - u8 *scsi_buf; int errors = rq->errors; unsigned long flags; @@ -434,15 +362,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); } else { pc->scsi_cmd->result = DID_OK << 16; - idescsi_transform_pc2 (drive, pc); - if (log) { - printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number); - if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) { - printk(", rst = "); - scsi_buf = pc->scsi_cmd->request_buffer; - hexdump(scsi_buf, min_t(unsigned, 16, pc->scsi_cmd->request_bufflen)); - } else printk("\n"); - } } host = pc->scsi_cmd->device->host; spin_lock_irqsave(host->host_lock, flags); @@ -637,19 +556,14 @@ static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc) return 1; sg = hwif->sg_table; - scsi_sg = pc->scsi_cmd->request_buffer; - segments = pc->scsi_cmd->use_sg; + scsi_sg = scsi_sglist(pc->scsi_cmd); + segments = scsi_sg_count(pc->scsi_cmd); if (segments > hwif->sg_max_nents) return 1; - if (!segments) { - hwif->sg_nents = 1; - sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer); - } else { - hwif->sg_nents = segments; - memcpy(sg, scsi_sg, sizeof(*sg) * segments); - } + hwif->sg_nents = segments; + memcpy(sg, scsi_sg, sizeof(*sg) * segments); return 0; } @@ -744,7 +658,6 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { if (drive->id && (drive->id->config & 0x0060) == 0x20) set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); - set_bit(IDESCSI_TRANSFORM, &scsi->transform); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); #if IDESCSI_DEBUG_LOG set_bit(IDESCSI_LOG_CMD, &scsi->log); @@ -838,6 +751,8 @@ static struct block_device_operations idescsi_ops = { static int idescsi_slave_configure(struct scsi_device * sdp) { /* Configure detected device */ + sdp->use_10_for_rw = 1; + sdp->use_10_for_ms = 1; scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); return 0; } @@ -862,24 +777,6 @@ static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg) return -EINVAL; } -static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd) -{ - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - - /* this was a layering violation and we can't support it - anymore, sorry. */ -#if 0 - struct gendisk *disk = cmd->request->rq_disk; - - if (disk) { - struct struct scsi_device_Template **p = disk->private_data; - if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0) - return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); - } -#endif - return test_bit(IDESCSI_TRANSFORM, &scsi->transform); -} - static int idescsi_queue (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { @@ -905,23 +802,14 @@ static int idescsi_queue (struct scsi_cmnd *cmd, pc->flags = 0; pc->rq = rq; memcpy (pc->c, cmd->cmnd, cmd->cmd_len); - if (cmd->use_sg) { - pc->buffer = NULL; - pc->sg = cmd->request_buffer; - } else { - pc->buffer = cmd->request_buffer; - pc->sg = NULL; - } + pc->buffer = NULL; + pc->sg = scsi_sglist(cmd); pc->b_count = 0; - pc->request_transfer = pc->buffer_size = cmd->request_bufflen; + pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); pc->scsi_cmd = cmd; pc->done = done; pc->timeout = jiffies + cmd->timeout_per_command; - if (should_transform(drive, cmd)) - set_bit(PC_TRANSFORM, &pc->flags); - idescsi_transform_pc1 (drive, pc); - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); hexdump(cmd->cmnd, cmd->cmd_len); -- cgit v1.1 From 10f4b89a0f0586a67f57efb2f5d12fffbb371490 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 19 Sep 2007 22:59:16 +0900 Subject: [SCSI] Fix signness of parameters in scsi module In scsi module I've found some inconsistency between variable type used in module_param_named and type passed to module_param_named as an argument. Especially the inconsistency of `max_scsi_luns' parameter is a bit serious because the description text says "last scsi LUN (should be between 1 and 2^32-1)". Signed-off-by: Masatake YAMATO Acked-by: Randy Dunlap Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 6 +++--- drivers/scsi/scsi_transport_fc.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 309b224..20df7fe 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -85,7 +85,7 @@ static unsigned int max_scsi_luns = MAX_SCSI_LUNS; static unsigned int max_scsi_luns = 1; #endif -module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); +module_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_luns, "last scsi LUN (should be between 1 and 2^32-1)"); @@ -109,14 +109,14 @@ MODULE_PARM_DESC(scan, "sync, async or none"); */ static unsigned int max_scsi_report_luns = 511; -module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR); +module_param_named(max_report_luns, max_scsi_report_luns, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_report_luns, "REPORT LUNS maximum number of LUNS received (should be" " between 1 and 16384)"); static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ+3; -module_param_named(inq_timeout, scsi_inq_timeout, int, S_IRUGO|S_IWUSR); +module_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(inq_timeout, "Timeout (in seconds) waiting for devices to answer INQUIRY." " Default is 5. Some non-compliant devices need more."); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 8df0f08..7a7cfe5 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -474,7 +474,7 @@ static DECLARE_TRANSPORT_CLASS(fc_vport_class, */ static unsigned int fc_dev_loss_tmo = 60; /* seconds */ -module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); +module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC transport should" " insulate the loss of a remote port. Once this value is" -- cgit v1.1 From f72abc2110dc07892ed815f46e433cd97309ab7c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 19 Sep 2007 22:08:56 +0200 Subject: [SCSI] MAINTAINERS: mark ide-scsi as Orphan Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: James Bottomley --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 01480f0..7b31474 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1894,6 +1894,11 @@ M: Gadi Oxman L: linux-kernel@vger.kernel.org S: Maintained +IDE-SCSI DRIVER +L: linux-ide@vger.kernel.org +L: linux-scsi@vger.kernel.org +S: Orphan + IEEE 1394 SUBSYSTEM P: Ben Collins M: ben.collins@ubuntu.com -- cgit v1.1 From 1a1d641490e59b6d71e3a4b38616161ee6738aac Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 20 Sep 2007 15:15:27 +0100 Subject: [SCSI] eata_pio: Clean up proc handling, bracketing and use cpu_relax() So its ancient, its crap, but it kept showing up in my scans for stuff that wanted fixing... - Redo the proc code to be far cleaner - Clean various return (0) type constructs - Use cpu_relax() The various waits ought to time out but thats another issue and probably not worth solving. Signed-off-by: Alan Cox Signed-off-by: James Bottomley --- drivers/scsi/eata_pio.c | 88 ++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index f33ad01..73260e5 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -107,59 +107,44 @@ static struct scsi_host_template driver_template; static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int rw) { - static u8 buff[512]; - int size, len = 0; - off_t begin = 0, pos = 0; + int len = 0; + off_t begin = 0, pos = 0; - if (rw) - return -ENOSYS; - if (offset == 0) - memset(buff, 0, sizeof(buff)); + if (rw) + return -ENOSYS; - size = sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " + len += sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); - len += size; pos = begin + len; - size = sprintf(buffer + len, "queued commands: %10ld\n" + len += sprintf(buffer + len, "queued commands: %10ld\n" "processed interrupts:%10ld\n", queue_counter, int_counter); - len += size; pos = begin + len; - - size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", + len += sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", shost->host_no, SD(shost)->name); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Firmware revision: v%s\n", + len += sprintf(buffer + len, "Firmware revision: v%s\n", SD(shost)->revision); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "IO: PIO\n"); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Host Bus: %s\n", + len += sprintf(buffer + len, "IO: PIO\n"); + len += sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base); + len += sprintf(buffer + len, "Host Bus: %s\n", (SD(shost)->bustype == 'P')?"PCI ": (SD(shost)->bustype == 'E')?"EISA":"ISA "); - len += size; - pos = begin + len; + pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; + if (pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) + goto stop_output; - stop_output: - DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); - *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Start slop */ - if(len>length) - len = length; /* Ending slop */ - DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); +stop_output: + DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; /* Ending slop */ + DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); - return (len); + return len; } static int eata_pio_release(struct Scsi_Host *sh) @@ -438,7 +423,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, "returning DID_BUS_BUSY, done.\n", cmd->pid); done(cmd); cp->status = FREE; - return (0); + return 0; } /* FIXME: timeout */ while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) @@ -452,7 +437,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, "Queued base %#.4lx pid: %ld " "slot %d irq %d\n", sh->base, cmd->pid, y, sh->irq)); - return (0); + return 0; } static int eata_pio_abort(struct scsi_cmnd *cmd) @@ -589,23 +574,28 @@ static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned i cp.cp_cdb[5] = 0; if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) - return (NULL); - while (!(inb(base + HA_RSTATUS) & HA_SDRQ)); + return NULL; + + while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) + cpu_relax(); + outsw(base + HA_RDATA, &cp, cplen); outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); for (z = 0; z < cppadlen; z++) outw(0, base + HA_RDATA); - while (inb(base + HA_RSTATUS) & HA_SBUSY); + while (inb(base + HA_RSTATUS) & HA_SBUSY) + cpu_relax(); + if (inb(base + HA_RSTATUS) & HA_SERROR) - return (NULL); + return NULL; else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - return (NULL); + return NULL; else { insw(base + HA_RDATA, &buff, 127); while (inb(base + HA_RSTATUS) & HA_SDRQ) inw(base + HA_RDATA); - return (buff); + return buff; } } -- cgit v1.1 From 5307b1e8b050f309901acc9c6121061206a70ba5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 20 Sep 2007 15:12:11 +0100 Subject: [SCSI] dtc: Fix typo (and pointed out by several people) Signed-off-by: Alan Cox Signed-off-by: James Bottomley --- drivers/scsi/dtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index da7409e..2596165 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -242,7 +242,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { addr = bases[current_base].address; #if (DTCDEBUG & DTCDEBUG_INIT) - printk(KERB_DEBUG "scsi-dtc : detected board.\n"); + printk(KERN_DEBUG "scsi-dtc : detected board.\n"); #endif goto found; } -- cgit v1.1 From d3849d512fb0ca1e369e3efcaec910a949f55f62 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 22 Sep 2007 08:29:36 +1000 Subject: [SCSI] Fix ibmvscsi client for multiplatform iSeries+pSeries kernel If you build a multiplatform kernel for iSeries and pSeries, with ibmvscsic support, the resulting client doesn't work on iSeries. This fixes that, using the appropriate low-level operations for the machine detected at runtime. [jejb: fixed up rejections around the srp transport patch] Signed-off-by: David Woodhouse Acked by: Brian King Signed-off-by: Paul Mackerras Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/Makefile | 2 - drivers/scsi/ibmvscsi/ibmvscsi.c | 46 ++++++++------ drivers/scsi/ibmvscsi/ibmvscsi.h | 32 +++++----- drivers/scsi/ibmvscsi/iseries_vscsi.c | 37 ++++++----- drivers/scsi/ibmvscsi/rpa_vscsi.c | 113 ++++++++++++++++++---------------- 5 files changed, 130 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index f67d9ef..6ac0633 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile @@ -1,9 +1,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o ibmvscsic-y += ibmvscsi.o -ifndef CONFIG_PPC_PSERIES ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o -endif ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 93bd01b..cda0cc3 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template; #define IBMVSCSI_VERSION "1.5.8" +static struct ibmvscsi_ops *ibmvscsi_ops; + MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); MODULE_LICENSE("GPL"); @@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) atomic_set(&hostdata->request_limit, 0); purge_requests(hostdata, DID_ERROR); - if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || - (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || + if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) || (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after reset\n"); @@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, } if ((rc = - ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { + ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { list_del(&evt_struct->list); del_timer(&evt_struct->timer); @@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, case 0x01: /* Initialization message */ dev_info(hostdata->dev, "partner initialized\n"); /* Send back a response */ - if ((rc = ibmvscsi_send_crq(hostdata, - 0xC002000000000000LL, 0)) == 0) { + if ((rc = ibmvscsi_ops->send_crq(hostdata, + 0xC002000000000000LL, 0)) == 0) { /* Now login */ send_srp_login(hostdata); } else { @@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, /* We need to re-setup the interpartition connection */ dev_info(hostdata->dev, "Re-enabling adapter!\n"); purge_requests(hostdata, DID_REQUEUE); - if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, - hostdata)) || - (ibmvscsi_send_crq(hostdata, - 0xC001000000000000LL, 0))) { + if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue, + hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, + 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after enable\n"); @@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, crq->format); purge_requests(hostdata, DID_ERROR); - if ((ibmvscsi_reset_crq_queue(&hostdata->queue, - hostdata)) || - (ibmvscsi_send_crq(hostdata, - 0xC001000000000000LL, 0))) { + if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, + hostdata)) || + (ibmvscsi_ops->send_crq(hostdata, + 0xC001000000000000LL, 0))) { atomic_set(&hostdata->request_limit, -1); dev_err(hostdata->dev, "error after reset\n"); @@ -1579,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) atomic_set(&hostdata->request_limit, -1); hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ - rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); + rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests); if (rc != 0 && rc != H_RESOURCE) { dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); goto init_crq_failed; @@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) * to fail if the other end is not acive. In that case we don't * want to scan */ - if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 + if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0 || rc == H_RESOURCE) { /* * Wait around max init_timeout secs for the adapter to finish @@ -1636,7 +1639,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) add_host_failed: release_event_pool(&hostdata->pool, hostdata); init_pool_failed: - ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); + ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests); init_crq_failed: scsi_host_put(host); scsi_host_alloc_failed: @@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev) { struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; release_event_pool(&hostdata->pool, hostdata); - ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, - max_requests); + ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, + max_requests); srp_remove_host(hostdata->host); scsi_remove_host(hostdata->host); @@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void) { int ret; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + ibmvscsi_ops = &iseriesvscsi_ops; + else if (firmware_has_feature(FW_FEATURE_VIO)) + ibmvscsi_ops = &rpavscsi_ops; + else + return -ENODEV; + ibmvscsi_transport_template = srp_attach_transport(&ibmvscsi_transport_functions); if (!ibmvscsi_transport_template) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index b19c2e2..46e850e 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -98,21 +98,25 @@ struct ibmvscsi_host_data { }; /* routines for managing a command/response queue */ -int ibmvscsi_init_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests); -void ibmvscsi_release_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests); -int ibmvscsi_reset_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata); - -int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata); - void ibmvscsi_handle_crq(struct viosrp_crq *crq, struct ibmvscsi_host_data *hostdata); -int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, - u64 word1, u64 word2); + +struct ibmvscsi_ops { + int (*init_crq_queue)(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests); + void (*release_crq_queue)(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests); + int (*reset_crq_queue)(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata); + int (*reenable_crq_queue)(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata); + int (*send_crq)(struct ibmvscsi_host_data *hostdata, + u64 word1, u64 word2); +}; + +extern struct ibmvscsi_ops iseriesvscsi_ops; +extern struct ibmvscsi_ops rpavscsi_ops; #endif /* IBMVSCSI_H */ diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 6aeb5f0..0775fde 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -53,7 +53,7 @@ struct srp_lp_event { /** * standard interface for handling logical partition events. */ -static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) +static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt) { struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; @@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) /* ------------------------------------------------------------ * Routines for driver initialization */ -int ibmvscsi_init_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static int iseriesvscsi_init_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { int rc; @@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, goto viopath_open_failed; } - rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); + rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event); if (rc < 0) { printk("vio_setHandler failed with rc %d in open_event_path\n", rc); @@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, return -1; } -void ibmvscsi_release_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static void iseriesvscsi_release_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { vio_clearHandler(viomajorsubtype_scsi); viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); @@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -int ibmvscsi_reset_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { return 0; } @@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { return 0; } /** - * ibmvscsi_send_crq: - Send a CRQ + * iseriesvscsi_send_crq: - Send a CRQ * @hostdata: the adapter * @word1: the first 64 bits of the data * @word2: the second 64 bits of the data */ -int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) +static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, + u64 word1, u64 word2) { single_host_data = hostdata; return HvCallEvent_signalLpEventFast(viopath_hostLp, @@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) VIOVERSION << 16, word1, word2, 0, 0); } + +struct ibmvscsi_ops iseriesvscsi_ops = { + .init_crq_queue = iseriesvscsi_init_crq_queue, + .release_crq_queue = iseriesvscsi_release_crq_queue, + .reset_crq_queue = iseriesvscsi_reset_crq_queue, + .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, + .send_crq = iseriesvscsi_send_crq, +}; diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 9c14e78..1821461 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -42,14 +42,14 @@ static unsigned int partition_number = -1; * Routines for managing the command/response queue */ /** - * ibmvscsi_handle_event: - Interrupt handler for crq events + * rpavscsi_handle_event: - Interrupt handler for crq events * @irq: number of irq to handle, not used * @dev_instance: ibmvscsi_host_data of host that received interrupt * * Disables interrupts and schedules srp_task * Always returns IRQ_HANDLED */ -static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) +static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance) { struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)dev_instance; @@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) * Frees irq, deallocates a page for messages, unmaps dma, and unregisters * the crq with the hypervisor. */ -void ibmvscsi_release_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static void rpavscsi_release_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { long rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) } /** - * ibmvscsi_send_crq: - Send a CRQ + * rpavscsi_send_crq: - Send a CRQ * @hostdata: the adapter * @word1: the first 64 bits of the data * @word2: the second 64 bits of the data */ -int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) +static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata, + u64 word1, u64 word2) { struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) } /** - * ibmvscsi_task: - Process srps asynchronously + * rpavscsi_task: - Process srps asynchronously * @data: ibmvscsi_host_data of host */ -static void ibmvscsi_task(void *data) +static void rpavscsi_task(void *data) { struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -190,6 +191,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) } /** + * reset_crq_queue: - resets a crq after a failure + * @queue: crq_queue to initialize and register + * @hostdata: ibmvscsi_host_data of host + * + */ +static int rpavscsi_reset_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) +{ + int rc; + struct vio_dev *vdev = to_vio_dev(hostdata->dev); + + /* Close the CRQ */ + do { + rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); + + /* Clean out the queue */ + memset(queue->msgs, 0x00, PAGE_SIZE); + queue->cur = 0; + + set_adapter_info(hostdata); + + /* And re-open it again */ + rc = plpar_hcall_norets(H_REG_CRQ, + vdev->unit_address, + queue->msg_token, PAGE_SIZE); + if (rc == 2) { + /* Adapter is good, but other end is not ready */ + dev_warn(hostdata->dev, "Partner adapter not ready\n"); + } else if (rc != 0) { + dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); + } + return rc; +} + +/** * initialize_crq_queue: - Initializes and registers CRQ with hypervisor * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host @@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) * the crq with the hypervisor. * Returns zero on success. */ -int ibmvscsi_init_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata, - int max_requests) +static int rpavscsi_init_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata, + int max_requests) { int rc; int retrc; @@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, queue->msg_token, PAGE_SIZE); if (rc == H_RESOURCE) /* maybe kexecing and resource is busy. try a reset */ - rc = ibmvscsi_reset_crq_queue(queue, + rc = rpavscsi_reset_crq_queue(queue, hostdata); if (rc == 2) { @@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, } if (request_irq(vdev->irq, - ibmvscsi_handle_event, + rpavscsi_handle_event, 0, "ibmvscsi", (void *)hostdata) != 0) { dev_err(hostdata->dev, "couldn't register irq 0x%x\n", vdev->irq); @@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, queue->cur = 0; spin_lock_init(&queue->lock); - tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, + tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task, (unsigned long)hostdata); return retrc; @@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, * @hostdata: ibmvscsi_host_data of host * */ -int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) +static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, + struct ibmvscsi_host_data *hostdata) { int rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); @@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, return rc; } -/** - * reset_crq_queue: - resets a crq after a failure - * @queue: crq_queue to initialize and register - * @hostdata: ibmvscsi_host_data of host - * - */ -int ibmvscsi_reset_crq_queue(struct crq_queue *queue, - struct ibmvscsi_host_data *hostdata) -{ - int rc; - struct vio_dev *vdev = to_vio_dev(hostdata->dev); - - /* Close the CRQ */ - do { - rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); - } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); - - /* Clean out the queue */ - memset(queue->msgs, 0x00, PAGE_SIZE); - queue->cur = 0; - - set_adapter_info(hostdata); - - /* And re-open it again */ - rc = plpar_hcall_norets(H_REG_CRQ, - vdev->unit_address, - queue->msg_token, PAGE_SIZE); - if (rc == 2) { - /* Adapter is good, but other end is not ready */ - dev_warn(hostdata->dev, "Partner adapter not ready\n"); - } else if (rc != 0) { - dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); - } - return rc; -} +struct ibmvscsi_ops rpavscsi_ops = { + .init_crq_queue = rpavscsi_init_crq_queue, + .release_crq_queue = rpavscsi_release_crq_queue, + .reset_crq_queue = rpavscsi_reset_crq_queue, + .reenable_crq_queue = rpavscsi_reenable_crq_queue, + .send_crq = rpavscsi_send_crq, +}; -- cgit v1.1 From 7f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 4 Aug 2007 10:06:25 -0500 Subject: [SCSI] move ULD attachment into the prep function One of the intents of the block prep function was to allow ULDs to use it for preprocessing. The original SCSI model was to have a single prep function and add a pointer indirect filter to build the necessary commands. This patch reverses that, does away with the init_command field of the scsi_driver structure and makes ULDs attach directly to the prep function instead. The value is really that it allows us to begin to separate the ULDs from the SCSI mid layer (as long as they don't use any core functions---which is hard at the moment---a ULD doesn't even need SCSI to bind). Acked-by: Jens Axboe Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 84 ++++++++++++++++++++-------------------------- drivers/scsi/sd.c | 48 ++++++++++++++++++-------- drivers/scsi/sr.c | 59 +++++++++++++++++++++----------- include/scsi/scsi_driver.h | 9 ++++- include/scsi/sd.h | 1 - 5 files changed, 119 insertions(+), 82 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 47d3cdd..94d82cb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1039,9 +1039,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd) printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors); - /* release the command and kill it */ - scsi_release_buffers(cmd); - scsi_put_command(cmd); return BLKPREP_KILL; } @@ -1078,9 +1075,13 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) scsi_io_completion(cmd, cmd->request_bufflen); } -static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) +int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; + int ret = scsi_prep_state_check(sdev, req); + + if (ret != BLKPREP_OK) + return ret; cmd = scsi_get_cmd_from_req(sdev, req); if (unlikely(!cmd)) @@ -1126,18 +1127,20 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) cmd->done = scsi_blk_pc_done; return BLKPREP_OK; } +EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); /* * Setup a REQ_TYPE_FS command. These are simple read/write request * from filesystems that still need to be translated to SCSI CDBs from * the ULD. */ -static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) +int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; - struct scsi_driver *drv; - int ret; + int ret = scsi_prep_state_check(sdev, req); + if (ret != BLKPREP_OK) + return ret; /* * Filesystem requests must transfer data. */ @@ -1147,26 +1150,12 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) if (unlikely(!cmd)) return BLKPREP_DEFER; - ret = scsi_init_io(cmd); - if (unlikely(ret)) - return ret; - - /* - * Initialize the actual SCSI command for this request. - */ - drv = *(struct scsi_driver **)req->rq_disk->private_data; - if (unlikely(!drv->init_command(cmd))) { - scsi_release_buffers(cmd); - scsi_put_command(cmd); - return BLKPREP_KILL; - } - - return BLKPREP_OK; + return scsi_init_io(cmd); } +EXPORT_SYMBOL(scsi_setup_fs_cmnd); -static int scsi_prep_fn(struct request_queue *q, struct request *req) +int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) { - struct scsi_device *sdev = q->queuedata; int ret = BLKPREP_OK; /* @@ -1212,35 +1201,25 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ret = BLKPREP_KILL; break; } - - if (ret != BLKPREP_OK) - goto out; } + return ret; +} +EXPORT_SYMBOL(scsi_prep_state_check); - switch (req->cmd_type) { - case REQ_TYPE_BLOCK_PC: - ret = scsi_setup_blk_pc_cmnd(sdev, req); - break; - case REQ_TYPE_FS: - ret = scsi_setup_fs_cmnd(sdev, req); - break; - default: - /* - * All other command types are not supported. - * - * Note that these days the SCSI subsystem does not use - * REQ_TYPE_SPECIAL requests anymore. These are only used - * (directly or via blk_insert_request) by non-SCSI drivers. - */ - blk_dump_rq_flags(req, "SCSI bad req"); - ret = BLKPREP_KILL; - break; - } +int scsi_prep_return(struct request_queue *q, struct request *req, int ret) +{ + struct scsi_device *sdev = q->queuedata; - out: switch (ret) { case BLKPREP_KILL: req->errors = DID_NO_CONNECT << 16; + /* release the command and kill it */ + if (req->special) { + struct scsi_cmnd *cmd = req->special; + scsi_release_buffers(cmd); + scsi_put_command(cmd); + req->special = NULL; + } break; case BLKPREP_DEFER: /* @@ -1257,6 +1236,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) return ret; } +EXPORT_SYMBOL(scsi_prep_return); + +static int scsi_prep_fn(struct request_queue *q, struct request *req) +{ + struct scsi_device *sdev = q->queuedata; + int ret = BLKPREP_KILL; + + if (req->cmd_type == REQ_TYPE_BLOCK_PC) + ret = scsi_setup_blk_pc_cmnd(sdev, req); + return scsi_prep_return(q, req, ret); +} /* * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2c6116f..38a4141 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -240,7 +240,6 @@ static struct scsi_driver sd_template = { .shutdown = sd_shutdown, }, .rescan = sd_rescan, - .init_command = sd_init_command, }; /* @@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) * * Returns 1 if successful and 0 if error (or cannot be done now). **/ -static int sd_init_command(struct scsi_cmnd * SCpnt) +static int sd_prep_fn(struct request_queue *q, struct request *rq) { - struct scsi_device *sdp = SCpnt->device; - struct request *rq = SCpnt->request; + struct scsi_cmnd *SCpnt; + struct scsi_device *sdp = q->queuedata; struct gendisk *disk = rq->rq_disk; sector_t block = rq->sector; - unsigned int this_count = SCpnt->request_bufflen >> 9; + unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; + int ret; + + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { + ret = scsi_setup_blk_pc_cmnd(sdp, rq); + goto out; + } else if (rq->cmd_type != REQ_TYPE_FS) { + ret = BLKPREP_KILL; + goto out; + } + ret = scsi_setup_fs_cmnd(sdp, rq); + if (ret != BLKPREP_OK) + goto out; + SCpnt = rq->special; + + /* from here on until we're complete, any goto out + * is used for a killable error condition */ + ret = BLKPREP_KILL; SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, "sd_init_command: block=%llu, " @@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) rq->nr_sectors)); SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "Retry with 0x%p\n", SCpnt)); - return 0; + goto out; } if (sdp->changed) { @@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * the changed bit has been reset */ /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ - return 0; + goto out; } + SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", (unsigned long long)block)); @@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) if ((block & 1) || (rq->nr_sectors & 1)) { scmd_printk(KERN_ERR, SCpnt, "Bad block number requested\n"); - return 0; + goto out; } else { block = block >> 1; this_count = this_count >> 1; @@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) if ((block & 3) || (rq->nr_sectors & 3)) { scmd_printk(KERN_ERR, SCpnt, "Bad block number requested\n"); - return 0; + goto out; } else { block = block >> 2; this_count = this_count >> 2; @@ -402,7 +419,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) if ((block & 7) || (rq->nr_sectors & 7)) { scmd_printk(KERN_ERR, SCpnt, "Bad block number requested\n"); - return 0; + goto out; } else { block = block >> 3; this_count = this_count >> 3; @@ -410,7 +427,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) } if (rq_data_dir(rq) == WRITE) { if (!sdp->writeable) { - return 0; + goto out; } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = DMA_TO_DEVICE; @@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->sc_data_direction = DMA_FROM_DEVICE; } else { scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); - return 0; + goto out; } SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, @@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) */ scmd_printk(KERN_ERR, SCpnt, "FUA write on READ/WRITE(6) drive\n"); - return 0; + goto out; } SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); @@ -501,7 +518,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * This indicates that the command is ready from our end to be * queued. */ - return 1; + ret = BLKPREP_OK; + out: + return scsi_prep_return(q, rq, ret); } /** @@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev) sd_revalidate_disk(gd); + blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); gd->driverfs_dev = &sdp->sdev_gendev; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 902eb11..a0c4e13 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -78,7 +78,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); static int sr_probe(struct device *); static int sr_remove(struct device *); -static int sr_init_command(struct scsi_cmnd *); static struct scsi_driver sr_template = { .owner = THIS_MODULE, @@ -87,7 +86,6 @@ static struct scsi_driver sr_template = { .probe = sr_probe, .remove = sr_remove, }, - .init_command = sr_init_command, }; static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; @@ -296,19 +294,39 @@ static void rw_intr(struct scsi_cmnd * SCpnt) scsi_io_completion(SCpnt, good_bytes); } -static int sr_init_command(struct scsi_cmnd * SCpnt) +static int sr_prep_fn(struct request_queue *q, struct request *rq) { int block=0, this_count, s_size, timeout = SR_TIMEOUT; - struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); + struct scsi_cd *cd; + struct scsi_cmnd *SCpnt; + struct scsi_device *sdp = q->queuedata; + int ret; + + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { + ret = scsi_setup_blk_pc_cmnd(sdp, rq); + goto out; + } else if (rq->cmd_type != REQ_TYPE_FS) { + ret = BLKPREP_KILL; + goto out; + } + ret = scsi_setup_fs_cmnd(sdp, rq); + if (ret != BLKPREP_OK) + goto out; + SCpnt = rq->special; + cd = scsi_cd(rq->rq_disk); + + /* from here on until we're complete, any goto out + * is used for a killable error condition */ + ret = BLKPREP_KILL; SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", cd->disk->disk_name, block)); if (!cd->device || !scsi_device_online(cd->device)) { SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", - SCpnt->request->nr_sectors)); + rq->nr_sectors)); SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); - return 0; + goto out; } if (cd->device->changed) { @@ -316,7 +334,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) * quietly refuse to do anything to a changed disc until the * changed bit has been reset */ - return 0; + goto out; } /* @@ -333,21 +351,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) if (s_size != 512 && s_size != 1024 && s_size != 2048) { scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); - return 0; + goto out; } - if (rq_data_dir(SCpnt->request) == WRITE) { + if (rq_data_dir(rq) == WRITE) { if (!cd->device->writeable) - return 0; + goto out; SCpnt->cmnd[0] = WRITE_10; SCpnt->sc_data_direction = DMA_TO_DEVICE; cd->cdi.media_written = 1; - } else if (rq_data_dir(SCpnt->request) == READ) { + } else if (rq_data_dir(rq) == READ) { SCpnt->cmnd[0] = READ_10; SCpnt->sc_data_direction = DMA_FROM_DEVICE; } else { - blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); - return 0; + blk_dump_rq_flags(rq, "Unknown sr command"); + goto out; } { @@ -368,10 +386,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) /* * request doesn't start on hw block boundary, add scatter pads */ - if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || + if (((unsigned int)rq->sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); - return 0; + goto out; } this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); @@ -379,12 +397,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", cd->cdi.name, - (rq_data_dir(SCpnt->request) == WRITE) ? + (rq_data_dir(rq) == WRITE) ? "writing" : "reading", - this_count, SCpnt->request->nr_sectors)); + this_count, rq->nr_sectors)); SCpnt->cmnd[1] = 0; - block = (unsigned int)SCpnt->request->sector / (s_size >> 9); + block = (unsigned int)rq->sector / (s_size >> 9); if (this_count > 0xffff) { this_count = 0xffff; @@ -419,7 +437,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) * This indicates that the command is ready from our end to be * queued. */ - return 1; + ret = BLKPREP_OK; + out: + return scsi_prep_return(q, rq, ret); } static int sr_block_open(struct inode *inode, struct file *file) @@ -590,6 +610,7 @@ static int sr_probe(struct device *dev) /* FIXME: need to handle a get_capabilities failure properly ?? */ get_capabilities(cd); + blk_queue_prep_rq(sdev->request_queue, sr_prep_fn); sr_vendor_init(cd); disk->driverfs_dev = &sdev->sdev_gendev; diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 3465f31..56a3047 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -5,13 +5,15 @@ struct module; struct scsi_cmnd; +struct scsi_device; +struct request; +struct request_queue; struct scsi_driver { struct module *owner; struct device_driver gendrv; - int (*init_command)(struct scsi_cmnd *); void (*rescan)(struct device *); }; #define to_scsi_driver(drv) \ @@ -25,4 +27,9 @@ extern int scsi_register_interface(struct class_interface *); #define scsi_unregister_interface(intf) \ class_interface_unregister(intf) +int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); +int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); +int scsi_prep_return(struct request_queue *q, struct request *req, int ret); + #endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/include/scsi/sd.h b/include/scsi/sd.h index ce02ad1..aa1e716 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h @@ -55,7 +55,6 @@ static void sd_shutdown(struct device *dev); static int sd_suspend(struct device *dev, pm_message_t state); static int sd_resume(struct device *dev); static void sd_rescan(struct device *); -static int sd_init_command(struct scsi_cmnd *); static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); static void scsi_disk_release(struct class_device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -- cgit v1.1 From c81d04c9e27966c0e4c5650d130f209bff9671f9 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 26 Jul 2007 11:41:13 -0700 Subject: [SCSI] qla2xxx: Collapse and simplify ISP2XXX firmware dump routines. Add IO-base-window accessor functions. Merge duplicate RISC-pause and soft-reset code segments. Drop 'eye-watering' __iomem casting. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.c | 1829 ++++++++++++---------------------------- drivers/scsi/qla2xxx/qla_def.h | 4 +- 2 files changed, 560 insertions(+), 1273 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index c668034..b52fa89 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -38,7 +38,7 @@ qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) } static int -qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, +qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, uint32_t cram_size, uint32_t *ext_mem, void **nxt) { int rval; @@ -152,6 +152,106 @@ qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, return rval; } +static uint32_t * +qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, + uint32_t count, uint32_t *buf) +{ + uint32_t __iomem *dmp_reg; + + WRT_REG_DWORD(®->iobase_addr, iobase); + dmp_reg = ®->iobase_window; + while (count--) + *buf++ = htonl(RD_REG_DWORD(dmp_reg++)); + + return buf; +} + +static inline int +qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) +{ + int rval = QLA_SUCCESS; + uint32_t cnt; + + if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { + WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | + HCCRX_CLR_HOST_INT); + RD_REG_DWORD(®->hccr); /* PCI Posting. */ + WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); + for (cnt = 30000; + (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && + rval == QLA_SUCCESS; cnt--) { + if (cnt) + udelay(100); + else + rval = QLA_FUNCTION_TIMEOUT; + } + } + + return rval; +} + +static int +qla24xx_soft_reset(scsi_qla_host_t *ha) +{ + int rval = QLA_SUCCESS; + uint32_t cnt; + uint16_t mb0, wd; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + /* Reset RISC. */ + WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); + for (cnt = 0; cnt < 30000; cnt++) { + if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) + break; + + udelay(10); + } + + WRT_REG_DWORD(®->ctrl_status, + CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); + pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); + + udelay(100); + /* Wait for firmware to complete NVRAM accesses. */ + mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); + for (cnt = 10000 ; cnt && mb0; cnt--) { + udelay(5); + mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); + barrier(); + } + + /* Wait for soft-reset to complete. */ + for (cnt = 0; cnt < 30000; cnt++) { + if ((RD_REG_DWORD(®->ctrl_status) & + CSRX_ISP_SOFT_RESET) == 0) + break; + + udelay(10); + } + WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); + RD_REG_DWORD(®->hccr); /* PCI Posting. */ + + for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && + rval == QLA_SUCCESS; cnt--) { + if (cnt) + udelay(100); + else + rval = QLA_FUNCTION_TIMEOUT; + } + + return rval; +} + +static inline void +qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, + uint16_t *buf) +{ + uint16_t __iomem *dmp_reg = ®->u.isp2300.fb_cmd; + + while (count--) + *buf++ = htons(RD_REG_WORD(dmp_reg++)); +} + /** * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. * @ha: HA context @@ -214,88 +314,61 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) } if (rval == QLA_SUCCESS) { - dmp_reg = (uint16_t __iomem *)(reg + 0); + dmp_reg = ®->flash_address; for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); + dmp_reg = ®->u.isp2300.req_q_in; for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); + dmp_reg = ®->u.isp2300.mailbox0; for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); WRT_REG_WORD(®->ctrl_status, 0x40); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) - fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 32, fw->resp_dma_reg); WRT_REG_WORD(®->ctrl_status, 0x50); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) - fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 48, fw->dma_reg); WRT_REG_WORD(®->ctrl_status, 0x00); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); + dmp_reg = ®->risc_hw; for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); WRT_REG_WORD(®->pcr, 0x2000); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) - fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); WRT_REG_WORD(®->pcr, 0x2200); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) - fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); WRT_REG_WORD(®->pcr, 0x2400); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) - fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); WRT_REG_WORD(®->pcr, 0x2600); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) - fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); WRT_REG_WORD(®->pcr, 0x2800); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) - fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); WRT_REG_WORD(®->pcr, 0x2A00); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) - fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); WRT_REG_WORD(®->pcr, 0x2C00); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) - fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); WRT_REG_WORD(®->pcr, 0x2E00); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) - fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); WRT_REG_WORD(®->ctrl_status, 0x10); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) - fw->frame_buf_hdw_reg[cnt] = - htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg); WRT_REG_WORD(®->ctrl_status, 0x20); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) - fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); WRT_REG_WORD(®->ctrl_status, 0x30); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) - fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); /* Reset RISC. */ WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); @@ -567,83 +640,59 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) rval = QLA_FUNCTION_TIMEOUT; } if (rval == QLA_SUCCESS) { - dmp_reg = (uint16_t __iomem *)(reg + 0); + dmp_reg = ®->flash_address; for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); + dmp_reg = ®->u.isp2100.mailbox0; for (cnt = 0; cnt < ha->mbx_count; cnt++) { - if (cnt == 8) { - dmp_reg = (uint16_t __iomem *) - ((uint8_t __iomem *)reg + 0xe0); - } + if (cnt == 8) + dmp_reg = ®->u_end.isp2200.mailbox8; + fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); } - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); + dmp_reg = ®->u.isp2100.unused_2[0]; for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); WRT_REG_WORD(®->ctrl_status, 0x00); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); + dmp_reg = ®->risc_hw; for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); WRT_REG_WORD(®->pcr, 0x2000); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) - fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); WRT_REG_WORD(®->pcr, 0x2100); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) - fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); WRT_REG_WORD(®->pcr, 0x2200); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) - fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); WRT_REG_WORD(®->pcr, 0x2300); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) - fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); WRT_REG_WORD(®->pcr, 0x2400); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) - fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); WRT_REG_WORD(®->pcr, 0x2500); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) - fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); WRT_REG_WORD(®->pcr, 0x2600); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) - fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); WRT_REG_WORD(®->pcr, 0x2700); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) - fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); WRT_REG_WORD(®->ctrl_status, 0x10); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) - fw->frame_buf_hdw_reg[cnt] = - htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg); WRT_REG_WORD(®->ctrl_status, 0x20); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) - fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); WRT_REG_WORD(®->ctrl_status, 0x30); - dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); - for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) - fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); + qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); /* Reset the ISP. */ WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); @@ -750,7 +799,6 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) int rval; uint32_t cnt; uint32_t risc_address; - uint16_t mb0, wd; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; uint32_t __iomem *dmp_reg; @@ -782,547 +830,198 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) fw = &ha->fw_dump->isp.isp24; qla2xxx_prep_dump(ha, ha->fw_dump); - rval = QLA_SUCCESS; fw->host_status = htonl(RD_REG_DWORD(®->host_status)); /* Pause RISC. */ - if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | - HCCRX_CLR_HOST_INT); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - for (cnt = 30000; - (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && - rval == QLA_SUCCESS; cnt--) { - if (cnt) - udelay(100); - else - rval = QLA_FUNCTION_TIMEOUT; - } - } - - if (rval == QLA_SUCCESS) { - /* Host interface registers. */ - dmp_reg = (uint32_t __iomem *)(reg + 0); - for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) - fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Disable interrupts. */ - WRT_REG_DWORD(®->ictrl, 0); - RD_REG_DWORD(®->ictrl); - - /* Shadow registers. */ - WRT_REG_DWORD(®->iobase_addr, 0x0F70); - RD_REG_DWORD(®->iobase_addr); - WRT_REG_DWORD(®->iobase_select, 0xB0000000); - fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0100000); - fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0200000); - fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0300000); - fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0400000); - fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0500000); - fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0600000); - fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - /* Mailbox registers. */ - mbx_reg = ®->mailbox0; - for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) - fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); - - /* Transfer sequence registers. */ - iter_reg = fw->xseq_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0xBF00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBFE0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) - fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBFF0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) - fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Receive sequence registers. */ - iter_reg = fw->rseq_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0xFF00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFD0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) - fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFE0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) - fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFF0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) - fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Command DMA registers. */ - WRT_REG_DWORD(®->iobase_addr, 0x7100); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) - fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Queues. */ - iter_reg = fw->req0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7200); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->resp0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7300); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->req1_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7400); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Transmit DMA registers. */ - iter_reg = fw->xmt0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7600); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7610); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt1_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7620); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7630); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt2_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7640); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7650); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt3_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7660); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7670); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt4_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7680); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7690); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x76A0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) - fw->xmt_data_dma_reg[cnt] = - htonl(RD_REG_DWORD(dmp_reg++)); - - /* Receive DMA registers. */ - iter_reg = fw->rcvt0_data_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7700); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7710); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->rcvt1_data_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7720); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7730); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* RISC registers. */ - iter_reg = fw->risc_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0x0F00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Local memory controller registers. */ - iter_reg = fw->lmc_reg; - WRT_REG_DWORD(®->iobase_addr, 0x3000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3050); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3060); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Fibre Protocol Module registers. */ - iter_reg = fw->fpm_hdw_reg; - WRT_REG_DWORD(®->iobase_addr, 0x4000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4050); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4060); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4070); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4080); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4090); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x40A0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x40B0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Frame Buffer registers. */ - iter_reg = fw->fb_hdw_reg; - WRT_REG_DWORD(®->iobase_addr, 0x6000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6100); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6130); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6150); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6170); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6190); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x61B0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Reset RISC. */ - WRT_REG_DWORD(®->ctrl_status, - CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - for (cnt = 0; cnt < 30000; cnt++) { - if ((RD_REG_DWORD(®->ctrl_status) & - CSRX_DMA_ACTIVE) == 0) - break; - - udelay(10); - } - - WRT_REG_DWORD(®->ctrl_status, - CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); - - udelay(100); - /* Wait for firmware to complete NVRAM accesses. */ - mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 10000 ; cnt && mb0; cnt--) { - udelay(5); - mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); - barrier(); - } - - /* Wait for soft-reset to complete. */ - for (cnt = 0; cnt < 30000; cnt++) { - if ((RD_REG_DWORD(®->ctrl_status) & - CSRX_ISP_SOFT_RESET) == 0) - break; - - udelay(10); - } - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - } - - for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && - rval == QLA_SUCCESS; cnt--) { - if (cnt) - udelay(100); - else - rval = QLA_FUNCTION_TIMEOUT; - } - - if (rval == QLA_SUCCESS) - rval = qla2xxx_dump_memory(ha, fw->code_ram, - sizeof(fw->code_ram), fw->ext_mem, &nxt); - - if (rval == QLA_SUCCESS) { - nxt = qla2xxx_copy_queues(ha, nxt); - if (ha->eft) - memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); - } - + rval = qla24xx_pause_risc(reg); + if (rval != QLA_SUCCESS) + goto qla24xx_fw_dump_failed_0; + + /* Host interface registers. */ + dmp_reg = ®->flash_addr; + for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) + fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Disable interrupts. */ + WRT_REG_DWORD(®->ictrl, 0); + RD_REG_DWORD(®->ictrl); + + /* Shadow registers. */ + WRT_REG_DWORD(®->iobase_addr, 0x0F70); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_select, 0xB0000000); + fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0100000); + fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0200000); + fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0300000); + fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0400000); + fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0500000); + fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0600000); + fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + /* Mailbox registers. */ + mbx_reg = ®->mailbox0; + for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) + fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); + + /* Transfer sequence registers. */ + iter_reg = fw->xseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); + qla24xx_read_window(reg, 0xBF70, 16, iter_reg); + + qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg); + qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); + + /* Receive sequence registers. */ + iter_reg = fw->rseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); + qla24xx_read_window(reg, 0xFF70, 16, iter_reg); + + qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg); + qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); + qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); + + /* Command DMA registers. */ + qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); + + /* Queues. */ + iter_reg = fw->req0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->resp0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->req1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Transmit DMA registers. */ + iter_reg = fw->xmt0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); + qla24xx_read_window(reg, 0x7610, 16, iter_reg); + + iter_reg = fw->xmt1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); + qla24xx_read_window(reg, 0x7630, 16, iter_reg); + + iter_reg = fw->xmt2_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); + qla24xx_read_window(reg, 0x7650, 16, iter_reg); + + iter_reg = fw->xmt3_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); + qla24xx_read_window(reg, 0x7670, 16, iter_reg); + + iter_reg = fw->xmt4_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); + qla24xx_read_window(reg, 0x7690, 16, iter_reg); + + qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); + + /* Receive DMA registers. */ + iter_reg = fw->rcvt0_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); + qla24xx_read_window(reg, 0x7710, 16, iter_reg); + + iter_reg = fw->rcvt1_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); + qla24xx_read_window(reg, 0x7730, 16, iter_reg); + + /* RISC registers. */ + iter_reg = fw->risc_gp_reg; + iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); + qla24xx_read_window(reg, 0x0F70, 16, iter_reg); + + /* Local memory controller registers. */ + iter_reg = fw->lmc_reg; + iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); + qla24xx_read_window(reg, 0x3060, 16, iter_reg); + + /* Fibre Protocol Module registers. */ + iter_reg = fw->fpm_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); + qla24xx_read_window(reg, 0x40B0, 16, iter_reg); + + /* Frame Buffer registers. */ + iter_reg = fw->fb_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); + qla24xx_read_window(reg, 0x61B0, 16, iter_reg); + + rval = qla24xx_soft_reset(ha); + if (rval != QLA_SUCCESS) + goto qla24xx_fw_dump_failed_0; + + rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), + fw->ext_mem, &nxt); + if (rval != QLA_SUCCESS) + goto qla24xx_fw_dump_failed_0; + + nxt = qla2xxx_copy_queues(ha, nxt); + if (ha->eft) + memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); + +qla24xx_fw_dump_failed_0: if (rval != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "Failed to dump firmware (%x)!!!\n", rval); @@ -1346,7 +1045,6 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) int rval; uint32_t cnt; uint32_t risc_address; - uint16_t mb0, wd; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; uint32_t __iomem *dmp_reg; @@ -1378,654 +1076,241 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) fw = &ha->fw_dump->isp.isp25; qla2xxx_prep_dump(ha, ha->fw_dump); - rval = QLA_SUCCESS; fw->host_status = htonl(RD_REG_DWORD(®->host_status)); /* Pause RISC. */ - if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | - HCCRX_CLR_HOST_INT); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - for (cnt = 30000; - (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && - rval == QLA_SUCCESS; cnt--) { - if (cnt) - udelay(100); - else - rval = QLA_FUNCTION_TIMEOUT; - } - } - - if (rval == QLA_SUCCESS) { - /* Host interface registers. */ - dmp_reg = (uint32_t __iomem *)(reg + 0); - for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) - fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Disable interrupts. */ - WRT_REG_DWORD(®->ictrl, 0); - RD_REG_DWORD(®->ictrl); - - /* Shadow registers. */ - WRT_REG_DWORD(®->iobase_addr, 0x0F70); - RD_REG_DWORD(®->iobase_addr); - WRT_REG_DWORD(®->iobase_select, 0xB0000000); - fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0100000); - fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0200000); - fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0300000); - fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0400000); - fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0500000); - fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0600000); - fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0700000); - fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0800000); - fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0900000); - fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - WRT_REG_DWORD(®->iobase_select, 0xB0A00000); - fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); - - /* RISC I/O register. */ - WRT_REG_DWORD(®->iobase_addr, 0x0010); - RD_REG_DWORD(®->iobase_addr); - fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); - - /* Mailbox registers. */ - mbx_reg = ®->mailbox0; - for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) - fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); - - /* Transfer sequence registers. */ - iter_reg = fw->xseq_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0xBF00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBF70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xseq_0_reg; - WRT_REG_DWORD(®->iobase_addr, 0xBFC0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBFD0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBFE0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xBFF0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) - fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Receive sequence registers. */ - iter_reg = fw->rseq_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0xFF00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFF70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->rseq_0_reg; - WRT_REG_DWORD(®->iobase_addr, 0xFFC0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFD0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFE0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) - fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xFFF0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) - fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Auxiliary sequence registers. */ - iter_reg = fw->aseq_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0xB000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB050); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB060); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB070); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->aseq_0_reg; - WRT_REG_DWORD(®->iobase_addr, 0xB0C0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB0D0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB0E0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->aseq_1_reg) / 4; cnt++) - fw->aseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0xB0F0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->aseq_2_reg) / 4; cnt++) - fw->aseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Command DMA registers. */ - WRT_REG_DWORD(®->iobase_addr, 0x7100); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) - fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Queues. */ - iter_reg = fw->req0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7200); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->resp0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7300); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->req1_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7400); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 8; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - dmp_reg = ®->iobase_q; - for (cnt = 0; cnt < 7; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Transmit DMA registers. */ - iter_reg = fw->xmt0_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7600); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7610); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt1_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7620); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7630); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt2_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7640); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7650); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt3_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7660); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7670); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->xmt4_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7680); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7690); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x76A0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) - fw->xmt_data_dma_reg[cnt] = - htonl(RD_REG_DWORD(dmp_reg++)); - - /* Receive DMA registers. */ - iter_reg = fw->rcvt0_data_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7700); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7710); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - iter_reg = fw->rcvt1_data_dma_reg; - WRT_REG_DWORD(®->iobase_addr, 0x7720); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x7730); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* RISC registers. */ - iter_reg = fw->risc_gp_reg; - WRT_REG_DWORD(®->iobase_addr, 0x0F00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F10); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F20); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F30); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F40); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F50); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F60); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x0F70); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Local memory controller registers. */ - iter_reg = fw->lmc_reg; - WRT_REG_DWORD(®->iobase_addr, 0x3000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3050); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3060); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x3070); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Fibre Protocol Module registers. */ - iter_reg = fw->fpm_hdw_reg; - WRT_REG_DWORD(®->iobase_addr, 0x4000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4050); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4060); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4070); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4080); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x4090); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x40A0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x40B0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Frame Buffer registers. */ - iter_reg = fw->fb_hdw_reg; - WRT_REG_DWORD(®->iobase_addr, 0x6000); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6010); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6020); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6030); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6040); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6100); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6130); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6150); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6170); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6190); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x61B0); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - WRT_REG_DWORD(®->iobase_addr, 0x6F00); - dmp_reg = ®->iobase_window; - for (cnt = 0; cnt < 16; cnt++) - *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); - - /* Reset RISC. */ - WRT_REG_DWORD(®->ctrl_status, - CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - for (cnt = 0; cnt < 30000; cnt++) { - if ((RD_REG_DWORD(®->ctrl_status) & - CSRX_DMA_ACTIVE) == 0) - break; - - udelay(10); - } - - WRT_REG_DWORD(®->ctrl_status, - CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); - - udelay(100); - /* Wait for firmware to complete NVRAM accesses. */ - mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 10000 ; cnt && mb0; cnt--) { - udelay(5); - mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); - barrier(); - } - - /* Wait for soft-reset to complete. */ - for (cnt = 0; cnt < 30000; cnt++) { - if ((RD_REG_DWORD(®->ctrl_status) & - CSRX_ISP_SOFT_RESET) == 0) - break; - - udelay(10); - } - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - } - - for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && - rval == QLA_SUCCESS; cnt--) { - if (cnt) - udelay(100); - else - rval = QLA_FUNCTION_TIMEOUT; - } - - if (rval == QLA_SUCCESS) - rval = qla2xxx_dump_memory(ha, fw->code_ram, - sizeof(fw->code_ram), fw->ext_mem, &nxt); - - if (rval == QLA_SUCCESS) { - nxt = qla2xxx_copy_queues(ha, nxt); - if (ha->eft) - memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); - } - + rval = qla24xx_pause_risc(reg); + if (rval != QLA_SUCCESS) + goto qla25xx_fw_dump_failed_0; + + /* Host interface registers. */ + dmp_reg = ®->flash_addr; + for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) + fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Disable interrupts. */ + WRT_REG_DWORD(®->ictrl, 0); + RD_REG_DWORD(®->ictrl); + + /* Shadow registers. */ + WRT_REG_DWORD(®->iobase_addr, 0x0F70); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_select, 0xB0000000); + fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0100000); + fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0200000); + fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0300000); + fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0400000); + fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0500000); + fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0600000); + fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0700000); + fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0800000); + fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0900000); + fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0A00000); + fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + /* RISC I/O register. */ + WRT_REG_DWORD(®->iobase_addr, 0x0010); + fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); + + /* Mailbox registers. */ + mbx_reg = ®->mailbox0; + for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) + fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); + + /* Transfer sequence registers. */ + iter_reg = fw->xseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); + qla24xx_read_window(reg, 0xBF70, 16, iter_reg); + + iter_reg = fw->xseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); + qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); + + qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); + + /* Receive sequence registers. */ + iter_reg = fw->rseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); + qla24xx_read_window(reg, 0xFF70, 16, iter_reg); + + iter_reg = fw->rseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); + qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); + + qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); + qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); + + /* Auxiliary sequence registers. */ + iter_reg = fw->aseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); + qla24xx_read_window(reg, 0xB070, 16, iter_reg); + + iter_reg = fw->aseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); + qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); + + qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); + qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); + + /* Command DMA registers. */ + qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); + + /* Queues. */ + iter_reg = fw->req0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->resp0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->req1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Transmit DMA registers. */ + iter_reg = fw->xmt0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); + qla24xx_read_window(reg, 0x7610, 16, iter_reg); + + iter_reg = fw->xmt1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); + qla24xx_read_window(reg, 0x7630, 16, iter_reg); + + iter_reg = fw->xmt2_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); + qla24xx_read_window(reg, 0x7650, 16, iter_reg); + + iter_reg = fw->xmt3_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); + qla24xx_read_window(reg, 0x7670, 16, iter_reg); + + iter_reg = fw->xmt4_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); + qla24xx_read_window(reg, 0x7690, 16, iter_reg); + + qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); + + /* Receive DMA registers. */ + iter_reg = fw->rcvt0_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); + qla24xx_read_window(reg, 0x7710, 16, iter_reg); + + iter_reg = fw->rcvt1_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); + qla24xx_read_window(reg, 0x7730, 16, iter_reg); + + /* RISC registers. */ + iter_reg = fw->risc_gp_reg; + iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); + qla24xx_read_window(reg, 0x0F70, 16, iter_reg); + + /* Local memory controller registers. */ + iter_reg = fw->lmc_reg; + iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); + qla24xx_read_window(reg, 0x3070, 16, iter_reg); + + /* Fibre Protocol Module registers. */ + iter_reg = fw->fpm_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); + qla24xx_read_window(reg, 0x40B0, 16, iter_reg); + + /* Frame Buffer registers. */ + iter_reg = fw->fb_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); + qla24xx_read_window(reg, 0x6F00, 16, iter_reg); + + rval = qla24xx_soft_reset(ha); + if (rval != QLA_SUCCESS) + goto qla25xx_fw_dump_failed_0; + + rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), + fw->ext_mem, &nxt); + if (rval != QLA_SUCCESS) + goto qla25xx_fw_dump_failed_0; + + nxt = qla2xxx_copy_queues(ha, nxt); + if (ha->eft) + memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); + +qla25xx_fw_dump_failed_0: if (rval != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "Failed to dump firmware (%x)!!!\n", rval); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c196486..4af0856 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -316,7 +316,9 @@ struct device_reg_2xxx { } u; uint16_t fpm_diag_config; - uint16_t unused_5[0x6]; /* Gap */ + uint16_t unused_5[0x4]; /* Gap */ + uint16_t risc_hw; + uint16_t unused_5_1; /* Gap */ uint16_t pcr; /* Processor Control Register. */ uint16_t unused_6[0x5]; /* Gap */ uint16_t mctr; /* Memory Configuration and Timing. */ -- cgit v1.1 From 338c9161e406591afbc1a6635a68d3b6d5362e00 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:33 -0700 Subject: [SCSI] qla2xxx: Add flash burst-read/write support. Newer ISPs support a mechanism to read and write flash-memory via the firmware LOAD/DUMP memory mailbox command routines. When supported, utilizing these mechanisms significantly reduces overall access times. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_gbl.h | 5 + drivers/scsi/qla2xxx/qla_mbx.c | 48 +++++++++ drivers/scsi/qla2xxx/qla_os.c | 2 +- drivers/scsi/qla2xxx/qla_sup.c | 221 +++++++++++++++++++++++++++++++---------- 4 files changed, 220 insertions(+), 56 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index aa1e411..e8122e8 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -134,6 +134,9 @@ extern int qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); extern int +qla2x00_dump_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); + +extern int qla2x00_execute_fw(scsi_qla_host_t *, uint32_t); extern void @@ -302,6 +305,8 @@ extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, uint32_t, uint32_t); extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, uint32_t, uint32_t); +extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, + uint32_t, uint32_t); extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d3746ec..e4f4b1f 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -2980,3 +2980,51 @@ qla2x00_send_change_request(scsi_qla_host_t *ha, uint16_t format, return rval; } + +int +qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, + uint32_t size) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + + DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); + + if (MSW(addr) || IS_FWI2_CAPABLE(ha)) { + mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; + mcp->mb[8] = MSW(addr); + mcp->out_mb = MBX_8|MBX_0; + } else { + mcp->mb[0] = MBC_DUMP_RISC_RAM; + mcp->out_mb = MBX_0; + } + mcp->mb[1] = LSW(addr); + mcp->mb[2] = MSW(req_dma); + mcp->mb[3] = LSW(req_dma); + mcp->mb[6] = MSW(MSD(req_dma)); + mcp->mb[7] = LSW(MSD(req_dma)); + mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; + if (IS_FWI2_CAPABLE(ha)) { + mcp->mb[4] = MSW(size); + mcp->mb[5] = LSW(size); + mcp->out_mb |= MBX_5|MBX_4; + } else { + mcp->mb[4] = LSW(size); + mcp->out_mb |= MBX_4; + } + + mcp->in_mb = MBX_0; + mcp->tov = 30; + mcp->flags = 0; + rval = qla2x00_mailbox_command(ha, mcp); + + if (rval != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, + ha->host_no, rval, mcp->mb[0])); + } else { + DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); + } + + return rval; +} diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index acca898..2a03400 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1384,7 +1384,7 @@ static struct isp_operations qla25xx_isp_ops = { .beacon_on = qla24xx_beacon_on, .beacon_off = qla24xx_beacon_off, .beacon_blink = qla24xx_beacon_blink, - .read_optrom = qla24xx_read_optrom_data, + .read_optrom = qla25xx_read_optrom_data, .write_optrom = qla24xx_write_optrom_data, .get_flash_version = qla24xx_get_flash_version, }; diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index a925a3f..ad3d1de 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -425,6 +425,9 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat) /* Flash Manipulation Routines */ /*****************************************************************************/ +#define OPTROM_BURST_SIZE 0x1000 +#define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4) + static inline uint32_t flash_conf_to_access_addr(uint32_t faddr) { @@ -544,41 +547,59 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) { int ret; - uint32_t liter; - uint32_t sec_mask, rest_addr, conf_addr, sec_end_mask; + uint32_t liter, miter; + uint32_t sec_mask, rest_addr, conf_addr; uint32_t fdata, findex ; uint8_t man_id, flash_id; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + dma_addr_t optrom_dma; + void *optrom = NULL; + uint32_t *s, *d; ret = QLA_SUCCESS; + /* Prepare burst-capable write on supported ISPs. */ + if (IS_QLA25XX(ha) && !(faddr & ~OPTROM_BURST_SIZE) && + dwords > OPTROM_BURST_DWORDS) { + optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, + &optrom_dma, GFP_KERNEL); + if (!optrom) { + qla_printk(KERN_DEBUG, ha, + "Unable to allocate memory for optrom burst write " + "(%x KB).\n", OPTROM_BURST_SIZE / 1024); + } + } + qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, ha->host_no, man_id, flash_id)); - sec_end_mask = 0; conf_addr = flash_conf_to_access_addr(0x03d8); switch (man_id) { case 0xbf: /* STT flash. */ - rest_addr = 0x1fff; - sec_mask = 0x3e000; + if (flash_id == 0x8e) { + rest_addr = 0x3fff; + sec_mask = 0x7c000; + } else { + rest_addr = 0x1fff; + sec_mask = 0x7e000; + } if (flash_id == 0x80) conf_addr = flash_conf_to_access_addr(0x0352); break; case 0x13: /* ST M25P80. */ rest_addr = 0x3fff; - sec_mask = 0x3c000; + sec_mask = 0x7c000; break; case 0x1f: // Atmel 26DF081A - rest_addr = 0x0fff; - sec_mask = 0xff000; - sec_end_mask = 0x003ff; + rest_addr = 0x3fff; + sec_mask = 0x7c000; conf_addr = flash_conf_to_access_addr(0x0320); break; default: /* Default to 64 kb sector size. */ rest_addr = 0x3fff; - sec_mask = 0x3c000; + sec_mask = 0x7c000; break; } @@ -592,56 +613,81 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, /* Some flash parts need an additional zero-write to clear bits.*/ qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); - do { /* Loop once to provide quick error exit. */ - for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { - if (man_id == 0x1f) { - findex = faddr << 2; - fdata = findex & sec_mask; - } else { - findex = faddr; - fdata = (findex & sec_mask) << 2; - } + for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { + if (man_id == 0x1f) { + findex = faddr << 2; + fdata = findex & sec_mask; + } else { + findex = faddr; + fdata = (findex & sec_mask) << 2; + } - /* Are we at the beginning of a sector? */ - if ((findex & rest_addr) == 0) { - /* - * Do sector unprotect at 4K boundry for Atmel - * part. - */ - if (man_id == 0x1f) - qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0339), - (fdata & 0xff00) | ((fdata << 16) & - 0xff0000) | ((fdata >> 16) & 0xff)); - ret = qla24xx_write_flash_dword(ha, conf_addr, - (fdata & 0xff00) |((fdata << 16) & + /* Are we at the beginning of a sector? */ + if ((findex & rest_addr) == 0) { + /* Do sector unprotect at 4K boundry for Atmel part. */ + if (man_id == 0x1f) + qla24xx_write_flash_dword(ha, + flash_conf_to_access_addr(0x0339), + (fdata & 0xff00) | ((fdata << 16) & 0xff0000) | ((fdata >> 16) & 0xff)); - if (ret != QLA_SUCCESS) { - DEBUG9(printk("%s(%ld) Unable to flash " - "sector: address=%x.\n", __func__, - ha->host_no, faddr)); - break; - } + ret = qla24xx_write_flash_dword(ha, conf_addr, + (fdata & 0xff00) |((fdata << 16) & + 0xff0000) | ((fdata >> 16) & 0xff)); + if (ret != QLA_SUCCESS) { + DEBUG9(printk("%s(%ld) Unable to flash " + "sector: address=%x.\n", __func__, + ha->host_no, faddr)); + break; } - ret = qla24xx_write_flash_dword(ha, + } + + /* Go with burst-write. */ + if (optrom && (liter + OPTROM_BURST_DWORDS) < dwords) { + /* Copy data to DMA'ble buffer. */ + for (miter = 0, s = optrom, d = dwptr; + miter < OPTROM_BURST_DWORDS; miter++, s++, d++) + *s = cpu_to_le32(*d); + + ret = qla2x00_load_ram(ha, optrom_dma, flash_data_to_access_addr(faddr), - cpu_to_le32(*dwptr)); + OPTROM_BURST_DWORDS); if (ret != QLA_SUCCESS) { - DEBUG9(printk("%s(%ld) Unable to program flash " - "address=%x data=%x.\n", __func__, - ha->host_no, faddr, *dwptr)); - break; + qla_printk(KERN_WARNING, ha, + "Unable to burst-write optrom segment " + "(%x/%x/%llx).\n", ret, + flash_data_to_access_addr(faddr), + optrom_dma); + qla_printk(KERN_WARNING, ha, + "Reverting to slow-write.\n"); + + dma_free_coherent(&ha->pdev->dev, + OPTROM_BURST_SIZE, optrom, optrom_dma); + optrom = NULL; + } else { + liter += OPTROM_BURST_DWORDS - 1; + faddr += OPTROM_BURST_DWORDS - 1; + dwptr += OPTROM_BURST_DWORDS - 1; + continue; } + } - /* Do sector protect at 4K boundry for Atmel part. */ - if (man_id == 0x1f && - ((faddr & sec_end_mask) == 0x3ff)) - qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0336), - (fdata & 0xff00) | ((fdata << 16) & - 0xff0000) | ((fdata >> 16) & 0xff)); + ret = qla24xx_write_flash_dword(ha, + flash_data_to_access_addr(faddr), cpu_to_le32(*dwptr)); + if (ret != QLA_SUCCESS) { + DEBUG9(printk("%s(%ld) Unable to program flash " + "address=%x data=%x.\n", __func__, + ha->host_no, faddr, *dwptr)); + break; } - } while (0); + + /* Do sector protect at 4K boundry for Atmel part. */ + if (man_id == 0x1f && + ((faddr & rest_addr) == rest_addr)) + qla24xx_write_flash_dword(ha, + flash_conf_to_access_addr(0x0336), + (fdata & 0xff00) | ((fdata << 16) & + 0xff0000) | ((fdata >> 16) & 0xff)); + } /* Enable flash write-protection. */ qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); @@ -651,6 +697,10 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + if (optrom) + dma_free_coherent(&ha->pdev->dev, + OPTROM_BURST_SIZE, optrom, optrom_dma); + return ret; } @@ -1728,7 +1778,6 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, { /* Suspend HBA. */ scsi_block_requests(ha->host); - ha->isp_ops->disable_intrs(ha); set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); /* Go with read. */ @@ -1736,7 +1785,6 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, /* Resume HBA. */ clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); - ha->isp_ops->enable_intrs(ha); scsi_unblock_requests(ha->host); return buf; @@ -1750,7 +1798,6 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, /* Suspend HBA. */ scsi_block_requests(ha->host); - ha->isp_ops->disable_intrs(ha); set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); /* Go with write. */ @@ -1767,6 +1814,70 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, return rval; } +uint8_t * +qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, + uint32_t offset, uint32_t length) +{ + int rval; + dma_addr_t optrom_dma; + void *optrom; + uint8_t *pbuf; + uint32_t faddr, left, burst; + + if (offset & ~OPTROM_BURST_SIZE) + goto slow_read; + if (length < OPTROM_BURST_SIZE) + goto slow_read; + + optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, + &optrom_dma, GFP_KERNEL); + if (!optrom) { + qla_printk(KERN_DEBUG, ha, + "Unable to allocate memory for optrom burst read " + "(%x KB).\n", OPTROM_BURST_SIZE / 1024); + + goto slow_read; + } + + pbuf = buf; + faddr = offset >> 2; + left = length >> 2; + burst = OPTROM_BURST_DWORDS; + while (left != 0) { + if (burst > left) + burst = left; + + rval = qla2x00_dump_ram(ha, optrom_dma, + flash_data_to_access_addr(faddr), burst); + if (rval) { + qla_printk(KERN_WARNING, ha, + "Unable to burst-read optrom segment " + "(%x/%x/%llx).\n", rval, + flash_data_to_access_addr(faddr), optrom_dma); + qla_printk(KERN_WARNING, ha, + "Reverting to slow-read.\n"); + + dma_free_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, + optrom, optrom_dma); + goto slow_read; + } + + memcpy(pbuf, optrom, burst * 4); + + left -= burst; + faddr += burst; + pbuf += burst * 4; + } + + dma_free_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, optrom, + optrom_dma); + + return buf; + +slow_read: + return qla24xx_read_optrom_data(ha, buf, offset, length); +} + /** * qla2x00_get_fcode_version() - Determine an FCODE image's version. * @ha: HA context -- cgit v1.1 From b7cc176c9eb3aa6989ac099efd8bdd6d0eaa784a Mon Sep 17 00:00:00 2001 From: Joe Carnuccio Date: Thu, 20 Sep 2007 14:07:35 -0700 Subject: [SCSI] qla2xxx: Allow region-based flash-part accesses. Additional cleanups and Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 108 +++++++++++++++++++++++++++++++++------- drivers/scsi/qla2xxx/qla_def.h | 2 + drivers/scsi/qla2xxx/qla_fw.h | 2 + drivers/scsi/qla2xxx/qla_sup.c | 4 +- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 0f2a9f5..8e7e00c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -175,10 +175,10 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, if (ha->optrom_state != QLA_SREADING) return 0; - if (off > ha->optrom_size) + if (off > ha->optrom_region_size) return 0; - if (off + count > ha->optrom_size) - count = ha->optrom_size - off; + if (off + count > ha->optrom_region_size) + count = ha->optrom_region_size - off; memcpy(buf, &ha->optrom_buffer[off], count); @@ -195,10 +195,10 @@ qla2x00_sysfs_write_optrom(struct kobject *kobj, if (ha->optrom_state != QLA_SWRITING) return -EINVAL; - if (off > ha->optrom_size) + if (off > ha->optrom_region_size) return -ERANGE; - if (off + count > ha->optrom_size) - count = ha->optrom_size - off; + if (off + count > ha->optrom_region_size) + count = ha->optrom_region_size - off; memcpy(&ha->optrom_buffer[off], buf, count); @@ -222,12 +222,16 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); - int val; + uint32_t start = 0; + uint32_t size = ha->optrom_size; + int val, valid; if (off) return 0; - if (sscanf(buf, "%d", &val) != 1) + if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) + return -EINVAL; + if (start > ha->optrom_size) return -EINVAL; switch (val) { @@ -237,6 +241,11 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, break; ha->optrom_state = QLA_SWAITING; + + DEBUG2(qla_printk(KERN_INFO, ha, + "Freeing flash region allocation -- 0x%x bytes.\n", + ha->optrom_region_size)); + vfree(ha->optrom_buffer); ha->optrom_buffer = NULL; break; @@ -244,44 +253,107 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, if (ha->optrom_state != QLA_SWAITING) break; + if (start & 0xfff) { + qla_printk(KERN_WARNING, ha, + "Invalid start region 0x%x/0x%x.\n", start, size); + return -EINVAL; + } + + ha->optrom_region_start = start; + ha->optrom_region_size = start + size > ha->optrom_size ? + ha->optrom_size - start : size; + ha->optrom_state = QLA_SREADING; - ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); + ha->optrom_buffer = vmalloc(ha->optrom_region_size); if (ha->optrom_buffer == NULL) { qla_printk(KERN_WARNING, ha, "Unable to allocate memory for optrom retrieval " - "(%x).\n", ha->optrom_size); + "(%x).\n", ha->optrom_region_size); ha->optrom_state = QLA_SWAITING; return count; } - memset(ha->optrom_buffer, 0, ha->optrom_size); - ha->isp_ops->read_optrom(ha, ha->optrom_buffer, 0, - ha->optrom_size); + DEBUG2(qla_printk(KERN_INFO, ha, + "Reading flash region -- 0x%x/0x%x.\n", + ha->optrom_region_start, ha->optrom_region_size)); + + memset(ha->optrom_buffer, 0, ha->optrom_region_size); + ha->isp_ops->read_optrom(ha, ha->optrom_buffer, + ha->optrom_region_start, ha->optrom_region_size); break; case 2: if (ha->optrom_state != QLA_SWAITING) break; + /* + * We need to be more restrictive on which FLASH regions are + * allowed to be updated via user-space. Regions accessible + * via this method include: + * + * ISP21xx/ISP22xx/ISP23xx type boards: + * + * 0x000000 -> 0x020000 -- Boot code. + * + * ISP2322/ISP24xx type boards: + * + * 0x000000 -> 0x07ffff -- Boot code. + * 0x080000 -> 0x0fffff -- Firmware. + * + * ISP25xx type boards: + * + * 0x000000 -> 0x07ffff -- Boot code. + * 0x080000 -> 0x0fffff -- Firmware. + * 0x120000 -> 0x12ffff -- VPD and HBA parameters. + */ + valid = 0; + if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) + valid = 1; + else if (start == (FA_BOOT_CODE_ADDR*4) || + start == (FA_RISC_CODE_ADDR*4)) + valid = 1; + else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4)) + valid = 1; + if (!valid) { + qla_printk(KERN_WARNING, ha, + "Invalid start region 0x%x/0x%x.\n", start, size); + return -EINVAL; + } + + ha->optrom_region_start = start; + ha->optrom_region_size = start + size > ha->optrom_size ? + ha->optrom_size - start : size; + ha->optrom_state = QLA_SWRITING; - ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); + ha->optrom_buffer = vmalloc(ha->optrom_region_size); if (ha->optrom_buffer == NULL) { qla_printk(KERN_WARNING, ha, "Unable to allocate memory for optrom update " - "(%x).\n", ha->optrom_size); + "(%x).\n", ha->optrom_region_size); ha->optrom_state = QLA_SWAITING; return count; } - memset(ha->optrom_buffer, 0, ha->optrom_size); + + DEBUG2(qla_printk(KERN_INFO, ha, + "Staging flash region write -- 0x%x/0x%x.\n", + ha->optrom_region_start, ha->optrom_region_size)); + + memset(ha->optrom_buffer, 0, ha->optrom_region_size); break; case 3: if (ha->optrom_state != QLA_SWRITING) break; - ha->isp_ops->write_optrom(ha, ha->optrom_buffer, 0, - ha->optrom_size); + DEBUG2(qla_printk(KERN_INFO, ha, + "Writing flash region -- 0x%x/0x%x.\n", + ha->optrom_region_start, ha->optrom_region_size)); + + ha->isp_ops->write_optrom(ha, ha->optrom_buffer, + ha->optrom_region_start, ha->optrom_region_size); break; + default: + count = -EINVAL; } return count; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 4af0856..e1e3428 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2478,6 +2478,8 @@ typedef struct scsi_qla_host { #define QLA_SWAITING 0 #define QLA_SREADING 1 #define QLA_SWRITING 2 + uint32_t optrom_region_start; + uint32_t optrom_region_size; /* PCI expansion ROM image information. */ #define ROM_CODE_TYPE_BIOS 0 diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 99fe496..d5344d7 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -779,6 +779,8 @@ struct device_reg_24xx { #define FA_NVRAM_VPD_SIZE 0x200 #define FA_NVRAM_VPD0_ADDR 0x00 #define FA_NVRAM_VPD1_ADDR 0x100 + +#define FA_BOOT_CODE_ADDR 0x00000 /* * RISC code begins at offset 512KB * within flash. Consisting of two diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index ad3d1de..40b059f 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -559,7 +559,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, ret = QLA_SUCCESS; /* Prepare burst-capable write on supported ISPs. */ - if (IS_QLA25XX(ha) && !(faddr & ~OPTROM_BURST_SIZE) && + if (IS_QLA25XX(ha) && !(faddr & 0xfff) && dwords > OPTROM_BURST_DWORDS) { optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, &optrom_dma, GFP_KERNEL); @@ -1824,7 +1824,7 @@ qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, uint8_t *pbuf; uint32_t faddr, left, burst; - if (offset & ~OPTROM_BURST_SIZE) + if (offset & 0xfff) goto slow_read; if (length < OPTROM_BURST_SIZE) goto slow_read; -- cgit v1.1 From 14e660e677ddd3574247495aae4ef63eb8899072 Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 20 Sep 2007 14:07:36 -0700 Subject: [SCSI] qla2xxx: Add PCI error recovery support. Additional cleanups and Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_isr.c | 28 +++++++++- drivers/scsi/qla2xxx/qla_os.c | 114 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index e1e3428..75ab898 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index eecae99..dcfb24b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -34,6 +34,7 @@ qla2100_intr_handler(int irq, void *dev_id) int status; unsigned long flags; unsigned long iter; + uint16_t hccr; uint16_t mb[4]; ha = (scsi_qla_host_t *) dev_id; @@ -48,7 +49,23 @@ qla2100_intr_handler(int irq, void *dev_id) spin_lock_irqsave(&ha->hardware_lock, flags); for (iter = 50; iter--; ) { - if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) + hccr = RD_REG_WORD(®->hccr); + if (hccr & HCCR_RISC_PAUSE) { + if (pci_channel_offline(ha->pdev)) + break; + + /* + * Issue a "HARD" reset in order for the RISC interrupt + * bit to be cleared. Schedule a big hammmer to get + * out of the RISC PAUSED state. + */ + WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); + RD_REG_WORD(®->hccr); + + ha->isp_ops->fw_dump(ha, 1); + set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + break; + } else if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) break; if (RD_REG_WORD(®->semaphore) & BIT_0) { @@ -127,6 +144,9 @@ qla2300_intr_handler(int irq, void *dev_id) for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->u.isp2300.host_status); if (stat & HSR_RISC_PAUSED) { + if (pci_channel_offline(ha->pdev)) + break; + hccr = RD_REG_WORD(®->hccr); if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8)) qla_printk(KERN_INFO, ha, "Parity error -- " @@ -1499,6 +1519,9 @@ qla24xx_intr_handler(int irq, void *dev_id) for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { + if (pci_channel_offline(ha->pdev)) + break; + hccr = RD_REG_DWORD(®->hccr); qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " @@ -1633,6 +1656,9 @@ qla24xx_msix_default(int irq, void *dev_id) for (iter = 50; iter--; ) { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { + if (pci_channel_offline(ha->pdev)) + break; + hccr = RD_REG_DWORD(®->hccr); qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2a03400..a8ab2d3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -385,6 +385,11 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) srb_t *sp; int rval; + if (unlikely(pci_channel_offline(ha->pdev))) { + cmd->result = DID_REQUEUE << 16; + goto qc_fail_command; + } + rval = fc_remote_port_chkready(rport); if (rval) { cmd->result = rval; @@ -447,6 +452,11 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) int rval; scsi_qla_host_t *pha = to_qla_parent(ha); + if (unlikely(pci_channel_offline(ha->pdev))) { + cmd->result = DID_REQUEUE << 16; + goto qc24_fail_command; + } + rval = fc_remote_port_chkready(rport); if (rval) { cmd->result = rval; @@ -1571,6 +1581,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (pci_enable_device(pdev)) goto probe_out; + if (pci_find_aer_capability(pdev)) + if (pci_enable_pcie_error_reporting(pdev)) + goto probe_out; + sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || @@ -2814,6 +2828,105 @@ qla2x00_release_firmware(void) up(&qla_fw_lock); } +static pci_ers_result_t +qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) +{ + switch (state) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; + case pci_channel_io_frozen: + pci_disable_device(pdev); + return PCI_ERS_RESULT_NEED_RESET; + case pci_channel_io_perm_failure: + qla2x00_remove_one(pdev); + return PCI_ERS_RESULT_DISCONNECT; + } + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t +qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) +{ + int risc_paused = 0; + uint32_t stat; + unsigned long flags; + scsi_qla_host_t *ha = pci_get_drvdata(pdev); + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; + + spin_lock_irqsave(&ha->hardware_lock, flags); + if (IS_QLA2100(ha) || IS_QLA2200(ha)){ + stat = RD_REG_DWORD(®->hccr); + if (stat & HCCR_RISC_PAUSE) + risc_paused = 1; + } else if (IS_QLA23XX(ha)) { + stat = RD_REG_DWORD(®->u.isp2300.host_status); + if (stat & HSR_RISC_PAUSED) + risc_paused = 1; + } else if (IS_FWI2_CAPABLE(ha)) { + stat = RD_REG_DWORD(®24->host_status); + if (stat & HSRX_RISC_PAUSED) + risc_paused = 1; + } + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + if (risc_paused) { + qla_printk(KERN_INFO, ha, "RISC paused -- mmio_enabled, " + "Dumping firmware!\n"); + ha->isp_ops->fw_dump(ha, 0); + + return PCI_ERS_RESULT_NEED_RESET; + } else + return PCI_ERS_RESULT_RECOVERED; +} + +static pci_ers_result_t +qla2xxx_pci_slot_reset(struct pci_dev *pdev) +{ + pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; + scsi_qla_host_t *ha = pci_get_drvdata(pdev); + + if (pci_enable_device(pdev)) { + qla_printk(KERN_WARNING, ha, + "Can't re-enable PCI device after reset.\n"); + + return ret; + } + pci_set_master(pdev); + + if (ha->isp_ops->pci_config(ha)) + return ret; + + set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); + if (qla2x00_abort_isp(ha)== QLA_SUCCESS) + ret = PCI_ERS_RESULT_RECOVERED; + clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); + + return ret; +} + +static void +qla2xxx_pci_resume(struct pci_dev *pdev) +{ + scsi_qla_host_t *ha = pci_get_drvdata(pdev); + int ret; + + ret = qla2x00_wait_for_hba_online(ha); + if (ret != QLA_SUCCESS) { + qla_printk(KERN_ERR, ha, + "the device failed to resume I/O " + "from slot/link_reset"); + } + pci_cleanup_aer_uncorrect_error_status(pdev); +} + +static struct pci_error_handlers qla2xxx_err_handler = { + .error_detected = qla2xxx_pci_error_detected, + .mmio_enabled = qla2xxx_pci_mmio_enabled, + .slot_reset = qla2xxx_pci_slot_reset, + .resume = qla2xxx_pci_resume, +}; + static struct pci_device_id qla2xxx_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) }, @@ -2839,6 +2952,7 @@ static struct pci_driver qla2xxx_pci_driver = { .id_table = qla2xxx_pci_tbl, .probe = qla2x00_probe_one, .remove = __devexit_p(qla2x00_remove_one), + .err_handler = &qla2xxx_err_handler, }; /** -- cgit v1.1 From 05236a050f8e3a20962bad98ad8ceb94bbdb748c Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:37 -0700 Subject: [SCSI] qla2xxx: Query additional RISC information during a pause. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_fw.h | 4 +++- drivers/scsi/qla2xxx/qla_isr.c | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index d5344d7..db63386 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -942,7 +942,9 @@ struct device_reg_24xx { uint16_t mailbox31; uint32_t iobase_window; - uint32_t unused_4[8]; /* Gap. */ + uint32_t unused_4; /* Gap. */ + uint32_t iobase_c8; + uint32_t unused_4_1[6]; /* Gap. */ uint32_t iobase_q; uint32_t unused_5[2]; /* Gap. */ uint32_t iobase_select; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index dcfb24b..f61c2fe 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -6,6 +6,7 @@ */ #include "qla_def.h" +#include #include static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); @@ -1484,6 +1485,52 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) WRT_REG_DWORD(®->rsp_q_out, ha->rsp_ring_index); } +static void +qla2xxx_check_risc_status(scsi_qla_host_t *ha) +{ + int rval; + uint32_t cnt; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + + if (!IS_QLA25XX(ha)) + return; + + rval = QLA_SUCCESS; + WRT_REG_DWORD(®->iobase_addr, 0x7C00); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_window, 0x0001); + for (cnt = 10000; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && + rval == QLA_SUCCESS; cnt--) { + if (cnt) { + WRT_REG_DWORD(®->iobase_window, 0x0001); + udelay(10); + } else + rval = QLA_FUNCTION_TIMEOUT; + } + if (rval == QLA_SUCCESS) + goto next_test; + + WRT_REG_DWORD(®->iobase_window, 0x0003); + for (cnt = 100; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && + rval == QLA_SUCCESS; cnt--) { + if (cnt) { + WRT_REG_DWORD(®->iobase_window, 0x0003); + udelay(10); + } else + rval = QLA_FUNCTION_TIMEOUT; + } + if (rval != QLA_SUCCESS) + goto done; + +next_test: + if (RD_REG_DWORD(®->iobase_c8) & BIT_3) + qla_printk(KERN_INFO, ha, "Additional code -- 0x55AA.\n"); + +done: + WRT_REG_DWORD(®->iobase_window, 0x0000); + RD_REG_DWORD(®->iobase_window); +} + /** * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. * @irq: @@ -1526,6 +1573,9 @@ qla24xx_intr_handler(int irq, void *dev_id) qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " "Dumping firmware!\n", hccr); + + qla2xxx_check_risc_status(ha); + ha->isp_ops->fw_dump(ha, 1); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; @@ -1663,6 +1713,9 @@ qla24xx_msix_default(int irq, void *dev_id) qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " "Dumping firmware!\n", hccr); + + qla2xxx_check_risc_status(ha); + ha->isp_ops->fw_dump(ha, 1); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; -- cgit v1.1 From c3b058afaea11273835f59694f8645a89915be9c Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:38 -0700 Subject: [SCSI] qla2xxx: Correct staging of RISC while attempting to pause. There's no need to reset the RISC prior to pausing. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index b52fa89..2defe0c 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -172,19 +172,16 @@ qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) int rval = QLA_SUCCESS; uint32_t cnt; - if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | - HCCRX_CLR_HOST_INT); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - for (cnt = 30000; - (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && - rval == QLA_SUCCESS; cnt--) { - if (cnt) - udelay(100); - else - rval = QLA_FUNCTION_TIMEOUT; - } + if (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) + return rval; + + WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); + for (cnt = 30000; (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && + rval == QLA_SUCCESS; cnt--) { + if (cnt) + udelay(100); + else + rval = QLA_FUNCTION_TIMEOUT; } return rval; -- cgit v1.1 From b58369273956775c3e8b7bbbe152593d52762099 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:39 -0700 Subject: [SCSI] qla2xxx: Query additional RISC registers during ISP25XX firmware dump. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.c | 18 ++++++++++++++++++ drivers/scsi/qla2xxx/qla_dbg.h | 2 ++ drivers/scsi/qla2xxx/qla_fw.h | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 2defe0c..ca7f70d 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1072,6 +1072,7 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) } fw = &ha->fw_dump->isp.isp25; qla2xxx_prep_dump(ha, ha->fw_dump); + ha->fw_dump->version = __constant_htonl(2); fw->host_status = htonl(RD_REG_DWORD(®->host_status)); @@ -1080,6 +1081,23 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (rval != QLA_SUCCESS) goto qla25xx_fw_dump_failed_0; + /* Host/Risc registers. */ + iter_reg = fw->host_risc_reg; + iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); + qla24xx_read_window(reg, 0x7010, 16, iter_reg); + + /* PCIe registers. */ + WRT_REG_DWORD(®->iobase_addr, 0x7C00); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_window, 0x01); + dmp_reg = ®->iobase_c4; + fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); + fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); + fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); + fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); + WRT_REG_DWORD(®->iobase_window, 0x00); + RD_REG_DWORD(®->iobase_window); + /* Host interface registers. */ dmp_reg = ®->flash_addr; for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index cca4b0d..a50ecf0 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -215,6 +215,8 @@ struct qla24xx_fw_dump { struct qla25xx_fw_dump { uint32_t host_status; + uint32_t host_risc_reg[32]; + uint32_t pcie_regs[4]; uint32_t host_reg[32]; uint32_t shadow_reg[11]; uint32_t risc_io_reg; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index db63386..25364b1 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -942,7 +942,7 @@ struct device_reg_24xx { uint16_t mailbox31; uint32_t iobase_window; - uint32_t unused_4; /* Gap. */ + uint32_t iobase_c4; uint32_t iobase_c8; uint32_t unused_4_1[6]; /* Gap. */ uint32_t iobase_q; -- cgit v1.1 From 63a8651f2548c6bb5132c0b4e7dad4f57a9274db Mon Sep 17 00:00:00 2001 From: Ravi Anand Date: Thu, 20 Sep 2007 14:07:40 -0700 Subject: [SCSI] qla2xxx: Correct infinite-login-retry issue. Where the DPC logic would get jammed into continuously reloging-into a port. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a8ab2d3..4314f94 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2437,7 +2437,6 @@ qla2x00_do_dpc(void *data) if (atomic_read(&fcport->state) != FCS_ONLINE && fcport->login_retry) { - fcport->login_retry--; if (fcport->flags & FCF_FABRIC_DEVICE) { if (fcport->flags & FCF_TAPE_PRESENT) @@ -2453,6 +2452,7 @@ qla2x00_do_dpc(void *data) qla2x00_local_device_login( ha, fcport); + fcport->login_retry--; if (status == QLA_SUCCESS) { fcport->old_loop_id = fcport->loop_id; @@ -2470,6 +2470,8 @@ qla2x00_do_dpc(void *data) } else { fcport->login_retry = 0; } + if (fcport->login_retry == 0) + fcport->loop_id = FC_NO_LOOP_ID; } if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) break; -- cgit v1.1 From 8a85e17152e8fb5f04a4791416a4642b260b95cb Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:41 -0700 Subject: [SCSI] qla2xxx: Set correct attribute count during FDMI RPA. Also remove legacy '/proc' name during OS_DEVICE_NAME registration. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_gs.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 75ab898..511e3cd 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1705,7 +1705,7 @@ struct ct_fdmi_hba_attributes { /* * Port attribute types. */ -#define FDMI_PORT_ATTR_COUNT 5 +#define FDMI_PORT_ATTR_COUNT 6 #define FDMI_PORT_FC4_TYPES 1 #define FDMI_PORT_SUPPORT_SPEED 2 #define FDMI_PORT_CURRENT_SPEED 3 diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index a7e2358..eb0784c 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1517,7 +1517,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) /* Attributes */ ct_req->req.rpa.attrs.count = - __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); + __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1); entries = ct_req->req.rpa.port_name; /* FC4 types. */ @@ -1600,7 +1600,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) /* OS device name. */ eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); - sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no); + strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME); alen = strlen(eiter->a.os_dev_name); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); @@ -1611,6 +1611,8 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) /* Hostname. */ if (strlen(fc_host_system_hostname(ha->host))) { + ct_req->req.rpa.attrs.count = + __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), -- cgit v1.1 From c45bcc8e771fa152ed540b8cb2ac8022280173bd Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:42 -0700 Subject: [SCSI] qla2xxx: Use the correct pointer-address during NVRAM writes. Original code, incorrectly passed the address-of a pointer rather than the pointer value itself. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 8e7e00c..445d583 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -146,7 +146,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, /* Write NVRAM. */ spin_lock_irqsave(&ha->hardware_lock, flags); ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); - ha->isp_ops->read_nvram(ha, (uint8_t *)&ha->nvram, ha->nvram_base, + ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, count); spin_unlock_irqrestore(&ha->hardware_lock, flags); -- cgit v1.1 From 4d0ea24769c81581b8fd25fd7deff281b1b97dee Mon Sep 17 00:00:00 2001 From: Seokmann Ju Date: Thu, 20 Sep 2007 14:07:43 -0700 Subject: [SCSI] qla2xxx: Retrieve max-NPIV support capabilities from FW. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 2 +- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 4 ++-- drivers/scsi/qla2xxx/qla_init.c | 16 +++++++++++----- drivers/scsi/qla2xxx/qla_mbx.c | 11 +++++++---- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 445d583..c90dc59 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1250,6 +1250,6 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha) fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); fc_host_supported_classes(ha->host) = FC_COS_CLASS3; - fc_host_max_npiv_vports(ha->host) = MAX_NUM_VPORT_FABRIC; + fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 511e3cd..1396f4d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2534,7 +2534,7 @@ typedef struct scsi_qla_host { #define VP_ERR_FAB_NORESOURCES 3 #define VP_ERR_FAB_LOGOUT 4 #define VP_ERR_ADAP_NORESOURCES 5 - int max_npiv_vports; /* 63 or 125 per topoloty */ + uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ int cur_vport_count; } scsi_qla_host_t; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e8122e8..09cb2a9 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -215,8 +215,8 @@ extern int qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *); extern int -qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *, - uint16_t *); +qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, + uint16_t *, uint16_t *, uint16_t *); extern int qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 083997c..e449f48 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -849,7 +849,8 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) return; /* Retrieve IOCB counts available to the firmware. */ - rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt); + rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt, + &ha->max_npiv_vports); if (rval) return; /* No point in continuing if current settings are sufficient. */ @@ -916,9 +917,15 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) &ha->fw_attributes, &ha->fw_memory_size); qla2x00_resize_request_q(ha); ha->flags.npiv_supported = 0; - if (IS_QLA24XX(ha) && - (ha->fw_attributes & BIT_2)) + if ((IS_QLA24XX(ha) || IS_QLA25XX(ha)) && + (ha->fw_attributes & BIT_2)) { ha->flags.npiv_supported = 1; + if ((!ha->max_npiv_vports) || + ((ha->max_npiv_vports + 1) % + MAX_MULTI_ID_FABRIC)) + ha->max_npiv_vports = + MAX_NUM_VPORT_FABRIC; + } if (ql2xallocfwdump) qla2x00_alloc_fw_dump(ha); @@ -1155,8 +1162,7 @@ qla2x00_init_rings(scsi_qla_host_t *ha) DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); - mid_init_cb->count = MAX_NUM_VPORT_FABRIC; - ha->max_npiv_vports = MAX_NUM_VPORT_FABRIC; + mid_init_cb->count = ha->max_npiv_vports; rval = qla2x00_init_firmware(ha, ha->init_cb_size); if (rval) { diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index e4f4b1f..ec48871 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1919,7 +1919,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, */ int qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, - uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt) + uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, + uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports) { int rval; mbx_cmd_t mc; @@ -1929,7 +1930,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; mcp->out_mb = MBX_0; - mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1940,9 +1941,9 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, ha->host_no, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " - "mb7=%x mb10=%x.\n", __func__, ha->host_no, + "mb7=%x mb10=%x mb11=%x.\n", __func__, ha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], - mcp->mb[10])); + mcp->mb[10], mcp->mb[11])); if (cur_xchg_cnt) *cur_xchg_cnt = mcp->mb[3]; @@ -1952,6 +1953,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, *cur_iocb_cnt = mcp->mb[7]; if (orig_iocb_cnt) *orig_iocb_cnt = mcp->mb[10]; + if (max_npiv_vports) + *max_npiv_vports = mcp->mb[11]; } return (rval); -- cgit v1.1 From e745759a0f662992327537be4ec01d9a43542fc4 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:44 -0700 Subject: [SCSI] qla2xxx: Remove unused member (list) from srb_t structure. This change reduces by as much as 16% the memory footprint for each allocated sbr_t structure requested from the mempool. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 1396f4d..b928e31 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -185,8 +185,6 @@ * SCSI Request Block */ typedef struct srb { - struct list_head list; - struct scsi_qla_host *ha; /* HA the SP is queued on */ struct fc_port *fcport; -- cgit v1.1 From f363b9434a464e72927b468ba33cb548f482669f Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:45 -0700 Subject: [SCSI] qla2xxx: Use shost_priv(). Drop usage of legacy to_qla_host() macro. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 88 ++++++++++++++++++++--------------------- drivers/scsi/qla2xxx/qla_dbg.c | 2 +- drivers/scsi/qla2xxx/qla_def.h | 2 - drivers/scsi/qla2xxx/qla_mid.c | 6 +-- drivers/scsi/qla2xxx/qla_os.c | 20 +++++----- 5 files changed, 58 insertions(+), 60 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index c90dc59..05fa779 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -18,7 +18,7 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); char *rbuf = (char *)ha->fw_dump; @@ -39,7 +39,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); int reading; @@ -89,7 +89,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); int size = ha->nvram_size; char *nvram_cache = ha->nvram; @@ -112,7 +112,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); unsigned long flags; uint16_t cnt; @@ -170,7 +170,7 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); if (ha->optrom_state != QLA_SREADING) @@ -190,7 +190,7 @@ qla2x00_sysfs_write_optrom(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); if (ha->optrom_state != QLA_SWRITING) @@ -220,7 +220,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); uint32_t start = 0; uint32_t size = ha->optrom_size; @@ -372,7 +372,7 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); int size = ha->vpd_size; char *vpd_cache = ha->vpd; @@ -395,7 +395,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); unsigned long flags; @@ -426,7 +426,7 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, + struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); uint16_t iter, addr, offset; int rval; @@ -531,7 +531,7 @@ qla2x00_drvr_version_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_fw_version_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); char fw_str[30]; return snprintf(buf, PAGE_SIZE, "%s\n", @@ -541,7 +541,7 @@ qla2x00_fw_version_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_serial_num_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); uint32_t sn; sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; @@ -552,14 +552,14 @@ qla2x00_serial_num_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_isp_name_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); } static ssize_t qla2x00_isp_id_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", ha->product_id[0], ha->product_id[1], ha->product_id[2], ha->product_id[3]); @@ -568,14 +568,14 @@ qla2x00_isp_id_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_model_name_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); } static ssize_t qla2x00_model_desc_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_desc ? ha->model_desc: ""); } @@ -583,7 +583,7 @@ qla2x00_model_desc_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_pci_info_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); char pci_info[30]; return snprintf(buf, PAGE_SIZE, "%s\n", @@ -593,7 +593,7 @@ qla2x00_pci_info_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_state_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int len = 0; if (atomic_read(&ha->loop_state) == LOOP_DOWN || @@ -631,7 +631,7 @@ qla2x00_state_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_zio_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int len = 0; switch (ha->zio_mode) { @@ -648,7 +648,7 @@ qla2x00_zio_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int val = 0; uint16_t zio_mode; @@ -674,7 +674,7 @@ qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) static ssize_t qla2x00_zio_timer_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); } @@ -683,7 +683,7 @@ static ssize_t qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, size_t count) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int val = 0; uint16_t zio_timer; @@ -701,7 +701,7 @@ qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, static ssize_t qla2x00_beacon_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int len = 0; if (ha->beacon_blink_led) @@ -715,7 +715,7 @@ static ssize_t qla2x00_beacon_store(struct class_device *cdev, const char *buf, size_t count) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); int val = 0; int rval; @@ -745,7 +745,7 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf, static ssize_t qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], ha->bios_revision[0]); @@ -754,7 +754,7 @@ qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], ha->efi_revision[0]); @@ -763,7 +763,7 @@ qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], ha->fcode_revision[0]); @@ -772,7 +772,7 @@ qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) static ssize_t qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf) { - scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], @@ -829,7 +829,7 @@ struct class_device_attribute *qla2x00_host_attrs[] = { static void qla2x00_get_host_port_id(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); fc_host_port_id(shost) = ha->d_id.b.domain << 16 | ha->d_id.b.area << 8 | ha->d_id.b.al_pa; @@ -838,7 +838,7 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) static void qla2x00_get_host_speed(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); uint32_t speed = 0; switch (ha->link_data_rate) { @@ -858,7 +858,7 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) static void qla2x00_get_host_port_type(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); uint32_t port_type = FC_PORTTYPE_UNKNOWN; switch (ha->current_topology) { @@ -882,7 +882,7 @@ static void qla2x00_get_starget_node_name(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(starget->dev.parent); - scsi_qla_host_t *ha = to_qla_host(host); + scsi_qla_host_t *ha = shost_priv(host); fc_port_t *fcport; u64 node_name = 0; @@ -900,7 +900,7 @@ static void qla2x00_get_starget_port_name(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(starget->dev.parent); - scsi_qla_host_t *ha = to_qla_host(host); + scsi_qla_host_t *ha = shost_priv(host); fc_port_t *fcport; u64 port_name = 0; @@ -918,7 +918,7 @@ static void qla2x00_get_starget_port_id(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(starget->dev.parent); - scsi_qla_host_t *ha = to_qla_host(host); + scsi_qla_host_t *ha = shost_priv(host); fc_port_t *fcport; uint32_t port_id = ~0U; @@ -937,7 +937,7 @@ static void qla2x00_get_rport_loss_tmo(struct fc_rport *rport) { struct Scsi_Host *host = rport_to_shost(rport); - scsi_qla_host_t *ha = to_qla_host(host); + scsi_qla_host_t *ha = shost_priv(host); rport->dev_loss_tmo = ha->port_down_retry_count + 5; } @@ -946,7 +946,7 @@ static void qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { struct Scsi_Host *host = rport_to_shost(rport); - scsi_qla_host_t *ha = to_qla_host(host); + scsi_qla_host_t *ha = shost_priv(host); if (timeout) ha->port_down_retry_count = timeout; @@ -959,7 +959,7 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) static int qla2x00_issue_lip(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); return 0; @@ -968,7 +968,7 @@ qla2x00_issue_lip(struct Scsi_Host *shost) static struct fc_host_statistics * qla2x00_get_fc_host_stats(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); int rval; uint16_t mb_stat[1]; link_stat_t stat_buf; @@ -1006,7 +1006,7 @@ done: static void qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); } @@ -1014,7 +1014,7 @@ qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) static void qla2x00_set_host_system_hostname(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); } @@ -1022,7 +1022,7 @@ qla2x00_set_host_system_hostname(struct Scsi_Host *shost) static void qla2x00_get_host_fabric_name(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); u64 node_name; if (ha->device_flags & SWITCH_FOUND) @@ -1036,7 +1036,7 @@ qla2x00_get_host_fabric_name(struct Scsi_Host *shost) static void qla2x00_get_host_port_state(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = to_qla_host(shost); + scsi_qla_host_t *ha = shost_priv(shost); if (!ha->flags.online) fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; @@ -1050,7 +1050,7 @@ static int qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) { int ret = 0; - scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; + scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha; ret = qla24xx_vport_create_req_sanity_check(fc_vport); @@ -1119,7 +1119,7 @@ vport_create_failed_2: int qla24xx_vport_delete(struct fc_vport *fc_vport) { - scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; + scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha = fc_vport->dd_data; qla24xx_disable_vp(vha); diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index ca7f70d..eaa04da 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1402,7 +1402,7 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) struct scsi_qla_host *ha; srb_t *sp; - ha = (struct scsi_qla_host *)cmd->device->host->hostdata; + ha = shost_priv(cmd->device->host); sp = (srb_t *) cmd->SCp.ptr; printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b928e31..1900fbf 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2545,8 +2545,6 @@ typedef struct scsi_qla_host { test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ atomic_read(&ha->loop_state) == LOOP_DOWN) -#define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata) - #define qla_printk(level, ha, format, arg...) \ dev_printk(level , &((ha)->pdev->dev) , format , ## arg) diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 54dc415..1a2cdcd 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -363,7 +363,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha) int qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) { - scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; + scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha; uint8_t port_name[WWN_SIZE]; @@ -397,7 +397,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *fc_vport) { - scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; + scsi_qla_host_t *ha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha; struct Scsi_Host *host; @@ -409,7 +409,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) return(NULL); } - vha = (scsi_qla_host_t *)host->hostdata; + vha = shost_priv(host); /* clone the parent hba */ memcpy(vha, ha, sizeof (scsi_qla_host_t)); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4314f94..a6bb8d0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -379,7 +379,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, static int qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; @@ -445,7 +445,7 @@ qc_fail_command: static int qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); srb_t *sp; @@ -663,7 +663,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) static int qla2xxx_eh_abort(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); srb_t *sp; int ret, i; unsigned int id, lun; @@ -803,7 +803,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) static int qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; unsigned int id, lun; @@ -932,7 +932,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) static int qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); scsi_qla_host_t *pha = to_qla_parent(ha); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; @@ -992,7 +992,7 @@ eh_bus_reset_done: static int qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) { - scsi_qla_host_t *ha = to_qla_host(cmd->device->host); + scsi_qla_host_t *ha = shost_priv(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; int ret = FAILED; unsigned int id, lun; @@ -1142,7 +1142,7 @@ qla2xxx_slave_alloc(struct scsi_device *sdev) static int qla2xxx_slave_configure(struct scsi_device *sdev) { - scsi_qla_host_t *ha = to_qla_host(sdev->host); + scsi_qla_host_t *ha = shost_priv(sdev->host); struct fc_rport *rport = starget_to_rport(sdev->sdev_target); if (sdev->tagged_supported) @@ -1543,7 +1543,7 @@ iospace_error_exit: static void qla2xxx_scan_start(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; + scsi_qla_host_t *ha = shost_priv(shost); set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); @@ -1553,7 +1553,7 @@ qla2xxx_scan_start(struct Scsi_Host *shost) static int qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) { - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; + scsi_qla_host_t *ha = shost_priv(shost); if (!ha->host) return 1; @@ -1600,7 +1600,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* Clear our data area */ - ha = (scsi_qla_host_t *)host->hostdata; + ha = shost_priv(host); memset(ha, 0, sizeof(scsi_qla_host_t)); ha->pdev = pdev; -- cgit v1.1 From 700ca0e7016008f65f75c2629e309fc03347c856 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:46 -0700 Subject: [SCSI] qla2xxx: Cleanup several 'sparse' warnings. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_iocb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 3a5e78c..7f6a89b 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -308,7 +308,7 @@ qla2x00_start_scsi(srb_t *sp) handle++; if (handle == MAX_OUTSTANDING_COMMANDS) handle = 1; - if (ha->outstanding_cmds[handle] == 0) + if (!ha->outstanding_cmds[handle]) break; } if (index == MAX_OUTSTANDING_COMMANDS) @@ -711,7 +711,7 @@ qla24xx_start_scsi(srb_t *sp) handle++; if (handle == MAX_OUTSTANDING_COMMANDS) handle = 1; - if (ha->outstanding_cmds[handle] == 0) + if (!ha->outstanding_cmds[handle]) break; } if (index == MAX_OUTSTANDING_COMMANDS) -- cgit v1.1 From 26ff776d1dd9147eb658c55f1df42c2c232036b5 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:47 -0700 Subject: [SCSI] qla2xxx: Sparse cleanups in qla_mid.c Make several needlessly global functions static: - qla2x00_mark_vp_devices_dead() - qla24xx_configure_vp() Remove unused function qla24xx_modify_vport(). Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_mid.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 1a2cdcd..821ee74 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -104,7 +104,7 @@ qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name) * * Context: */ -void +static void qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) { fc_port_t *fcport; @@ -179,37 +179,7 @@ enable_failed: return 1; } -/** - * qla24xx_modify_vport() - Modifies the virtual fabric port's configuration - * @ha: HA context - * @vp: pointer to buffer of virtual port parameters. - * @ret_code: return error code: - * - * Returns the virtual port id, or MAX_VSAN_ID, if couldn't create. - */ -uint32_t -qla24xx_modify_vhba(scsi_qla_host_t *ha, vport_params_t *vp, uint32_t *vp_id) -{ - scsi_qla_host_t *vha; - - vha = qla24xx_find_vhost_by_name(ha, vp->port_name); - if (!vha) { - *vp_id = MAX_NUM_VPORT_LOOP; - return VP_RET_CODE_WWPN; - } - - if (qla24xx_enable_vp(vha)) { - scsi_host_put(vha->host); - qla2x00_mem_free(vha); - *vp_id = MAX_NUM_VPORT_LOOP; - return VP_RET_CODE_RESOURCES; - } - - *vp_id = vha->vp_idx; - return VP_RET_CODE_OK; -} - -void +static void qla24xx_configure_vp(scsi_qla_host_t *vha) { struct fc_vport *fc_vport; -- cgit v1.1 From 8b3253d10f1c7910c96d4acad4ef490f30799b21 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:48 -0700 Subject: [SCSI] qla2xxx: Clear options-flags while staging firmware-execution. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_mbx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index ec48871..c53ec67 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -391,7 +391,8 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) mcp->mb[1] = MSW(risc_addr); mcp->mb[2] = LSW(risc_addr); mcp->mb[3] = 0; - mcp->out_mb |= MBX_3|MBX_2|MBX_1; + mcp->mb[4] = 0; + mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; mcp->in_mb |= MBX_1; } else { mcp->mb[1] = LSW(risc_addr); -- cgit v1.1 From 87f27015b8d9f19d6de295e2316cff7960c9950b Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:49 -0700 Subject: [SCSI] qla2xxx: Rework MSI-X handlers. Since MSI-X vectors do not require a clearing "handshake" from the system perspective, and the registered handler will not be called more than once for one occurrence of receipt of a vector, there is no requirement to flush the risc register write clearing the interrupt condition in the risc. Also, since the msi-x registered handlers are optimised for a particular vector, it is preferable to handle the one vector received per invocation of the handler. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_isr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f61c2fe..c4768c4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1679,7 +1679,6 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) qla24xx_process_response_queue(ha); WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); - RD_REG_DWORD_RELAXED(®->hccr); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -1693,7 +1692,6 @@ qla24xx_msix_default(int irq, void *dev_id) struct device_reg_24xx __iomem *reg; int status; unsigned long flags; - unsigned long iter; uint32_t stat; uint32_t hccr; uint16_t mb[4]; @@ -1703,7 +1701,7 @@ qla24xx_msix_default(int irq, void *dev_id) status = 0; spin_lock_irqsave(&ha->hardware_lock, flags); - for (iter = 50; iter--; ) { + do { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { if (pci_channel_offline(ha->pdev)) @@ -1748,8 +1746,7 @@ qla24xx_msix_default(int irq, void *dev_id) break; } WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); - RD_REG_DWORD_RELAXED(®->hccr); - } + } while (0); spin_unlock_irqrestore(&ha->hardware_lock, flags); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && -- cgit v1.1 From 39bd962269f0f10ba890aea4769693f8f9a3cb47 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:34 -0700 Subject: [SCSI] qla2xxx: Limit iIDMA speed adjustments. Do not adjust the iIDMA speed on ports which have a faster link-speed than the HBA itself. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e449f48..191dafd 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2132,15 +2132,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) if (!IS_IIDMA_CAPABLE(ha)) return; - if (fcport->fp_speed == PORT_SPEED_UNKNOWN) { - DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " - "unsupported FM port operating speed.\n", - ha->host_no, fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7])); + if (fcport->fp_speed == PORT_SPEED_UNKNOWN || + fcport->fp_speed > ha->link_data_rate) return; - } rval = qla2x00_set_idma_speed(ha, fcport->loop_id, fcport->fp_speed, mb); -- cgit v1.1 From 095862ab982a56fb4ea237420bb8fcf1393ca287 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Thu, 20 Sep 2007 14:07:50 -0700 Subject: [SCSI] qla2xxx: Update version number to 8.02.00-k4. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 18095b9..2d551a3 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.02.00-k3" +#define QLA2XXX_VERSION "8.02.00-k4" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 -- cgit v1.1 From 24430458bb924e371ff894e26bfa9f73707f53fb Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 27 Jul 2007 13:00:48 -0400 Subject: [SCSI] arcmsr: Fix hardware wait loops Remove _interruptible, since receiving a signal while waiting on a hardware condition will simply cause the driver to busy-wait. Using msleep_interruptible() is rarely the right thing to do, when waiting on a hardware condition to change. Also, replace msleep with ssleep while doing this, where appropriate. [jejb: fix up merge conflict] Signed-off-by: Jeff Garzik Acked-by: Nick Cheng Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr_hba.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 50e1310..7832a10 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2092,8 +2092,10 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) if (atomic_read(&acb->ccboutstandingcount) != 0) { /* talk to iop 331 outstanding command aborted */ arcmsr_abort_allcmd(acb); + /* wait for 3 sec for all command aborted*/ ssleep(3); + /* disable all outbound interrupt */ intmask_org = arcmsr_disable_outbound_ints(acb); /* clear all outbound posted Q */ -- cgit v1.1 From 488a5c8a9a3b67ae117784cd0d73bef53a73d57d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 27 Jul 2007 13:01:15 -0400 Subject: [SCSI] arcmsr: irq handler fixes, cleanups, micro-opts * Remove IRQF_DISABLED, it is clearly wrong for this driver. * Remove wasteful spin_lock_irqsave() in interrupt handler. The lighter-weight spin_lock() is all that's needed. * Annotate with FIXME where arcmsr_interrupt() is called without any spinlock being acquired. * Eliminate pointless cast from void pointer in arcmsr_do_interrupt() [jejb: conflict resolution] Signed-off-by: Jeff Garzik Acked-by: Nick Cheng Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr_hba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 7832a10..f4d2d52 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -422,7 +422,7 @@ static int arcmsr_probe(struct pci_dev *pdev, goto out_release_regions; error = request_irq(pdev->irq, arcmsr_do_interrupt, - IRQF_SHARED, "arcmsr", acb); + IRQF_SHARED, "arcmsr", acb); if (error) goto out_free_ccb_pool; -- cgit v1.1 From 4390e60163979621f59e3a25a260289986eacb85 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 10 Aug 2007 14:50:44 -0700 Subject: [SCSI] osst: Use mutex instead of semaphore The OnStream SCSI Tape driver uses a semaphore as mutex. Use the mutex API instead of the (binary) semaphore. Signed-off-by: Matthias Kaehlcke Reviewed-by: Satyam Sharma Signed-off-by: Andrew Morton Acked-by: Willem Riede Signed-off-by: James Bottomley --- drivers/scsi/osst.c | 16 ++++++++-------- drivers/scsi/osst.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 1197395..331b789 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -3298,7 +3298,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co char * name = tape_name(STp); - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return (-ERESTARTSYS); /* @@ -3600,7 +3600,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name out: if (SRpnt != NULL) osst_release_request(SRpnt); - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -3619,7 +3619,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo char * name = tape_name(STp); - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return (-ERESTARTSYS); /* @@ -3785,7 +3785,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo out: if (SRpnt != NULL) osst_release_request(SRpnt); - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -4852,7 +4852,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, char * name = tape_name(STp); void __user * p = (void __user *)arg; - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; #if DEBUG @@ -5163,14 +5163,14 @@ static int osst_ioctl(struct inode * inode,struct file * file, } if (SRpnt) osst_release_request(SRpnt); - up(&STp->lock); + mutex_unlock(&STp->lock); return scsi_ioctl(STp->device, cmd_in, p); out: if (SRpnt) osst_release_request(SRpnt); - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -5865,7 +5865,7 @@ static int osst_probe(struct device *dev) tpnt->modes[2].defined = 1; tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; - init_MUTEX(&tpnt->lock); + mutex_init(&tpnt->lock); osst_nr_dev++; write_unlock(&os_scsi_tapes_lock); diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 2cc7b5a..5aa2274 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h @@ -4,6 +4,7 @@ #include #include +#include /* FIXME - rename and use the following two types or delete them! * and the types really should go to st.h anyway... @@ -532,7 +533,7 @@ struct osst_tape { struct scsi_driver *driver; unsigned capacity; struct scsi_device *device; - struct semaphore lock; /* for serialization */ + struct mutex lock; /* for serialization */ struct completion wait; /* for SCSI commands */ struct osst_buffer * buffer; -- cgit v1.1 From 7c07d613d22680f1caf2bd9ee49838ec7730b9da Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 5 Aug 2007 13:36:11 -0500 Subject: [SCSI] sg: use idr to replace static arrays sg uses a scheme to reallocate a single contiguous array of all its pointers for lookup and management. This didn't matter too much when sg could only attach 256 nodes, but now the maximum has been bumped up to 32k we're starting to push the limits of the maximum allocatable contiguous memory. The solution to this is to eliminate the static array and do everything via idr, which this patch does. Acked-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/sg.c | 253 ++++++++++++++++++++++++------------------------------ 1 file changed, 112 insertions(+), 141 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index fdc6618..f6f5fc7 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -43,6 +43,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #include #include #include +#include #include #include #include @@ -99,12 +100,11 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ; #define SG_SECTOR_SZ 512 #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) -#define SG_DEV_ARR_LUMP 32 /* amount to over allocate sg_dev_arr by */ - static int sg_add(struct class_device *, struct class_interface *); static void sg_remove(struct class_device *, struct class_interface *); -static DEFINE_RWLOCK(sg_dev_arr_lock); /* Also used to lock +static DEFINE_IDR(sg_index_idr); +static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock file descriptor list for device */ static struct class_interface sg_interface = { @@ -162,6 +162,7 @@ typedef struct sg_device { /* holds the state of each scsi generic device */ struct scsi_device *device; wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ int sg_tablesize; /* adapter's max scatter-gather table size */ + u32 index; /* device index number */ Sg_fd *headfp; /* first open fd belonging to this device */ volatile char detached; /* 0->attached, 1->detached pending removal */ volatile char exclude; /* opened for exclusive access */ @@ -209,10 +210,6 @@ static Sg_device *sg_get_dev(int dev); static int sg_last_dev(void); #endif -static Sg_device **sg_dev_arr = NULL; -static int sg_dev_max; -static int sg_nr_dev; - #define SZ_SG_HEADER sizeof(struct sg_header) #define SZ_SG_IO_HDR sizeof(sg_io_hdr_t) #define SZ_SG_IOVEC sizeof(sg_iovec_t) @@ -1331,40 +1328,35 @@ static struct class *sg_sysfs_class; static int sg_sysfs_valid = 0; -static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) +static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) { struct request_queue *q = scsidp->request_queue; Sg_device *sdp; unsigned long iflags; - void *old_sg_dev_arr = NULL; - int k, error; + int error; + u32 k; sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); if (!sdp) { printk(KERN_WARNING "kmalloc Sg_device failure\n"); - return -ENOMEM; + return ERR_PTR(-ENOMEM); + } + error = -ENOMEM; + if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) { + printk(KERN_WARNING "idr expansion Sg_device failure\n"); + goto out; } - write_lock_irqsave(&sg_dev_arr_lock, iflags); - if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */ - Sg_device **tmp_da; - int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - - tmp_da = kzalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); - if (unlikely(!tmp_da)) - goto expand_failed; + write_lock_irqsave(&sg_index_lock, iflags); + error = idr_get_new(&sg_index_idr, sdp, &k); + write_unlock_irqrestore(&sg_index_lock, iflags); - write_lock_irqsave(&sg_dev_arr_lock, iflags); - memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); - old_sg_dev_arr = sg_dev_arr; - sg_dev_arr = tmp_da; - sg_dev_max = tmp_dev_max; + if (error) { + printk(KERN_WARNING "idr allocation Sg_device failure: %d\n", + error); + goto out; } - for (k = 0; k < sg_dev_max; k++) - if (!sg_dev_arr[k]) - break; if (unlikely(k >= SG_MAX_DEVS)) goto overflow; @@ -1375,25 +1367,17 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) sdp->device = scsidp; init_waitqueue_head(&sdp->o_excl_wait); sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); + sdp->index = k; - sg_nr_dev++; - sg_dev_arr[k] = sdp; - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - error = k; - + error = 0; out: - if (error < 0) + if (error) { kfree(sdp); - kfree(old_sg_dev_arr); - return error; - - expand_failed: - printk(KERN_WARNING "sg_alloc: device array cannot be resized\n"); - error = -ENOMEM; - goto out; + return ERR_PTR(error); + } + return sdp; overflow: - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); sdev_printk(KERN_WARNING, scsidp, "Unable to attach sg device type=%d, minor " "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); @@ -1408,7 +1392,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) struct gendisk *disk; Sg_device *sdp = NULL; struct cdev * cdev = NULL; - int error, k; + int error; unsigned long iflags; disk = alloc_disk(1); @@ -1427,15 +1411,15 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) cdev->owner = THIS_MODULE; cdev->ops = &sg_fops; - error = sg_alloc(disk, scsidp); - if (error < 0) { + sdp = sg_alloc(disk, scsidp); + if (IS_ERR(sdp)) { printk(KERN_WARNING "sg_alloc failed\n"); + error = PTR_ERR(sdp); goto out; } - k = error; - sdp = sg_dev_arr[k]; - error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); + class_set_devdata(cl_dev, sdp); + error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1); if (error) goto cdev_add_err; @@ -1444,8 +1428,8 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) struct class_device * sg_class_member; sg_class_member = class_device_create(sg_sysfs_class, NULL, - MKDEV(SCSI_GENERIC_MAJOR, k), - cl_dev->dev, "%s", + MKDEV(SCSI_GENERIC_MAJOR, sdp->index), + cl_dev->dev, "%s", disk->disk_name); if (IS_ERR(sg_class_member)) printk(KERN_WARNING "sg_add: " @@ -1455,21 +1439,21 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) &sg_class_member->kobj, "generic"); if (error) printk(KERN_ERR "sg_add: unable to make symlink " - "'generic' back to sg%d\n", k); + "'generic' back to sg%d\n", sdp->index); } else - printk(KERN_WARNING "sg_add: sg_sys INvalid\n"); + printk(KERN_WARNING "sg_add: sg_sys Invalid\n"); sdev_printk(KERN_NOTICE, scsidp, - "Attached scsi generic sg%d type %d\n", k,scsidp->type); + "Attached scsi generic sg%d type %d\n", sdp->index, + scsidp->type); return 0; cdev_add_err: - write_lock_irqsave(&sg_dev_arr_lock, iflags); - kfree(sg_dev_arr[k]); - sg_dev_arr[k] = NULL; - sg_nr_dev--; - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); + write_lock_irqsave(&sg_index_lock, iflags); + idr_remove(&sg_index_idr, sdp->index); + write_unlock_irqrestore(&sg_index_lock, iflags); + kfree(sdp); out: put_disk(disk); @@ -1482,64 +1466,56 @@ static void sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) { struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); - Sg_device *sdp = NULL; + Sg_device *sdp = class_get_devdata(cl_dev); unsigned long iflags; Sg_fd *sfp; Sg_fd *tsfp; Sg_request *srp; Sg_request *tsrp; - int k, delay; + int delay; - if (NULL == sg_dev_arr) + if (!sdp) return; + delay = 0; - write_lock_irqsave(&sg_dev_arr_lock, iflags); - for (k = 0; k < sg_dev_max; k++) { - sdp = sg_dev_arr[k]; - if ((NULL == sdp) || (sdp->device != scsidp)) - continue; /* dirty but lowers nesting */ - if (sdp->headfp) { - sdp->detached = 1; - for (sfp = sdp->headfp; sfp; sfp = tsfp) { - tsfp = sfp->nextfp; - for (srp = sfp->headrp; srp; srp = tsrp) { - tsrp = srp->nextrp; - if (sfp->closed || (0 == sg_srp_done(srp, sfp))) - sg_finish_rem_req(srp); - } - if (sfp->closed) { - scsi_device_put(sdp->device); - __sg_remove_sfp(sdp, sfp); - } else { - delay = 1; - wake_up_interruptible(&sfp->read_wait); - kill_fasync(&sfp->async_qp, SIGPOLL, - POLL_HUP); - } + write_lock_irqsave(&sg_index_lock, iflags); + if (sdp->headfp) { + sdp->detached = 1; + for (sfp = sdp->headfp; sfp; sfp = tsfp) { + tsfp = sfp->nextfp; + for (srp = sfp->headrp; srp; srp = tsrp) { + tsrp = srp->nextrp; + if (sfp->closed || (0 == sg_srp_done(srp, sfp))) + sg_finish_rem_req(srp); } - SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); - if (NULL == sdp->headfp) { - sg_dev_arr[k] = NULL; + if (sfp->closed) { + scsi_device_put(sdp->device); + __sg_remove_sfp(sdp, sfp); + } else { + delay = 1; + wake_up_interruptible(&sfp->read_wait); + kill_fasync(&sfp->async_qp, SIGPOLL, + POLL_HUP); } - } else { /* nothing active, simple case */ - SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); - sg_dev_arr[k] = NULL; } - sg_nr_dev--; - break; - } - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); - - if (sdp) { - sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); - class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); - cdev_del(sdp->cdev); - sdp->cdev = NULL; - put_disk(sdp->disk); - sdp->disk = NULL; - if (NULL == sdp->headfp) - kfree((char *) sdp); - } + SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index)); + if (NULL == sdp->headfp) { + idr_remove(&sg_index_idr, sdp->index); + } + } else { /* nothing active, simple case */ + SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index)); + idr_remove(&sg_index_idr, sdp->index); + } + write_unlock_irqrestore(&sg_index_lock, iflags); + + sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); + class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); + cdev_del(sdp->cdev); + sdp->cdev = NULL; + put_disk(sdp->disk); + sdp->disk = NULL; + if (NULL == sdp->headfp) + kfree(sdp); if (delay) msleep(10); /* dirty detach so delay device destruction */ @@ -1609,9 +1585,7 @@ exit_sg(void) sg_sysfs_valid = 0; unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS); - kfree((char *)sg_dev_arr); - sg_dev_arr = NULL; - sg_dev_max = 0; + idr_destroy(&sg_index_idr); } static int @@ -2331,10 +2305,10 @@ sg_get_nth_sfp(Sg_device * sdp, int nth) unsigned long iflags; int k; - read_lock_irqsave(&sg_dev_arr_lock, iflags); + read_lock_irqsave(&sg_index_lock, iflags); for (k = 0, resp = sdp->headfp; resp && (k < nth); ++k, resp = resp->nextfp) ; - read_unlock_irqrestore(&sg_dev_arr_lock, iflags); + read_unlock_irqrestore(&sg_index_lock, iflags); return resp; } #endif @@ -2361,7 +2335,7 @@ sg_add_sfp(Sg_device * sdp, int dev) sfp->cmd_q = SG_DEF_COMMAND_Q; sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; sfp->parentdp = sdp; - write_lock_irqsave(&sg_dev_arr_lock, iflags); + write_lock_irqsave(&sg_index_lock, iflags); if (!sdp->headfp) sdp->headfp = sfp; else { /* add to tail of existing list */ @@ -2370,7 +2344,7 @@ sg_add_sfp(Sg_device * sdp, int dev) pfp = pfp->nextfp; pfp->nextfp = sfp; } - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); + write_unlock_irqrestore(&sg_index_lock, iflags); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); if (unlikely(sg_big_buff != def_reserved_size)) sg_big_buff = def_reserved_size; @@ -2431,22 +2405,14 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) if (0 == dirty) { unsigned long iflags; - write_lock_irqsave(&sg_dev_arr_lock, iflags); + write_lock_irqsave(&sg_index_lock, iflags); __sg_remove_sfp(sdp, sfp); if (sdp->detached && (NULL == sdp->headfp)) { - int k, maxd; - - maxd = sg_dev_max; - for (k = 0; k < maxd; ++k) { - if (sdp == sg_dev_arr[k]) - break; - } - if (k < maxd) - sg_dev_arr[k] = NULL; - kfree((char *) sdp); + idr_remove(&sg_index_idr, sdp->index); + kfree(sdp); res = 1; } - write_unlock_irqrestore(&sg_dev_arr_lock, iflags); + write_unlock_irqrestore(&sg_index_lock, iflags); } else { /* MOD_INC's to inhibit unloading sg and associated adapter driver */ /* only bump the access_count if we actually succeeded in @@ -2546,16 +2512,25 @@ sg_allow_access(unsigned char opcode, char dev_type) #ifdef CONFIG_SCSI_PROC_FS static int +sg_idr_max_id(int id, void *p, void *data) +{ + int *k = data; + + if (*k < id) + *k = id; + + return 0; +} + +static int sg_last_dev(void) { - int k; + int k = 0; unsigned long iflags; - read_lock_irqsave(&sg_dev_arr_lock, iflags); - for (k = sg_dev_max - 1; k >= 0; --k) - if (sg_dev_arr[k] && sg_dev_arr[k]->device) - break; - read_unlock_irqrestore(&sg_dev_arr_lock, iflags); + read_lock_irqsave(&sg_index_lock, iflags); + idr_for_each(&sg_index_idr, sg_idr_max_id, &k); + read_unlock_irqrestore(&sg_index_lock, iflags); return k + 1; /* origin 1 */ } #endif @@ -2563,15 +2538,13 @@ sg_last_dev(void) static Sg_device * sg_get_dev(int dev) { - Sg_device *sdp = NULL; + Sg_device *sdp; unsigned long iflags; - if (sg_dev_arr && (dev >= 0)) { - read_lock_irqsave(&sg_dev_arr_lock, iflags); - if (dev < sg_dev_max) - sdp = sg_dev_arr[dev]; - read_unlock_irqrestore(&sg_dev_arr_lock, iflags); - } + read_lock_irqsave(&sg_index_lock, iflags); + sdp = idr_find(&sg_index_idr, dev); + read_unlock_irqrestore(&sg_index_lock, iflags); + return sdp; } @@ -2805,8 +2778,6 @@ static void * dev_seq_start(struct seq_file *s, loff_t *pos) if (! it) return NULL; - if (NULL == sg_dev_arr) - return NULL; it->index = *pos; it->max = sg_last_dev(); if (it->index >= it->max) @@ -2942,8 +2913,8 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v) Sg_device *sdp; if (it && (0 == it->index)) { - seq_printf(s, "dev_max(currently)=%d max_active_device=%d " - "(origin 1)\n", sg_dev_max, (int)it->max); + seq_printf(s, "max_active_device=%d(origin 1)\n", + (int)it->max); seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); } sdp = it ? sg_get_dev(it->index) : NULL; -- cgit v1.1 From 31765d7d3da9bb575f80faecae0b931afa3532c6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 17 Aug 2007 11:02:10 -0600 Subject: [SCSI] Improve error message when offlining a device The current code prints: scsi 13:0:4:0: scsi: Device offlined - not ready after error recovery which is repetitively redundant. This patch changes that message to: scsi 6:0:6:0: Device offlined - not ready after error recovery Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index c8e351f..c05d020 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1137,9 +1137,8 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, struct scsi_cmnd *scmd, *next; list_for_each_entry_safe(scmd, next, work_q, eh_entry) { - sdev_printk(KERN_INFO, scmd->device, - "scsi: Device offlined - not" - " ready after error recovery\n"); + sdev_printk(KERN_INFO, scmd->device, "Device offlined - " + "not ready after error recovery\n"); scsi_device_set_state(scmd->device, SDEV_OFFLINE); if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) { /* -- cgit v1.1 From a57b1fccdfa65b78481f5e651833d979e545de04 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 20 Aug 2007 09:18:48 -0600 Subject: [SCSI] scsi_scan: Cope with kthread_run failing If kthread_run failed, we would fail to scan the host, and leak the allocated async_scan_data. Since using a separate thread is just an optimisation, do the scan synchronously if we fail to spawn a thread. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 20df7fe..b53c5f6 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1799,6 +1799,7 @@ static int do_scan_async(void *_data) **/ void scsi_scan_host(struct Scsi_Host *shost) { + struct task_struct *p; struct async_scan_data *data; if (strncmp(scsi_scan_type, "none", 4) == 0) @@ -1810,7 +1811,9 @@ void scsi_scan_host(struct Scsi_Host *shost) return; } - kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); + p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); + if (unlikely(IS_ERR(p))) + do_scan_async(data); } EXPORT_SYMBOL(scsi_scan_host); -- cgit v1.1 From 34f8f0d294423a7e2ef84a741890b1bfa317aa4e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:58 -0600 Subject: [SCSI] ibmmca: Stop leaking scsi_hosts on exit There was a missing call to scsi_host_put() causing us to leak a scsi host every time this module was unloaded. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/ibmmca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 4275d1b..82f116a 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -1693,6 +1693,7 @@ static int __devexit ibmmca_remove(struct device *dev) scsi_remove_host(shpnt); release_region(shpnt->io_port, shpnt->n_io_port); free_irq(shpnt->irq, dev); + scsi_host_put(shpnt); return 0; } -- cgit v1.1 From 6fdea8dbbe4fc021afb601ef5339d5c5825c5cb6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:57:01 -0600 Subject: [SCSI] ide-scsi: Close narrow race in release We were releasing the block devices before removing the host, so commands could still be coming in which would cause a panic. Just remove the host before releasing the block devices to close this race. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/ide-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3b55a6c..d81bb076 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -671,6 +671,7 @@ static void ide_scsi_remove(ide_drive_t *drive) struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); struct gendisk *g = scsi->disk; + scsi_remove_host(scsihost); ide_proc_unregister_driver(drive, scsi->driver); ide_unregister_region(g); @@ -679,7 +680,6 @@ static void ide_scsi_remove(ide_drive_t *drive) g->private_data = NULL; put_disk(g); - scsi_remove_host(scsihost); ide_scsi_put(scsi); } -- cgit v1.1 From dffe807cdbc6d2409b9bcc87a9517bb7c0d25b65 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:56 -0600 Subject: [SCSI] ncr53c8xx: Call scsi_host_put in release Since ncr53c8xx_attach() calls scsi_host_put(), make ncr53c8xx_release() call scsi_host_put() too, for symmetry. Both callers already expect it to put the host for them, so that works out nicely. While the zalon driver does 'use' the host pointer afterwards, it only compares it for equality and doesn't dereference it, so that's safe. While I'm at it, get rid of pointless checks for NULL, use shost_priv() and change ncr53c8xx_release to return void. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/ncr53c8xx.c | 11 ++++------- drivers/scsi/ncr53c8xx.h | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 030ba49..91fa66c 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -8528,18 +8528,15 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt, } -int ncr53c8xx_release(struct Scsi_Host *host) +void ncr53c8xx_release(struct Scsi_Host *host) { - struct host_data *host_data; + struct host_data *host_data = shost_priv(host); #ifdef DEBUG_NCR53C8XX printk("ncr53c8xx: release\n"); #endif - if (!host) - return 1; - host_data = (struct host_data *)host->hostdata; - if (host_data && host_data->ncb) + if (host_data->ncb) ncr_detach(host_data->ncb); - return 1; + scsi_host_put(host); } static void ncr53c8xx_set_period(struct scsi_target *starget, int period) diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index b39357d..0e008da 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h @@ -1321,7 +1321,7 @@ struct ncr_device { }; extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device); -extern int ncr53c8xx_release(struct Scsi_Host *host); +extern void ncr53c8xx_release(struct Scsi_Host *host); irqreturn_t ncr53c8xx_intr(int irq, void *dev_id); extern int ncr53c8xx_init(void); extern void ncr53c8xx_exit(void); -- cgit v1.1 From 1bd405734651c9ebd1c872a452614f9fe381c673 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:57 -0600 Subject: [SCSI] aha152x: Close narrow race in release We were releasing the IRQ before removing the host, so commands could still be coming in which would never be seen by the interrupt handler. Just remove the host before releasing the IRQ to close this race. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/aha152x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index d30a307..f08e71e 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -907,9 +907,10 @@ out_host_put: void aha152x_release(struct Scsi_Host *shpnt) { - if(!shpnt) + if (!shpnt) return; + scsi_remove_host(shpnt); if (shpnt->irq) free_irq(shpnt->irq, shpnt); @@ -923,7 +924,6 @@ void aha152x_release(struct Scsi_Host *shpnt) pnp_device_detach(HOSTDATA(shpnt)->pnpdev); #endif - scsi_remove_host(shpnt); list_del(&HOSTDATA(shpnt)->host_list); scsi_host_put(shpnt); } -- cgit v1.1 From c131993b4cbfb6d564619e609b3d0b471ec52c5d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:59 -0600 Subject: [SCSI] qlogicfas: Close narrow race in release We were releasing the IRQ before removing the host, so commands could still be coming in which would never be seen by the interrupt handler. Just remove the host before releasing the IRQ to close this race. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/qlogicfas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index 94baca8..1e874f1 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c @@ -166,6 +166,7 @@ static int qlogicfas_release(struct Scsi_Host *shost) { struct qlogicfas408_priv *priv = get_priv_by_host(shost); + scsi_remove_host(shost); if (shost->irq) { qlogicfas408_disable_ints(priv); free_irq(shost->irq, shost); @@ -174,7 +175,6 @@ static int qlogicfas_release(struct Scsi_Host *shost) free_dma(shost->dma_channel); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); - scsi_remove_host(shost); scsi_host_put(shost); return 0; -- cgit v1.1 From a60ebc52cbfafc291c6b0b89e41ecaf3685c8e2a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:54 -0600 Subject: [SCSI] simscsi: Free scsi host on error If scsi_add_host returned an error, the host would never be freed. We need to call scsi_host_put() if an error happens. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- arch/ia64/hp/sim/simscsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index e62694f..a43e1e1 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -373,8 +373,13 @@ simscsi_init(void) return -ENOMEM; error = scsi_add_host(host, NULL); - if (!error) - scsi_scan_host(host); + if (error) + goto free_host; + scsi_scan_host(host); + return 0; + + free_host: + scsi_host_put(host); return error; } -- cgit v1.1 From f01abb362f878b8e2de69c03662d8e7f3ae1d6f8 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:56:55 -0600 Subject: [SCSI] aic94xx: Free scsi host on error If an error occurred during initialisation, we would sometimes fail to call scsi_host_put() and thus end up with a leaked scsi_host. It was also possible to miss calling scsi_remove_host(). Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_init.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 63d1045..b70d6e7 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -583,7 +583,7 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); if (!asd_ha) { asd_printk("out of memory\n"); - goto Err; + goto Err_put; } asd_ha->pcidev = dev; asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; @@ -600,14 +600,12 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, shost->max_cmd_len = 16; err = scsi_add_host(shost, &dev->dev); - if (err) { - scsi_host_put(shost); + if (err) goto Err_free; - } err = asd_dev->setup(asd_ha); if (err) - goto Err_free; + goto Err_remove; err = -ENODEV; if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) @@ -618,14 +616,14 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, ; else { asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); - goto Err_free; + goto Err_remove; } pci_set_drvdata(dev, asd_ha); err = asd_map_ha(asd_ha); if (err) - goto Err_free; + goto Err_remove; err = asd_create_ha_caches(asd_ha); if (err) @@ -692,9 +690,12 @@ Err_free_cache: asd_destroy_ha_caches(asd_ha); Err_unmap: asd_unmap_ha(asd_ha); +Err_remove: + scsi_remove_host(shost); Err_free: kfree(asd_ha); - scsi_remove_host(shost); +Err_put: + scsi_host_put(shost); Err: pci_disable_device(dev); return err; -- cgit v1.1 From a50ee7a72888d072512e4434c44959743bfb1570 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 15 Aug 2007 12:57:00 -0600 Subject: [SCSI] ips: Close narrow race in release We were releasing the IRQ before removing the host, so commands could still be coming in which would never be seen by the interrupt handler. Just remove the host before releasing the IRQ to close this race. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index b17771b..36b6765 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -656,6 +656,8 @@ ips_release(struct Scsi_Host *sh) METHOD_TRACE("ips_release", 1); + scsi_remove_host(sh); + for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; if (i == IPS_MAX_ADAPTERS) { @@ -707,7 +709,6 @@ ips_release(struct Scsi_Host *sh) /* free IRQ */ free_irq(ha->irq, ha); - scsi_remove_host(sh); scsi_host_put(sh); ips_released_controllers++; -- cgit v1.1 From 8c8fdc591057956c2ecbba1371a48b8857fe6d9d Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Sat, 22 Sep 2007 21:55:19 +0200 Subject: [SCSI] ips: Update version information This patch just makes the version number in ips.c and ips.h consistent. It seems that this has been forgotten in a60768e2d43eb30a1adb8a119aeac35dc0d03ef6. It also removes code duplication, each number is now only once in the code to avoid similar errors in the future. Signed-off-by: Bernhard Walle Acked-by: Mark Salyzyn Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 4 ++-- drivers/scsi/ips.h | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 36b6765..2ed099e 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -204,8 +204,8 @@ module_param(ips, charp, 0); /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "7.12" -#define IPS_VERSION_LOW ".05 " +#define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING +#define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " " #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 24123d5..3bcbd9f 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -1172,12 +1172,13 @@ typedef struct { *************************************************************************/ #define IPS_VER_MAJOR 7 -#define IPS_VER_MAJOR_STRING "7" +#define IPS_VER_MAJOR_STRING __stringify(IPS_VER_MAJOR) #define IPS_VER_MINOR 12 -#define IPS_VER_MINOR_STRING "12" -#define IPS_VER_BUILD 02 -#define IPS_VER_BUILD_STRING "02" -#define IPS_VER_STRING "7.12.02" +#define IPS_VER_MINOR_STRING __stringify(IPS_VER_MINOR) +#define IPS_VER_BUILD 05 +#define IPS_VER_BUILD_STRING __stringify(IPS_VER_BUILD) +#define IPS_VER_STRING IPS_VER_MAJOR_STRING "." \ + IPS_VER_MINOR_STRING "." IPS_VER_BUILD_STRING #define IPS_RELEASE_ID 0x00020000 #define IPS_BUILD_IDENT 761 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." -- cgit v1.1 From 13ba9bcbfd6741e4c01ac5a505888b7b3a6d99da Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 26 Sep 2007 19:54:49 +0200 Subject: [SCSI] fix scsi_is_sdev_device() after switch to default sdev attributes Signed-off-by: Kay Sievers Signed-off-by: James Bottomley --- drivers/scsi/scsi_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 0088c4d..8e880ef 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -995,7 +995,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) int scsi_is_sdev_device(const struct device *dev) { - return dev->release == scsi_device_dev_release; + return dev->type == &scsi_dev_type; } EXPORT_SYMBOL(scsi_is_sdev_device); -- cgit v1.1 From 12a441622b753684cc73d1c6f225e9ac53e0bf77 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 18 Sep 2007 19:54:43 -0600 Subject: [SCSI] Remove ->pid field from scsi_cmnd The pid field is a duplicate of the serial_number field and has been scheduled for removal for a long time. A few drivers were still using it, so just change them to use serial_number instead. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/dc395x.c | 110 +++++++++++++++++++++++----------------------- drivers/scsi/eata.c | 44 +++++++++---------- drivers/scsi/eata_pio.c | 12 ++--- drivers/scsi/in2000.c | 30 ++++++------- drivers/scsi/ncr53c8xx.c | 7 +-- drivers/scsi/qla1280.c | 2 +- drivers/scsi/scsi.c | 6 +-- drivers/scsi/scsi_error.c | 6 --- drivers/scsi/tmscsim.c | 18 ++++---- drivers/scsi/u14-34f.c | 44 +++++++++---------- drivers/scsi/wd33c93.c | 32 +++++++------- include/scsi/scsi_cmnd.h | 11 ++--- include/scsi/scsi_host.h | 2 +- 13 files changed, 153 insertions(+), 171 deletions(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 7b8a345..1591824 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -778,7 +778,7 @@ static void srb_waiting_insert(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_add(&srb->list, &dcb->srb_waiting_list); } @@ -787,7 +787,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_add_tail(&srb->list, &dcb->srb_waiting_list); } @@ -795,7 +795,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb, static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) { dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_add_tail(&srb->list, &dcb->srb_going_list); } @@ -805,7 +805,7 @@ static void srb_going_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) struct ScsiReqBlk *i; struct ScsiReqBlk *tmp; dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) if (i == srb) { @@ -821,7 +821,7 @@ static void srb_waiting_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *i; struct ScsiReqBlk *tmp; dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) if (i == srb) { @@ -836,7 +836,7 @@ static void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb, { dprintkdbg(DBG_0, "srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_move(&srb->list, &dcb->srb_waiting_list); } @@ -846,7 +846,7 @@ static void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb, { dprintkdbg(DBG_0, "srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); list_move(&srb->list, &dcb->srb_going_list); } @@ -982,7 +982,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, int nseg; enum dma_data_direction dir = cmd->sc_data_direction; dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n", - cmd->pid, dcb->target_id, dcb->target_lun); + cmd->serial_number, dcb->target_id, dcb->target_lun); srb->dcb = dcb; srb->cmd = cmd; @@ -1086,7 +1086,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_ struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)cmd->device->host->hostdata; dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n", - cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); /* Assume BAD_TARGET; will be cleared later */ cmd->result = DID_BAD_TARGET << 16; @@ -1139,7 +1139,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_ /* process immediately */ send_srb(acb, srb); } - dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->pid); + dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->serial_number); return 0; complete: @@ -1203,7 +1203,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb, else dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) " "cmnd=0x%02x <%02i-%i>\n", - srb, srb->cmd, srb->cmd->pid, + srb, srb->cmd, srb->cmd->serial_number, srb->cmd->cmnd[0], srb->cmd->device->id, srb->cmd->device->lun); printk(" sglist=%p cnt=%i idx=%i len=%zu\n", @@ -1300,7 +1300,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd) (struct AdapterCtlBlk *)cmd->device->host->hostdata; dprintkl(KERN_INFO, "eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n", - cmd->pid, cmd->device->id, cmd->device->lun, cmd); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd); if (timer_pending(&acb->waiting_timer)) del_timer(&acb->waiting_timer); @@ -1367,7 +1367,7 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd) struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n", - cmd->pid, cmd->device->id, cmd->device->lun, cmd); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd); dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); if (!dcb) { @@ -1494,7 +1494,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, u8 s_stat, scsicommand, i, identify_message; u8 *ptr; dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */ @@ -1504,7 +1504,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, #if 1 if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) { dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n", - srb->cmd->pid, s_stat, s_stat2); + srb->cmd->serial_number, s_stat, s_stat2); /* * Try anyway? * @@ -1522,14 +1522,14 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, if (acb->active_dcb) { dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a" "command while another command (pid#%li) is active.", - srb->cmd->pid, + srb->cmd->serial_number, acb->active_dcb->active_srb ? - acb->active_dcb->active_srb->cmd->pid : 0); + acb->active_dcb->active_srb->cmd->serial_number : 0); return 1; } if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) { dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n", - srb->cmd->pid); + srb->cmd->serial_number); return 1; } /* Allow starting of SCSI commands half a second before we allow the mid-level @@ -1603,7 +1603,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, if (tag_number >= dcb->max_command) { dprintkl(KERN_WARNING, "start_scsi: (pid#%li) " "Out of tags target=<%02i-%i>)\n", - srb->cmd->pid, srb->cmd->device->id, + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); srb->state = SRB_READY; DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, @@ -1622,7 +1622,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, /*polling:*/ /* Send CDB ..command block ......... */ dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun, srb->cmd->cmnd[0], srb->tag_number); if (srb->flag & AUTO_REQSENSE) { DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE); @@ -1647,7 +1647,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, * : Let's process it first! */ dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun); srb->state = SRB_READY; free_tag(dcb, srb); srb->msg_count = 0; @@ -1842,7 +1842,7 @@ static irqreturn_t dc395x_interrupt(int irq, void *dev_id) static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { - dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->serial_number); if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) *pscsi_status = PH_BUS_FREE; /*.. initial phase */ @@ -1856,18 +1856,18 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, { u16 i; u8 *ptr; - dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->serial_number); clear_fifo(acb, "msgout_phase1"); if (!(srb->state & SRB_MSGOUT)) { srb->state |= SRB_MSGOUT; dprintkl(KERN_DEBUG, "msgout_phase1: (pid#%li) Phase unexpected\n", - srb->cmd->pid); /* So what ? */ + srb->cmd->serial_number); /* So what ? */ } if (!srb->msg_count) { dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n", - srb->cmd->pid); + srb->cmd->serial_number); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); @@ -1887,7 +1887,7 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { - dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->serial_number); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); } @@ -1898,7 +1898,7 @@ static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, struct DeviceCtlBlk *dcb; u8 *ptr; u16 i; - dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->serial_number); clear_fifo(acb, "command_phase1"); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN); @@ -2042,7 +2042,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 scsi_status = *pscsi_status; u32 d_left_counter = 0; dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); /* * KG: We need to drain the buffers before we draw any conclusions! @@ -2172,7 +2172,7 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); clear_fifo(acb, "data_out_phase1"); /* do prepare before transfer when data out phase */ data_io_transfer(acb, srb, XFERDATAOUT); @@ -2184,7 +2184,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 scsi_status = *pscsi_status; dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); /* * KG: DataIn is much more tricky than DataOut. When the device is finished @@ -2205,7 +2205,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, if (scsi_status & PARITYERROR) { dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " - "Parity Error\n", srb->cmd->pid); + "Parity Error\n", srb->cmd->serial_number); srb->status |= PARITY_ERROR; } /* @@ -2395,7 +2395,7 @@ static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); data_io_transfer(acb, srb, XFERDATAIN); } @@ -2407,7 +2407,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb, u8 bval; dprintkdbg(DBG_0, "data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun, ((io_dir & DMACMD_DIR) ? 'r' : 'w'), srb->total_xfer_length, srb->sg_index, srb->sg_count); if (srb == acb->tmp_srb) @@ -2580,7 +2580,7 @@ static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */ srb->state = SRB_COMPLETED; @@ -2594,7 +2594,7 @@ static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); + srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); srb->state = SRB_STATUS; DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP); @@ -2636,7 +2636,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb = NULL; struct ScsiReqBlk *i; dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n", - srb->cmd->pid, tag, srb); + srb->cmd->serial_number, tag, srb); if (!(dcb->tag_mask & (1 << tag))) dprintkl(KERN_DEBUG, @@ -2655,7 +2655,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, goto mingx0; dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n", - srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun); + srb->cmd->serial_number, srb->dcb->target_id, srb->dcb->target_lun); if (dcb->flag & ABORT_DEV_) { /*srb->state = SRB_ABORT_SENT; */ enable_msgout_abort(acb, srb); @@ -2865,7 +2865,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { struct DeviceCtlBlk *dcb = acb->active_dcb; - dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->serial_number); srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); if (msgin_completed(srb->msgin_buf, acb->msg_len)) { @@ -2933,7 +2933,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, */ dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " "SAVE POINTER rem=%i Ignore\n", - srb->cmd->pid, srb->total_xfer_length); + srb->cmd->serial_number, srb->total_xfer_length); break; case RESTORE_POINTERS: @@ -2943,7 +2943,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, case ABORT: dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " "<%02i-%i> ABORT msg\n", - srb->cmd->pid, dcb->target_id, + srb->cmd->serial_number, dcb->target_id, dcb->target_lun); dcb->flag |= ABORT_DEV_; enable_msgout_abort(acb, srb); @@ -2975,7 +2975,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { - dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->serial_number); clear_fifo(acb, "msgin_phase1"); DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); if (!(srb->state & SRB_MSGIN)) { @@ -3041,7 +3041,7 @@ static void disconnect(struct AdapterCtlBlk *acb) } srb = dcb->active_srb; acb->active_dcb = NULL; - dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->pid); + dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->serial_number); srb->scsi_phase = PH_BUS_FREE; /* initial phase */ clear_fifo(acb, "disconnect"); @@ -3072,13 +3072,13 @@ static void disconnect(struct AdapterCtlBlk *acb) srb->state = SRB_READY; dprintkl(KERN_DEBUG, "disconnect: (pid#%li) Unexpected\n", - srb->cmd->pid); + srb->cmd->serial_number); srb->target_status = SCSI_STAT_SEL_TIMEOUT; goto disc1; } else { /* Normal selection timeout */ dprintkdbg(DBG_KG, "disconnect: (pid#%li) " - "<%02i-%i> SelTO\n", srb->cmd->pid, + "<%02i-%i> SelTO\n", srb->cmd->serial_number, dcb->target_id, dcb->target_lun); if (srb->retry_count++ > DC395x_MAX_RETRIES || acb->scan_devices) { @@ -3090,7 +3090,7 @@ static void disconnect(struct AdapterCtlBlk *acb) srb_going_to_waiting_move(dcb, srb); dprintkdbg(DBG_KG, "disconnect: (pid#%li) Retry\n", - srb->cmd->pid); + srb->cmd->serial_number); waiting_set_timer(acb, HZ / 20); } } else if (srb->state & SRB_DISCONNECT) { @@ -3144,7 +3144,7 @@ static void reselect(struct AdapterCtlBlk *acb) if (!acb->scan_devices) { dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> " "Arb lost but Resel win rsel=%i stat=0x%04x\n", - srb->cmd->pid, dcb->target_id, + srb->cmd->serial_number, dcb->target_id, dcb->target_lun, rsel_tar_lun_id, DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); arblostflag = 1; @@ -3318,7 +3318,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, enum dma_data_direction dir = cmd->sc_data_direction; int ckc_only = 1; - dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, + dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count, @@ -3499,7 +3499,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, if (srb->total_xfer_length) dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> " "cmnd=0x%02x Missed %i bytes\n", - cmd->pid, cmd->device->id, cmd->device->lun, + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0], srb->total_xfer_length); } @@ -3509,7 +3509,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); else { dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n", - cmd->pid, cmd->result); + cmd->serial_number, cmd->result); srb_free_insert(acb, srb); } pci_unmap_srb(acb, srb); @@ -3538,7 +3538,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, p = srb->cmd; dir = p->sc_data_direction; result = MK_RES(0, did_flag, 0, 0); - printk("G:%li(%02i-%i) ", p->pid, + printk("G:%li(%02i-%i) ", p->serial_number, p->device->id, p->device->lun); srb_going_remove(dcb, srb); free_tag(dcb, srb); @@ -3568,7 +3568,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, p = srb->cmd; result = MK_RES(0, did_flag, 0, 0); - printk("W:%li<%02i-%i>", p->pid, p->device->id, + printk("W:%li<%02i-%i>", p->serial_number, p->device->id, p->device->lun); srb_waiting_remove(dcb, srb); srb_free_insert(acb, srb); @@ -3678,7 +3678,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, { struct scsi_cmnd *cmd = srb->cmd; dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n", - cmd->pid, cmd->device->id, cmd->device->lun); + cmd->serial_number, cmd->device->id, cmd->device->lun); srb->flag |= AUTO_REQSENSE; srb->adapter_status = 0; @@ -3709,7 +3709,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */ dprintkl(KERN_DEBUG, "request_sense: (pid#%li) failed <%02i-%i>\n", - srb->cmd->pid, dcb->target_id, dcb->target_lun); + srb->cmd->serial_number, dcb->target_id, dcb->target_lun); srb_going_to_waiting_move(dcb, srb); waiting_set_timer(acb, HZ / 100); } @@ -4717,13 +4717,13 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer, dcb->target_id, dcb->target_lun, list_size(&dcb->srb_waiting_list)); list_for_each_entry(srb, &dcb->srb_waiting_list, list) - SPRINTF(" %li", srb->cmd->pid); + SPRINTF(" %li", srb->cmd->serial_number); if (!list_empty(&dcb->srb_going_list)) SPRINTF("\nDCB (%02i-%i): Going : %i:", dcb->target_id, dcb->target_lun, list_size(&dcb->srb_going_list)); list_for_each_entry(srb, &dcb->srb_going_list, list) - SPRINTF(" %li", srb->cmd->pid); + SPRINTF(" %li", srb->cmd->serial_number); if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) SPRINTF("\n"); } diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index a83e9f1..ec22331 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -1758,7 +1758,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, if (SCpnt->host_scribble) panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", - ha->board_name, SCpnt->pid, SCpnt); + ha->board_name, SCpnt->serial_number, SCpnt); /* i is the mailbox number, look for the first free mailbox starting from last_cp_used */ @@ -1792,7 +1792,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, if (do_trace) scmd_printk(KERN_INFO, SCpnt, - "qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid); + "qcomm, mbox %d, pid %ld.\n", i, SCpnt->serial_number); cpp->reqsen = 1; cpp->dispri = 1; @@ -1825,7 +1825,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, unmap_dma(i, ha); SCpnt->host_scribble = NULL; scmd_printk(KERN_INFO, SCpnt, - "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); + "qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number); return 1; } @@ -1841,13 +1841,13 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) if (SCarg->host_scribble == NULL) { scmd_printk(KERN_INFO, SCarg, - "abort, pid %ld inactive.\n", SCarg->pid); + "abort, pid %ld inactive.\n", SCarg->serial_number); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; scmd_printk(KERN_WARNING, SCarg, - "abort, mbox %d, pid %ld.\n", i, SCarg->pid); + "abort, mbox %d, pid %ld.\n", i, SCarg->serial_number); if (i >= shost->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); @@ -1892,7 +1892,7 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) SCarg->host_scribble = NULL; ha->cp_stat[i] = FREE; printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", - ha->board_name, i, SCarg->pid); + ha->board_name, i, SCarg->serial_number); SCarg->scsi_done(SCarg); return SUCCESS; } @@ -1909,12 +1909,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) struct hostdata *ha = (struct hostdata *)shost->hostdata; scmd_printk(KERN_INFO, SCarg, - "reset, enter, pid %ld.\n", SCarg->pid); + "reset, enter, pid %ld.\n", SCarg->serial_number); spin_lock_irq(shost->host_lock); if (SCarg->host_scribble == NULL) - printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid); + printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->serial_number); if (ha->in_reset) { printk("%s: reset, exit, already in reset.\n", ha->board_name); @@ -1954,13 +1954,13 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { ha->cp_stat[i] = ABORTING; printk("%s: reset, mbox %d aborting, pid %ld.\n", - ha->board_name, i, SCpnt->pid); + ha->board_name, i, SCpnt->serial_number); } else { ha->cp_stat[i] = IN_RESET; printk("%s: reset, mbox %d in reset, pid %ld.\n", - ha->board_name, i, SCpnt->pid); + ha->board_name, i, SCpnt->serial_number); } if (SCpnt->host_scribble == NULL) @@ -2015,7 +2015,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) printk ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - ha->board_name, i, SCpnt->pid); + ha->board_name, i, SCpnt->serial_number); } else if (ha->cp_stat[i] == ABORTING) { @@ -2029,7 +2029,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) printk ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", - ha->board_name, i, SCpnt->pid); + ha->board_name, i, SCpnt->serial_number); } else @@ -2043,7 +2043,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) do_trace = 0; if (arg_done) - printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->pid); + printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->serial_number); else printk("%s: reset, exit.\n", ha->board_name); @@ -2182,7 +2182,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec, cpp = &ha->cp[k]; SCpnt = cpp->SCpnt; ll[n] = SCpnt->request->nr_sectors; - pl[n] = SCpnt->pid; + pl[n] = SCpnt->serial_number; if (!n) continue; @@ -2230,7 +2230,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec, "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld" " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->pid, k, flushcount, + SCpnt->serial_number, k, flushcount, n_ready, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), @@ -2277,7 +2277,7 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, "%s, pid %ld, mbox %d, adapter" " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->pid, k); + SCpnt->serial_number, k); ha->cp_stat[k] = ABORTING; continue; } @@ -2391,11 +2391,11 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) if (SCpnt->host_scribble == NULL) panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name, - i, SCpnt->pid, SCpnt); + i, SCpnt->serial_number, SCpnt); if (*(unsigned int *)SCpnt->host_scribble != i) panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", - ha->board_name, i, SCpnt->pid, + ha->board_name, i, SCpnt->serial_number, *(unsigned int *)SCpnt->host_scribble); sync_dma(i, ha); @@ -2445,12 +2445,12 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) "target_status 0x%x, sense key 0x%x.\n", ha->board_name, SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid, + SCpnt->device->lun, SCpnt->serial_number, spp->target_status, SCpnt->sense_buffer[2]); ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; - if (ha->last_retried_pid == SCpnt->pid) + if (ha->last_retried_pid == SCpnt->serial_number) ha->retries = 0; break; @@ -2485,7 +2485,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) #endif ha->retries++; - ha->last_retried_pid = SCpnt->pid; + ha->last_retried_pid = SCpnt->serial_number; } else status = DID_ERROR << 16; @@ -2516,7 +2516,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," " pid %ld, reg 0x%x, count %d.\n", i, spp->adapter_status, spp->target_status, - SCpnt->pid, reg, ha->iocount); + SCpnt->serial_number, reg, ha->iocount); unmap_dma(i, ha); diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 73260e5..96180bb 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -375,7 +375,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, "eata_pio_queue pid %ld, y %d\n", - cmd->pid, y)); + cmd->serial_number, y)); cmd->scsi_done = (void *) done; @@ -420,7 +420,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, cmd->result = DID_BUS_BUSY << 16; scmd_printk(KERN_NOTICE, cmd, "eata_pio_queue pid %ld, HBA busy, " - "returning DID_BUS_BUSY, done.\n", cmd->pid); + "returning DID_BUS_BUSY, done.\n", cmd->serial_number); done(cmd); cp->status = FREE; return 0; @@ -435,7 +435,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, "Queued base %#.4lx pid: %ld " - "slot %d irq %d\n", sh->base, cmd->pid, y, sh->irq)); + "slot %d irq %d\n", sh->base, cmd->serial_number, y, sh->irq)); return 0; } @@ -446,7 +446,7 @@ static int eata_pio_abort(struct scsi_cmnd *cmd) DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, "eata_pio_abort called pid: %ld\n", - cmd->pid)); + cmd->serial_number)); while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) if (--loop == 0) { @@ -482,7 +482,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd) DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, "eata_pio_reset called pid:%ld\n", - cmd->pid)); + cmd->serial_number)); spin_lock_irq(host->host_lock); @@ -501,7 +501,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd) sp = HD(cmd)->ccb[x].cmd; HD(cmd)->ccb[x].status = RESET; - printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->pid); + printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->serial_number); if (sp == NULL) panic("eata_pio_reset: slot %d, sp==NULL.\n", x); diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 312190a..ab7cbf3 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -343,7 +343,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) instance = cmd->device->host; hostdata = (struct IN2000_hostdata *) instance->hostdata; - DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->pid)) + DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->serial_number)) /* Set up a few fields in the Scsi_Cmnd structure for our own use: * - host_scribble is the pointer to the next cmd in the input queue @@ -427,7 +427,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) in2000_execute(cmd->device->host); - DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) + DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number)) return 0; } @@ -703,7 +703,7 @@ static void in2000_execute(struct Scsi_Host *instance) * to search the input_Q again... */ - DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid)) + DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number)) } @@ -1147,7 +1147,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) case CSR_XFER_DONE | PHS_COMMAND: case CSR_UNEXP | PHS_COMMAND: case CSR_SRV_REQ | PHS_COMMAND: - DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid)) + DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number)) transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata); hostdata->state = S_CONNECTED; break; @@ -1189,7 +1189,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) switch (msg) { case COMMAND_COMPLETE: - DB(DB_INTR, printk("CCMP-%ld", cmd->pid)) + DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number)) write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); hostdata->state = S_PRE_CMP_DISC; break; @@ -1327,7 +1327,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); if (phs == 0x60) { - DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid)) + DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number)) cmd->SCp.Message = COMMAND_COMPLETE; lun = read_3393(hostdata, WD_TARGET_LUN); DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) @@ -1348,7 +1348,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) in2000_execute(instance); } else { - printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->pid); + printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->serial_number); } break; @@ -1415,7 +1415,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) spin_unlock_irqrestore(instance->host_lock, flags); return IRQ_HANDLED; } - DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) + DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number)) hostdata->connected = NULL; hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; @@ -1440,7 +1440,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) */ write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); - DB(DB_INTR, printk("DISC-%ld", cmd->pid)) + DB(DB_INTR, printk("DISC-%ld", cmd->serial_number)) if (cmd == NULL) { printk(" - Already disconnected! "); hostdata->state = S_UNCONNECTED; @@ -1573,7 +1573,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) } else hostdata->state = S_CONNECTED; - DB(DB_INTR, printk("-%ld", cmd->pid)) + DB(DB_INTR, printk("-%ld", cmd->serial_number)) break; default: @@ -1702,7 +1702,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd) prev->host_scribble = cmd->host_scribble; cmd->host_scribble = NULL; cmd->result = DID_ABORT << 16; - printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->pid); + printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->serial_number); cmd->scsi_done(cmd); return SUCCESS; } @@ -1723,7 +1723,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd) if (hostdata->connected == cmd) { - printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->pid); + printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->serial_number); printk("sending wd33c93 ABORT command - "); write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED); @@ -2268,7 +2268,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, strcat(bp, "\nconnected: "); if (hd->connected) { cmd = (Scsi_Cmnd *) hd->connected; - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); } } @@ -2276,7 +2276,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, strcat(bp, "\ninput_Q: "); cmd = (Scsi_Cmnd *) hd->input_Q; while (cmd) { - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (Scsi_Cmnd *) cmd->host_scribble; } @@ -2285,7 +2285,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, strcat(bp, "\ndisconnected_Q:"); cmd = (Scsi_Cmnd *) hd->disconnected_Q; while (cmd) { - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (Scsi_Cmnd *) cmd->host_scribble; } diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 91fa66c..016c462 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -8143,12 +8143,7 @@ static int ncr53c8xx_abort(struct scsi_cmnd *cmd) unsigned long flags; struct scsi_cmnd *done_list; -#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS - printk("ncr53c8xx_abort: pid=%lu serial_number=%ld\n", - cmd->pid, cmd->serial_number); -#else - printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid); -#endif + printk("ncr53c8xx_abort: command pid %lu\n", cmd->serial_number); NCR_LOCK_NCB(np, flags); diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 54d8bdf..fba8aa8 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -4086,7 +4086,7 @@ __qla1280_print_scsi_cmd(struct scsi_cmnd *cmd) } */ printk(" tag=%d, transfersize=0x%x \n", cmd->tag, cmd->transfersize); - printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); + printk(" Pid=%li, SP=0x%p\n", cmd->serial_number, CMD_SP(cmd)); printk(" underflow size = 0x%x, direction=0x%x\n", cmd->underflow, cmd->sc_data_direction); } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a5de1a8..07a7c2a 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -442,7 +442,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) #endif /* - * Assign a serial number and pid to the request for error recovery + * Assign a serial number to the request for error recovery * and debugging purposes. Protected by the Host_Lock of host. */ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) @@ -450,10 +450,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd cmd->serial_number = host->cmd_serial_number++; if (cmd->serial_number == 0) cmd->serial_number = host->cmd_serial_number++; - - cmd->pid = host->cmd_pid++; - if (cmd->pid == 0) - cmd->pid = host->cmd_pid++; } /* diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index c05d020..44e6721 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1681,12 +1681,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) init_timer(&scmd->eh_timeout); - /* - * Sometimes the command can get back into the timer chain, - * so use the pid as an identifier. - */ - scmd->pid = 0; - spin_lock_irqsave(shost->host_lock, flags); shost->tmf_in_progress = 1; spin_unlock_irqrestore(shost->host_lock, flags); diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 5db1520..5c72ca3 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -567,12 +567,12 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr pDCB->TagMask |= 1 << tag[1]; pSRB->TagNumber = tag[1]; DC390_write8(ScsiFifo, tag[1]); - DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->pid, pSRB, tag[1])); + DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->serial_number, pSRB, tag[1])); cmd = SEL_W_ATN3; } else { /* No TagQ */ //no_tag: - DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->pid, pSRB)); + DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->serial_number, pSRB)); } pSRB->SRBState = SRB_START_; @@ -623,7 +623,7 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr { dc390_freetag (pDCB, pSRB); DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n", - scmd->pid, scmd->device->id, scmd->device->lun)); + scmd->serial_number, scmd->device->id, scmd->device->lun)); pSRB->SRBState = SRB_READY; //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); pACB->SelLost++; @@ -1708,7 +1708,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* status = pSRB->TargetStatus; DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\ - pSRB, pcmd->pid)); + pSRB, pcmd->serial_number)); if(pSRB->SRBFlag & AUTO_REQSENSE) { /* Last command was a Request Sense */ pSRB->SRBFlag &= ~AUTO_REQSENSE; @@ -1729,7 +1729,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* } else { SET_RES_DRV(pcmd->result, DRIVER_SENSE); //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8); - DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); + DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); pSRB->TotalXferredLen = 0; SET_RES_DID(pcmd->result, DID_SOFT_ERROR); } @@ -1749,7 +1749,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* else if (status == SAM_STAT_TASK_SET_FULL) { scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1); - DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); + DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); pSRB->TotalXferredLen = 0; SET_RES_DID(pcmd->result, DID_SOFT_ERROR); } @@ -1803,7 +1803,7 @@ cmd_done: /* Add to free list */ dc390_Free_insert (pACB, pSRB); - DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid)); + DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->serial_number)); pcmd->scsi_done (pcmd); return; @@ -1998,7 +1998,7 @@ static int DC390_abort(struct scsi_cmnd *cmd) struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata; scmd_printk(KERN_WARNING, cmd, - "DC390: Abort command (pid %li)\n", cmd->pid); + "DC390: Abort command (pid %li)\n", cmd->serial_number); /* abort() is too stupid for already sent commands at the moment. * If it's called we are in trouble anyway, so let's dump some info @@ -2006,7 +2006,7 @@ static int DC390_abort(struct scsi_cmnd *cmd) dc390_dumpinfo(pACB, pDCB, NULL); pDCB->DCBFlag |= ABORT_DEV_; - printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->pid); + printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->serial_number); return FAILED; } diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 9e8232a..fc9f518 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -1254,7 +1254,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs if (SCpnt->host_scribble) panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", - BN(j), SCpnt->pid, SCpnt); + BN(j), SCpnt->serial_number, SCpnt); /* i is the mailbox number, look for the first free mailbox starting from last_cp_used */ @@ -1285,7 +1285,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", BN(j), i, SCpnt->device->channel, SCpnt->device->id, - SCpnt->device->lun, SCpnt->pid); + SCpnt->device->lun, SCpnt->serial_number); cpp->opcode = OP_SCSI; cpp->channel = SCpnt->device->channel; @@ -1312,7 +1312,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs unmap_dma(i, j); SCpnt->host_scribble = NULL; scmd_printk(KERN_INFO, SCpnt, - "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); + "qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number); return 1; } @@ -1333,13 +1333,13 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { if (SCarg->host_scribble == NULL) { scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n", - SCarg->pid); + SCarg->serial_number); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n", - i, SCarg->pid); + i, SCarg->serial_number); if (i >= sh[j]->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); @@ -1383,7 +1383,7 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { SCarg->host_scribble = NULL; HD(j)->cp_stat[i] = FREE; printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", - BN(j), i, SCarg->pid); + BN(j), i, SCarg->serial_number); SCarg->scsi_done(SCarg); return SUCCESS; } @@ -1397,12 +1397,12 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { struct scsi_cmnd *SCpnt; j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; - scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->pid); + scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->serial_number); spin_lock_irq(sh[j]->host_lock); if (SCarg->host_scribble == NULL) - printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); + printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->serial_number); if (HD(j)->in_reset) { printk("%s: reset, exit, already in reset.\n", BN(j)); @@ -1440,13 +1440,13 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { HD(j)->cp_stat[i] = ABORTING; printk("%s: reset, mbox %d aborting, pid %ld.\n", - BN(j), i, SCpnt->pid); + BN(j), i, SCpnt->serial_number); } else { HD(j)->cp_stat[i] = IN_RESET; printk("%s: reset, mbox %d in reset, pid %ld.\n", - BN(j), i, SCpnt->pid); + BN(j), i, SCpnt->serial_number); } if (SCpnt->host_scribble == NULL) @@ -1495,7 +1495,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { HD(j)->cp_stat[i] = LOCKED; printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); + BN(j), i, SCpnt->serial_number); } else if (HD(j)->cp_stat[i] == ABORTING) { @@ -1508,7 +1508,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { HD(j)->cp_stat[i] = FREE; printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); + BN(j), i, SCpnt->serial_number); } else @@ -1522,7 +1522,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { HD(j)->in_reset = FALSE; do_trace = FALSE; - if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid); + if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->serial_number); else printk("%s: reset, exit.\n", BN(j)); spin_unlock_irq(sh[j]->host_lock); @@ -1639,7 +1639,7 @@ static int reorder(unsigned int j, unsigned long cursec, if (!input_only) for (n = 0; n < n_ready; n++) { k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; - ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid; + ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->serial_number; if (!n) continue; @@ -1666,7 +1666,7 @@ static int reorder(unsigned int j, unsigned long cursec, printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, - SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, + SCpnt->lun, SCpnt->serial_number, k, flushcount, n_ready, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), YESNO(overlap), cpp->xdir); @@ -1703,7 +1703,7 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in scmd_printk(KERN_INFO, SCpnt, "%s, pid %ld, mbox %d, adapter" " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->pid, k); + SCpnt->serial_number, k); HD(j)->cp_stat[k] = ABORTING; continue; } @@ -1787,11 +1787,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { if (SCpnt->host_scribble == NULL) panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i, - SCpnt->pid, SCpnt); + SCpnt->serial_number, SCpnt); if (*(unsigned int *)SCpnt->host_scribble != i) panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", - BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble); + BN(j), i, SCpnt->serial_number, *(unsigned int *)SCpnt->host_scribble); sync_dma(i, j); @@ -1835,12 +1835,12 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) scmd_printk(KERN_INFO, SCpnt, "ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n", - SCpnt->pid, spp->target_status, + SCpnt->serial_number, spp->target_status, SCpnt->sense_buffer[2]); HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0; - if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; + if (HD(j)->last_retried_pid == SCpnt->serial_number) HD(j)->retries = 0; break; case ASST: /* Selection Time Out */ @@ -1877,7 +1877,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { #endif HD(j)->retries++; - HD(j)->last_retried_pid = SCpnt->pid; + HD(j)->last_retried_pid = SCpnt->serial_number; } else status = DID_ERROR << 16; @@ -1907,7 +1907,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { #endif scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\ " pid %ld, reg 0x%x, count %d.\n", - i, spp->adapter_status, spp->target_status, SCpnt->pid, + i, spp->adapter_status, spp->target_status, SCpnt->serial_number, reg, HD(j)->iocount); unmap_dma(i, j); diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index b92ff04..0e8e642 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -381,7 +381,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata; DB(DB_QUEUE_COMMAND, - printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->pid)) + printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->serial_number)) /* Set up a few fields in the scsi_cmnd structure for our own use: * - host_scribble is the pointer to the next cmd in the input queue @@ -463,7 +463,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, wd33c93_execute(cmd->device->host); - DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) + DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number)) spin_unlock_irq(&hostdata->lock); return 0; @@ -686,7 +686,7 @@ wd33c93_execute(struct Scsi_Host *instance) */ DB(DB_EXECUTE, - printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid)) + printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number)) } static void @@ -963,7 +963,7 @@ wd33c93_intr(struct Scsi_Host *instance) case CSR_XFER_DONE | PHS_COMMAND: case CSR_UNEXP | PHS_COMMAND: case CSR_SRV_REQ | PHS_COMMAND: - DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid)) + DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number)) transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata); hostdata->state = S_CONNECTED; @@ -1007,7 +1007,7 @@ wd33c93_intr(struct Scsi_Host *instance) switch (msg) { case COMMAND_COMPLETE: - DB(DB_INTR, printk("CCMP-%ld", cmd->pid)) + DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number)) write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK); hostdata->state = S_PRE_CMP_DISC; break; @@ -1174,7 +1174,7 @@ wd33c93_intr(struct Scsi_Host *instance) write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); if (phs == 0x60) { - DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid)) + DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number)) cmd->SCp.Message = COMMAND_COMPLETE; lun = read_wd33c93(regs, WD_TARGET_LUN); DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) @@ -1201,7 +1201,7 @@ wd33c93_intr(struct Scsi_Host *instance) } else { printk ("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", - asr, sr, phs, cmd->pid); + asr, sr, phs, cmd->serial_number); spin_unlock_irqrestore(&hostdata->lock, flags); } break; @@ -1266,7 +1266,7 @@ wd33c93_intr(struct Scsi_Host *instance) spin_unlock_irqrestore(&hostdata->lock, flags); return; } - DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) + DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number)) hostdata->connected = NULL; hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; @@ -1292,7 +1292,7 @@ wd33c93_intr(struct Scsi_Host *instance) */ write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); - DB(DB_INTR, printk("DISC-%ld", cmd->pid)) + DB(DB_INTR, printk("DISC-%ld", cmd->serial_number)) if (cmd == NULL) { printk(" - Already disconnected! "); hostdata->state = S_UNCONNECTED; @@ -1491,7 +1491,7 @@ wd33c93_intr(struct Scsi_Host *instance) } else hostdata->state = S_CONNECTED; - DB(DB_INTR, printk("-%ld", cmd->pid)) + DB(DB_INTR, printk("-%ld", cmd->serial_number)) spin_unlock_irqrestore(&hostdata->lock, flags); break; @@ -1638,7 +1638,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) cmd->result = DID_ABORT << 16; printk ("scsi%d: Abort - removing command %ld from input_Q. ", - instance->host_no, cmd->pid); + instance->host_no, cmd->serial_number); enable_irq(cmd->device->host->irq); cmd->scsi_done(cmd); return SUCCESS; @@ -1663,7 +1663,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) unsigned long timeout; printk("scsi%d: Aborting connected command %ld - ", - instance->host_no, cmd->pid); + instance->host_no, cmd->serial_number); printk("stopping DMA - "); if (hostdata->dma == D_DMA_RUNNING) { @@ -1730,7 +1730,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) if (tmp == cmd) { printk ("scsi%d: Abort - command %ld found on disconnected_Q - ", - instance->host_no, cmd->pid); + instance->host_no, cmd->serial_number); printk("Abort SNOOZE. "); enable_irq(cmd->device->host->irq); return FAILED; @@ -2184,7 +2184,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off if (hd->connected) { cmd = (struct scsi_cmnd *) hd->connected; sprintf(tbuf, " %ld-%d:%d(%02x)", - cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); } } @@ -2193,7 +2193,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off cmd = (struct scsi_cmnd *) hd->input_Q; while (cmd) { sprintf(tbuf, " %ld-%d:%d(%02x)", - cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (struct scsi_cmnd *) cmd->host_scribble; } @@ -2203,7 +2203,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off cmd = (struct scsi_cmnd *) hd->disconnected_Q; while (cmd) { sprintf(tbuf, " %ld-%d:%d(%02x)", - cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); + cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (struct scsi_cmnd *) cmd->host_scribble; } diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 53e1705..4fddef7 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -39,14 +39,12 @@ struct scsi_cmnd { * A SCSI Command is assigned a nonzero serial_number before passed * to the driver's queue command function. The serial_number is * cleared when scsi_done is entered indicating that the command - * has been completed. It currently doesn't have much use other - * than printk's. Some lldd's use this number for other purposes. - * It's almost certain that such usages are either incorrect or - * meaningless. Please kill all usages other than printk's. Also, - * as this number is always identical to ->pid, please convert - * printk's to use ->pid, so that we can kill this field. + * has been completed. It is a bug for LLDDs to use this number + * for purposes other than printk (and even that is only useful + * for debugging). */ unsigned long serial_number; + /* * This is set to jiffies as it was when the command was first * allocated. It is used to time how long the command has @@ -116,7 +114,6 @@ struct scsi_cmnd { int result; /* Status code from lower level driver */ unsigned char tag; /* SCSI-II queued command tag */ - unsigned long pid; /* Process ID, starts at 0. Unique per host. */ }; extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 5b79697..7d210cd 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -580,7 +580,7 @@ struct Scsi_Host { * Used to assign serial numbers to the cmds. * Protected by the host lock. */ - unsigned long cmd_serial_number, cmd_pid; + unsigned long cmd_serial_number; unsigned active_mode:2; unsigned unchecked_isa_dma:1; -- cgit v1.1 From 311b581e1d87be87f78e6e17fc50f468f2dec561 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Sep 2007 09:08:46 -0500 Subject: [SCSI] Fix device not ready printk Because scsi_print_sense_hdr prefixes with KERN_INFO, the output from scsi_io_completion looks like: sd 0:0:0:0: [sdb] Device not ready: <6>: Sense Key : 0x2 [current] : ASC=0x4 ASCQ=0x3 By using scsi_show_sense_hdr, we can get the much more appealing output: sd 0:0:0:0: [sdb] Device not ready: Sense Key : 0x2 [current] sd 0:0:0:0: [sdb] Device not ready: ASC=0x4 ASCQ=0x3 Acked-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/constants.c | 14 ++++++++++++++ drivers/scsi/scsi_lib.c | 10 +++++----- include/scsi/scsi_dbg.h | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 7bdeed1..024553f 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1235,6 +1235,20 @@ scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) } EXPORT_SYMBOL(scsi_print_sense_hdr); +/* + * Print normalized SCSI sense header with device information and a prefix. + */ +void +scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const char *desc, + struct scsi_sense_hdr *sshdr) +{ + scmd_printk(KERN_INFO, scmd, "%s: ", desc); + scsi_show_sense_hdr(sshdr); + scmd_printk(KERN_INFO, scmd, "%s: ", desc); + scsi_show_extd_sense(sshdr->asc, sshdr->ascq); +} +EXPORT_SYMBOL(scsi_cmd_print_sense_hdr); + static void scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, struct scsi_sense_hdr *sshdr) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 94d82cb..86fd3ab 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -944,11 +944,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) break; } } - if (!(req->cmd_flags & REQ_QUIET)) { - scmd_printk(KERN_INFO, cmd, - "Device not ready: "); - scsi_print_sense_hdr("", &sshdr); - } + if (!(req->cmd_flags & REQ_QUIET)) + scsi_cmd_print_sense_hdr(cmd, + "Device not ready", + &sshdr); + scsi_end_request(cmd, 0, this_count, 1); return; case VOLUME_OVERFLOW: diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index 5a43a4c..e89844c 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -9,6 +9,8 @@ extern void __scsi_print_command(unsigned char *); extern void scsi_show_extd_sense(unsigned char, unsigned char); extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); +extern void scsi_cmd_print_sense_hdr(struct scsi_cmnd *, const char *, + struct scsi_sense_hdr *); extern void scsi_print_sense(char *, struct scsi_cmnd *); extern void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, -- cgit v1.1 From 1d0c7c8dcf289557f13b6b0f6d71b6a03b12b747 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 25 Sep 2007 12:42:02 -0400 Subject: [SCSI] pluto: Don't abuse ->done for internal commands We can simply call the internal done function directly Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/pluto.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index e221389..0363c1c 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -160,7 +160,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) SCpnt->request->cmd_flags &= ~REQ_STARTED; - SCpnt->done = pluto_detect_done; SCpnt->request_bufflen = 256; SCpnt->request_buffer = fcs[i].inquiry; PLD(("set up %d %08lx\n", i, (long)SCpnt)) @@ -195,7 +194,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) SCpnt = &(fcs[i].cmd); /* Let FC mid-level free allocated resources */ - SCpnt->done (SCpnt); + pluto_detect_scsi_done(SCpnt); if (!SCpnt->result) { struct pluto_inquiry *inq; -- cgit v1.1 From cce99c6925b8d6a59cf584411277c1c20c330334 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 25 Sep 2007 12:42:01 -0400 Subject: [SCSI] Fix mistaken uses of ->done All these drivers meant to call ->scsi_done() but got confused. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/NCR5380.c | 8 ++++---- drivers/scsi/NCR53C9x.c | 2 +- drivers/scsi/atari_NCR5380.c | 4 ++-- drivers/scsi/sun3_NCR5380.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index f8e449a..5b27966 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -2133,7 +2133,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); return; #endif /* @@ -2196,7 +2196,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); /* XXX - need to source or sink data here, as appropriate */ } else cmd->SCp.this_residual -= transfersize - len; @@ -2740,7 +2740,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { tmp->host_scribble = NULL; tmp->result = DID_ABORT << 16; dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no)); - tmp->done(tmp); + tmp->scsi_done(tmp); return SUCCESS; } #if (NDEBUG & NDEBUG_ABORT) @@ -2805,7 +2805,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { *prev = (Scsi_Cmnd *) tmp->host_scribble; tmp->host_scribble = NULL; tmp->result = DID_ABORT << 16; - tmp->done(tmp); + tmp->scsi_done(tmp); return SUCCESS; } } diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 79b4df1..96e8e29 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -1385,7 +1385,7 @@ int esp_abort(Scsi_Cmnd *SCptr) this->host_scribble = NULL; esp_release_dmabufs(esp, this); this->result = DID_ABORT << 16; - this->done(this); + this->scsi_done(this); if(don) esp->dma_ints_on(esp); return SUCCESS; diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 03dbe60..743df4c 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -2041,7 +2041,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); return; #endif case PHASE_DATAIN: @@ -2100,7 +2100,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); /* XXX - need to source or sink data here, as appropriate */ } else { #ifdef REAL_DMA diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 98e3fe1..3769537 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -2055,7 +2055,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); return; #endif case PHASE_DATAIN: @@ -2115,7 +2115,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) sink = 1; do_abort(instance); cmd->result = DID_ERROR << 16; - cmd->done(cmd); + cmd->scsi_done(cmd); /* XXX - need to source or sink data here, as appropriate */ } else { #ifdef REAL_DMA -- cgit v1.1 From e7eae9f6e94cd49261c2997b0b4f768c1351bc02 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:15:59 -0600 Subject: [SCSI] mpt fusion: add use of shost_priv and remove all the typecasting The driver is currently typecasting to obtain the shost hostdata. The driver is updated to use the shost_priv macro. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 10 +++--- drivers/message/fusion/mptfc.c | 17 ++++----- drivers/message/fusion/mptsas.c | 14 ++++---- drivers/message/fusion/mptscsih.c | 74 +++++++++++++++++---------------------- drivers/message/fusion/mptspi.c | 23 ++++++------ 5 files changed, 62 insertions(+), 76 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b7d1159..70178a8 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -348,7 +348,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) if (ioctl->ioc->sh == NULL) return -EPERM; - hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata; + hd = shost_priv(ioctl->ioc->sh); if (hd == NULL) return -EPERM; @@ -449,7 +449,7 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc) MPT_SCSI_HOST * hd; unsigned long flags; - hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; + hd = shost_priv(ioc->sh); if (hd == NULL) return; @@ -2026,7 +2026,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) case MPI_FUNCTION_SCSI_TASK_MGMT: { MPT_SCSI_HOST *hd = NULL; - if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) { + if ((ioc->sh == NULL) || ((hd = shost_priv(ioc->sh)) == NULL)) { printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver not loaded or SCSI host not found. \n", ioc->name, __FILE__, __LINE__); @@ -2466,7 +2466,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) karg.soft_resets = 0; karg.timeouts = 0; if (ioc->sh != NULL) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + MPT_SCSI_HOST *hd = shost_priv(ioc->sh); if (hd && (cim_rev == 1)) { karg.hard_resets = hd->hard_resets; @@ -2683,7 +2683,7 @@ mptctl_hp_targetinfo(unsigned long arg) pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma); } } - hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; + hd = shost_priv(ioc->sh); if (hd != NULL) karg.select_timeouts = hd->sel_timeout[karg.hdr.id]; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 19438ec..df1e6fa 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -196,7 +196,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, int ready; MPT_ADAPTER *ioc; - hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; + hd = shost_priv(SCpnt->device->host); ioc = hd->ioc; spin_lock_irqsave(shost->host_lock, flags); while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { @@ -204,8 +204,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "mptfc_block_error_handler.%d: %d:%d, port status is " "DID_IMM_RETRY, deferring %s recovery.\n", - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + ioc->name, ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun, caller)); msleep(1000); spin_lock_irqsave(shost->host_lock, flags); @@ -216,16 +215,14 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt, dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "%s.%d: %d:%d, failing recovery, " "port state %d, vdevice %p.\n", caller, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + ioc->name, ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun, ready, SCpnt->device->hostdata)); return FAILED; } dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "%s.%d: %d:%d, executing recovery.\n", caller, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, - ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, + ioc->name, ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun)); return (*func)(SCpnt); } @@ -615,7 +612,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - hd = (MPT_SCSI_HOST *)sdev->host->hostdata; + hd = shost_priv(sdev->host); ioc = hd->ioc; vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); @@ -1279,7 +1276,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) spin_unlock_irqrestore(&ioc->FreeQlock, flags); - hd = (MPT_SCSI_HOST *) sh->hostdata; + hd = shost_priv(sh); hd->ioc = ioc; /* SCSI needs scsi_cmnd lookup table! @@ -1386,7 +1383,7 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ioc->name, event)); if (ioc->sh == NULL || - ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) + ((hd = shost_priv(ioc->sh)) == NULL)) return 1; switch (event) { diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index d2f1b8e..adbdbd4 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -575,7 +575,7 @@ static void mptsas_target_reset_queue(MPT_ADAPTER *ioc, EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + MPT_SCSI_HOST *hd = shost_priv(ioc->sh); VirtTarget *vtarget = NULL; struct mptsas_target_reset_event *target_reset_list; u8 id, channel; @@ -622,7 +622,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, static void mptsas_dev_reset_complete(MPT_ADAPTER *ioc) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + MPT_SCSI_HOST *hd = shost_priv(ioc->sh); struct list_head *head = &hd->target_reset_list; struct mptsas_target_reset_event *target_reset_list; struct mptsas_hotplug_event *ev; @@ -739,7 +739,7 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) if (!ioc->sh || !ioc->sh->hostdata) goto out; - hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + hd = shost_priv(ioc->sh); if (!hd->ioc) goto out; @@ -839,7 +839,7 @@ static int mptsas_target_alloc(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(&starget->dev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); VirtTarget *vtarget; u8 id, channel; struct sas_rphy *rphy; @@ -908,7 +908,7 @@ static void mptsas_target_destroy(struct scsi_target *starget) { struct Scsi_Host *host = dev_to_shost(&starget->dev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); struct sas_rphy *rphy; struct mptsas_portinfo *p; int i; @@ -941,7 +941,7 @@ static int mptsas_slave_alloc(struct scsi_device *sdev) { struct Scsi_Host *host = sdev->host; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); struct sas_rphy *rphy; struct mptsas_portinfo *p; VirtDevice *vdevice; @@ -3215,7 +3215,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->sg_tablesize = numSGE; } - hd = (MPT_SCSI_HOST *) sh->hostdata; + hd = shost_priv(sh); hd->ioc = ioc; /* SCSI needs scsi_cmnd lookup table! diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 17369f8..b1f68ca 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -647,8 +647,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) VirtDevice *vdevice; VirtTarget *vtarget; - hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; - + hd = shost_priv(ioc->sh); req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); req_idx_MR = (mr != NULL) ? le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx; @@ -1105,7 +1104,7 @@ mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSI return; if (sc->device->host == NULL) return; - if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL) + if ((hd = shost_priv(sc->device->host)) == NULL) return; ioc = hd->ioc; if (time - hd->last_queue_full > 10 * HZ) { @@ -1137,7 +1136,7 @@ mptscsih_remove(struct pci_dev *pdev) scsi_remove_host(host); - if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL) + if((hd = shost_priv(host)) == NULL) return; mptscsih_shutdown(pdev); @@ -1174,15 +1173,6 @@ mptscsih_remove(struct pci_dev *pdev) void mptscsih_shutdown(struct pci_dev *pdev) { - MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct Scsi_Host *host = ioc->sh; - MPT_SCSI_HOST *hd; - - if(!host) - return; - - hd = (MPT_SCSI_HOST *)host->hostdata; - } #ifdef CONFIG_PM @@ -1228,7 +1218,7 @@ mptscsih_info(struct Scsi_Host *SChost) MPT_SCSI_HOST *h; int size = 0; - h = (MPT_SCSI_HOST *)SChost->hostdata; + h = shost_priv(SChost); if (h) { if (h->info_kbuf == NULL) @@ -1322,7 +1312,7 @@ int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; int size = 0; @@ -1371,7 +1361,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) int ii; MPT_ADAPTER *ioc; - hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; + hd = shost_priv(SCpnt->device->host); ioc = hd->ioc; lun = SCpnt->device->lun; SCpnt->scsi_done = done; @@ -1807,7 +1797,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { + if ((hd = shost_priv(SCpnt->device->host)) == NULL) { SCpnt->result = DID_RESET << 16; SCpnt->scsi_done(SCpnt); printk(KERN_ERR MYNAM ": task abort: " @@ -1913,7 +1903,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ + if ((hd = shost_priv(SCpnt->device->host)) == NULL){ printk(KERN_ERR MYNAM ": target reset: " "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; @@ -1976,7 +1966,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ + if ((hd = shost_priv(SCpnt->device->host)) == NULL){ printk(KERN_ERR MYNAM ": bus reset: " "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; @@ -2020,7 +2010,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) MPT_ADAPTER *ioc; /* If we can't locate the host to reset, then we failed. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ + if ((hd = shost_priv(SCpnt->device->host)) == NULL){ printk(KERN_ERR MYNAM ": host reset: " "Can't locate host! (sc=%p)\n", SCpnt); return FAILED; @@ -2186,7 +2176,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m return 1; } - hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + hd = shost_priv(ioc->sh); pScsiTmReply = (SCSITaskMgmtReply_t*)mr; pScsiTmReq = (SCSITaskMgmt_t*)mf; tmType = pScsiTmReq->TaskType; @@ -2380,7 +2370,7 @@ void mptscsih_slave_destroy(struct scsi_device *sdev) { struct Scsi_Host *host = sdev->host; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); VirtTarget *vtarget; VirtDevice *vdevice; struct scsi_target *starget; @@ -2407,7 +2397,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(sdev->host); VirtTarget *vtarget; struct scsi_target *starget; int max_depth; @@ -2452,7 +2442,7 @@ mptscsih_slave_configure(struct scsi_device *sdev) VirtTarget *vtarget; VirtDevice *vdevice; struct scsi_target *starget; - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; + MPT_SCSI_HOST *hd = shost_priv(sh); MPT_ADAPTER *ioc = hd->ioc; starget = scsi_target(sdev); @@ -2567,7 +2557,7 @@ SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) MPT_SCSI_HOST *hd; int i; - hd = (MPT_SCSI_HOST *) sc->device->host->hostdata; + hd = shost_priv(sc->device->host); for (i = 0; i < hd->ioc->req_depth; i++) { if (hd->ScsiLookup[i] == sc) { @@ -2595,10 +2585,10 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) * before all scsi hosts have been attached, then an alt_ioc * may have a NULL sh pointer. */ - if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL)) + if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL) return 0; else - hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; + hd = shost_priv(ioc->sh); if (reset_phase == MPT_IOC_SETUP_RESET) { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Setup-Diag Reset\n", ioc->name)); @@ -2691,7 +2681,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ioc->name, event)); if (ioc->sh == NULL || - ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) + ((hd = shost_priv(ioc->sh)) == NULL)) return 1; switch (event) { @@ -2770,7 +2760,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) int completionCode; u16 req_idx; - hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; + hd = shost_priv(ioc->sh); if ((mf == NULL) || (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { @@ -3254,7 +3244,7 @@ static ssize_t mptscsih_version_fw_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", @@ -3269,7 +3259,7 @@ static ssize_t mptscsih_version_bios_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n", @@ -3284,7 +3274,7 @@ static ssize_t mptscsih_version_mpi_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion); @@ -3295,7 +3285,7 @@ static ssize_t mptscsih_version_product_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name); @@ -3307,7 +3297,7 @@ static ssize_t mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02xh\n", @@ -3320,7 +3310,7 @@ static ssize_t mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default); @@ -3332,7 +3322,7 @@ static ssize_t mptscsih_board_name_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name); @@ -3343,7 +3333,7 @@ static ssize_t mptscsih_board_assembly_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly); @@ -3355,7 +3345,7 @@ static ssize_t mptscsih_board_tracer_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer); @@ -3367,7 +3357,7 @@ static ssize_t mptscsih_io_delay_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay); @@ -3379,7 +3369,7 @@ static ssize_t mptscsih_device_delay_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay); @@ -3391,7 +3381,7 @@ static ssize_t mptscsih_debug_level_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level); @@ -3401,7 +3391,7 @@ mptscsih_debug_level_store(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *host = class_to_shost(cdev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(host); MPT_ADAPTER *ioc = hd->ioc; int val = 0; diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 02062f1..3c24928 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -397,7 +397,7 @@ mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id) static int mptspi_target_alloc(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(shost); VirtTarget *vtarget; MPT_ADAPTER *ioc; @@ -514,7 +514,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) { struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(shost); struct _MPT_ADAPTER *ioc = hd->ioc; struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0; dma_addr_t pg0_dma; @@ -702,7 +702,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, static int mptspi_slave_alloc(struct scsi_device *sdev) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; + MPT_SCSI_HOST *hd = shost_priv(sdev->host); VirtTarget *vtarget; VirtDevice *vdevice; struct scsi_target *starget; @@ -735,8 +735,7 @@ static int mptspi_slave_alloc(struct scsi_device *sdev) static int mptspi_slave_configure(struct scsi_device *sdev) { - struct _MPT_SCSI_HOST *hd = - (struct _MPT_SCSI_HOST *)sdev->host->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(sdev->host); VirtTarget *vtarget = scsi_target(sdev)->hostdata; int ret; @@ -764,7 +763,7 @@ static int mptspi_slave_configure(struct scsi_device *sdev) static int mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host); VirtDevice *vdevice = SCpnt->device->hostdata; MPT_ADAPTER *ioc = hd->ioc; @@ -839,7 +838,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1) { struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(shost); struct _MPT_ADAPTER *ioc = hd->ioc; struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1; dma_addr_t pg1_dma; @@ -1027,7 +1026,7 @@ static void mptspi_write_qas(struct scsi_target *starget, int qas) { struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; struct Scsi_Host *shost = dev_to_shost(&starget->dev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(shost); VirtTarget *vtarget = starget->hostdata; u32 nego; @@ -1137,7 +1136,7 @@ static int mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) { u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); if (hd && event == MPI_EVENT_INTEGRATED_RAID) { int reason @@ -1267,7 +1266,7 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) static int mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); int rc; rc = mptscsih_ioc_reset(ioc, reset_phase); @@ -1286,7 +1285,7 @@ static int mptspi_resume(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); - struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; + struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); int rc; rc = mptscsih_resume(pdev); @@ -1441,7 +1440,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) spin_unlock_irqrestore(&ioc->FreeQlock, flags); - hd = (MPT_SCSI_HOST *) sh->hostdata; + hd = shost_priv(sh); hd->ioc = ioc; /* SCSI needs scsi_cmnd lookup table! -- cgit v1.1 From bc6e089a13a5c0ac36247616baecd6fc77405e7f Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:16:28 -0600 Subject: [SCSI] mpt fusion: Fix sparse warnings List below is output from C=2 sparse compilation, which are fixed with this patch. 1) mptspi: pg0 is defined in x86 version of include/asm/pgtable.h 2) mptsas: context imbalance in 'mptsas_probe' different lock contexts for basic block 3) mptbase: from mpt_attach - cast adds address space to expression 4) mptbase: from mpt_do_upload - request[] is bad constant expression Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 27 ++++++++++++++++----------- drivers/message/fusion/mptsas.c | 1 + drivers/message/fusion/mptspi.c | 22 +++++++++++----------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 5987f8b..52fb216 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1452,6 +1452,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) { MPT_ADAPTER *ioc; u8 __iomem *mem; + u8 __iomem *pmem; unsigned long mem_phys; unsigned long port; u32 msize; @@ -1576,11 +1577,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->chip = (SYSIF_REGS __iomem *)mem; /* Save Port IO values in case we need to do downloadboot */ - { - u8 *pmem = (u8*)port; - ioc->pio_mem_phys = port; - ioc->pio_chip = (SYSIF_REGS __iomem *)pmem; - } + ioc->pio_mem_phys = port; + pmem = (u8 __iomem *)port; + ioc->pio_chip = (SYSIF_REGS __iomem *)pmem; pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); @@ -3103,7 +3102,6 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc) static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) { - u8 request[ioc->req_sz]; u8 reply[sizeof(FWUploadReply_t)]; FWUpload_t *prequest; FWUploadReply_t *preply; @@ -3129,11 +3127,16 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) return -ENOMEM; } - prequest = (FWUpload_t *)&request; - preply = (FWUploadReply_t *)&reply; + prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) : + kzalloc(ioc->req_sz, GFP_KERNEL); + if (!prequest) { + dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed " + "while allocating memory \n", ioc->name)); + mpt_free_fw_memory(ioc); + return -ENOMEM; + } - /* Destination... */ - memset(prequest, 0, ioc->req_sz); + preply = (FWUploadReply_t *)&reply; reply_sz = sizeof(reply); memset(preply, 0, reply_sz); @@ -3145,11 +3148,12 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ptcsge->DetailsLength = 12; ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT; ptcsge->ImageSize = cpu_to_le32(sz); + ptcsge++; sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t); flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; - mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma); + mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); sgeoffset += sizeof(u32) + sizeof(dma_addr_t); dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n", @@ -3184,6 +3188,7 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) ioc->name)); mpt_free_fw_memory(ioc); } + kfree(prequest); return cmdStatus; } diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index adbdbd4..4c641c6 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3224,6 +3224,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); if (!hd->ScsiLookup) { error = -ENOMEM; + spin_unlock_irqrestore(&ioc->FreeQlock, flags); goto out_mptsas_probe; } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3c24928..ed6a778 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -516,8 +516,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct _MPT_SCSI_HOST *hd = shost_priv(shost); struct _MPT_ADAPTER *ioc = hd->ioc; - struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0; - dma_addr_t pg0_dma; + struct _CONFIG_PAGE_SCSI_DEVICE_0 *spi_dev_pg0; + dma_addr_t spi_dev_pg0_dma; int size; struct _x_config_parms cfg; struct _CONFIG_PAGE_HEADER hdr; @@ -535,8 +535,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, size += 2048; */ - pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL); - if (pg0 == NULL) { + spi_dev_pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &spi_dev_pg0_dma, GFP_KERNEL); + if (spi_dev_pg0 == NULL) { starget_printk(MYIOC_s_ERR_FMT, starget, "dma_alloc_coherent for parameters failed\n", ioc->name); return -EINVAL; @@ -552,7 +552,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, memset(&cfg, 0, sizeof(cfg)); cfg.cfghdr.hdr = &hdr; - cfg.physAddr = pg0_dma; + cfg.physAddr = spi_dev_pg0_dma; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; cfg.dir = 0; cfg.pageAddr = starget->id; @@ -562,12 +562,12 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, goto out_free; } err = 0; - memcpy(pass_pg0, pg0, size); + memcpy(pass_pg0, spi_dev_pg0, size); - mptspi_print_read_nego(hd, starget, le32_to_cpu(pg0->NegotiatedParameters)); + mptspi_print_read_nego(hd, starget, le32_to_cpu(spi_dev_pg0->NegotiatedParameters)); out_free: - dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); + dma_free_coherent(&ioc->pcidev->dev, size, spi_dev_pg0, spi_dev_pg0_dma); return err; } @@ -594,11 +594,11 @@ static u32 mptspi_getRP(struct scsi_target *starget) static void mptspi_read_parameters(struct scsi_target *starget) { int nego; - struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0; + struct _CONFIG_PAGE_SCSI_DEVICE_0 spi_dev_pg0; - mptspi_read_spi_device_pg0(starget, &pg0); + mptspi_read_spi_device_pg0(starget, &spi_dev_pg0); - nego = le32_to_cpu(pg0.NegotiatedParameters); + nego = le32_to_cpu(spi_dev_pg0.NegotiatedParameters); spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0; spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0; -- cgit v1.1 From e8206381f5842269691f3164ec0d79b7059bd710 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:16:53 -0600 Subject: [SCSI] mpt fusion: lock down ScsiLookup ScsiLookup is an array of pending scmd pointers that the scsi lld maintains. This array is touched from queuecommand, eh threads, and interrupt context. This array should put under locks, hence this patch to synchronize its access. I've added some nice little function wrappers for this, and moved the ScsiLookup array over to MPT_ADAPTER struct. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 3 +- drivers/message/fusion/mptfc.c | 7 +- drivers/message/fusion/mptsas.c | 7 +- drivers/message/fusion/mptscsih.c | 212 ++++++++++++++++++++++++-------------- drivers/message/fusion/mptspi.c | 7 +- 5 files changed, 149 insertions(+), 87 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 9456564..eb65c49 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -704,6 +704,8 @@ typedef struct _MPT_ADAPTER struct work_struct fc_rescan_work; char fc_rescan_work_q_name[KOBJ_NAME_LEN]; struct workqueue_struct *fc_rescan_work_q; + struct scsi_cmnd **ScsiLookup; + spinlock_t scsi_lookup_lock; } MPT_ADAPTER; /* @@ -817,7 +819,6 @@ typedef struct _MPT_SCSI_HOST { MPT_ADAPTER *ioc; int port; u32 pad0; - struct scsi_cmnd **ScsiLookup; MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ struct timer_list timer; /* Pool of memory for holding SCpnts before doing diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index df1e6fa..3cdd4e9 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -1282,14 +1282,15 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* SCSI needs scsi_cmnd lookup table! * (with size equal to req_depth*PtrSz!) */ - hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); - if (!hd->ScsiLookup) { + ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); + if (!ioc->ScsiLookup) { error = -ENOMEM; goto out_mptfc_probe; } + spin_lock_init(&ioc->scsi_lookup_lock); dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", - ioc->name, hd->ScsiLookup)); + ioc->name, ioc->ScsiLookup)); /* Clear the TM flags */ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 4c641c6..ba4f5e7 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3221,15 +3221,16 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* SCSI needs scsi_cmnd lookup table! * (with size equal to req_depth*PtrSz!) */ - hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); - if (!hd->ScsiLookup) { + ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); + if (!ioc->ScsiLookup) { error = -ENOMEM; spin_unlock_irqrestore(&ioc->FreeQlock, flags); goto out_mptsas_probe; } + spin_lock_init(&ioc->scsi_lookup_lock); dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", - ioc->name, hd->ScsiLookup)); + ioc->name, ioc->ScsiLookup)); /* Clear the TM flags */ diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b1f68ca..dc5e996 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -80,6 +80,10 @@ MODULE_VERSION(my_VERSION); /* * Other private/forward protos... */ +static struct scsi_cmnd * mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i); +static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i); +static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd); +static int SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd); int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq); int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); @@ -90,7 +94,6 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); -static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); @@ -658,12 +661,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) printk (MYIOC_s_ERR_FMT "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n", ioc->name, req_idx, req_idx_MR, mf, mr, - hd->ScsiLookup[req_idx_MR]); + mptscsih_get_scsi_lookup(ioc, req_idx_MR)); return 0; } - sc = hd->ScsiLookup[req_idx]; - hd->ScsiLookup[req_idx] = NULL; + sc = mptscsih_getclear_scsi_lookup(ioc, req_idx); if (sc == NULL) { MPIHeader_t *hdr = (MPIHeader_t *)mf; @@ -969,48 +971,32 @@ static void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) { MPT_ADAPTER *ioc = hd->ioc; - struct scsi_cmnd *SCpnt; - MPT_FRAME_HDR *mf; + struct scsi_cmnd *sc; + SCSIIORequest_t *mf = NULL; int ii; - int max = ioc->req_depth; - - dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush_ScsiLookup called\n", ioc->name)); - for (ii= 0; ii < max; ii++) { - if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { - - /* Command found. - */ - - /* Null ScsiLookup index - */ - hd->ScsiLookup[ii] = NULL; + int channel, id; - mf = MPT_INDEX_2_MFPTR(ioc, ii); - dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush: ScsiDone (mf=%p,sc=%p)\n", - ioc->name, mf, SCpnt)); - - /* Free Chain buffers */ - mptscsih_freeChainBuffers(ioc, ii); - - /* Free Message frames */ - mpt_free_msg_frame(ioc, mf); - - if ((unsigned char *)mf != SCpnt->host_scribble) - continue; - - /* Set status, free OS resources (SG DMA buffers) - * Do OS callback - */ - scsi_dma_unmap(SCpnt); - - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - SCpnt->scsi_done(SCpnt); /* Issue the command callback */ - } + for (ii= 0; ii < ioc->req_depth; ii++) { + sc = mptscsih_getclear_scsi_lookup(ioc, ii); + if (!sc) + continue; + mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii); + if (!mf) + continue; + channel = mf->Bus; + id = mf->TargetID; + mptscsih_freeChainBuffers(ioc, ii); + mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf); + if ((unsigned char *)mf != sc->host_scribble) + continue; + scsi_dma_unmap(sc); + sc->result = DID_RESET << 16; + sc->host_scribble = NULL; + sdev_printk(MYIOC_s_INFO_FMT, sc->device, + "completing cmds: fw_channel %d, fw_id %d, sc=%p," + " mf = %p, idx=%x\n", ioc->name, channel, id, sc, mf, ii); + sc->scsi_done(sc); } - - return; } /* @@ -1032,16 +1018,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) { SCSIIORequest_t *mf = NULL; int ii; - int max = hd->ioc->req_depth; struct scsi_cmnd *sc; struct scsi_lun lun; MPT_ADAPTER *ioc = hd->ioc; + unsigned long flags; - dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n", - ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); - - for (ii=0; ii < max; ii++) { - if ((sc = hd->ScsiLookup[ii]) != NULL) { + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); + for (ii = 0; ii < ioc->req_depth; ii++) { + if ((sc = ioc->ScsiLookup[ii]) != NULL) { mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii); if (mf == NULL) @@ -1060,13 +1044,12 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) memcmp(lun.scsi_lun, mf->LUN, 8)) continue; - /* Cleanup - */ - hd->ScsiLookup[ii] = NULL; - mptscsih_freeChainBuffers(ioc, ii); - mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf); if ((unsigned char *)mf != sc->host_scribble) continue; + ioc->ScsiLookup[ii] = NULL; + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); + mptscsih_freeChainBuffers(ioc, ii); + mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf); scsi_dma_unmap(sc); sc->host_scribble = NULL; sc->result = DID_NO_CONNECT << 16; @@ -1074,8 +1057,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, sc, mf, ii); sc->scsi_done(sc); + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); } } + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); return; } @@ -1143,10 +1128,10 @@ mptscsih_remove(struct pci_dev *pdev) sz1=0; - if (hd->ScsiLookup != NULL) { + if (ioc->ScsiLookup != NULL) { sz1 = ioc->req_depth * sizeof(void *); - kfree(hd->ScsiLookup); - hd->ScsiLookup = NULL; + kfree(ioc->ScsiLookup); + ioc->ScsiLookup = NULL; } dprintk(ioc, printk(MYIOC_s_DEBUG_FMT @@ -1463,7 +1448,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) } SCpnt->host_scribble = (unsigned char *)mf; - hd->ScsiLookup[my_idx] = SCpnt; + mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt); mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", @@ -1472,7 +1457,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) return 0; fail: - hd->ScsiLookup[my_idx] = NULL; mptscsih_freeChainBuffers(ioc, my_idx); mpt_free_msg_frame(ioc, mf); return SCSI_MLQUEUE_HOST_BUSY; @@ -1834,7 +1818,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) /* Find this command */ - if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { + if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) { /* Cmd not found in ScsiLookup. * Do OS callback. */ @@ -1870,7 +1854,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, ctx2abort, mptscsih_get_tm_timeout(ioc)); - if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && + if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx && SCpnt->serial_number == sn) retval = FAILED; @@ -2551,21 +2535,101 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR } } -static int -SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) +/** + * mptscsih_get_scsi_lookup + * + * retrieves scmd entry from ScsiLookup[] array list + * + * @ioc: Pointer to MPT_ADAPTER structure + * @i: index into the array + * + * Returns the scsi_cmd pointer + * + **/ +static struct scsi_cmnd * +mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i) { - MPT_SCSI_HOST *hd; - int i; + unsigned long flags; + struct scsi_cmnd *scmd; + + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); + scmd = ioc->ScsiLookup[i]; + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); + + return scmd; +} + +/** + * mptscsih_getclear_scsi_lookup + * + * retrieves and clears scmd entry from ScsiLookup[] array list + * + * @ioc: Pointer to MPT_ADAPTER structure + * @i: index into the array + * + * Returns the scsi_cmd pointer + * + **/ +static struct scsi_cmnd * +mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i) +{ + unsigned long flags; + struct scsi_cmnd *scmd; + + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); + scmd = ioc->ScsiLookup[i]; + ioc->ScsiLookup[i] = NULL; + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); + + return scmd; +} + +/** + * mptscsih_set_scsi_lookup + * + * writes a scmd entry into the ScsiLookup[] array list + * + * @ioc: Pointer to MPT_ADAPTER structure + * @i: index into the array + * @scmd: scsi_cmnd pointer + * + **/ +static void +mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd) +{ + unsigned long flags; - hd = shost_priv(sc->device->host); + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); + ioc->ScsiLookup[i] = scmd; + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); +} + +/** + * SCPNT_TO_LOOKUP_IDX + * + * search's for a given scmd in the ScsiLookup[] array list + * + * @ioc: Pointer to MPT_ADAPTER structure + * @scmd: scsi_cmnd pointer + * + **/ +static int +SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc) +{ + unsigned long flags; + int i, index=-1; - for (i = 0; i < hd->ioc->req_depth; i++) { - if (hd->ScsiLookup[i] == sc) { - return i; + spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); + for (i = 0; i < ioc->req_depth; i++) { + if (ioc->ScsiLookup[i] == sc) { + index = i; + goto out; } } - return -1; + out: + spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); + return index; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -2574,7 +2638,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { MPT_SCSI_HOST *hd; unsigned long flags; - int ii; dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": IOC %s_reset routed to SCSI host driver!\n", @@ -2630,11 +2693,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) * Init all control structures. */ - /* ScsiLookup initialization - */ - for (ii=0; ii < ioc->req_depth; ii++) - hd->ScsiLookup[ii] = NULL; - /* 2. Chain Buffer initialization */ @@ -2772,7 +2830,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) del_timer(&hd->timer); req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); - hd->ScsiLookup[req_idx] = NULL; + mptscsih_set_scsi_lookup(ioc, req_idx, NULL); pReq = (SCSIIORequest_t *) mf; if (mf != hd->cmdPtr) { diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index ed6a778..42fdf7d 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -1446,14 +1446,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* SCSI needs scsi_cmnd lookup table! * (with size equal to req_depth*PtrSz!) */ - hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); - if (!hd->ScsiLookup) { + ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); + if (!ioc->ScsiLookup) { error = -ENOMEM; goto out_mptspi_probe; } + spin_lock_init(&ioc->scsi_lookup_lock); dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", - ioc->name, hd->ScsiLookup)); + ioc->name, ioc->ScsiLookup)); /* Clear the TM flags */ -- cgit v1.1 From c51d0beaaed902ef48ed1f3b1834d37b7ffd55e8 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:17:21 -0600 Subject: [SCSI] mpt fusion: fix up fusion prints using the sdev_printk, dev_printk, and shost_printk API Cleaning up prints that use the xxx_printk API, in that the fusion preamble "mptbase: iocX" follows the info provided by the print API. The way its currently coded, the [H:C:T] print in sdev_printk will be inbetween "mptbase" and "iocX", instead of before. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 1 + drivers/message/fusion/mptsas.c | 15 ++++++++------- drivers/message/fusion/mptscsih.c | 4 ++-- drivers/message/fusion/mptspi.c | 18 +++++++++--------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index eb65c49..d7682e0 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -186,6 +186,7 @@ * MPT drivers. NOTE: Users of these macro defs must * themselves define their own MYNAM. */ +#define MYIOC_s_FMT MYNAM ": %s: " #define MYIOC_s_DEBUG_FMT KERN_DEBUG MYNAM ": %s: " #define MYIOC_s_INFO_FMT KERN_INFO MYNAM ": %s: " #define MYIOC_s_NOTE_FMT KERN_NOTICE MYNAM ": %s: " diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index ba4f5e7..e4c94f9 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -318,8 +318,8 @@ mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rp } if (rphy) { - dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT, - &rphy->dev, "add:", ioc->name)); + dsaswideprintk(ioc, dev_printk(KERN_DEBUG, + &rphy->dev, MYIOC_s_FMT "add:", ioc->name)); dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n", ioc->name, rphy, rphy->dev.release)); } @@ -341,8 +341,8 @@ mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_po phy_info->port_details->port = port; if (port) { - dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT, - &port->dev, "add:", ioc->name)); + dsaswideprintk(ioc, dev_printk(KERN_DEBUG, + &port->dev, MYIOC_s_FMT "add:", ioc->name)); dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n", ioc->name, port, port->dev.release)); } @@ -2296,8 +2296,9 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) expander_sas_address) continue; dsaswideprintk(ioc, - dev_printk(MYIOC_s_DEBUG_FMT, &port->dev, - "delete port (%d)\n", ioc->name, port->port_identifier)); + dev_printk(KERN_DEBUG, &port->dev, + MYIOC_s_FMT "delete port (%d)\n", ioc->name, + port->port_identifier)); sas_port_delete(port); mptsas_port_delete(ioc, phy_info->port_details); } @@ -2681,7 +2682,7 @@ mptsas_hotplug_work(struct work_struct *work) printk(MYIOC_s_INFO_FMT "removing %s device, channel %d, id %d, phy %d\n", ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); - dev_printk(MYIOC_s_DEBUG_FMT, &port->dev, + dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT "delete port (%d)\n", ioc->name, port->port_identifier); sas_port_delete(port); mptsas_port_delete(ioc, phy_info->port_details); diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index dc5e996..bdff950 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -992,7 +992,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) scsi_dma_unmap(sc); sc->result = DID_RESET << 16; sc->host_scribble = NULL; - sdev_printk(MYIOC_s_INFO_FMT, sc->device, + sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT "completing cmds: fw_channel %d, fw_id %d, sc=%p," " mf = %p, idx=%x\n", ioc->name, channel, id, sc, mf, ii); sc->scsi_done(sc); @@ -1053,7 +1053,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) scsi_dma_unmap(sc); sc->host_scribble = NULL; sc->result = DID_NO_CONNECT << 16; - sdev_printk(MYIOC_s_INFO_FMT, sc->device, "completing cmds: fw_channel %d," + sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT "completing cmds: fw_channel %d," "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, sc, mf, ii); sc->scsi_done(sc); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 42fdf7d..25bcfcf 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -537,7 +537,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, spi_dev_pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &spi_dev_pg0_dma, GFP_KERNEL); if (spi_dev_pg0 == NULL) { - starget_printk(MYIOC_s_ERR_FMT, starget, + starget_printk(KERN_ERR, starget, MYIOC_s_FMT "dma_alloc_coherent for parameters failed\n", ioc->name); return -EINVAL; } @@ -558,7 +558,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, cfg.pageAddr = starget->id; if (mpt_config(ioc, &cfg)) { - starget_printk(MYIOC_s_ERR_FMT, starget, "mpt_config failed\n", ioc->name); + starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name); goto out_free; } err = 0; @@ -681,7 +681,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, /* If this is a piece of a RAID, then quiesce first */ if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { - starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), + starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT "Integrated RAID quiesce failed\n", ioc->name); return; } @@ -692,7 +692,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) - starget_printk(MYIOC_s_ERR_FMT, scsi_target(sdev), + starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT "Integrated RAID resume failed\n", ioc->name); mptspi_read_parameters(sdev->sdev_target); @@ -856,7 +856,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL); if (pg1 == NULL) { - starget_printk(MYIOC_s_ERR_FMT, starget, + starget_printk(KERN_ERR, starget, MYIOC_s_FMT "dma_alloc_coherent for parameters failed\n", ioc->name); return -EINVAL; } @@ -886,7 +886,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters)); if (mpt_config(ioc, &cfg)) { - starget_printk(MYIOC_s_ERR_FMT, starget, + starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name); goto out_free; } @@ -1104,11 +1104,11 @@ static void mpt_work_wrapper(struct work_struct *work) if(vtarget->id != disk) continue; - starget_printk(MYIOC_s_INFO_FMT, vtarget->starget, + starget_printk(KERN_INFO, vtarget->starget, MYIOC_s_FMT "Integrated RAID requests DV of new device\n", ioc->name); mptspi_dv_device(hd, sdev); } - shost_printk(MYIOC_s_INFO_FMT, shost, + shost_printk(KERN_INFO, shost, MYIOC_s_FMT "Integrated RAID detects new device %d\n", ioc->name, disk); scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1); } @@ -1120,7 +1120,7 @@ static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) MPT_ADAPTER *ioc = hd->ioc; if (!wqw) { - shost_printk(MYIOC_s_ERR_FMT, ioc->sh, + shost_printk(KERN_ERR, ioc->sh, MYIOC_s_FMT "Failed to act on RAID event for physical disk %d\n", ioc->name, disk); return; -- cgit v1.1 From e1fc2b5167f9c3614099e55d3f49763a26a5a339 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:17:49 -0600 Subject: [SCSI] mptlan: bug fix, only half the message frame is dma'd resulting in corruption NB = number of blocks. This represents the number of blocks to transfer. The block size is based on the message frame size provided in the ioc_facts. A value of zero indicates the entire message frame should be copied. This is two bit value. So by setting this to non-zero vaule, you increase performance by reducing amount of data needing to be dma'd. The value that is stored in ioc->ReqeustNB is sometimes a non-zero vaule, which creates a bug in mptlan, where not the entire message frame is getting transfer to firware, resulting in corruption. This fix sets the default to zero, thus entire message frame is copied. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptlan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index b550471..8558322 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1224,6 +1224,8 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) } pRecvReq = (LANReceivePostRequest_t *) mf; + i = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + mpt_dev->RequestNB[i] = 0; count = buckets; if (count > max) count = max; -- cgit v1.1 From ab37128797148edb5993d98b638d668f75ee5119 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 29 Sep 2007 10:22:54 -0600 Subject: [SCSI] mptctl : shutup uninitialized variable warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/message/fusion/mptctl.c: In function ‘mptctl_mpt_command’: drivers/message/fusion/mptctl.c:1764: warning: ‘bufIn.len’ may be used uninitialized in this function drivers/message/fusion/mptctl.c:1765: warning: ‘bufOut.len’ may be used uninitialized in this function come because gcc gets confused by some "goto" statements in above function. The warnings have been verified to be bogus, however, the function does initialize these later (after the offending goto's) in the function anyway. So let's move those initializations to top of function, thereby also shutting up these warnings. Signed-off-by: Eric Moore Signed-off-by: Satyam Sharma Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 70178a8..6029509 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1774,7 +1774,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ulong timeout; struct scsi_device *sdev; + /* bufIn and bufOut are used for user to kernel space transfers + */ bufIn.kptr = bufOut.kptr = NULL; + bufIn.len = bufOut.len = 0; if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || (ioc == NULL)) { @@ -2108,11 +2111,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) psge = (char *) (((int *) mf) + karg.dataSgeOffset); flagsLength = 0; - /* bufIn and bufOut are used for user to kernel space transfers - */ - bufIn.kptr = bufOut.kptr = NULL; - bufIn.len = bufOut.len = 0; - if (karg.dataOutSize > 0) sgSize ++; -- cgit v1.1 From 8bd4578e10f8f7973ae3e8dde66b7bd369b271b8 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 30 Sep 2007 10:03:17 -0400 Subject: [SCSI] aic94xx: fix SSP IU status print-out The SSP response DPRINTK in asd_get_response_tasklet() was printing a hardcoded status result, rather than the status from the SSP response IU. Arguably, this should not be a DPRINTK either, since the admin might want to know about this. Signed-off-by: Jeff Garzik Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_task.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index d5d8cab..4c759ce 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -207,7 +207,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, "stat(0x%x) is not CHECK_CONDITION" "\n", SAS_ADDR(task->dev->sas_addr), - ts->stat); + iu->status); } } } else { -- cgit v1.1 From 50865c1d38e3fbe17a1843582a8e10f2dbbeb6d3 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 30 Sep 2007 23:23:39 -0500 Subject: [SCSI] Update Documentation/scsi/00-INDEX Update Documentation/scsi/00-INDEX to match current files. Signed-off-by: Rob Landley Signed-off-by: James Bottomley --- Documentation/scsi/00-INDEX | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Documentation/scsi/00-INDEX b/Documentation/scsi/00-INDEX index 1235483..aa1f7e9 100644 --- a/Documentation/scsi/00-INDEX +++ b/Documentation/scsi/00-INDEX @@ -2,14 +2,20 @@ - this file 53c700.txt - info on driver for 53c700 based adapters -AM53C974.txt - - info on driver for AM53c974 based adapters BusLogic.txt - info on driver for adapters with BusLogic chips -ChangeLog +ChangeLog.1992-1997 - Changes to scsi files, if not listed elsewhere +ChangeLog.arcmsr + - Changes to driver for ARECA's SATA RAID controller cards ChangeLog.ips - IBM ServeRAID driver Changelog +ChangeLog.lpfc + - Changes to lpfc driver +ChangeLog.megaraid + - Changes to LSI megaraid controller. +ChangeLog.megaraid_sas + - Changes to serial attached scsi version of LSI megaraid controller. ChangeLog.ncr53c8xx - Changes to ncr53c8xx driver ChangeLog.sym53c8xx @@ -20,26 +26,44 @@ FlashPoint.txt - info on driver for BusLogic FlashPoint adapters LICENSE.FlashPoint - Licence of the Flashpoint driver +LICENSE.qla2xxx + - License for QLogic Linux Fibre Channel HBA Driver firmware. Mylex.txt - info on driver for Mylex adapters NinjaSCSI.txt - info on WorkBiT NinjaSCSI-32/32Bi driver +aacraid.txt + - Driver supporting Adaptec RAID controllers aha152x.txt - info on driver for Adaptec AHA152x based adapters +aic79xx.txt + - Adaptec Ultra320 SCSI host adapters aic7xxx.txt - info on driver for Adaptec controllers aic7xxx_old.txt - info on driver for Adaptec controllers, old generation +arcmsr_spec.txt + - ARECA FIRMWARE SPEC (for IOP331 adapter) +dc395x.txt + - README file for the dc395x SCSI driver dpti.txt - info on driver for DPT SmartRAID and Adaptec I2O RAID based adapters dtc3x80.txt - info on driver for DTC 2x80 based adapters g_NCR5380.txt - info on driver for NCR5380 and NCR53c400 based adapters +hptiop.txt + - HIGHPOINT ROCKETRAID 3xxx RAID DRIVER ibmmca.txt - info on driver for IBM adapters with MCA bus in2000.txt - info on in2000 driver +libsas.txt + - Serial Attached SCSI management layer. +lpfc.txt + - LPFC driver release notes +megaraid.txt + - Common Management Module, shared code handling ioctls for LSI drivers ncr53c7xx.txt - info on driver for NCR53c7xx based adapters ncr53c8xx.txt @@ -50,6 +74,8 @@ ppa.txt - info on driver for IOmega zip drive qlogicfas.txt - info on driver for QLogic FASxxx based adapters +scsi-changer.txt + - README for the SCSI media changer driver scsi-generic.txt - info on the sg driver for generic (non-disk/CD/tape) SCSI devices. scsi.txt @@ -58,6 +84,8 @@ scsi_mid_low_api.txt - info on API between SCSI layer and low level drivers scsi_eh.txt - info on SCSI midlayer error handling infrastructure +scsi_fc_transport.txt + - SCSI Fiber Channel Tansport st.txt - info on scsi tape driver sym53c500_cs.txt -- cgit v1.1 From 9ec76fbf7d6da3e98070a7059699d0ca019b0c9b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 1 Oct 2007 08:07:52 -0600 Subject: [SCSI] qlogicpti: Add a slave_configure method By configuring targets in slave_configure, we can eliminate a shadow queuecommand, a shadow scsi_done, a write to the host template, abuse of SCp->Message and SCp->Status, a use of kmap_atomic() and sniffing the results of INQUIRY. Signed-off-by: Matthew Wilcox Acked-by: David S. Miller Signed-off-by: James Bottomley --- drivers/scsi/qlogicpti.c | 171 +++++++---------------------------------------- drivers/scsi/qlogicpti.h | 3 +- 2 files changed, 27 insertions(+), 147 deletions(-) diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 5948872..e93f803 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -310,8 +310,6 @@ static inline void qlogicpti_set_hostdev_defaults(struct qlogicpti *qpti) } qpti->dev_param[i].device_enable = 1; } - /* this is very important to set! */ - qpti->sbits = 1 << qpti->scsi_id; } static int qlogicpti_reset_hardware(struct Scsi_Host *host) @@ -951,153 +949,35 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); } -static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out) +static int qlogicpti_slave_configure(struct scsi_device *sdev) { - unsigned char *buf; - unsigned int buflen; - - if (cmd->use_sg) { - struct scatterlist *sg; + struct qlogicpti *qpti = shost_priv(sdev->host); + int tgt = sdev->id; + u_short param[6]; - sg = (struct scatterlist *) cmd->request_buffer; - buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; - buflen = sg->length; + /* tags handled in midlayer */ + /* enable sync mode? */ + if (sdev->sdtr) { + qpti->dev_param[tgt].device_flags |= 0x10; } else { - buf = cmd->request_buffer; - buflen = cmd->request_bufflen; + qpti->dev_param[tgt].synchronous_offset = 0; + qpti->dev_param[tgt].synchronous_period = 0; } - - *buf_out = buf; - return buflen; -} - -static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf) -{ - if (cmd->use_sg) { - struct scatterlist *sg; - - sg = (struct scatterlist *) cmd->request_buffer; - kunmap_atomic(buf - sg->offset, KM_IRQ0); - } -} - -/* - * Until we scan the entire bus with inquiries, go throught this fella... - */ -static void ourdone(struct scsi_cmnd *Cmnd) -{ - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; - int tgt = Cmnd->device->id; - void (*done) (struct scsi_cmnd *); - - /* This grot added by DaveM, blame him for ugliness. - * The issue is that in the 2.3.x driver we use the - * host_scribble portion of the scsi command as a - * completion linked list at interrupt service time, - * so we have to store the done function pointer elsewhere. - */ - done = (void (*)(struct scsi_cmnd *)) - (((unsigned long) Cmnd->SCp.Message) -#ifdef __sparc_v9__ - | ((unsigned long) Cmnd->SCp.Status << 32UL) -#endif - ); - - if ((qpti->sbits & (1 << tgt)) == 0) { - int ok = host_byte(Cmnd->result) == DID_OK; - if (Cmnd->cmnd[0] == 0x12 && ok) { - unsigned char *iqd; - unsigned int iqd_len; - - iqd_len = scsi_rbuf_get(Cmnd, &iqd); - - /* tags handled in midlayer */ - /* enable sync mode? */ - if (iqd[7] & 0x10) { - qpti->dev_param[tgt].device_flags |= 0x10; - } else { - qpti->dev_param[tgt].synchronous_offset = 0; - qpti->dev_param[tgt].synchronous_period = 0; - } - /* are we wide capable? */ - if (iqd[7] & 0x20) { - qpti->dev_param[tgt].device_flags |= 0x20; - } - - scsi_rbuf_put(Cmnd, iqd); - - qpti->sbits |= (1 << tgt); - } else if (!ok) { - qpti->sbits |= (1 << tgt); - } - } - done(Cmnd); -} - -static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *)); - -static int qlogicpti_queuecommand_slow(struct scsi_cmnd *Cmnd, - void (*done)(struct scsi_cmnd *)) -{ - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; - - /* - * done checking this host adapter? - * If not, then rewrite the command - * to finish through ourdone so we - * can peek at Inquiry data results. - */ - if (qpti->sbits && qpti->sbits != 0xffff) { - /* See above about in ourdone this ugliness... */ - Cmnd->SCp.Message = ((unsigned long)done) & 0xffffffff; -#ifdef CONFIG_SPARC64 - Cmnd->SCp.Status = ((unsigned long)done >> 32UL) & 0xffffffff; -#endif - return qlogicpti_queuecommand(Cmnd, ourdone); - } - - /* - * We've peeked at all targets for this bus- time - * to set parameters for devices for real now. - */ - if (qpti->sbits == 0xffff) { - int i; - for(i = 0; i < MAX_TARGETS; i++) { - u_short param[6]; - param[0] = MBOX_SET_TARGET_PARAMS; - param[1] = (i << 8); - param[2] = (qpti->dev_param[i].device_flags << 8); - if (qpti->dev_param[i].device_flags & 0x10) { - param[3] = (qpti->dev_param[i].synchronous_offset << 8) | - qpti->dev_param[i].synchronous_period; - } else { - param[3] = 0; - } - (void) qlogicpti_mbox_command(qpti, param, 0); - } - /* - * set to zero so any traverse through ourdone - * doesn't start the whole process again, - */ - qpti->sbits = 0; - } - - /* check to see if we're done with all adapters... */ - for (qpti = qptichain; qpti != NULL; qpti = qpti->next) { - if (qpti->sbits) { - break; - } + /* are we wide capable? */ + if (sdev->wdtr) + qpti->dev_param[tgt].device_flags |= 0x20; + + param[0] = MBOX_SET_TARGET_PARAMS; + param[1] = (tgt << 8); + param[2] = (qpti->dev_param[tgt].device_flags << 8); + if (qpti->dev_param[tgt].device_flags & 0x10) { + param[3] = (qpti->dev_param[tgt].synchronous_offset << 8) | + qpti->dev_param[tgt].synchronous_period; + } else { + param[3] = 0; } - - /* - * if we hit the end of the chain w/o finding adapters still - * capability-configuring, then we're done with all adapters - * and can rock on.. - */ - if (qpti == NULL) - Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand; - - return qlogicpti_queuecommand(Cmnd, done); + qlogicpti_mbox_command(qpti, param, 0); + return 0; } /* @@ -1390,7 +1270,8 @@ static struct scsi_host_template qpti_template = { .module = THIS_MODULE, .name = "qlogicpti", .info = qlogicpti_info, - .queuecommand = qlogicpti_queuecommand_slow, + .queuecommand = qlogicpti_queuecommand, + .slave_configure = qlogicpti_slave_configure, .eh_abort_handler = qlogicpti_abort, .eh_bus_reset_handler = qlogicpti_reset, .can_queue = QLOGICPTI_REQ_QUEUE_LEN, diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h index 6cd1c07..ef6da2d 100644 --- a/drivers/scsi/qlogicpti.h +++ b/drivers/scsi/qlogicpti.h @@ -380,8 +380,7 @@ struct qlogicpti { unsigned char swsreg; unsigned int gotirq : 1, /* this instance got an irq */ - is_pti : 1, /* Non-zero if this is a PTI board. */ - sbits : 16; /* syncmode known bits */ + is_pti : 1; /* Non-zero if this is a PTI board. */ }; /* How to twiddle them bits... */ -- cgit v1.1 From 687d2bc4877081a44c41b5b312e012cc69edda53 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 25 Sep 2007 12:42:03 -0400 Subject: [SCSI] gdth: Stop abusing ->done for internal commands The ->done member was being used to mark commands as being internal. I decided to put a magic number in ->underflow instead. I believe this to be safe as no current user of ->underflow has any of the bottom 9 bits set. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 19 +++++++++++-------- drivers/scsi/gdth_proc.c | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index b20c188..317a282 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -692,6 +692,9 @@ static const struct file_operations gdth_fops = { .release = gdth_close, }; +#define GDTH_MAGIC 0xc2e7c389 /* I got it from /dev/urandom */ +#define IS_GDTH_INTERNAL_CMD(scp) (scp->underflow == GDTH_MAGIC) + #include "gdth_proc.h" #include "gdth_proc.c" @@ -715,7 +718,7 @@ static void gdth_scsi_done(struct scsi_cmnd *scp) { TRACE2(("gdth_scsi_done()\n")); - if (scp->request) + if (IS_GDTH_INTERNAL_CMD(scp)) complete((struct completion *)scp->request); } @@ -738,7 +741,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->done = gdth_scsi_done; /* some fn. test this */ + scp->underflow = GDTH_MAGIC; gdth_queuecommand(scp, gdth_scsi_done); wait_for_completion(&wait); @@ -2355,7 +2358,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); - if (scp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(scp)) { scp->SCp.this_residual = (int)priority; b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; t = scp->device->id; @@ -2418,7 +2421,7 @@ static void gdth_next(int hanum) for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - if (nscp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(nscp)) { b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; t = nscp->device->id; @@ -2444,7 +2447,7 @@ static void gdth_next(int hanum) firsttime = FALSE; } - if (nscp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(nscp)) { if (nscp->SCp.phase == -1) { nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ if (nscp->cmnd[0] == TEST_UNIT_READY) { @@ -2507,7 +2510,7 @@ static void gdth_next(int hanum) else nscp->scsi_done(nscp); } - } else if (nscp->done == gdth_scsi_done) { + } else if (IS_GDTH_INTERNAL_CMD(nscp)) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) this_cmd = FALSE; next_cmd = FALSE; @@ -3848,7 +3851,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) scp->sense_buffer[2] = NOT_READY; scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); } - if (scp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(scp)) { ha->dvr.size = sizeof(ha->dvr.eu.sync); ha->dvr.eu.sync.ionode = hanum; ha->dvr.eu.sync.service = service; @@ -4945,7 +4948,7 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) #endif priority = DEFAULT_PRI; - if (scp->done == gdth_scsi_done) + if (IS_GDTH_INTERNAL_CMD(scp)) priority = scp->SCp.this_residual; else gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 32982eb..1f8d9a5 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -805,7 +805,7 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (scp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(scp)) { b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; @@ -829,7 +829,7 @@ static void gdth_start_timeout(int hanum, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (scp->done != gdth_scsi_done) { + if (!IS_GDTH_INTERNAL_CMD(scp)) { b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -- cgit v1.1 From 6f5391c283d7fdcf24bf40786ea79061919d1e1d Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 25 Sep 2007 12:42:04 -0400 Subject: [SCSI] Get rid of scsi_cmnd->done The ULD ->done callback moves into the scsi_driver. By moving the call to scsi_io_completion() from scsi_blk_pc_done() to scsi_finish_command(), we can eliminate the latter entirely. By returning 'good_bytes' from the ->done callback (rather than invoking scsi_io_completion()), we can stop exporting scsi_io_completion(). Also move the prototypes from sd.h to sd.c as they're all internal anyway. Rename sd_rw_intr to sd_done and rw_intr to sr_done. Inspired-by: Christoph Hellwig Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi.c | 20 +++++++++++++++++--- drivers/scsi/scsi_error.c | 1 - drivers/scsi/scsi_lib.c | 14 -------------- drivers/scsi/scsi_priv.h | 1 + drivers/scsi/sd.c | 28 ++++++++++++++++++---------- drivers/scsi/sr.c | 21 ++++++--------------- include/scsi/scsi_cmnd.h | 2 -- include/scsi/scsi_driver.h | 1 + include/scsi/sd.h | 13 ------------- 9 files changed, 43 insertions(+), 58 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 07a7c2a..1929488 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -367,9 +368,8 @@ void scsi_log_send(struct scsi_cmnd *cmd) scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," - " done = 0x%p, queuecommand 0x%p\n", + " queuecommand 0x%p\n", scsi_sglist(cmd), scsi_bufflen(cmd), - cmd->done, cmd->device->host->hostt->queuecommand); } @@ -654,6 +654,12 @@ void __scsi_done(struct scsi_cmnd *cmd) blk_complete_request(rq); } +/* Move this to a header if it becomes more generally useful */ +static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) +{ + return *(struct scsi_driver **)cmd->request->rq_disk->private_data; +} + /* * Function: scsi_finish_command * @@ -665,6 +671,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct Scsi_Host *shost = sdev->host; + struct scsi_driver *drv; + unsigned int good_bytes; scsi_device_unbusy(sdev); @@ -690,7 +698,13 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); - cmd->done(cmd); + good_bytes = cmd->request_bufflen; + if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { + drv = scsi_cmd_to_driver(cmd); + if (drv->done) + good_bytes = drv->done(cmd); + } + scsi_io_completion(cmd, good_bytes); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 44e6721..f49feb9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1671,7 +1671,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); scmd->scsi_done = scsi_reset_provider_done_command; - scmd->done = NULL; scmd->request_buffer = NULL; scmd->request_bufflen = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 86fd3ab..fac3429 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -982,7 +982,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } scsi_end_request(cmd, 0, this_count, !result); } -EXPORT_SYMBOL(scsi_io_completion); /* * Function: scsi_init_io() @@ -1063,18 +1062,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, return cmd; } -static void scsi_blk_pc_done(struct scsi_cmnd *cmd) -{ - BUG_ON(!blk_pc_request(cmd->request)); - /* - * This will complete the whole command with uptodate=1 so - * as far as the block layer is concerned the command completed - * successfully. Since this is a REQ_BLOCK_PC command the - * caller should check the request's errors value - */ - scsi_io_completion(cmd, cmd->request_bufflen); -} - int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; @@ -1124,7 +1111,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) cmd->transfersize = req->data_len; cmd->allowed = req->retries; cmd->timeout_per_command = req->timeout; - cmd->done = scsi_blk_pc_done; return BLKPREP_OK; } EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index ee8efe8..eff0059 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -68,6 +68,7 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); extern void scsi_device_unbusy(struct scsi_device *sdev); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern void scsi_next_command(struct scsi_cmnd *cmd); +extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_run_host_queues(struct Scsi_Host *shost); extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); extern void scsi_free_queue(struct request_queue *q); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 38a4141..0a3a528 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -86,6 +86,19 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); +static int sd_revalidate_disk(struct gendisk *); +static int sd_probe(struct device *); +static int sd_remove(struct device *); +static void sd_shutdown(struct device *); +static int sd_suspend(struct device *, pm_message_t state); +static int sd_resume(struct device *); +static void sd_rescan(struct device *); +static int sd_done(struct scsi_cmnd *); +static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); +static void scsi_disk_release(struct class_device *cdev); +static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); +static void sd_print_result(struct scsi_disk *, int); + static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -240,6 +253,7 @@ static struct scsi_driver sd_template = { .shutdown = sd_shutdown, }, .rescan = sd_rescan, + .done = sd_done, }; /* @@ -509,12 +523,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* - * This is the completion routine we use. This is matched in terms - * of capability to this function. - */ - SCpnt->done = sd_rw_intr; - - /* * This indicates that the command is ready from our end to be * queued. */ @@ -908,13 +916,13 @@ static struct block_device_operations sd_fops = { }; /** - * sd_rw_intr - bottom half handler: called when the lower level + * sd_done - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. * @SCpnt: mid-level's per command structure. * * Note: potentially run from within an ISR. Must not block. **/ -static void sd_rw_intr(struct scsi_cmnd * SCpnt) +static int sd_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; unsigned int xfer_size = SCpnt->request_bufflen; @@ -935,7 +943,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); if (sense_valid) { SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_rw_intr: sb[respc,sk,asc," + "sd_done: sb[respc,sk,asc," "ascq]=%x,%x,%x,%x\n", sshdr.response_code, sshdr.sense_key, sshdr.asc, @@ -1007,7 +1015,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) break; } out: - scsi_io_completion(SCpnt, good_bytes); + return good_bytes; } static int media_not_present(struct scsi_disk *sdkp, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index a0c4e13..c619990 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -78,6 +78,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); static int sr_probe(struct device *); static int sr_remove(struct device *); +static int sr_done(struct scsi_cmnd *); static struct scsi_driver sr_template = { .owner = THIS_MODULE, @@ -86,6 +87,7 @@ static struct scsi_driver sr_template = { .probe = sr_probe, .remove = sr_remove, }, + .done = sr_done, }; static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; @@ -208,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) } /* - * rw_intr is the interrupt routine for the device driver. + * sr_done is the interrupt routine for the device driver. * - * It will be notified on the end of a SCSI read / write, and will take on + * It will be notified on the end of a SCSI read / write, and will take one * of several actions based on success or failure. */ -static void rw_intr(struct scsi_cmnd * SCpnt) +static int sr_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; int this_count = SCpnt->request_bufflen; @@ -286,12 +288,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) } } - /* - * This calls the generic completion function, now that we know - * how many actual sectors finished, and how many sectors we need - * to say have failed. - */ - scsi_io_completion(SCpnt, good_bytes); + return good_bytes; } static int sr_prep_fn(struct request_queue *q, struct request *rq) @@ -428,12 +425,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) SCpnt->timeout_per_command = timeout; /* - * This is the completion routine we use. This is matched in terms - * of capability to this function. - */ - SCpnt->done = rw_intr; - - /* * This indicates that the command is ready from our end to be * queued. */ diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 4fddef7..65ab514 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -33,7 +33,6 @@ struct scsi_cmnd { struct list_head list; /* scsi_cmnd participates in queue lists */ struct list_head eh_entry; /* entry for the host eh_cmd_q */ int eh_eflags; /* Used by error handlr */ - void (*done) (struct scsi_cmnd *); /* Mid-level done function */ /* * A SCSI Command is assigned a nonzero serial_number before passed @@ -121,7 +120,6 @@ extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, struct device *); -extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 56a3047..1f5ca7f 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -15,6 +15,7 @@ struct scsi_driver { struct device_driver gendrv; void (*rescan)(struct device *); + int (*done)(struct scsi_cmnd *); }; #define to_scsi_driver(drv) \ container_of((drv), struct scsi_driver, gendrv) diff --git a/include/scsi/sd.h b/include/scsi/sd.h index aa1e716..f751331 100644 --- a/include/scsi/sd.h +++ b/include/scsi/sd.h @@ -47,19 +47,6 @@ struct scsi_disk { }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) -static int sd_revalidate_disk(struct gendisk *disk); -static void sd_rw_intr(struct scsi_cmnd * SCpnt); -static int sd_probe(struct device *); -static int sd_remove(struct device *); -static void sd_shutdown(struct device *dev); -static int sd_suspend(struct device *dev, pm_message_t state); -static int sd_resume(struct device *dev); -static void sd_rescan(struct device *); -static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); -static void scsi_disk_release(struct class_device *cdev); -static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -static void sd_print_result(struct scsi_disk *, int); - #define sd_printk(prefix, sdsk, fmt, a...) \ (sdsk)->disk ? \ sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ -- cgit v1.1 From 512193588db0d38ae6aa78802bb15f3ef3104a00 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:22 -0400 Subject: [SCSI] advansys: Eliminate prototypes Rearrange a lot of the functions in the file to get rid of all the forward declarations. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 17795 +++++++++++++++++++++++----------------------- 1 file changed, 8804 insertions(+), 8991 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 0303fc7..4f047cc 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -878,7 +878,6 @@ typedef struct asceep_config { #define ASC_1000_ID0W_FIX 0x00C1 #define ASC_1000_ID1B 0x25 #define ASC_EISA_REV_IOP_MASK (0x0C83) -#define ASC_EISA_PID_IOP_MASK (0x0C80) #define ASC_EISA_CFG_IOP_MASK (0x0C86) #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) #define INS_HALTINT (ushort)0x6281 @@ -903,10 +902,10 @@ typedef struct asc_mc_saved { #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B) #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val) #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val) -#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)); -#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)); -#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data); -#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)); +#define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) +#define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) +#define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) +#define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) @@ -962,83 +961,6 @@ typedef struct asc_mc_saved { #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) -static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg); -static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg); -static void AscWaitEEPRead(void); -static void AscWaitEEPWrite(void); -static ushort AscReadEEPWord(PortAddr, uchar); -static ushort AscWriteEEPWord(PortAddr, uchar, ushort); -static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); -static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort); -static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); -static int AscStartChip(PortAddr); -static int AscStopChip(PortAddr); -static void AscSetChipIH(PortAddr, ushort); -static int AscIsChipHalted(PortAddr); -static void AscAckInterrupt(PortAddr); -static void AscDisableInterrupt(PortAddr); -static void AscEnableInterrupt(PortAddr); -static void AscSetBank(PortAddr, uchar); -static int AscResetChipAndScsiBus(ASC_DVC_VAR *); -#ifdef CONFIG_ISA -static uchar AscGetIsaDmaSpeed(PortAddr); -#endif /* CONFIG_ISA */ -static uchar AscReadLramByte(PortAddr, ushort); -static ushort AscReadLramWord(PortAddr, ushort); -#if CC_VERY_LONG_SG_LIST -static ASC_DCNT AscReadLramDWord(PortAddr, ushort); -#endif /* CC_VERY_LONG_SG_LIST */ -static void AscWriteLramWord(PortAddr, ushort, ushort); -static void AscWriteLramByte(PortAddr, ushort, uchar); -static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int); -static void AscMemWordSetLram(PortAddr, ushort, ushort, int); -static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int); -static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int); -static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int); -static ushort AscInitAscDvcVar(ASC_DVC_VAR *); -static ushort AscInitFromEEP(ASC_DVC_VAR *); -static ushort AscInitMicroCodeVar(ASC_DVC_VAR *); -static int AscTestExternalLram(ASC_DVC_VAR *); -static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar); -static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar); -static void AscSetChipSDTR(PortAddr, uchar, uchar); -static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar); -static uchar AscAllocFreeQueue(PortAddr, uchar); -static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar); -static int AscHostReqRiscHalt(PortAddr); -static int AscStopQueueExe(PortAddr); -static int AscSendScsiQueue(ASC_DVC_VAR *, - ASC_SCSI_Q *scsiq, uchar n_q_required); -static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar); -static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar); -static int AscSetChipSynRegAtID(PortAddr, uchar, uchar); -static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar); -static ushort AscInitLram(ASC_DVC_VAR *); -static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort); -static int AscIsrChipHalted(ASC_DVC_VAR *); -static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, - ASC_QDONE_INFO *, ASC_DCNT); -static int AscIsrQDone(ASC_DVC_VAR *); -#ifdef CONFIG_ISA -static ushort AscGetEisaChipCfg(PortAddr); -#endif /* CONFIG_ISA */ -static uchar AscGetChipScsiCtrl(PortAddr); -static uchar AscGetChipVersion(PortAddr, ushort); -static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort); -static void AscToggleIRQAct(PortAddr); -static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); -static void DvcGetQinfo(PortAddr, ushort, uchar *, int); -static ushort AscInitAsc1000Driver(ASC_DVC_VAR *); -static void AscAsyncFix(ASC_DVC_VAR *, struct scsi_device *); -static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *); -static int AscISR(ASC_DVC_VAR *); -static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar); -static int AscSgListToQueue(int); -#ifdef CONFIG_ISA -static void AscEnableIsaDma(uchar); -#endif /* CONFIG_ISA */ -static const char *advansys_info(struct Scsi_Host *shost); - #define ADV_LIB_VERSION_MAJOR 5 #define ADV_LIB_VERSION_MINOR 14 @@ -2109,36 +2031,6 @@ typedef struct adv_scsi_req_q { #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ -static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, - uchar *, ASC_SDCNT *, int); - -/* - * Adv Library functions available to drivers. - */ -static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); -static int AdvISR(ADV_DVC_VAR *); -static int AdvInitAsc3550Driver(ADV_DVC_VAR *); -static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *); -static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *); -static int AdvResetChipAndSB(ADV_DVC_VAR *); -static int AdvResetSB(ADV_DVC_VAR *asc_dvc); - -/* - * Internal Adv Library functions. - */ -static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT); -static int AdvInitFrom3550EEP(ADV_DVC_VAR *); -static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *); -static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *); -static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); -static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); -static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); -static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); -static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); -static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); -static void AdvWaitEEPCmd(AdvPortAddr); -static ushort AdvReadEEPWord(AdvPortAddr, int); - /* Read byte from a register. */ #define AdvReadByteRegister(iop_base, reg_off) \ (ADV_MEM_READB((iop_base) + (reg_off))) @@ -2676,1721 +2568,1373 @@ static ASC_SG_HEAD asc_sg_head = { 0 }; #ifdef ADVANSYS_DEBUG static int asc_dbglvl = 3; -#endif /* ADVANSYS_DEBUG */ - -static int advansys_slave_configure(struct scsi_device *); -static int asc_execute_scsi_cmnd(struct scsi_cmnd *); -static int asc_build_req(asc_board_t *, struct scsi_cmnd *); -static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); -static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); -#ifdef CONFIG_PROC_FS -static int asc_proc_copy(off_t, off_t, char *, int, char *, int); -static int asc_prt_board_devices(struct Scsi_Host *, char *, int); -static int asc_prt_adv_bios(struct Scsi_Host *, char *, int); -static int asc_get_eeprom_string(ushort *serialnum, uchar *cp); -static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int); -static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int); -static int asc_prt_driver_conf(struct Scsi_Host *, char *, int); -static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int); -static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int); -static int asc_prt_line(char *, int, char *fmt, ...); -#endif /* CONFIG_PROC_FS */ - -/* Statistics function prototypes. */ -#ifdef ADVANSYS_STATS -#ifdef CONFIG_PROC_FS -static int asc_prt_board_stats(struct Scsi_Host *, char *, int); -#endif /* CONFIG_PROC_FS */ -#endif /* ADVANSYS_STATS */ - -/* Debug function prototypes. */ -#ifdef ADVANSYS_DEBUG -static void asc_prt_scsi_host(struct Scsi_Host *); -static void asc_prt_scsi_cmnd(struct scsi_cmnd *); -static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *); -static void asc_prt_asc_dvc_var(ASC_DVC_VAR *); -static void asc_prt_asc_scsi_q(ASC_SCSI_Q *); -static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *); -static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *); -static void asc_prt_adv_dvc_var(ADV_DVC_VAR *); -static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *); -static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *); -static void asc_prt_hex(char *f, uchar *, int); -#endif /* ADVANSYS_DEBUG */ -#ifdef CONFIG_PROC_FS /* - * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...} - * - * *buffer: I/O buffer - * **start: if inout == FALSE pointer into buffer where user read should start - * offset: current offset into a /proc/scsi/advansys/[0...] file - * length: length of buffer - * hostno: Scsi_Host host_no - * inout: TRUE - user is writing; FALSE - user is reading - * - * Return the number of bytes read from or written to a - * /proc/scsi/advansys/[0...] file. - * - * Note: This function uses the per board buffer 'prtbuf' which is - * allocated when the board is initialized in advansys_detect(). The - * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is - * used to write to the buffer. The way asc_proc_copy() is written - * if 'prtbuf' is too small it will not be overwritten. Instead the - * user just won't get all the available statistics. + * asc_prt_scsi_host() */ -static int -advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, - off_t offset, int length, int inout) +static void asc_prt_scsi_host(struct Scsi_Host *s) { asc_board_t *boardp; - char *cp; - int cplen; - int cnt; - int totcnt; - int leftlen; - char *curbuf; - off_t advoffset; - ASC_DBG(1, "advansys_proc_info: begin\n"); + boardp = ASC_BOARDP(s); - /* - * User write not supported. - */ - if (inout == TRUE) { - return (-ENOSYS); - } + printk("Scsi_Host at addr 0x%lx\n", (ulong)s); + printk(" host_busy %u, host_no %d, last_reset %d,\n", + s->host_busy, s->host_no, (unsigned)s->last_reset); - /* - * User read of /proc/scsi/advansys/[0...] file. - */ + printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", + (ulong)s->base, (ulong)s->io_port, s->irq); - boardp = ASC_BOARDP(shost); + printk(" dma_channel %d, this_id %d, can_queue %d,\n", + s->dma_channel, s->this_id, s->can_queue); - /* Copy read data starting at the beginning of the buffer. */ - *start = buffer; - curbuf = buffer; - advoffset = 0; - totcnt = 0; - leftlen = length; + printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", + s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); - /* - * Get board configuration information. - * - * advansys_info() returns the board string from its own static buffer. - */ - cp = (char *)advansys_info(shost); - strcat(cp, "\n"); - cplen = strlen(cp); - /* Copy board information. */ - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; + if (ASC_NARROW_BOARD(boardp)) { + asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); + asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); + } else { + asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); + asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); } - advoffset += cplen; - curbuf += cnt; +} - /* - * Display Wide Board BIOS Information. - */ - if (ASC_WIDE_BOARD(boardp)) { - cp = boardp->prtbuf; - cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, - cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; - } +/* + * asc_prt_scsi_cmnd() + */ +static void asc_prt_scsi_cmnd(struct scsi_cmnd *s) +{ + printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s); - /* - * Display driver information for each device attached to the board. - */ - cp = boardp->prtbuf; - cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", + (ulong)s->device->host, (ulong)s->device, s->device->id, + s->device->lun, s->device->channel); - /* - * Display EEPROM configuration for the board. - */ - cp = boardp->prtbuf; - if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); - } else { - cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); - } - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + asc_prt_hex(" CDB", s->cmnd, s->cmd_len); - /* - * Display driver configuration and information for the board. - */ - cp = boardp->prtbuf; - cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + printk("sc_data_direction %u, resid %d\n", + s->sc_data_direction, s->resid); -#ifdef ADVANSYS_STATS - /* - * Display driver statistics for the board. - */ - cp = boardp->prtbuf; - cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; -#endif /* ADVANSYS_STATS */ + printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len); - /* - * Display Asc Library dynamic configuration information - * for the board. - */ - cp = boardp->prtbuf; - if (ASC_NARROW_BOARD(boardp)) { - cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE); - } else { - cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); - } - BUG_ON(cplen >= ASC_PRTBUF_SIZE); - cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); - totcnt += cnt; - leftlen -= cnt; - if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - return totcnt; - } - advoffset += cplen; - curbuf += cnt; + printk(" serial_number 0x%x, retries %d, allowed %d\n", + (unsigned)s->serial_number, s->retries, s->allowed); - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + printk(" timeout_per_command %d\n", s->timeout_per_command); - return totcnt; + printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n", + s->scsi_done, s->done, s->host_scribble, s->result); + + printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid); } -#endif /* CONFIG_PROC_FS */ /* - * advansys_info() - * - * Return suitable for printing on the console with the argument - * adapter's configuration information. - * - * Note: The information line should not exceed ASC_INFO_SIZE bytes, - * otherwise the static 'info' array will be overrun. + * asc_prt_asc_dvc_var() */ -static const char *advansys_info(struct Scsi_Host *shost) +static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) { - static char info[ASC_INFO_SIZE]; - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; - ADV_DVC_VAR *adv_dvc_varp; - char *busname; - char *widename = NULL; + printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h); - boardp = ASC_BOARDP(shost); - if (ASC_NARROW_BOARD(boardp)) { - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; - ASC_DBG(1, "advansys_info: begin\n"); - if (asc_dvc_varp->bus_type & ASC_IS_ISA) { - if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == - ASC_IS_ISAPNP) { - busname = "ISA PnP"; - } else { - busname = "ISA"; - } - sprintf(info, - "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", - ASC_VERSION, busname, - (ulong)shost->io_port, - (ulong)shost->io_port + ASC_IOADR_GAP - 1, - shost->irq, shost->dma_channel); - } else { - if (asc_dvc_varp->bus_type & ASC_IS_VL) { - busname = "VL"; - } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { - busname = "EISA"; - } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { - if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) - == ASC_IS_PCI_ULTRA) { - busname = "PCI Ultra"; - } else { - busname = "PCI"; - } - } else { - busname = "?"; - ASC_PRINT2("advansys_info: board %d: unknown " - "bus type %d\n", boardp->id, - asc_dvc_varp->bus_type); - } - sprintf(info, - "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", - ASC_VERSION, busname, (ulong)shost->io_port, - (ulong)shost->io_port + ASC_IOADR_GAP - 1, - shost->irq); - } - } else { - /* - * Wide Adapter Information - * - * Memory-mapped I/O is used instead of I/O space to access - * the adapter, but display the I/O Port range. The Memory - * I/O address is displayed through the driver /proc file. - */ - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - widename = "Ultra-Wide"; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - widename = "Ultra2-Wide"; - } else { - widename = "Ultra3-Wide"; - } - sprintf(info, - "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", - ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, - (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); - } - BUG_ON(strlen(info) >= ASC_INFO_SIZE); - ASC_DBG(1, "advansys_info: end\n"); - return info; + printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl " + "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); + + printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type, + (unsigned)h->init_sdtr); + + printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, " + "chip_no 0x%x,\n", (unsigned)h->sdtr_done, + (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready, + (unsigned)h->chip_no); + + printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait " + "%u,\n", (unsigned)h->queue_full_or_busy, + (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); + + printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, " + "in_critical_cnt %u,\n", (unsigned)h->is_in_int, + (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng, + (unsigned)h->in_critical_cnt); + + printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, " + "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage, + (unsigned)h->init_state, (unsigned)h->no_scam, + (unsigned)h->pci_fix_asyn_xfer); + + printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); } -static void asc_scsi_done(struct scsi_cmnd *scp) +/* + * asc_prt_asc_dvc_cfg() + */ +static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) { - struct asc_board *boardp = ASC_BOARDP(scp->device->host); + printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h); - if (scp->use_sg) - dma_unmap_sg(boardp->dev, - (struct scatterlist *)scp->request_buffer, - scp->use_sg, scp->sc_data_direction); - else if (scp->request_bufflen) - dma_unmap_single(boardp->dev, scp->SCp.dma_handle, - scp->request_bufflen, scp->sc_data_direction); + printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n", + h->can_tagged_qng, h->cmd_qng_enabled); + printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n", + h->disc_enable, h->sdtr_enable); - ASC_STATS(scp->device->host, done); + printk + (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", + h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, + h->chip_version); - scp->scsi_done(scp); + printk + (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", + to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, + h->mcode_date); + + printk(" mcode_version %d, overrun_buf 0x%lx\n", + h->mcode_version, (ulong)h->overrun_buf); } /* - * advansys_queuecommand() - interrupt-driven I/O entrypoint. - * - * This function always returns 0. Command return status is saved - * in the 'scp' result field. + * asc_prt_asc_scsi_q() */ -static int -advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) { - struct Scsi_Host *shost = scp->device->host; - asc_board_t *boardp = ASC_BOARDP(shost); - unsigned long flags; - int asc_res, result = 0; + ASC_SG_HEAD *sgp; + int i; - ASC_STATS(shost, queuecommand); - scp->scsi_done = done; + printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); - /* - * host_lock taken by mid-level prior to call, but need - * to protect against own ISR - */ - spin_lock_irqsave(&boardp->lock, flags); - asc_res = asc_execute_scsi_cmnd(scp); - spin_unlock_irqrestore(&boardp->lock, flags); + printk + (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", + q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, + q->q2.tag_code); + + printk + (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", + (ulong)le32_to_cpu(q->q1.data_addr), + (ulong)le32_to_cpu(q->q1.data_cnt), + (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); + + printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", + (ulong)q->cdbptr, q->q2.cdb_len, + (ulong)q->sg_head, q->q1.sg_queue_cnt); + + if (q->sg_head) { + sgp = q->sg_head; + printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); + printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, + sgp->queue_cnt); + for (i = 0; i < sgp->entry_cnt; i++) { + printk(" [%u]: addr 0x%lx, bytes %lu\n", + i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), + (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); + } - switch (asc_res) { - case ASC_NOERROR: - break; - case ASC_BUSY: - result = SCSI_MLQUEUE_HOST_BUSY; - break; - case ASC_ERROR: - default: - asc_scsi_done(scp); - break; } +} - return result; +/* + * asc_prt_asc_qdone_info() + */ +static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) +{ + printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); + printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", + (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, + q->d2.tag_code); + printk + (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", + q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); } /* - * advansys_reset() - * - * Reset the bus associated with the command 'scp'. + * asc_prt_adv_dvc_var() * - * This function runs its own thread. Interrupts must be blocked but - * sleeping is allowed and no locking other than for host structures is - * required. Returns SUCCESS or FAILED. + * Display an ADV_DVC_VAR structure. */ -static int advansys_reset(struct scsi_cmnd *scp) +static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) { - struct Scsi_Host *shost; - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; - ADV_DVC_VAR *adv_dvc_varp; - ulong flags; - int status; - int ret = SUCCESS; + printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h); - ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp); + printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", + (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able); -#ifdef ADVANSYS_STATS - if (scp->device->host != NULL) { - ASC_STATS(scp->device->host, reset); - } -#endif /* ADVANSYS_STATS */ + printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n", + (ulong)h->isr_callback, (unsigned)h->sdtr_able, + (unsigned)h->wdtr_able); - if ((shost = scp->device->host) == NULL) { - scp->result = HOST_BYTE(DID_ERROR); - return FAILED; - } + printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", + (unsigned)h->start_motor, + (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no); - boardp = ASC_BOARDP(shost); + printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", + (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, + (ulong)h->carr_freelist); - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n", - boardp->id); - /* - * Check for re-entrancy. - */ - spin_lock_irqsave(&boardp->lock, flags); - if (boardp->flags & ASC_HOST_IN_RESET) { - spin_unlock_irqrestore(&boardp->lock, flags); - return FAILED; - } - boardp->flags |= ASC_HOST_IN_RESET; - spin_unlock_irqrestore(&boardp->lock, flags); + printk(" icq_sp 0x%lx, irq_sp 0x%lx\n", + (ulong)h->icq_sp, (ulong)h->irq_sp); - if (ASC_NARROW_BOARD(boardp)) { - /* - * Narrow Board - */ - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + printk(" no_scam 0x%x, tagqng_able 0x%x\n", + (unsigned)h->no_scam, (unsigned)h->tagqng_able); - /* - * Reset the chip and SCSI bus. - */ - ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); - status = AscInitAsc1000Driver(asc_dvc_varp); - - /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ - if (asc_dvc_varp->err_code) { - ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " - "error: 0x%x\n", boardp->id, - asc_dvc_varp->err_code); - ret = FAILED; - } else if (status) { - ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " - "warning: 0x%x\n", boardp->id, status); - } else { - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "successful.\n", boardp->id); - } - - ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); - spin_lock_irqsave(&boardp->lock, flags); - - } else { - /* - * Wide Board - * - * If the suggest reset bus flags are set, then reset the bus. - * Otherwise only reset the device. - */ - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + printk(" chip_scsi_id 0x%x, cfg 0x%lx\n", + (unsigned)h->chip_scsi_id, (ulong)h->cfg); +} - /* - * Reset the target's SCSI bus. - */ - ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); - switch (AdvResetChipAndSB(adv_dvc_varp)) { - case ASC_TRUE: - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "successful.\n", boardp->id); - break; - case ASC_FALSE: - default: - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "error.\n", boardp->id); - ret = FAILED; - break; - } - spin_lock_irqsave(&boardp->lock, flags); - (void)AdvISR(adv_dvc_varp); - } - /* Board lock is held. */ +/* + * asc_prt_adv_dvc_cfg() + * + * Display an ADV_DVC_CFG structure. + */ +static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) +{ + printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h); - /* Save the time of the most recently completed reset. */ - boardp->last_reset = jiffies; + printk(" disc_enable 0x%x, termination 0x%x\n", + h->disc_enable, h->termination); - /* Clear reset flag. */ - boardp->flags &= ~ASC_HOST_IN_RESET; - spin_unlock_irqrestore(&boardp->lock, flags); + printk(" chip_version 0x%x, mcode_date 0x%x\n", + h->chip_version, h->mcode_date); - ASC_DBG1(1, "advansys_reset: ret %d\n", ret); + printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", + h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); - return ret; + printk(" control_flag 0x%x\n", h->control_flag); } /* - * advansys_biosparam() - * - * Translate disk drive geometry if the "BIOS greater than 1 GB" - * support is enabled for a drive. + * asc_prt_adv_scsi_req_q() * - * ip (information pointer) is an int array with the following definition: - * ip[0]: heads - * ip[1]: sectors - * ip[2]: cylinders + * Display an ADV_SCSI_REQ_Q structure. */ -static int -advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int ip[]) +static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) { - asc_board_t *boardp; + int sg_blk_cnt; + struct asc_sg_block *sg_ptr; - ASC_DBG(1, "advansys_biosparam: begin\n"); - ASC_STATS(sdev->host, biosparam); - boardp = ASC_BOARDP(sdev->host); - if (ASC_NARROW_BOARD(boardp)) { - if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & - ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { - ip[0] = 255; - ip[1] = 63; - } else { - ip[0] = 64; - ip[1] = 32; - } - } else { - if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & - BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) { - ip[0] = 255; - ip[1] = 63; - } else { - ip[0] = 64; - ip[1] = 32; + printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); + + printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", + q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); + + printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", + q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); + + printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", + (ulong)le32_to_cpu(q->data_cnt), + (ulong)le32_to_cpu(q->sense_addr), q->sense_len); + + printk + (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", + q->cdb_len, q->done_status, q->host_status, q->scsi_status); + + printk(" sg_working_ix 0x%x, target_cmd %u\n", + q->sg_working_ix, q->target_cmd); + + printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", + (ulong)le32_to_cpu(q->scsiq_rptr), + (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); + + /* Display the request's ADV_SG_BLOCK structures. */ + if (q->sg_list_ptr != NULL) { + sg_blk_cnt = 0; + while (1) { + /* + * 'sg_ptr' is a physical address. Convert it to a virtual + * address by indexing 'sg_blk_cnt' into the virtual address + * array 'sg_list_ptr'. + * + * XXX - Assumes all SG physical blocks are virtually contiguous. + */ + sg_ptr = + &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); + asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); + if (sg_ptr->sg_ptr == 0) { + break; + } + sg_blk_cnt++; } } - ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); - ASC_DBG(1, "advansys_biosparam: end\n"); - return 0; } -static struct scsi_host_template advansys_template = { - .proc_name = DRV_NAME, -#ifdef CONFIG_PROC_FS - .proc_info = advansys_proc_info, -#endif - .name = DRV_NAME, - .info = advansys_info, - .queuecommand = advansys_queuecommand, - .eh_bus_reset_handler = advansys_reset, - .bios_param = advansys_biosparam, - .slave_configure = advansys_slave_configure, - /* - * Because the driver may control an ISA adapter 'unchecked_isa_dma' - * must be set. The flag will be cleared in advansys_board_found - * for non-ISA adapters. - */ - .unchecked_isa_dma = 1, - /* - * All adapters controlled by this driver are capable of large - * scatter-gather lists. According to the mid-level SCSI documentation - * this obviates any performance gain provided by setting - * 'use_clustering'. But empirically while CPU utilization is increased - * by enabling clustering, I/O throughput increases as well. - */ - .use_clustering = ENABLE_CLUSTERING, -}; - /* - * First-level interrupt handler. + * asc_prt_adv_sgblock() * - * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host. + * Display an ADV_SG_BLOCK structure. */ -static irqreturn_t advansys_interrupt(int irq, void *dev_id) +static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) { - unsigned long flags; - struct Scsi_Host *shost = dev_id; - asc_board_t *boardp = ASC_BOARDP(shost); - irqreturn_t result = IRQ_NONE; + int i; - ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); - spin_lock_irqsave(&boardp->lock, flags); - if (ASC_NARROW_BOARD(boardp)) { - if (AscIsIntPending(shost->io_port)) { - result = IRQ_HANDLED; - ASC_STATS(shost, interrupt); - ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); - AscISR(&boardp->dvc_var.asc_dvc_var); - } - } else { - ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); - if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { - result = IRQ_HANDLED; - ASC_STATS(shost, interrupt); - } + printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", + (ulong)b, sgblockno); + printk(" sg_cnt %u, sg_ptr 0x%lx\n", + b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); + BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); + if (b->sg_ptr != 0) + BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); + for (i = 0; i < b->sg_cnt; i++) { + printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", + i, (ulong)b->sg_list[i].sg_addr, + (ulong)b->sg_list[i].sg_count); } - spin_unlock_irqrestore(&boardp->lock, flags); - - ASC_DBG(1, "advansys_interrupt: end\n"); - return result; } -static void -advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc) +/* + * asc_prt_hex() + * + * Print hexadecimal output in 4 byte groupings 32 bytes + * or 8 double-words per line. + */ +static void asc_prt_hex(char *f, uchar *s, int l) { - ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id; - ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng; + int i; + int j; + int k; + int m; - if (sdev->lun == 0) { - ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr; - if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) { - asc_dvc->init_sdtr |= tid_bit; + printk("%s: (%d bytes)\n", f, l); + + for (i = 0; i < l; i += 32) { + + /* Display a maximum of 8 double-words per line. */ + if ((k = (l - i) / 4) >= 8) { + k = 8; + m = 0; } else { - asc_dvc->init_sdtr &= ~tid_bit; + m = (l - i) % 4; } - if (orig_init_sdtr != asc_dvc->init_sdtr) - AscAsyncFix(asc_dvc, sdev); - } - - if (sdev->tagged_supported) { - if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) { - if (sdev->lun == 0) { - asc_dvc->cfg->can_tagged_qng |= tid_bit; - asc_dvc->use_tagged_qng |= tid_bit; - } - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - asc_dvc->max_dvc_qng[sdev->id]); - } - } else { - if (sdev->lun == 0) { - asc_dvc->cfg->can_tagged_qng &= ~tid_bit; - asc_dvc->use_tagged_qng &= ~tid_bit; + for (j = 0; j < k; j++) { + printk(" %2.2X%2.2X%2.2X%2.2X", + (unsigned)s[i + (j * 4)], + (unsigned)s[i + (j * 4) + 1], + (unsigned)s[i + (j * 4) + 2], + (unsigned)s[i + (j * 4) + 3]); } - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - } - if ((sdev->lun == 0) && - (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) { - AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, - asc_dvc->cfg->disc_enable); - AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, - asc_dvc->use_tagged_qng); - AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, - asc_dvc->cfg->can_tagged_qng); + switch (m) { + case 0: + default: + break; + case 1: + printk(" %2.2X", (unsigned)s[i + (j * 4)]); + break; + case 2: + printk(" %2.2X%2.2X", + (unsigned)s[i + (j * 4)], + (unsigned)s[i + (j * 4) + 1]); + break; + case 3: + printk(" %2.2X%2.2X%2.2X", + (unsigned)s[i + (j * 4) + 1], + (unsigned)s[i + (j * 4) + 2], + (unsigned)s[i + (j * 4) + 3]); + break; + } - asc_dvc->max_dvc_qng[sdev->id] = - asc_dvc->cfg->max_tag_qng[sdev->id]; - AscWriteLramByte(asc_dvc->iop_base, - (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id), - asc_dvc->max_dvc_qng[sdev->id]); + printk("\n"); } } +#endif /* ADVANSYS_DEBUG */ /* - * Wide Transfers + * advansys_info() * - * If the EEPROM enabled WDTR for the device and the device supports wide - * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and - * write the new value to the microcode. + * Return suitable for printing on the console with the argument + * adapter's configuration information. + * + * Note: The information line should not exceed ASC_INFO_SIZE bytes, + * otherwise the static 'info' array will be overrun. */ -static void -advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask) +static const char *advansys_info(struct Scsi_Host *shost) { - unsigned short cfg_word; - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); - if ((cfg_word & tidmask) != 0) - return; - - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); + static char info[ASC_INFO_SIZE]; + asc_board_t *boardp; + ASC_DVC_VAR *asc_dvc_varp; + ADV_DVC_VAR *adv_dvc_varp; + char *busname; + char *widename = NULL; - /* - * Clear the microcode SDTR and WDTR negotiation done indicators for - * the target to cause it to negotiate with the new setting set above. - * WDTR when accepted causes the target to enter asynchronous mode, so - * SDTR must be negotiated. - */ - AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); - AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); + boardp = ASC_BOARDP(shost); + if (ASC_NARROW_BOARD(boardp)) { + asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + ASC_DBG(1, "advansys_info: begin\n"); + if (asc_dvc_varp->bus_type & ASC_IS_ISA) { + if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == + ASC_IS_ISAPNP) { + busname = "ISA PnP"; + } else { + busname = "ISA"; + } + sprintf(info, + "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", + ASC_VERSION, busname, + (ulong)shost->io_port, + (ulong)shost->io_port + ASC_IOADR_GAP - 1, + shost->irq, shost->dma_channel); + } else { + if (asc_dvc_varp->bus_type & ASC_IS_VL) { + busname = "VL"; + } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { + busname = "EISA"; + } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { + if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) + == ASC_IS_PCI_ULTRA) { + busname = "PCI Ultra"; + } else { + busname = "PCI"; + } + } else { + busname = "?"; + ASC_PRINT2("advansys_info: board %d: unknown " + "bus type %d\n", boardp->id, + asc_dvc_varp->bus_type); + } + sprintf(info, + "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", + ASC_VERSION, busname, (ulong)shost->io_port, + (ulong)shost->io_port + ASC_IOADR_GAP - 1, + shost->irq); + } + } else { + /* + * Wide Adapter Information + * + * Memory-mapped I/O is used instead of I/O space to access + * the adapter, but display the I/O Port range. The Memory + * I/O address is displayed through the driver /proc file. + */ + adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + widename = "Ultra-Wide"; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + widename = "Ultra2-Wide"; + } else { + widename = "Ultra3-Wide"; + } + sprintf(info, + "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", + ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, + (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); + } + BUG_ON(strlen(info) >= ASC_INFO_SIZE); + ASC_DBG(1, "advansys_info: end\n"); + return info; } +#ifdef CONFIG_PROC_FS /* - * Synchronous Transfers + * asc_prt_line() * - * If the EEPROM enabled SDTR for the device and the device - * supports synchronous transfers, then turn on the device's - * 'sdtr_able' bit. Write the new value to the microcode. + * If 'cp' is NULL print to the console, otherwise print to a buffer. + * + * Return 0 if printing to the console, otherwise return the number of + * bytes written to the buffer. + * + * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack + * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. */ -static void -advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask) +static int asc_prt_line(char *buf, int buflen, char *fmt, ...) { - unsigned short cfg_word; - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); - if ((cfg_word & tidmask) != 0) - return; - - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); + va_list args; + int ret; + char s[ASC_PRTLINE_SIZE]; - /* - * Clear the microcode "SDTR negotiation" done indicator for the - * target to cause it to negotiate with the new setting set above. - */ - AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); - cfg_word &= ~tidmask; - AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + va_start(args, fmt); + ret = vsprintf(s, fmt, args); + BUG_ON(ret >= ASC_PRTLINE_SIZE); + if (buf == NULL) { + (void)printk(s); + ret = 0; + } else { + ret = min(buflen, ret); + memcpy(buf, s, ret); + } + va_end(args); + return ret; } /* - * PPR (Parallel Protocol Request) Capable + * asc_prt_board_devices() * - * If the device supports DT mode, then it must be PPR capable. - * The PPR message will be used in place of the SDTR and WDTR - * messages to negotiate synchronous speed and offset, transfer - * width, and protocol options. + * Print driver information for devices attached to the board. + * + * Note: no single line should be greater than ASC_PRTLINE_SIZE, + * cf. asc_prt_line(). + * + * Return the number of characters copied into 'cp'. No more than + * 'cplen' characters will be copied to 'cp'. */ -static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc, - AdvPortAddr iop_base, unsigned short tidmask) -{ - AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); - adv_dvc->ppr_able |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); -} - -static void -advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) +static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) { - AdvPortAddr iop_base = adv_dvc->iop_base; - unsigned short tidmask = 1 << sdev->id; + asc_board_t *boardp; + int leftlen; + int totlen; + int len; + int chip_scsi_id; + int i; - if (sdev->lun == 0) { - /* - * Handle WDTR, SDTR, and Tag Queuing. If the feature - * is enabled in the EEPROM and the device supports the - * feature, then enable it in the microcode. - */ + boardp = ASC_BOARDP(shost); + leftlen = cplen; + totlen = len = 0; - if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr) - advansys_wide_enable_wdtr(iop_base, tidmask); - if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr) - advansys_wide_enable_sdtr(iop_base, tidmask); - if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr) - advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask); + len = asc_prt_line(cp, leftlen, + "\nDevice Information for AdvanSys SCSI Host %d:\n", + shost->host_no); + ASC_PRT_NEXT(); - /* - * Tag Queuing is disabled for the BIOS which runs in polled - * mode and would see no benefit from Tag Queuing. Also by - * disabling Tag Queuing in the BIOS devices with Tag Queuing - * bugs will at least work with the BIOS. - */ - if ((adv_dvc->tagqng_able & tidmask) && - sdev->tagged_supported) { - unsigned short cfg_word; - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); - cfg_word |= tidmask; - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, - cfg_word); - AdvWriteByteLram(iop_base, - ASC_MC_NUMBER_OF_MAX_CMD + sdev->id, - adv_dvc->max_dvc_qng); - } + if (ASC_NARROW_BOARD(boardp)) { + chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; + } else { + chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; } - if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) { - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - adv_dvc->max_dvc_qng); - } else { - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); + len = asc_prt_line(cp, leftlen, "Target IDs Detected:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) { + len = asc_prt_line(cp, leftlen, " %X,", i); + ASC_PRT_NEXT(); + } } + len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id); + ASC_PRT_NEXT(); + + return totlen; } /* - * Set the number of commands to queue per device for the - * specified host adapter. + * Display Wide Board BIOS Information. */ -static int advansys_slave_configure(struct scsi_device *sdev) +static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp = ASC_BOARDP(sdev->host); - boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; + asc_board_t *boardp; + int leftlen; + int totlen; + int len; + ushort major, minor, letter; + + boardp = ASC_BOARDP(shost); + leftlen = cplen; + totlen = len = 0; + + len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: "); + ASC_PRT_NEXT(); /* - * Save a pointer to the sdev and set its initial/maximum - * queue depth. Only save the pointer for a lun0 dev though. + * If the BIOS saved a valid signature, then fill in + * the BIOS code segment base address. */ - if (sdev->lun == 0) - boardp->device[sdev->id] = sdev; + if (boardp->bios_signature != 0x55AA) { + len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n"); + ASC_PRT_NEXT(); + len = asc_prt_line(cp, leftlen, + "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"); + ASC_PRT_NEXT(); + len = asc_prt_line(cp, leftlen, + "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n"); + ASC_PRT_NEXT(); + } else { + major = (boardp->bios_version >> 12) & 0xF; + minor = (boardp->bios_version >> 8) & 0xF; + letter = (boardp->bios_version & 0xFF); - if (ASC_NARROW_BOARD(boardp)) - advansys_narrow_slave_configure(sdev, - &boardp->dvc_var.asc_dvc_var); - else - advansys_wide_slave_configure(sdev, - &boardp->dvc_var.adv_dvc_var); + len = asc_prt_line(cp, leftlen, "%d.%d%c\n", + major, minor, + letter >= 26 ? '?' : letter + 'A'); + ASC_PRT_NEXT(); - return 0; + /* + * Current available ROM BIOS release is 3.1I for UW + * and 3.2I for U2W. This code doesn't differentiate + * UW and U2W boards. + */ + if (major < 3 || (major <= 3 && minor < 1) || + (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) { + len = asc_prt_line(cp, leftlen, + "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"); + ASC_PRT_NEXT(); + len = asc_prt_line(cp, leftlen, + "ftp://ftp.connectcom.net/pub\n"); + ASC_PRT_NEXT(); + } + } + + return totlen; } /* - * Execute a single 'Scsi_Cmnd'. - * - * The function 'done' is called when the request has been completed. - * - * Scsi_Cmnd: - * - * host - board controlling device - * device - device to send command - * target - target of device - * lun - lun of device - * cmd_len - length of SCSI CDB - * cmnd - buffer for SCSI 8, 10, or 12 byte CDB - * use_sg - if non-zero indicates scatter-gather request with use_sg elements + * Add serial number to information bar if signature AAh + * is found in at bit 15-9 (7 bits) of word 1. * - * if (use_sg == 0) { - * request_buffer - buffer address for request - * request_bufflen - length of request buffer - * } else { - * request_buffer - pointer to scatterlist structure - * } + * Serial Number consists fo 12 alpha-numeric digits. * - * sense_buffer - sense command buffer + * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits) + * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits) + * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits) + * 5 - Product revision (A-J) Word0: " " * - * result (4 bytes of an int): - * Byte Meaning - * 0 SCSI Status Byte Code - * 1 SCSI One Byte Message Code - * 2 Host Error Code - * 3 Mid-Level Error Code + * Signature Word1: 15-9 (7 bits) + * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit) + * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits) * - * host driver fields: - * SCp - Scsi_Pointer used for command processing status - * scsi_done - used to save caller's done function - * host_scribble - used for pointer to another struct scsi_cmnd + * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits) * - * If this function returns ASC_NOERROR the request will be completed - * from the interrupt handler. + * Note 1: Only production cards will have a serial number. * - * If this function returns ASC_ERROR the host error code has been set, - * and the called must call asc_scsi_done. + * Note 2: Signature is most significant 7 bits (0xFE). * - * If ASC_BUSY is returned the request will be returned to the midlayer - * and re-tried later. + * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE. */ -static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) +static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) { - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; - ADV_DVC_VAR *adv_dvc_varp; - ADV_SCSI_REQ_Q *adv_scsiqp; - struct scsi_device *device; - int ret; + ushort w, num; - ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", - (ulong)scp, (ulong)scp->scsi_done); + if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) { + return ASC_FALSE; + } else { + /* + * First word - 6 digits. + */ + w = serialnum[0]; - boardp = ASC_BOARDP(scp->device->host); - device = boardp->device[scp->device->id]; + /* Product type - 1st digit. */ + if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') { + /* Product type is P=Prototype */ + *cp += 0x8; + } + cp++; + + /* Manufacturing location - 2nd digit. */ + *cp++ = 'A' + ((w & 0x1C00) >> 10); + + /* Product ID - 3rd, 4th digits. */ + num = w & 0x3FF; + *cp++ = '0' + (num / 100); + num %= 100; + *cp++ = '0' + (num / 10); + + /* Product revision - 5th digit. */ + *cp++ = 'A' + (num % 10); - if (ASC_NARROW_BOARD(boardp)) { /* - * Build and execute Narrow Board request. + * Second word */ - - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + w = serialnum[1]; /* - * Build Asc Library request structure using the - * global structures 'asc_scsi_req' and 'asc_sg_head'. - * - * If an error is returned, then the request has been - * queued on the board done queue. It will be completed - * by the caller. + * Year - 6th digit. * - * asc_build_req() can not return ASC_BUSY. + * If bit 15 of third word is set, then the + * last digit of the year is greater than 7. */ - if (asc_build_req(boardp, scp) == ASC_ERROR) { - ASC_STATS(scp->device->host, build_error); - return ASC_ERROR; + if (serialnum[2] & 0x8000) { + *cp++ = '8' + ((w & 0x1C0) >> 6); + } else { + *cp++ = '0' + ((w & 0x1C0) >> 6); } - switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { - case ASC_NOERROR: - ASC_STATS(scp->device->host, exe_noerror); - /* - * Increment monotonically increasing per device - * successful request counter. Wrapping doesn't matter. - */ - boardp->reqcnt[scp->device->id]++; - ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), " - "ASC_NOERROR\n"); - break; - case ASC_BUSY: - ASC_STATS(scp->device->host, exe_busy); - break; - case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_error); - scp->result = HOST_BYTE(DID_ERROR); - break; - default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AscExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_unknown); - scp->result = HOST_BYTE(DID_ERROR); - break; - } - } else { - /* - * Build and execute Wide Board request. - */ - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + /* Week of year - 7th, 8th digits. */ + num = w & 0x003F; + *cp++ = '0' + num / 10; + num %= 10; + *cp++ = '0' + num; /* - * Build and get a pointer to an Adv Library request structure. - * - * If the request is successfully built then send it below, - * otherwise return with an error. + * Third word */ - switch (adv_build_req(boardp, scp, &adv_scsiqp)) { - case ASC_NOERROR: - ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_NOERROR\n"); - break; - case ASC_BUSY: - ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_BUSY\n"); - /* - * The asc_stats fields 'adv_build_noreq' and - * 'adv_build_nosg' count wide board busy conditions. - * They are updated in adv_build_req and - * adv_get_sglist, respectively. - */ - return ASC_BUSY; - case ASC_ERROR: - default: - ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_ERROR\n"); - ASC_STATS(scp->device->host, build_error); - return ASC_ERROR; - } + w = serialnum[2] & 0x7FFF; - switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { - case ASC_NOERROR: - ASC_STATS(scp->device->host, exe_noerror); - /* - * Increment monotonically increasing per device - * successful request counter. Wrapping doesn't matter. - */ - boardp->reqcnt[scp->device->id]++; - ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), " - "ASC_NOERROR\n"); - break; - case ASC_BUSY: - ASC_STATS(scp->device->host, exe_busy); - break; - case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_error); - scp->result = HOST_BYTE(DID_ERROR); - break; - default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AdvExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_unknown); - scp->result = HOST_BYTE(DID_ERROR); - break; - } - } + /* Serial number - 9th digit. */ + *cp++ = 'A' + (w / 1000); - ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); - return ret; + /* 10th, 11th, 12th digits. */ + num = w % 1000; + *cp++ = '0' + num / 100; + num %= 100; + *cp++ = '0' + num / 10; + num %= 10; + *cp++ = '0' + num; + + *cp = '\0'; /* Null Terminate the string. */ + return ASC_TRUE; + } } /* - * Build a request structure for the Asc Library (Narrow Board). + * asc_prt_asc_board_eeprom() * - * The global structures 'asc_scsi_q' and 'asc_sg_head' are - * used to build the request. + * Print board EEPROM configuration. * - * If an error occurs, then return ASC_ERROR. + * Note: no single line should be greater than ASC_PRTLINE_SIZE, + * cf. asc_prt_line(). + * + * Return the number of characters copied into 'cp'. No more than + * 'cplen' characters will be copied to 'cp'. */ -static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) +static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) { - /* - * Mutually exclusive access is required to 'asc_scsi_q' and - * 'asc_sg_head' until after the request is started. - */ - memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); + asc_board_t *boardp; + ASC_DVC_VAR *asc_dvc_varp; + int leftlen; + int totlen; + int len; + ASCEEP_CONFIG *ep; + int i; +#ifdef CONFIG_ISA + int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 }; +#endif /* CONFIG_ISA */ + uchar serialstr[13]; - /* - * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. - */ - asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); + boardp = ASC_BOARDP(shost); + asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + ep = &boardp->eep_config.asc_eep; - /* - * Build the ASC_SCSI_Q request. - */ - asc_scsi_q.cdbptr = &scp->cmnd[0]; - asc_scsi_q.q2.cdb_len = scp->cmd_len; - asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); - asc_scsi_q.q1.target_lun = scp->device->lun; - asc_scsi_q.q2.target_ix = - ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); - asc_scsi_q.q1.sense_addr = - cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); - asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); + leftlen = cplen; + totlen = len = 0; - /* - * If there are any outstanding requests for the current target, - * then every 255th request send an ORDERED request. This heuristic - * tries to retain the benefit of request sorting while preventing - * request starvation. 255 is the max number of tags or pending commands - * a device may have outstanding. - * - * The request count is incremented below for every successfully - * started request. - * - */ - if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && - (boardp->reqcnt[scp->device->id] % 255) == 0) { - asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; - } else { - asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; - } + len = asc_prt_line(cp, leftlen, + "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", + shost->host_no); + ASC_PRT_NEXT(); - /* - * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather - * buffer command. - */ - if (scp->use_sg == 0) { - /* - * CDB request of single contiguous buffer. - */ - ASC_STATS(scp->device->host, cont_cnt); - scp->SCp.dma_handle = scp->request_bufflen ? - dma_map_single(boardp->dev, scp->request_buffer, - scp->request_bufflen, - scp->sc_data_direction) : 0; - asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); - asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); - ASC_STATS_ADD(scp->device->host, cont_xfer, - ASC_CEILING(scp->request_bufflen, 512)); - asc_scsi_q.q1.sg_queue_cnt = 0; - asc_scsi_q.sg_head = NULL; + if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr) + == ASC_TRUE) { + len = + asc_prt_line(cp, leftlen, " Serial Number: %s\n", + serialstr); + ASC_PRT_NEXT(); } else { - /* - * CDB scatter-gather request list. - */ - int sgcnt; - int use_sg; - struct scatterlist *slp; - - slp = (struct scatterlist *)scp->request_buffer; - use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - - if (use_sg > scp->device->host->sg_tablesize) { - ASC_PRINT3("asc_build_req: board %d: use_sg %d > " - "sg_tablesize %d\n", boardp->id, use_sg, - scp->device->host->sg_tablesize); - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - scp->result = HOST_BYTE(DID_ERROR); - return ASC_ERROR; + if (ep->adapter_info[5] == 0xBB) { + len = asc_prt_line(cp, leftlen, + " Default Settings Used for EEPROM-less Adapter.\n"); + ASC_PRT_NEXT(); + } else { + len = asc_prt_line(cp, leftlen, + " Serial Number Signature Not Present.\n"); + ASC_PRT_NEXT(); } + } - ASC_STATS(scp->device->host, sg_cnt); + len = asc_prt_line(cp, leftlen, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, + ep->max_tag_qng); + ASC_PRT_NEXT(); - /* - * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q - * structure to point to it. - */ - memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); + len = asc_prt_line(cp, leftlen, + " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam); + ASC_PRT_NEXT(); - asc_scsi_q.q1.cntl |= QC_SG_HEAD; - asc_scsi_q.sg_head = &asc_sg_head; - asc_scsi_q.q1.data_cnt = 0; - asc_scsi_q.q1.data_addr = 0; - /* This is a byte value, otherwise it would need to be swapped. */ - asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; - ASC_STATS_ADD(scp->device->host, sg_elem, - asc_sg_head.entry_cnt); + len = asc_prt_line(cp, leftlen, " Target ID: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %d", i); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* - * Convert scatter-gather list into ASC_SG_HEAD list. - */ - for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { - asc_sg_head.sg_list[sgcnt].addr = - cpu_to_le32(sg_dma_address(slp)); - asc_sg_head.sg_list[sgcnt].bytes = - cpu_to_le32(sg_dma_len(slp)); - ASC_STATS_ADD(scp->device->host, sg_xfer, - ASC_CEILING(sg_dma_len(slp), 512)); - } + len = asc_prt_line(cp, leftlen, " Disconnects: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep-> + disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); - ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); + len = asc_prt_line(cp, leftlen, " Command Queuing: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep-> + use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - return ASC_NOERROR; + len = asc_prt_line(cp, leftlen, " Start Motor: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep-> + start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); + + len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep-> + init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); + +#ifdef CONFIG_ISA + if (asc_dvc_varp->bus_type & ASC_IS_ISA) { + len = asc_prt_line(cp, leftlen, + " Host ISA DMA speed: %d MB/S\n", + isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]); + ASC_PRT_NEXT(); + } +#endif /* CONFIG_ISA */ + + return totlen; } /* - * Build a request structure for the Adv Library (Wide Board). + * asc_prt_adv_board_eeprom() * - * If an adv_req_t can not be allocated to issue the request, - * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. + * Print board EEPROM configuration. * - * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the - * microcode for DMA addresses or math operations are byte swapped - * to little-endian order. + * Note: no single line should be greater than ASC_PRTLINE_SIZE, + * cf. asc_prt_line(). + * + * Return the number of characters copied into 'cp'. No more than + * 'cplen' characters will be copied to 'cp'. */ -static int -adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, - ADV_SCSI_REQ_Q **adv_scsiqpp) +static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) { - adv_req_t *reqp; - ADV_SCSI_REQ_Q *scsiqp; + asc_board_t *boardp; + ADV_DVC_VAR *adv_dvc_varp; + int leftlen; + int totlen; + int len; int i; - int ret; + char *termstr; + uchar serialstr[13]; + ADVEEP_3550_CONFIG *ep_3550 = NULL; + ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL; + ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL; + ushort word; + ushort *wordp; + ushort sdtr_speed = 0; - /* - * Allocate an adv_req_t structure from the board to execute - * the command. - */ - if (boardp->adv_reqp == NULL) { - ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); - ASC_STATS(scp->device->host, adv_build_noreq); - return ASC_BUSY; + boardp = ASC_BOARDP(shost); + adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + ep_3550 = &boardp->eep_config.adv_3550_eep; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + ep_38C0800 = &boardp->eep_config.adv_38C0800_eep; } else { - reqp = boardp->adv_reqp; - boardp->adv_reqp = reqp->next_reqp; - reqp->next_reqp = NULL; + ep_38C1600 = &boardp->eep_config.adv_38C1600_eep; } - /* - * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. - */ - scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); - - /* - * Initialize the structure. - */ - scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0; + leftlen = cplen; + totlen = len = 0; - /* - * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. - */ - scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp); + len = asc_prt_line(cp, leftlen, + "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", + shost->host_no); + ASC_PRT_NEXT(); - /* - * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. - */ - reqp->cmndp = scp; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + wordp = &ep_3550->serial_number_word1; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + wordp = &ep_38C0800->serial_number_word1; + } else { + wordp = &ep_38C1600->serial_number_word1; + } - /* - * Build the ADV_SCSI_REQ_Q request. - */ + if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) { + len = + asc_prt_line(cp, leftlen, " Serial Number: %s\n", + serialstr); + ASC_PRT_NEXT(); + } else { + len = asc_prt_line(cp, leftlen, + " Serial Number Signature Not Present.\n"); + ASC_PRT_NEXT(); + } - /* Set CDB length and copy it to the request structure. */ - scsiqp->cdb_len = scp->cmd_len; - /* Copy first 12 CDB bytes to cdb[]. */ - for (i = 0; i < scp->cmd_len && i < 12; i++) { - scsiqp->cdb[i] = scp->cmnd[i]; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + len = asc_prt_line(cp, leftlen, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_3550->adapter_scsi_id, + ep_3550->max_host_qng, ep_3550->max_dvc_qng); + ASC_PRT_NEXT(); + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + len = asc_prt_line(cp, leftlen, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_38C0800->adapter_scsi_id, + ep_38C0800->max_host_qng, + ep_38C0800->max_dvc_qng); + ASC_PRT_NEXT(); + } else { + len = asc_prt_line(cp, leftlen, + " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", + ep_38C1600->adapter_scsi_id, + ep_38C1600->max_host_qng, + ep_38C1600->max_dvc_qng); + ASC_PRT_NEXT(); } - /* Copy last 4 CDB bytes, if present, to cdb16[]. */ - for (; i < scp->cmd_len; i++) { - scsiqp->cdb16[i - 12] = scp->cmnd[i]; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + word = ep_3550->termination; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + word = ep_38C0800->termination_lvd; + } else { + word = ep_38C1600->termination_lvd; + } + switch (word) { + case 1: + termstr = "Low Off/High Off"; + break; + case 2: + termstr = "Low Off/High On"; + break; + case 3: + termstr = "Low On/High On"; + break; + default: + case 0: + termstr = "Automatic"; + break; } - scsiqp->target_id = scp->device->id; - scsiqp->target_lun = scp->device->lun; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + len = asc_prt_line(cp, leftlen, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_3550->termination, termstr, + ep_3550->bios_ctrl); + ASC_PRT_NEXT(); + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + len = asc_prt_line(cp, leftlen, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_38C0800->termination_lvd, termstr, + ep_38C0800->bios_ctrl); + ASC_PRT_NEXT(); + } else { + len = asc_prt_line(cp, leftlen, + " termination: %u (%s), bios_ctrl: 0x%x\n", + ep_38C1600->termination_lvd, termstr, + ep_38C1600->bios_ctrl); + ASC_PRT_NEXT(); + } - scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); - scsiqp->sense_len = sizeof(scp->sense_buffer); + len = asc_prt_line(cp, leftlen, " Target ID: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %X", i); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* - * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather - * buffer command. - */ + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + word = ep_3550->disc_enable; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + word = ep_38C0800->disc_enable; + } else { + word = ep_38C1600->disc_enable; + } + len = asc_prt_line(cp, leftlen, " Disconnects: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); - scsiqp->vdata_addr = scp->request_buffer; - scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + word = ep_3550->tagqng_able; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + word = ep_38C0800->tagqng_able; + } else { + word = ep_38C1600->tagqng_able; + } + len = asc_prt_line(cp, leftlen, " Command Queuing: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - if (scp->use_sg == 0) { - /* - * CDB request of single contiguous buffer. - */ - reqp->sgblkp = NULL; - scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); - if (scp->request_bufflen) { - scsiqp->vdata_addr = scp->request_buffer; - scp->SCp.dma_handle = - dma_map_single(boardp->dev, scp->request_buffer, - scp->request_bufflen, - scp->sc_data_direction); - } else { - scsiqp->vdata_addr = NULL; - scp->SCp.dma_handle = 0; - } - scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); - scsiqp->sg_list_ptr = NULL; - scsiqp->sg_real_addr = 0; - ASC_STATS(scp->device->host, cont_cnt); - ASC_STATS_ADD(scp->device->host, cont_xfer, - ASC_CEILING(scp->request_bufflen, 512)); + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + word = ep_3550->start_motor; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + word = ep_38C0800->start_motor; } else { - /* - * CDB scatter-gather request list. - */ - struct scatterlist *slp; - int use_sg; - - slp = (struct scatterlist *)scp->request_buffer; - use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - - if (use_sg > ADV_MAX_SG_LIST) { - ASC_PRINT3("adv_build_req: board %d: use_sg %d > " - "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg, - scp->device->host->sg_tablesize); - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - scp->result = HOST_BYTE(DID_ERROR); - - /* - * Free the 'adv_req_t' structure by adding it back - * to the board free list. - */ - reqp->next_reqp = boardp->adv_reqp; - boardp->adv_reqp = reqp; + word = ep_38C1600->start_motor; + } + len = asc_prt_line(cp, leftlen, " Start Motor: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - return ASC_ERROR; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep_3550-> + sdtr_able & ADV_TID_TO_TIDMASK(i)) ? + 'Y' : 'N'); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); + } - ret = adv_get_sglist(boardp, reqp, scp, use_sg); - if (ret != ADV_SUCCESS) { - /* - * Free the adv_req_t structure by adding it back to - * the board free list. - */ - reqp->next_reqp = boardp->adv_reqp; - boardp->adv_reqp = reqp; - - return ret; + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + len = asc_prt_line(cp, leftlen, " Ultra Transfer: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (ep_3550-> + ultra_able & ADV_TID_TO_TIDMASK(i)) + ? 'Y' : 'N'); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); + } - ASC_STATS(scp->device->host, sg_cnt); - ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + word = ep_3550->wdtr_able; + } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + word = ep_38C0800->wdtr_able; + } else { + word = ep_38C1600->wdtr_able; + } + len = asc_prt_line(cp, leftlen, " Wide Transfer: "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + len = asc_prt_line(cp, leftlen, " %c", + (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); - ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); + if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 || + adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) { + len = asc_prt_line(cp, leftlen, + " Synchronous Transfer Speed (Mhz):\n "); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + char *speed_str; - *adv_scsiqpp = scsiqp; + if (i == 0) { + sdtr_speed = adv_dvc_varp->sdtr_speed1; + } else if (i == 4) { + sdtr_speed = adv_dvc_varp->sdtr_speed2; + } else if (i == 8) { + sdtr_speed = adv_dvc_varp->sdtr_speed3; + } else if (i == 12) { + sdtr_speed = adv_dvc_varp->sdtr_speed4; + } + switch (sdtr_speed & ADV_MAX_TID) { + case 0: + speed_str = "Off"; + break; + case 1: + speed_str = " 5"; + break; + case 2: + speed_str = " 10"; + break; + case 3: + speed_str = " 20"; + break; + case 4: + speed_str = " 40"; + break; + case 5: + speed_str = " 80"; + break; + default: + speed_str = "Unk"; + break; + } + len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str); + ASC_PRT_NEXT(); + if (i == 7) { + len = asc_prt_line(cp, leftlen, "\n "); + ASC_PRT_NEXT(); + } + sdtr_speed >>= 4; + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); + } - return ASC_NOERROR; + return totlen; } /* - * Build scatter-gather list for Adv Library (Wide Board). + * asc_prt_driver_conf() * - * Additional ADV_SG_BLOCK structures will need to be allocated - * if the total number of scatter-gather elements exceeds - * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are - * assumed to be physically contiguous. + * Note: no single line should be greater than ASC_PRTLINE_SIZE, + * cf. asc_prt_line(). * - * Return: - * ADV_SUCCESS(1) - SG List successfully created - * ADV_ERROR(-1) - SG List creation failed + * Return the number of characters copied into 'cp'. No more than + * 'cplen' characters will be copied to 'cp'. */ -static int -adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, - int use_sg) +static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) { - adv_sgblk_t *sgblkp; - ADV_SCSI_REQ_Q *scsiqp; - struct scatterlist *slp; - int sg_elem_cnt; - ADV_SG_BLOCK *sg_block, *prev_sg_block; - ADV_PADDR sg_block_paddr; - int i; - - scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); - slp = (struct scatterlist *)scp->request_buffer; - sg_elem_cnt = use_sg; - prev_sg_block = NULL; - reqp->sgblkp = NULL; + asc_board_t *boardp; + int leftlen; + int totlen; + int len; + int chip_scsi_id; - for (;;) { - /* - * Allocate a 'adv_sgblk_t' structure from the board free - * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK - * (15) scatter-gather elements. - */ - if ((sgblkp = boardp->adv_sgblkp) == NULL) { - ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); - ASC_STATS(scp->device->host, adv_build_nosg); + boardp = ASC_BOARDP(shost); - /* - * Allocation failed. Free 'adv_sgblk_t' structures - * already allocated for the request. - */ - while ((sgblkp = reqp->sgblkp) != NULL) { - /* Remove 'sgblkp' from the request list. */ - reqp->sgblkp = sgblkp->next_sgblkp; + leftlen = cplen; + totlen = len = 0; - /* Add 'sgblkp' to the board free list. */ - sgblkp->next_sgblkp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgblkp; - } - return ASC_BUSY; - } + len = asc_prt_line(cp, leftlen, + "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", + shost->host_no); + ASC_PRT_NEXT(); - /* Complete 'adv_sgblk_t' board allocation. */ - boardp->adv_sgblkp = sgblkp->next_sgblkp; - sgblkp->next_sgblkp = NULL; + len = asc_prt_line(cp, leftlen, + " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n", + shost->host_busy, shost->last_reset, shost->max_id, + shost->max_lun, shost->max_channel); + ASC_PRT_NEXT(); - /* - * Get 8 byte aligned virtual and physical addresses - * for the allocated ADV_SG_BLOCK structure. - */ - sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); - sg_block_paddr = virt_to_bus(sg_block); + len = asc_prt_line(cp, leftlen, + " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", + shost->unique_id, shost->can_queue, shost->this_id, + shost->sg_tablesize, shost->cmd_per_lun); + ASC_PRT_NEXT(); - /* - * Check if this is the first 'adv_sgblk_t' for the - * request. - */ - if (reqp->sgblkp == NULL) { - /* Request's first scatter-gather block. */ - reqp->sgblkp = sgblkp; + len = asc_prt_line(cp, leftlen, + " unchecked_isa_dma %d, use_clustering %d\n", + shost->unchecked_isa_dma, shost->use_clustering); + ASC_PRT_NEXT(); - /* - * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical - * address pointers. - */ - scsiqp->sg_list_ptr = sg_block; - scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr); - } else { - /* Request's second or later scatter-gather block. */ - sgblkp->next_sgblkp = reqp->sgblkp; - reqp->sgblkp = sgblkp; - - /* - * Point the previous ADV_SG_BLOCK structure to - * the newly allocated ADV_SG_BLOCK structure. - */ - prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); - } + len = asc_prt_line(cp, leftlen, + " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n", + boardp->flags, boardp->last_reset, jiffies, + boardp->asc_n_io_port); + ASC_PRT_NEXT(); - for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { - sg_block->sg_list[i].sg_addr = - cpu_to_le32(sg_dma_address(slp)); - sg_block->sg_list[i].sg_count = - cpu_to_le32(sg_dma_len(slp)); - ASC_STATS_ADD(scp->device->host, sg_xfer, - ASC_CEILING(sg_dma_len(slp), 512)); + len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port); + ASC_PRT_NEXT(); - if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ - sg_block->sg_cnt = i + 1; - sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */ - return ADV_SUCCESS; - } - slp++; - } - sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; - prev_sg_block = sg_block; + if (ASC_NARROW_BOARD(boardp)) { + chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; + } else { + chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; } + + return totlen; } /* - * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). + * asc_prt_asc_board_info() * - * Interrupt callback function for the Narrow SCSI Asc Library. + * Print dynamic board configuration information. + * + * Note: no single line should be greater than ASC_PRTLINE_SIZE, + * cf. asc_prt_line(). + * + * Return the number of characters copied into 'cp'. No more than + * 'cplen' characters will be copied to 'cp'. */ -static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) +static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) { asc_board_t *boardp; - struct scsi_cmnd *scp; - struct Scsi_Host *shost; + int chip_scsi_id; + int leftlen; + int totlen; + int len; + ASC_DVC_VAR *v; + ASC_DVC_CFG *c; + int i; + int renegotiate = 0; - ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", - (ulong)asc_dvc_varp, (ulong)qdonep); - ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); + boardp = ASC_BOARDP(shost); + v = &boardp->dvc_var.asc_dvc_var; + c = &boardp->dvc_cfg.asc_dvc_cfg; + chip_scsi_id = c->chip_scsi_id; - /* - * Get the struct scsi_cmnd structure and Scsi_Host structure for the - * command that has been completed. - */ - scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); - ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp); + leftlen = cplen; + totlen = len = 0; - if (scp == NULL) { - ASC_PRINT("asc_isr_callback: scp is NULL\n"); - return; - } - ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); + len = asc_prt_line(cp, leftlen, + "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", + shost->host_no); + ASC_PRT_NEXT(); - shost = scp->device->host; - ASC_STATS(shost, callback); - ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); + len = asc_prt_line(cp, leftlen, + " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n", + c->chip_version, c->lib_version, c->lib_serial_no, + c->mcode_date); + ASC_PRT_NEXT(); - boardp = ASC_BOARDP(shost); - BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); + len = asc_prt_line(cp, leftlen, + " mcode_version 0x%x, err_code %u\n", + c->mcode_version, v->err_code); + ASC_PRT_NEXT(); - /* - * 'qdonep' contains the command's ending status. - */ - switch (qdonep->d3.done_stat) { - case QD_NO_ERROR: - ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); - scp->result = 0; + /* Current number of commands waiting for the host. */ + len = asc_prt_line(cp, leftlen, + " Total Command Pending: %d\n", v->cur_total_qng); + ASC_PRT_NEXT(); - /* - * Check for an underrun condition. - * - * If there was no error and an underrun condition, then - * return the number of underrun bytes. - */ - if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && - qdonep->remain_bytes <= scp->request_bufflen) { - ASC_DBG1(1, - "asc_isr_callback: underrun condition %u bytes\n", - (unsigned)qdonep->remain_bytes); - scp->resid = qdonep->remain_bytes; + len = asc_prt_line(cp, leftlen, " Command Queuing:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } - break; - - case QD_WITH_ERROR: - ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); - switch (qdonep->d3.host_stat) { - case QHSTA_NO_ERROR: - if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { - ASC_DBG(2, - "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); - ASC_DBG_PRT_SENSE(2, scp->sense_buffer, - sizeof(scp->sense_buffer)); - /* - * Note: The 'status_byte()' macro used by - * target drivers defined in scsi.h shifts the - * status byte returned by host drivers right - * by 1 bit. This is why target drivers also - * use right shifted status byte definitions. - * For instance target drivers use - * CHECK_CONDITION, defined to 0x1, instead of - * the SCSI defined check condition value of - * 0x2. Host drivers are supposed to return - * the status byte as it is defined by SCSI. - */ - scp->result = DRIVER_BYTE(DRIVER_SENSE) | - STATUS_BYTE(qdonep->d3.scsi_stat); - } else { - scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); - } - break; + len = asc_prt_line(cp, leftlen, " %X:%c", + i, + (v-> + use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? + 'Y' : 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - default: - /* QHSTA error occurred */ - ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n", - qdonep->d3.host_stat); - scp->result = HOST_BYTE(DID_BAD_TARGET); - break; + /* Current number of commands waiting for a device. */ + len = asc_prt_line(cp, leftlen, " Command Queue Pending:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } - break; - - case QD_ABORTED_BY_HOST: - ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); - scp->result = - HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3. - scsi_msg) | - STATUS_BYTE(qdonep->d3.scsi_stat); - break; - - default: - ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", - qdonep->d3.done_stat); - scp->result = - HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3. - scsi_msg) | - STATUS_BYTE(qdonep->d3.scsi_stat); - break; + len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* - * If the 'init_tidmask' bit isn't already set for the target and the - * current request finished normally, then set the bit for the target - * to indicate that a device is present. - */ - if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && - qdonep->d3.done_stat == QD_NO_ERROR && - qdonep->d3.host_stat == QHSTA_NO_ERROR) { - boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); + /* Current limit on number of commands that can be sent to a device. */ + len = asc_prt_line(cp, leftlen, " Command Queue Limit:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } + len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - asc_scsi_done(scp); - - return; -} + /* Indicate whether the device has returned queue full status. */ + len = asc_prt_line(cp, leftlen, " Command Queue Full:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } + if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) { + len = asc_prt_line(cp, leftlen, " %X:Y-%d", + i, boardp->queue_full_cnt[i]); + } else { + len = asc_prt_line(cp, leftlen, " %X:N", i); + } + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); -/* - * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). - * - * Callback function for the Wide SCSI Adv Library. - */ -static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) -{ - asc_board_t *boardp; - adv_req_t *reqp; - adv_sgblk_t *sgblkp; - struct scsi_cmnd *scp; - struct Scsi_Host *shost; - ADV_DCNT resid_cnt; - - ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", - (ulong)adv_dvc_varp, (ulong)scsiqp); - ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); - - /* - * Get the adv_req_t structure for the command that has been - * completed. The adv_req_t structure actually contains the - * completed ADV_SCSI_REQ_Q structure. - */ - reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr); - ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp); - if (reqp == NULL) { - ASC_PRINT("adv_isr_callback: reqp is NULL\n"); - return; - } - - /* - * Get the struct scsi_cmnd structure and Scsi_Host structure for the - * command that has been completed. - * - * Note: The adv_req_t request structure and adv_sgblk_t structure, - * if any, are dropped, because a board structure pointer can not be - * determined. - */ - scp = reqp->cmndp; - ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp); - if (scp == NULL) { - ASC_PRINT - ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); - return; + len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ASC_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } + len = asc_prt_line(cp, leftlen, " %X:%c", + i, + (v-> + sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); } - ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); - - shost = scp->device->host; - ASC_STATS(shost, callback); - ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); - - boardp = ASC_BOARDP(shost); - BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* - * 'done_status' contains the command's ending status. - */ - switch (scsiqp->done_status) { - case QD_NO_ERROR: - ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); - scp->result = 0; + for (i = 0; i <= ASC_MAX_TID; i++) { + uchar syn_period_ix; - /* - * Check for an underrun condition. - * - * If there was no error and an underrun condition, then - * then return the number of underrun bytes. - */ - resid_cnt = le32_to_cpu(scsiqp->data_cnt); - if (scp->request_bufflen != 0 && resid_cnt != 0 && - resid_cnt <= scp->request_bufflen) { - ASC_DBG1(1, - "adv_isr_callback: underrun condition %lu bytes\n", - (ulong)resid_cnt); - scp->resid = resid_cnt; + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || + ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } - break; - case QD_WITH_ERROR: - ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); - switch (scsiqp->host_status) { - case QHSTA_NO_ERROR: - if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { - ASC_DBG(2, - "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); - ASC_DBG_PRT_SENSE(2, scp->sense_buffer, - sizeof(scp->sense_buffer)); - /* - * Note: The 'status_byte()' macro used by - * target drivers defined in scsi.h shifts the - * status byte returned by host drivers right - * by 1 bit. This is why target drivers also - * use right shifted status byte definitions. - * For instance target drivers use - * CHECK_CONDITION, defined to 0x1, instead of - * the SCSI defined check condition value of - * 0x2. Host drivers are supposed to return - * the status byte as it is defined by SCSI. - */ - scp->result = DRIVER_BYTE(DRIVER_SENSE) | - STATUS_BYTE(scsiqp->scsi_status); - } else { - scp->result = STATUS_BYTE(scsiqp->scsi_status); - } - break; + len = asc_prt_line(cp, leftlen, " %X:", i); + ASC_PRT_NEXT(); - default: - /* Some other QHSTA error occurred. */ - ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n", - scsiqp->host_status); - scp->result = HOST_BYTE(DID_BAD_TARGET); - break; - } - break; + if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) { + len = asc_prt_line(cp, leftlen, " Asynchronous"); + ASC_PRT_NEXT(); + } else { + syn_period_ix = + (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - + 1); - case QD_ABORTED_BY_HOST: - ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); - scp->result = - HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); - break; + len = asc_prt_line(cp, leftlen, + " Transfer Period Factor: %d (%d.%d Mhz),", + v->sdtr_period_tbl[syn_period_ix], + 250 / + v->sdtr_period_tbl[syn_period_ix], + ASC_TENTHS(250, + v-> + sdtr_period_tbl + [syn_period_ix])); + ASC_PRT_NEXT(); - default: - ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", - scsiqp->done_status); - scp->result = - HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); - break; - } + len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", + boardp-> + sdtr_data[i] & ASC_SYN_MAX_OFFSET); + ASC_PRT_NEXT(); + } - /* - * If the 'init_tidmask' bit isn't already set for the target and the - * current request finished normally, then set the bit for the target - * to indicate that a device is present. - */ - if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && - scsiqp->done_status == QD_NO_ERROR && - scsiqp->host_status == QHSTA_NO_ERROR) { - boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); + if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { + len = asc_prt_line(cp, leftlen, "*\n"); + renegotiate = 1; + } else { + len = asc_prt_line(cp, leftlen, "\n"); + } + ASC_PRT_NEXT(); } - asc_scsi_done(scp); - - /* - * Free all 'adv_sgblk_t' structures allocated for the request. - */ - while ((sgblkp = reqp->sgblkp) != NULL) { - /* Remove 'sgblkp' from the request list. */ - reqp->sgblkp = sgblkp->next_sgblkp; - - /* Add 'sgblkp' to the board free list. */ - sgblkp->next_sgblkp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgblkp; + if (renegotiate) { + len = asc_prt_line(cp, leftlen, + " * = Re-negotiation pending before next command.\n"); + ASC_PRT_NEXT(); } - /* - * Free the adv_req_t structure used with the command by adding - * it back to the board free list. - */ - reqp->next_reqp = boardp->adv_reqp; - boardp->adv_reqp = reqp; - - ASC_DBG(1, "adv_isr_callback: done\n"); - - return; -} - -/* - * adv_async_callback() - Adv Library asynchronous event callback function. - */ -static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) -{ - switch (code) { - case ADV_ASYNC_SCSI_BUS_RESET_DET: - /* - * The firmware detected a SCSI Bus reset. - */ - ASC_DBG(0, - "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n"); - break; - - case ADV_ASYNC_RDMA_FAILURE: - /* - * Handle RDMA failure by resetting the SCSI Bus and - * possibly the chip if it is unresponsive. Log the error - * with a unique code. - */ - ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n"); - AdvResetChipAndSB(adv_dvc_varp); - break; - - case ADV_HOST_SCSI_BUS_RESET: - /* - * Host generated SCSI bus reset occurred. - */ - ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n"); - break; - - default: - ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code); - break; - } + return totlen; } -#ifdef CONFIG_PROC_FS /* - * asc_prt_board_devices() + * asc_prt_adv_board_info() * - * Print driver information for devices attached to the board. + * Print dynamic board configuration information. * * Note: no single line should be greater than ASC_PRTLINE_SIZE, * cf. asc_prt_line(). @@ -4398,206 +3942,279 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) * Return the number of characters copied into 'cp'. No more than * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) +static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) { asc_board_t *boardp; int leftlen; int totlen; int len; - int chip_scsi_id; int i; + ADV_DVC_VAR *v; + ADV_DVC_CFG *c; + AdvPortAddr iop_base; + ushort chip_scsi_id; + ushort lramword; + uchar lrambyte; + ushort tagqng_able; + ushort sdtr_able, wdtr_able; + ushort wdtr_done, sdtr_done; + ushort period = 0; + int renegotiate = 0; boardp = ASC_BOARDP(shost); + v = &boardp->dvc_var.adv_dvc_var; + c = &boardp->dvc_cfg.adv_dvc_cfg; + iop_base = v->iop_base; + chip_scsi_id = v->chip_scsi_id; + leftlen = cplen; totlen = len = 0; len = asc_prt_line(cp, leftlen, - "\nDevice Information for AdvanSys SCSI Host %d:\n", + "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", shost->host_no); ASC_PRT_NEXT(); - if (ASC_NARROW_BOARD(boardp)) { - chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; - } else { - chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; - } + len = asc_prt_line(cp, leftlen, + " iop_base 0x%lx, cable_detect: %X, err_code %u\n", + v->iop_base, + AdvReadWordRegister(iop_base, + IOPW_SCSI_CFG1) & CABLE_DETECT, + v->err_code); + ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, "Target IDs Detected:"); + len = asc_prt_line(cp, leftlen, + " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n", + c->chip_version, c->lib_version, c->mcode_date, + c->mcode_version); + ASC_PRT_NEXT(); + + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + len = asc_prt_line(cp, leftlen, " Queuing Enabled:"); ASC_PRT_NEXT(); for (i = 0; i <= ADV_MAX_TID; i++) { - if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) { - len = asc_prt_line(cp, leftlen, " %X,", i); - ASC_PRT_NEXT(); + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } + + len = asc_prt_line(cp, leftlen, " %X:%c", + i, + (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); } - len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id); + len = asc_prt_line(cp, leftlen, "\n"); ASC_PRT_NEXT(); - return totlen; -} + len = asc_prt_line(cp, leftlen, " Queue Limit:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } -/* - * Display Wide Board BIOS Information. - */ -static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) -{ - asc_board_t *boardp; - int leftlen; - int totlen; - int len; - ushort major, minor, letter; + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, + lrambyte); - boardp = ASC_BOARDP(shost); - leftlen = cplen; - totlen = len = 0; + len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: "); + len = asc_prt_line(cp, leftlen, " Command Pending:"); ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } - /* - * If the BIOS saved a valid signature, then fill in - * the BIOS code segment base address. - */ - if (boardp->bios_signature != 0x55AA) { - len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n"); - ASC_PRT_NEXT(); - } else { - major = (boardp->bios_version >> 12) & 0xF; - minor = (boardp->bios_version >> 8) & 0xF; - letter = (boardp->bios_version & 0xFF); + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, + lrambyte); - len = asc_prt_line(cp, leftlen, "%d.%d%c\n", - major, minor, - letter >= 26 ? '?' : letter + 'A'); + len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* - * Current available ROM BIOS release is 3.1I for UW - * and 3.2I for U2W. This code doesn't differentiate - * UW and U2W boards. - */ - if (major < 3 || (major <= 3 && minor < 1) || - (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) { - len = asc_prt_line(cp, leftlen, - "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - "ftp://ftp.connectcom.net/pub\n"); - ASC_PRT_NEXT(); + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + len = asc_prt_line(cp, leftlen, " Wide Enabled:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } + + len = asc_prt_line(cp, leftlen, " %X:%c", + i, + (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - return totlen; -} + AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done); + len = asc_prt_line(cp, leftlen, " Transfer Bit Width:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } -/* - * Add serial number to information bar if signature AAh - * is found in at bit 15-9 (7 bits) of word 1. - * - * Serial Number consists fo 12 alpha-numeric digits. - * - * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits) - * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits) - * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits) - * 5 - Product revision (A-J) Word0: " " - * - * Signature Word1: 15-9 (7 bits) - * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit) - * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits) - * - * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits) - * - * Note 1: Only production cards will have a serial number. - * - * Note 2: Signature is most significant 7 bits (0xFE). - * - * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE. - */ -static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) -{ - ushort w, num; + AdvReadWordLram(iop_base, + ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), + lramword); - if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) { - return ASC_FALSE; - } else { - /* - * First word - 6 digits. - */ - w = serialnum[0]; + len = asc_prt_line(cp, leftlen, " %X:%d", + i, (lramword & 0x8000) ? 16 : 8); + ASC_PRT_NEXT(); - /* Product type - 1st digit. */ - if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') { - /* Product type is P=Prototype */ - *cp += 0x8; + if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) && + (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { + len = asc_prt_line(cp, leftlen, "*"); + ASC_PRT_NEXT(); + renegotiate = 1; } - cp++; + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* Manufacturing location - 2nd digit. */ - *cp++ = 'A' + ((w & 0x1C00) >> 10); + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + len = asc_prt_line(cp, leftlen, " Synchronous Enabled:"); + ASC_PRT_NEXT(); + for (i = 0; i <= ADV_MAX_TID; i++) { + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; + } - /* Product ID - 3rd, 4th digits. */ - num = w & 0x3FF; - *cp++ = '0' + (num / 100); - num %= 100; - *cp++ = '0' + (num / 10); + len = asc_prt_line(cp, leftlen, " %X:%c", + i, + (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : + 'N'); + ASC_PRT_NEXT(); + } + len = asc_prt_line(cp, leftlen, "\n"); + ASC_PRT_NEXT(); - /* Product revision - 5th digit. */ - *cp++ = 'A' + (num % 10); + AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done); + for (i = 0; i <= ADV_MAX_TID; i++) { - /* - * Second word - */ - w = serialnum[1]; + AdvReadWordLram(iop_base, + ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), + lramword); + lramword &= ~0x8000; - /* - * Year - 6th digit. - * - * If bit 15 of third word is set, then the - * last digit of the year is greater than 7. - */ - if (serialnum[2] & 0x8000) { - *cp++ = '8' + ((w & 0x1C0) >> 6); - } else { - *cp++ = '0' + ((w & 0x1C0) >> 6); + if ((chip_scsi_id == i) || + ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || + ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) { + continue; } - /* Week of year - 7th, 8th digits. */ - num = w & 0x003F; - *cp++ = '0' + num / 10; - num %= 10; - *cp++ = '0' + num; - - /* - * Third word - */ - w = serialnum[2] & 0x7FFF; + len = asc_prt_line(cp, leftlen, " %X:", i); + ASC_PRT_NEXT(); - /* Serial number - 9th digit. */ - *cp++ = 'A' + (w / 1000); + if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */ + len = asc_prt_line(cp, leftlen, " Asynchronous"); + ASC_PRT_NEXT(); + } else { + len = + asc_prt_line(cp, leftlen, + " Transfer Period Factor: "); + ASC_PRT_NEXT(); - /* 10th, 11th, 12th digits. */ - num = w % 1000; - *cp++ = '0' + num / 100; - num %= 100; - *cp++ = '0' + num / 10; - num %= 10; - *cp++ = '0' + num; + if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */ + len = + asc_prt_line(cp, leftlen, "9 (80.0 Mhz),"); + ASC_PRT_NEXT(); + } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */ + len = + asc_prt_line(cp, leftlen, "10 (40.0 Mhz),"); + ASC_PRT_NEXT(); + } else { /* 20 Mhz or below. */ - *cp = '\0'; /* Null Terminate the string. */ - return ASC_TRUE; + period = (((lramword >> 8) * 25) + 50) / 4; + + if (period == 0) { /* Should never happen. */ + len = + asc_prt_line(cp, leftlen, + "%d (? Mhz), "); + ASC_PRT_NEXT(); + } else { + len = asc_prt_line(cp, leftlen, + "%d (%d.%d Mhz),", + period, 250 / period, + ASC_TENTHS(250, + period)); + ASC_PRT_NEXT(); + } + } + + len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", + lramword & 0x1F); + ASC_PRT_NEXT(); + } + + if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { + len = asc_prt_line(cp, leftlen, "*\n"); + renegotiate = 1; + } else { + len = asc_prt_line(cp, leftlen, "\n"); + } + ASC_PRT_NEXT(); } + + if (renegotiate) { + len = asc_prt_line(cp, leftlen, + " * = Re-negotiation pending before next command.\n"); + ASC_PRT_NEXT(); + } + + return totlen; } /* - * asc_prt_asc_board_eeprom() + * asc_proc_copy() * - * Print board EEPROM configuration. + * Copy proc information to a read buffer taking into account the current + * read offset in the file and the remaining space in the read buffer. + */ +static int +asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, + char *cp, int cplen) +{ + int cnt = 0; + + ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", + (unsigned)offset, (unsigned)advoffset, cplen); + if (offset <= advoffset) { + /* Read offset below current offset, copy everything. */ + cnt = min(cplen, leftlen); + ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", + (ulong)curbuf, (ulong)cp, cnt); + memcpy(curbuf, cp, cnt); + } else if (offset < advoffset + cplen) { + /* Read offset within current range, partial copy. */ + cnt = (advoffset + cplen) - offset; + cp = (cp + cplen) - cnt; + cnt = min(cnt, leftlen); + ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", + (ulong)curbuf, (ulong)cp, cnt); + memcpy(curbuf, cp, cnt); + } + return cnt; +} + +#ifdef ADVANSYS_STATS +/* + * asc_prt_board_stats() * * Note: no single line should be greater than ASC_PRTLINE_SIZE, * cf. asc_prt_line(). @@ -4605,4673 +4222,864 @@ static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) * Return the number of characters copied into 'cp'. No more than * 'cplen' characters will be copied to 'cp'. */ -static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) +static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; int leftlen; int totlen; int len; - ASCEEP_CONFIG *ep; - int i; -#ifdef CONFIG_ISA - int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 }; -#endif /* CONFIG_ISA */ - uchar serialstr[13]; - - boardp = ASC_BOARDP(shost); - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; - ep = &boardp->eep_config.asc_eep; + struct asc_stats *s; + asc_board_t *boardp; leftlen = cplen; totlen = len = 0; + boardp = ASC_BOARDP(shost); + s = &boardp->asc_stats; + len = asc_prt_line(cp, leftlen, - "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", + "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shost->host_no); ASC_PRT_NEXT(); - if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr) - == ASC_TRUE) { - len = - asc_prt_line(cp, leftlen, " Serial Number: %s\n", - serialstr); - ASC_PRT_NEXT(); - } else { - if (ep->adapter_info[5] == 0xBB) { - len = asc_prt_line(cp, leftlen, - " Default Settings Used for EEPROM-less Adapter.\n"); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Serial Number Signature Not Present.\n"); - ASC_PRT_NEXT(); - } - } - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, - ep->max_tag_qng); + " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", + s->queuecommand, s->reset, s->biosparam, + s->interrupt); ASC_PRT_NEXT(); len = asc_prt_line(cp, leftlen, - " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam); + " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", + s->callback, s->done, s->build_error, + s->adv_build_noreq, s->adv_build_nosg); ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, " Target ID: "); + len = asc_prt_line(cp, leftlen, + " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", + s->exe_noerror, s->exe_busy, s->exe_error, + s->exe_unknown); ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %d", i); + + /* + * Display data transfer statistics. + */ + if (s->cont_cnt > 0) { + len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, " Disconnects: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); + len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", + s->cont_xfer / 2, + ASC_TENTHS(s->cont_xfer, 2)); ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, " Command Queuing: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); + /* Contiguous transfer average size */ + len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", + (s->cont_xfer / 2) / s->cont_cnt, + ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt)); ASC_PRT_NEXT(); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, " Start Motor: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); + if (s->sg_cnt > 0) { + + len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", + s->sg_cnt, s->sg_elem); ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep-> - init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); + len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", + s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2)); ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); -#ifdef CONFIG_ISA - if (asc_dvc_varp->bus_type & ASC_IS_ISA) { - len = asc_prt_line(cp, leftlen, - " Host ISA DMA speed: %d MB/S\n", - isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]); + /* Scatter gather transfer statistics */ + len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", + s->sg_elem / s->sg_cnt, + ASC_TENTHS(s->sg_elem, s->sg_cnt)); + ASC_PRT_NEXT(); + + len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", + (s->sg_xfer / 2) / s->sg_elem, + ASC_TENTHS((s->sg_xfer / 2), s->sg_elem)); + ASC_PRT_NEXT(); + + len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", + (s->sg_xfer / 2) / s->sg_cnt, + ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt)); ASC_PRT_NEXT(); } -#endif /* CONFIG_ISA */ + + /* + * Display request queuing statistics. + */ + len = asc_prt_line(cp, leftlen, + " Active and Waiting Request Queues (Time Unit: %d HZ):\n", + HZ); + ASC_PRT_NEXT(); return totlen; } +#endif /* ADVANSYS_STATS */ /* - * asc_prt_adv_board_eeprom() + * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...} * - * Print board EEPROM configuration. + * *buffer: I/O buffer + * **start: if inout == FALSE pointer into buffer where user read should start + * offset: current offset into a /proc/scsi/advansys/[0...] file + * length: length of buffer + * hostno: Scsi_Host host_no + * inout: TRUE - user is writing; FALSE - user is reading * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). + * Return the number of bytes read from or written to a + * /proc/scsi/advansys/[0...] file. * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. + * Note: This function uses the per board buffer 'prtbuf' which is + * allocated when the board is initialized in advansys_detect(). The + * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is + * used to write to the buffer. The way asc_proc_copy() is written + * if 'prtbuf' is too small it will not be overwritten. Instead the + * user just won't get all the available statistics. */ -static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) +static int +advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, + off_t offset, int length, int inout) { asc_board_t *boardp; - ADV_DVC_VAR *adv_dvc_varp; + char *cp; + int cplen; + int cnt; + int totcnt; int leftlen; - int totlen; - int len; - int i; - char *termstr; - uchar serialstr[13]; - ADVEEP_3550_CONFIG *ep_3550 = NULL; - ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL; - ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL; - ushort word; - ushort *wordp; - ushort sdtr_speed = 0; + char *curbuf; + off_t advoffset; - boardp = ASC_BOARDP(shost); - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - ep_3550 = &boardp->eep_config.adv_3550_eep; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - ep_38C0800 = &boardp->eep_config.adv_38C0800_eep; - } else { - ep_38C1600 = &boardp->eep_config.adv_38C1600_eep; + ASC_DBG(1, "advansys_proc_info: begin\n"); + + /* + * User write not supported. + */ + if (inout == TRUE) { + return (-ENOSYS); } - leftlen = cplen; - totlen = len = 0; + /* + * User read of /proc/scsi/advansys/[0...] file. + */ - len = asc_prt_line(cp, leftlen, - "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + boardp = ASC_BOARDP(shost); - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - wordp = &ep_3550->serial_number_word1; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - wordp = &ep_38C0800->serial_number_word1; - } else { - wordp = &ep_38C1600->serial_number_word1; + /* Copy read data starting at the beginning of the buffer. */ + *start = buffer; + curbuf = buffer; + advoffset = 0; + totcnt = 0; + leftlen = length; + + /* + * Get board configuration information. + * + * advansys_info() returns the board string from its own static buffer. + */ + cp = (char *)advansys_info(shost); + strcat(cp, "\n"); + cplen = strlen(cp); + /* Copy board information. */ + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } + advoffset += cplen; + curbuf += cnt; - if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) { - len = - asc_prt_line(cp, leftlen, " Serial Number: %s\n", - serialstr); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Serial Number Signature Not Present.\n"); - ASC_PRT_NEXT(); + /* + * Display Wide Board BIOS Information. + */ + if (ASC_WIDE_BOARD(boardp)) { + cp = boardp->prtbuf; + cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, + cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; + } + advoffset += cplen; + curbuf += cnt; } - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_3550->adapter_scsi_id, - ep_3550->max_host_qng, ep_3550->max_dvc_qng); - ASC_PRT_NEXT(); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_38C0800->adapter_scsi_id, - ep_38C0800->max_host_qng, - ep_38C0800->max_dvc_qng); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n", - ep_38C1600->adapter_scsi_id, - ep_38C1600->max_host_qng, - ep_38C1600->max_dvc_qng); - ASC_PRT_NEXT(); + /* + * Display driver information for each device attached to the board. + */ + cp = boardp->prtbuf; + cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - word = ep_3550->termination; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - word = ep_38C0800->termination_lvd; + advoffset += cplen; + curbuf += cnt; + + /* + * Display EEPROM configuration for the board. + */ + cp = boardp->prtbuf; + if (ASC_NARROW_BOARD(boardp)) { + cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); } else { - word = ep_38C1600->termination_lvd; + cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); } - switch (word) { - case 1: - termstr = "Low Off/High Off"; - break; - case 2: - termstr = "Low Off/High On"; - break; - case 3: - termstr = "Low On/High On"; - break; - default: - case 0: - termstr = "Automatic"; - break; + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } + advoffset += cplen; + curbuf += cnt; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_3550->termination, termstr, - ep_3550->bios_ctrl); - ASC_PRT_NEXT(); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_38C0800->termination_lvd, termstr, - ep_38C0800->bios_ctrl); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - " termination: %u (%s), bios_ctrl: 0x%x\n", - ep_38C1600->termination_lvd, termstr, - ep_38C1600->bios_ctrl); - ASC_PRT_NEXT(); + /* + * Display driver configuration and information for the board. + */ + cp = boardp->prtbuf; + cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } + advoffset += cplen; + curbuf += cnt; - len = asc_prt_line(cp, leftlen, " Target ID: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %X", i); - ASC_PRT_NEXT(); +#ifdef ADVANSYS_STATS + /* + * Display driver statistics for the board. + */ + cp = boardp->prtbuf; + cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + advoffset += cplen; + curbuf += cnt; +#endif /* ADVANSYS_STATS */ - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - word = ep_3550->disc_enable; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - word = ep_38C0800->disc_enable; + /* + * Display Asc Library dynamic configuration information + * for the board. + */ + cp = boardp->prtbuf; + if (ASC_NARROW_BOARD(boardp)) { + cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE); } else { - word = ep_38C1600->disc_enable; + cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); } - len = asc_prt_line(cp, leftlen, " Disconnects: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); + BUG_ON(cplen >= ASC_PRTBUF_SIZE); + cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); + totcnt += cnt; + leftlen -= cnt; + if (leftlen == 0) { + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + return totcnt; } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + advoffset += cplen; + curbuf += cnt; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - word = ep_3550->tagqng_able; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - word = ep_38C0800->tagqng_able; - } else { - word = ep_38C1600->tagqng_able; - } - len = asc_prt_line(cp, leftlen, " Command Queuing: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - word = ep_3550->start_motor; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - word = ep_38C0800->start_motor; + return totcnt; +} +#endif /* CONFIG_PROC_FS */ + +static void asc_scsi_done(struct scsi_cmnd *scp) +{ + struct asc_board *boardp = ASC_BOARDP(scp->device->host); + + if (scp->use_sg) + dma_unmap_sg(boardp->dev, + (struct scatterlist *)scp->request_buffer, + scp->use_sg, scp->sc_data_direction); + else if (scp->request_bufflen) + dma_unmap_single(boardp->dev, scp->SCp.dma_handle, + scp->request_bufflen, scp->sc_data_direction); + + ASC_STATS(scp->device->host, done); + + scp->scsi_done(scp); +} + +static void AscSetBank(PortAddr iop_base, uchar bank) +{ + uchar val; + + val = AscGetChipControl(iop_base) & + (~ + (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | + CC_CHIP_RESET)); + if (bank == 1) { + val |= CC_BANK_ONE; + } else if (bank == 2) { + val |= CC_DIAG | CC_BANK_ONE; } else { - word = ep_38C1600->start_motor; + val &= ~CC_BANK_ONE; } - len = asc_prt_line(cp, leftlen, " Start Motor: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); + AscSetChipControl(iop_base, val); + return; +} + +static void AscSetChipIH(PortAddr iop_base, ushort ins_code) +{ + AscSetBank(iop_base, 1); + AscWriteChipIH(iop_base, ins_code); + AscSetBank(iop_base, 0); + return; +} + +static int AscStartChip(PortAddr iop_base) +{ + AscSetChipControl(iop_base, 0); + if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { + return (0); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + return (1); +} - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep_3550-> - sdtr_able & ADV_TID_TO_TIDMASK(i)) ? - 'Y' : 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); +static int AscStopChip(PortAddr iop_base) +{ + uchar cc_val; + + cc_val = + AscGetChipControl(iop_base) & + (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); + AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT)); + AscSetChipIH(iop_base, INS_HALT); + AscSetChipIH(iop_base, INS_RFLAG_WTM); + if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { + return (0); } + return (1); +} - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - len = asc_prt_line(cp, leftlen, " Ultra Transfer: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (ep_3550-> - ultra_able & ADV_TID_TO_TIDMASK(i)) - ? 'Y' : 'N'); - ASC_PRT_NEXT(); +static int AscIsChipHalted(PortAddr iop_base) +{ + if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { + if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { + return (1); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); } + return (0); +} - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - word = ep_3550->wdtr_able; - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - word = ep_38C0800->wdtr_able; - } else { - word = ep_38C1600->wdtr_able; - } - len = asc_prt_line(cp, leftlen, " Wide Transfer: "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - len = asc_prt_line(cp, leftlen, " %c", - (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N'); - ASC_PRT_NEXT(); +static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) +{ + PortAddr iop_base; + int i = 10; + + iop_base = asc_dvc->iop_base; + while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) + && (i-- > 0)) { + mdelay(100); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + AscStopChip(iop_base); + AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); + udelay(60); + AscSetChipIH(iop_base, INS_RFLAG_WTM); + AscSetChipIH(iop_base, INS_HALT); + AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); + AscSetChipControl(iop_base, CC_HALT); + mdelay(200); + AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); + AscSetChipStatus(iop_base, 0); + return (AscIsChipHalted(iop_base)); +} - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 || - adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) { - len = asc_prt_line(cp, leftlen, - " Synchronous Transfer Speed (Mhz):\n "); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - char *speed_str; +static int AscFindSignature(PortAddr iop_base) +{ + ushort sig_word; - if (i == 0) { - sdtr_speed = adv_dvc_varp->sdtr_speed1; - } else if (i == 4) { - sdtr_speed = adv_dvc_varp->sdtr_speed2; - } else if (i == 8) { - sdtr_speed = adv_dvc_varp->sdtr_speed3; - } else if (i == 12) { - sdtr_speed = adv_dvc_varp->sdtr_speed4; - } - switch (sdtr_speed & ADV_MAX_TID) { - case 0: - speed_str = "Off"; - break; - case 1: - speed_str = " 5"; - break; - case 2: - speed_str = " 10"; - break; - case 3: - speed_str = " 20"; - break; - case 4: - speed_str = " 40"; - break; - case 5: - speed_str = " 80"; - break; - default: - speed_str = "Unk"; - break; - } - len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str); - ASC_PRT_NEXT(); - if (i == 7) { - len = asc_prt_line(cp, leftlen, "\n "); - ASC_PRT_NEXT(); - } - sdtr_speed >>= 4; + ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n", + iop_base, AscGetChipSignatureByte(iop_base)); + if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) { + ASC_DBG2(1, + "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n", + iop_base, AscGetChipSignatureWord(iop_base)); + sig_word = AscGetChipSignatureWord(iop_base); + if ((sig_word == (ushort)ASC_1000_ID0W) || + (sig_word == (ushort)ASC_1000_ID0W_FIX)) { + return (1); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); } - - return totlen; + return (0); } -/* - * asc_prt_driver_conf() - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. - */ -static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) +static void AscEnableInterrupt(PortAddr iop_base) { - asc_board_t *boardp; - int leftlen; - int totlen; - int len; - int chip_scsi_id; + ushort cfg; - boardp = ASC_BOARDP(shost); + cfg = AscGetChipCfgLsw(iop_base); + AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); + return; +} - leftlen = cplen; - totlen = len = 0; +static void AscDisableInterrupt(PortAddr iop_base) +{ + ushort cfg; - len = asc_prt_line(cp, leftlen, - "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + cfg = AscGetChipCfgLsw(iop_base); + AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); + return; +} - len = asc_prt_line(cp, leftlen, - " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n", - shost->host_busy, shost->last_reset, shost->max_id, - shost->max_lun, shost->max_channel); - ASC_PRT_NEXT(); +static uchar AscReadLramByte(PortAddr iop_base, ushort addr) +{ + unsigned char byte_data; + unsigned short word_data; - len = asc_prt_line(cp, leftlen, - " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n", - shost->unique_id, shost->can_queue, shost->this_id, - shost->sg_tablesize, shost->cmd_per_lun); - ASC_PRT_NEXT(); + if (isodd_word(addr)) { + AscSetChipLramAddr(iop_base, addr - 1); + word_data = AscGetChipLramData(iop_base); + byte_data = (word_data >> 8) & 0xFF; + } else { + AscSetChipLramAddr(iop_base, addr); + word_data = AscGetChipLramData(iop_base); + byte_data = word_data & 0xFF; + } + return byte_data; +} - len = asc_prt_line(cp, leftlen, - " unchecked_isa_dma %d, use_clustering %d\n", - shost->unchecked_isa_dma, shost->use_clustering); - ASC_PRT_NEXT(); +static ushort AscReadLramWord(PortAddr iop_base, ushort addr) +{ + ushort word_data; - len = asc_prt_line(cp, leftlen, - " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n", - boardp->flags, boardp->last_reset, jiffies, - boardp->asc_n_io_port); - ASC_PRT_NEXT(); + AscSetChipLramAddr(iop_base, addr); + word_data = AscGetChipLramData(iop_base); + return (word_data); +} - len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port); - ASC_PRT_NEXT(); +#if CC_VERY_LONG_SG_LIST +static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr) +{ + ushort val_low, val_high; + ASC_DCNT dword_data; - if (ASC_NARROW_BOARD(boardp)) { - chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; - } else { - chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; + AscSetChipLramAddr(iop_base, addr); + val_low = AscGetChipLramData(iop_base); + val_high = AscGetChipLramData(iop_base); + dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low; + return (dword_data); +} +#endif /* CC_VERY_LONG_SG_LIST */ + +static void +AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) +{ + int i; + + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < words; i++) { + AscSetChipLramData(iop_base, set_wval); } +} - return totlen; +static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) +{ + AscSetChipLramAddr(iop_base, addr); + AscSetChipLramData(iop_base, word_val); + return; +} + +static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) +{ + ushort word_data; + + if (isodd_word(addr)) { + addr--; + word_data = AscReadLramWord(iop_base, addr); + word_data &= 0x00FF; + word_data |= (((ushort)byte_val << 8) & 0xFF00); + } else { + word_data = AscReadLramWord(iop_base, addr); + word_data &= 0xFF00; + word_data |= ((ushort)byte_val & 0x00FF); + } + AscWriteLramWord(iop_base, addr, word_data); + return; } /* - * asc_prt_asc_board_info() - * - * Print dynamic board configuration information. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). + * Copy 2 bytes to LRAM. * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. + * The source data is assumed to be in little-endian order in memory + * and is maintained in little-endian order when written to LRAM. */ -static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) +static void +AscMemWordCopyPtrToLram(PortAddr iop_base, + ushort s_addr, uchar *s_buffer, int words) { - asc_board_t *boardp; - int chip_scsi_id; - int leftlen; - int totlen; - int len; - ASC_DVC_VAR *v; - ASC_DVC_CFG *c; int i; - int renegotiate = 0; - - boardp = ASC_BOARDP(shost); - v = &boardp->dvc_var.asc_dvc_var; - c = &boardp->dvc_cfg.asc_dvc_cfg; - chip_scsi_id = c->chip_scsi_id; - - leftlen = cplen; - totlen = len = 0; - len = asc_prt_line(cp, leftlen, - "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < 2 * words; i += 2) { + /* + * On a little-endian system the second argument below + * produces a little-endian ushort which is written to + * LRAM in little-endian order. On a big-endian system + * the second argument produces a big-endian ushort which + * is "transparently" byte-swapped by outpw() and written + * in little-endian order to LRAM. + */ + outpw(iop_base + IOP_RAM_DATA, + ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); + } + return; +} - len = asc_prt_line(cp, leftlen, - " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n", - c->chip_version, c->lib_version, c->lib_serial_no, - c->mcode_date); - ASC_PRT_NEXT(); +/* + * Copy 4 bytes to LRAM. + * + * The source data is assumed to be in little-endian order in memory + * and is maintained in little-endian order when writen to LRAM. + */ +static void +AscMemDWordCopyPtrToLram(PortAddr iop_base, + ushort s_addr, uchar *s_buffer, int dwords) +{ + int i; - len = asc_prt_line(cp, leftlen, - " mcode_version 0x%x, err_code %u\n", - c->mcode_version, v->err_code); - ASC_PRT_NEXT(); + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < 4 * dwords; i += 4) { + outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ + outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ + } + return; +} - /* Current number of commands waiting for the host. */ - len = asc_prt_line(cp, leftlen, - " Total Command Pending: %d\n", v->cur_total_qng); - ASC_PRT_NEXT(); +/* + * Copy 2 bytes from LRAM. + * + * The source data is assumed to be in little-endian order in LRAM + * and is maintained in little-endian order when written to memory. + */ +static void +AscMemWordCopyPtrFromLram(PortAddr iop_base, + ushort s_addr, uchar *d_buffer, int words) +{ + int i; + ushort word; - len = asc_prt_line(cp, leftlen, " Command Queuing:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (v-> - use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? - 'Y' : 'N'); - ASC_PRT_NEXT(); + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < 2 * words; i += 2) { + word = inpw(iop_base + IOP_RAM_DATA); + d_buffer[i] = word & 0xff; + d_buffer[i + 1] = (word >> 8) & 0xff; } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + return; +} - /* Current number of commands waiting for a device. */ - len = asc_prt_line(cp, leftlen, " Command Queue Pending:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); +static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) +{ + ASC_DCNT sum; + int i; - /* Current limit on number of commands that can be sent to a device. */ - len = asc_prt_line(cp, leftlen, " Command Queue Limit:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]); - ASC_PRT_NEXT(); + sum = 0L; + for (i = 0; i < words; i++, s_addr += 2) { + sum += AscReadLramWord(iop_base, s_addr); } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + return (sum); +} - /* Indicate whether the device has returned queue full status. */ - len = asc_prt_line(cp, leftlen, " Command Queue Full:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) { - len = asc_prt_line(cp, leftlen, " %X:Y-%d", - i, boardp->queue_full_cnt[i]); - } else { - len = asc_prt_line(cp, leftlen, " %X:N", i); - } - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Synchronous Transfer:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ASC_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (v-> - sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - for (i = 0; i <= ASC_MAX_TID; i++) { - uchar syn_period_ix; - - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || - ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - len = asc_prt_line(cp, leftlen, " %X:", i); - ASC_PRT_NEXT(); - - if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) { - len = asc_prt_line(cp, leftlen, " Asynchronous"); - ASC_PRT_NEXT(); - } else { - syn_period_ix = - (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - - 1); - - len = asc_prt_line(cp, leftlen, - " Transfer Period Factor: %d (%d.%d Mhz),", - v->sdtr_period_tbl[syn_period_ix], - 250 / - v->sdtr_period_tbl[syn_period_ix], - ASC_TENTHS(250, - v-> - sdtr_period_tbl - [syn_period_ix])); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", - boardp-> - sdtr_data[i] & ASC_SYN_MAX_OFFSET); - ASC_PRT_NEXT(); - } +static ushort AscInitLram(ASC_DVC_VAR *asc_dvc) +{ + uchar i; + ushort s_addr; + PortAddr iop_base; + ushort warn_code; - if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*\n"); - renegotiate = 1; - } else { - len = asc_prt_line(cp, leftlen, "\n"); - } - ASC_PRT_NEXT(); + iop_base = asc_dvc->iop_base; + warn_code = 0; + AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, + (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) * + 64) >> 1)); + i = ASC_MIN_ACTIVE_QNO; + s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), + (uchar)(i + 1)); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), + (uchar)(asc_dvc->max_total_qng)); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), + (uchar)i); + i++; + s_addr += ASC_QBLK_SIZE; + for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), + (uchar)(i + 1)); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), + (uchar)(i - 1)); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), + (uchar)i); } - - if (renegotiate) { - len = asc_prt_line(cp, leftlen, - " * = Re-negotiation pending before next command.\n"); - ASC_PRT_NEXT(); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), + (uchar)ASC_QLINK_END); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), + (uchar)(asc_dvc->max_total_qng - 1)); + AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), + (uchar)asc_dvc->max_total_qng); + i++; + s_addr += ASC_QBLK_SIZE; + for (; i <= (uchar)(asc_dvc->max_total_qng + 3); + i++, s_addr += ASC_QBLK_SIZE) { + AscWriteLramByte(iop_base, + (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i); + AscWriteLramByte(iop_base, + (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i); + AscWriteLramByte(iop_base, + (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i); } - - return totlen; + return warn_code; } -/* - * asc_prt_adv_board_info() - * - * Print dynamic board configuration information. - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. - */ -static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) +static ASC_DCNT +AscLoadMicroCode(PortAddr iop_base, + ushort s_addr, uchar *mcode_buf, ushort mcode_size) { - asc_board_t *boardp; - int leftlen; - int totlen; - int len; - int i; - ADV_DVC_VAR *v; - ADV_DVC_CFG *c; - AdvPortAddr iop_base; - ushort chip_scsi_id; - ushort lramword; - uchar lrambyte; - ushort tagqng_able; - ushort sdtr_able, wdtr_able; - ushort wdtr_done, sdtr_done; - ushort period = 0; - int renegotiate = 0; - - boardp = ASC_BOARDP(shost); - v = &boardp->dvc_var.adv_dvc_var; - c = &boardp->dvc_cfg.adv_dvc_cfg; - iop_base = v->iop_base; - chip_scsi_id = v->chip_scsi_id; - - leftlen = cplen; - totlen = len = 0; - - len = asc_prt_line(cp, leftlen, - "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " iop_base 0x%lx, cable_detect: %X, err_code %u\n", - v->iop_base, - AdvReadWordRegister(iop_base, - IOPW_SCSI_CFG1) & CABLE_DETECT, - v->err_code); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n", - c->chip_version, c->lib_version, c->mcode_date, - c->mcode_version); - ASC_PRT_NEXT(); - - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - len = asc_prt_line(cp, leftlen, " Queuing Enabled:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, " Queue Limit:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, - lrambyte); - - len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); + ASC_DCNT chksum; + ushort mcode_word_size; + ushort mcode_chksum; - len = asc_prt_line(cp, leftlen, " Command Pending:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } + /* Write the microcode buffer starting at LRAM address 0. */ + mcode_word_size = (ushort)(mcode_size >> 1); + AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); + AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, - lrambyte); + chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); + ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum); + mcode_chksum = (ushort)AscMemSumLramWord(iop_base, + (ushort)ASC_CODE_SEC_BEG, + (ushort)((mcode_size - + s_addr - (ushort) + ASC_CODE_SEC_BEG) / + 2)); + ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n", + (ulong)mcode_chksum); + AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); + AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); + return (chksum); +} - len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - len = asc_prt_line(cp, leftlen, " Wide Enabled:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done); - len = asc_prt_line(cp, leftlen, " Transfer Bit Width:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - AdvReadWordLram(iop_base, - ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), - lramword); - - len = asc_prt_line(cp, leftlen, " %X:%d", - i, (lramword & 0x8000) ? 16 : 8); - ASC_PRT_NEXT(); - - if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) && - (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*"); - ASC_PRT_NEXT(); - renegotiate = 1; - } - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); +/* Microcode buffer is kept after initialization for error recovery. */ +static uchar _asc_mcode_buf[] = { + 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04, + 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, + 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, + 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, + 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, + 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, + 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, + 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, + 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04, + 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88, + 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, + 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, + 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, + 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6, + 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, + 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, + 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, + 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23, + 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, + 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, + 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, + 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01, + 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, + 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, + 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23, + 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, + 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, + 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, + 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84, + 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, + 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, + 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, + 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, + 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, + 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, + 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, + 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82, + 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95, + 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, + 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, + 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23, + 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, + 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, + 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, + 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02, + 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02, + 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, + 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, + 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, + 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82, + 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, + 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, + 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6, + 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6, + 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, + 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, + 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01, + 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, + 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, + 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, + 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83, + 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33, + 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, + 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, + 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00, + 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03, + 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, + 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, + 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95, + 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42, + 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, + 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, + 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84, + 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, + 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, + 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, + 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4, + 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, + 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, + 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, + 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84, + 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, + 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, + 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, + 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, + 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, + 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, + 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, + 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00, + 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98, + 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, + 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, + 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62, + 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23, + 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, + 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, + 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95, + 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, + 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, + 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, + 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01, + 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, + 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, + 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, + 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05, + 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, + 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, + 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, + 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63, + 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, + 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, + 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, + 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85, + 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, + 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, + 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, + 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87, + 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, + 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, + 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, + 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60, + 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, + 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, + 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, + 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33, + 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, + 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, + 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, + 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, + 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, + 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, + 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, + 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06, + 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, + 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, + 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, + 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33, + 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, + 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, + 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, + 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88, + 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, + 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, + 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, + 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, + 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, + 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, + 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, + 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, + 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, + 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, + 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, + 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, + 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, + 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, + 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, + 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, + 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, + 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, + 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, + 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, + 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, + 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, + 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, + 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01, + 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, + 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, + 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, + 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88, + 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, + 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, + 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, + 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, + 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, + 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, + 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, + 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73, + 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, + 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, + 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, + 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23, + 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, +}; - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - len = asc_prt_line(cp, leftlen, " Synchronous Enabled:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - len = asc_prt_line(cp, leftlen, " %X:%c", - i, - (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : - 'N'); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); - - AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done); - for (i = 0; i <= ADV_MAX_TID; i++) { - - AdvReadWordLram(iop_base, - ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i), - lramword); - lramword &= ~0x8000; - - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) || - ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - - len = asc_prt_line(cp, leftlen, " %X:", i); - ASC_PRT_NEXT(); - - if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */ - len = asc_prt_line(cp, leftlen, " Asynchronous"); - ASC_PRT_NEXT(); - } else { - len = - asc_prt_line(cp, leftlen, - " Transfer Period Factor: "); - ASC_PRT_NEXT(); - - if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */ - len = - asc_prt_line(cp, leftlen, "9 (80.0 Mhz),"); - ASC_PRT_NEXT(); - } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */ - len = - asc_prt_line(cp, leftlen, "10 (40.0 Mhz),"); - ASC_PRT_NEXT(); - } else { /* 20 Mhz or below. */ - - period = (((lramword >> 8) * 25) + 50) / 4; - - if (period == 0) { /* Should never happen. */ - len = - asc_prt_line(cp, leftlen, - "%d (? Mhz), "); - ASC_PRT_NEXT(); - } else { - len = asc_prt_line(cp, leftlen, - "%d (%d.%d Mhz),", - period, 250 / period, - ASC_TENTHS(250, - period)); - ASC_PRT_NEXT(); - } - } - - len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d", - lramword & 0x1F); - ASC_PRT_NEXT(); - } - - if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) { - len = asc_prt_line(cp, leftlen, "*\n"); - renegotiate = 1; - } else { - len = asc_prt_line(cp, leftlen, "\n"); - } - ASC_PRT_NEXT(); - } - - if (renegotiate) { - len = asc_prt_line(cp, leftlen, - " * = Re-negotiation pending before next command.\n"); - ASC_PRT_NEXT(); - } - - return totlen; -} - -/* - * asc_proc_copy() - * - * Copy proc information to a read buffer taking into account the current - * read offset in the file and the remaining space in the read buffer. - */ -static int -asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, - char *cp, int cplen) -{ - int cnt = 0; - - ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", - (unsigned)offset, (unsigned)advoffset, cplen); - if (offset <= advoffset) { - /* Read offset below current offset, copy everything. */ - cnt = min(cplen, leftlen); - ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", - (ulong)curbuf, (ulong)cp, cnt); - memcpy(curbuf, cp, cnt); - } else if (offset < advoffset + cplen) { - /* Read offset within current range, partial copy. */ - cnt = (advoffset + cplen) - offset; - cp = (cp + cplen) - cnt; - cnt = min(cnt, leftlen); - ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", - (ulong)curbuf, (ulong)cp, cnt); - memcpy(curbuf, cp, cnt); - } - return cnt; -} - -/* - * asc_prt_line() - * - * If 'cp' is NULL print to the console, otherwise print to a buffer. - * - * Return 0 if printing to the console, otherwise return the number of - * bytes written to the buffer. - * - * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack - * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. - */ -static int asc_prt_line(char *buf, int buflen, char *fmt, ...) -{ - va_list args; - int ret; - char s[ASC_PRTLINE_SIZE]; - - va_start(args, fmt); - ret = vsprintf(s, fmt, args); - BUG_ON(ret >= ASC_PRTLINE_SIZE); - if (buf == NULL) { - (void)printk(s); - ret = 0; - } else { - ret = min(buflen, ret); - memcpy(buf, s, ret); - } - va_end(args); - return ret; -} -#endif /* CONFIG_PROC_FS */ - -/* - * void - * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) - * - * Calling/Exit State: - * none - * - * Description: - * Output an ASC_SCSI_Q structure to the chip - */ -static void -DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) -{ - int i; - - ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words); - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < 2 * words; i += 2) { - if (i == 4 || i == 20) { - continue; - } - outpw(iop_base + IOP_RAM_DATA, - ((ushort)outbuf[i + 1] << 8) | outbuf[i]); - } -} - -/* - * void - * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) - * - * Calling/Exit State: - * none - * - * Description: - * Input an ASC_QDONE_INFO structure from the chip - */ -static void -DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) -{ - int i; - ushort word; - - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < 2 * words; i += 2) { - if (i == 10) { - continue; - } - word = inpw(iop_base + IOP_RAM_DATA); - inbuf[i] = word & 0xff; - inbuf[i + 1] = (word >> 8) & 0xff; - } - ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words); -} - -/* - * Return the BIOS address of the adapter at the specified - * I/O port and with the specified bus type. - */ -static unsigned short __devinit -AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type) -{ - unsigned short cfg_lsw; - unsigned short bios_addr; - - /* - * The PCI BIOS is re-located by the motherboard BIOS. Because - * of this the driver can not determine where a PCI BIOS is - * loaded and executes. - */ - if (bus_type & ASC_IS_PCI) - return 0; - -#ifdef CONFIG_ISA - if ((bus_type & ASC_IS_EISA) != 0) { - cfg_lsw = AscGetEisaChipCfg(iop_base); - cfg_lsw &= 0x000F; - bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE; - return bios_addr; - } -#endif /* CONFIG_ISA */ - - cfg_lsw = AscGetChipCfgLsw(iop_base); - - /* - * ISA PnP uses the top bit as the 32K BIOS flag - */ - if (bus_type == ASC_IS_ISAPNP) - cfg_lsw &= 0x7FFF; - bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE; - return bios_addr; -} - -/* - * DvcGetPhyAddr() - * - * Return the physical address of 'vaddr' and set '*lenp' to the - * number of physically contiguous bytes that follow 'vaddr'. - * 'flag' indicates the type of structure whose physical address - * is being translated. - * - * Note: Because Linux currently doesn't page the kernel and all - * kernel buffers are physically contiguous, leave '*lenp' unchanged. - */ -ADV_PADDR -DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, - uchar *vaddr, ADV_SDCNT *lenp, int flag) -{ - ADV_PADDR paddr; - - paddr = virt_to_bus(vaddr); - - ASC_DBG4(4, - "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", - (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp), - (ulong)paddr); - - return paddr; -} - -#ifdef ADVANSYS_STATS -#ifdef CONFIG_PROC_FS -/* - * asc_prt_board_stats() - * - * Note: no single line should be greater than ASC_PRTLINE_SIZE, - * cf. asc_prt_line(). - * - * Return the number of characters copied into 'cp'. No more than - * 'cplen' characters will be copied to 'cp'. - */ -static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) -{ - int leftlen; - int totlen; - int len; - struct asc_stats *s; - asc_board_t *boardp; - - leftlen = cplen; - totlen = len = 0; - - boardp = ASC_BOARDP(shost); - s = &boardp->asc_stats; - - len = asc_prt_line(cp, leftlen, - "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", - shost->host_no); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", - s->queuecommand, s->reset, s->biosparam, - s->interrupt); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", - s->callback, s->done, s->build_error, - s->adv_build_noreq, s->adv_build_nosg); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", - s->exe_noerror, s->exe_busy, s->exe_error, - s->exe_unknown); - ASC_PRT_NEXT(); - - /* - * Display data transfer statistics. - */ - if (s->cont_cnt > 0) { - len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", - s->cont_xfer / 2, - ASC_TENTHS(s->cont_xfer, 2)); - ASC_PRT_NEXT(); - - /* Contiguous transfer average size */ - len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", - (s->cont_xfer / 2) / s->cont_cnt, - ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt)); - ASC_PRT_NEXT(); - } - - if (s->sg_cnt > 0) { - - len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", - s->sg_cnt, s->sg_elem); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", - s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2)); - ASC_PRT_NEXT(); - - /* Scatter gather transfer statistics */ - len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", - s->sg_elem / s->sg_cnt, - ASC_TENTHS(s->sg_elem, s->sg_cnt)); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", - (s->sg_xfer / 2) / s->sg_elem, - ASC_TENTHS((s->sg_xfer / 2), s->sg_elem)); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", - (s->sg_xfer / 2) / s->sg_cnt, - ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt)); - ASC_PRT_NEXT(); - } - - /* - * Display request queuing statistics. - */ - len = asc_prt_line(cp, leftlen, - " Active and Waiting Request Queues (Time Unit: %d HZ):\n", - HZ); - ASC_PRT_NEXT(); - - return totlen; -} -#endif /* CONFIG_PROC_FS */ -#endif /* ADVANSYS_STATS */ - -#ifdef ADVANSYS_DEBUG -/* - * asc_prt_scsi_host() - */ -static void asc_prt_scsi_host(struct Scsi_Host *s) -{ - asc_board_t *boardp; - - boardp = ASC_BOARDP(s); - - printk("Scsi_Host at addr 0x%lx\n", (ulong)s); - printk(" host_busy %u, host_no %d, last_reset %d,\n", - s->host_busy, s->host_no, (unsigned)s->last_reset); - - printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", - (ulong)s->base, (ulong)s->io_port, s->irq); - - printk(" dma_channel %d, this_id %d, can_queue %d,\n", - s->dma_channel, s->this_id, s->can_queue); - - printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", - s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); - - if (ASC_NARROW_BOARD(boardp)) { - asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); - asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); - } else { - asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); - asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); - } -} - -/* - * asc_prt_scsi_cmnd() - */ -static void asc_prt_scsi_cmnd(struct scsi_cmnd *s) -{ - printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s); - - printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", - (ulong)s->device->host, (ulong)s->device, s->device->id, - s->device->lun, s->device->channel); - - asc_prt_hex(" CDB", s->cmnd, s->cmd_len); - - printk("sc_data_direction %u, resid %d\n", - s->sc_data_direction, s->resid); - - printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len); - - printk(" serial_number 0x%x, retries %d, allowed %d\n", - (unsigned)s->serial_number, s->retries, s->allowed); - - printk(" timeout_per_command %d\n", s->timeout_per_command); - - printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n", - s->scsi_done, s->done, s->host_scribble, s->result); - - printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid); -} - -/* - * asc_prt_asc_dvc_var() - */ -static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) -{ - printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h); - - printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl " - "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); - - printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type, - (unsigned)h->init_sdtr); - - printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, " - "chip_no 0x%x,\n", (unsigned)h->sdtr_done, - (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready, - (unsigned)h->chip_no); - - printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait " - "%u,\n", (unsigned)h->queue_full_or_busy, - (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); - - printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, " - "in_critical_cnt %u,\n", (unsigned)h->is_in_int, - (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng, - (unsigned)h->in_critical_cnt); - - printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, " - "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage, - (unsigned)h->init_state, (unsigned)h->no_scam, - (unsigned)h->pci_fix_asyn_xfer); - - printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); -} - -/* - * asc_prt_asc_dvc_cfg() - */ -static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) -{ - printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h); - - printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n", - h->can_tagged_qng, h->cmd_qng_enabled); - printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n", - h->disc_enable, h->sdtr_enable); - - printk - (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", - h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, - h->chip_version); - - printk - (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", - to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, - h->mcode_date); - - printk(" mcode_version %d, overrun_buf 0x%lx\n", - h->mcode_version, (ulong)h->overrun_buf); -} - -/* - * asc_prt_asc_scsi_q() - */ -static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) -{ - ASC_SG_HEAD *sgp; - int i; - - printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); - - printk - (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", - q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, - q->q2.tag_code); - - printk - (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", - (ulong)le32_to_cpu(q->q1.data_addr), - (ulong)le32_to_cpu(q->q1.data_cnt), - (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); - - printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", - (ulong)q->cdbptr, q->q2.cdb_len, - (ulong)q->sg_head, q->q1.sg_queue_cnt); - - if (q->sg_head) { - sgp = q->sg_head; - printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); - printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, - sgp->queue_cnt); - for (i = 0; i < sgp->entry_cnt; i++) { - printk(" [%u]: addr 0x%lx, bytes %lu\n", - i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), - (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); - } - - } -} - -/* - * asc_prt_asc_qdone_info() - */ -static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) -{ - printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); - printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", - (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, - q->d2.tag_code); - printk - (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", - q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); -} - -/* - * asc_prt_adv_dvc_var() - * - * Display an ADV_DVC_VAR structure. - */ -static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) -{ - printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h); - - printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", - (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able); - - printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n", - (ulong)h->isr_callback, (unsigned)h->sdtr_able, - (unsigned)h->wdtr_able); - - printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", - (unsigned)h->start_motor, - (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no); - - printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", - (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, - (ulong)h->carr_freelist); - - printk(" icq_sp 0x%lx, irq_sp 0x%lx\n", - (ulong)h->icq_sp, (ulong)h->irq_sp); - - printk(" no_scam 0x%x, tagqng_able 0x%x\n", - (unsigned)h->no_scam, (unsigned)h->tagqng_able); - - printk(" chip_scsi_id 0x%x, cfg 0x%lx\n", - (unsigned)h->chip_scsi_id, (ulong)h->cfg); -} - -/* - * asc_prt_adv_dvc_cfg() - * - * Display an ADV_DVC_CFG structure. - */ -static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) -{ - printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h); - - printk(" disc_enable 0x%x, termination 0x%x\n", - h->disc_enable, h->termination); - - printk(" chip_version 0x%x, mcode_date 0x%x\n", - h->chip_version, h->mcode_date); - - printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", - h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); - - printk(" control_flag 0x%x\n", h->control_flag); -} - -/* - * asc_prt_adv_scsi_req_q() - * - * Display an ADV_SCSI_REQ_Q structure. - */ -static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) -{ - int sg_blk_cnt; - struct asc_sg_block *sg_ptr; - - printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); - - printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", - q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); - - printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", - q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); - - printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", - (ulong)le32_to_cpu(q->data_cnt), - (ulong)le32_to_cpu(q->sense_addr), q->sense_len); - - printk - (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", - q->cdb_len, q->done_status, q->host_status, q->scsi_status); - - printk(" sg_working_ix 0x%x, target_cmd %u\n", - q->sg_working_ix, q->target_cmd); - - printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", - (ulong)le32_to_cpu(q->scsiq_rptr), - (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); - - /* Display the request's ADV_SG_BLOCK structures. */ - if (q->sg_list_ptr != NULL) { - sg_blk_cnt = 0; - while (1) { - /* - * 'sg_ptr' is a physical address. Convert it to a virtual - * address by indexing 'sg_blk_cnt' into the virtual address - * array 'sg_list_ptr'. - * - * XXX - Assumes all SG physical blocks are virtually contiguous. - */ - sg_ptr = - &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); - asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); - if (sg_ptr->sg_ptr == 0) { - break; - } - sg_blk_cnt++; - } - } -} - -/* - * asc_prt_adv_sgblock() - * - * Display an ADV_SG_BLOCK structure. - */ -static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) -{ - int i; - - printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", - (ulong)b, sgblockno); - printk(" sg_cnt %u, sg_ptr 0x%lx\n", - b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); - BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); - if (b->sg_ptr != 0) - BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); - for (i = 0; i < b->sg_cnt; i++) { - printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", - i, (ulong)b->sg_list[i].sg_addr, - (ulong)b->sg_list[i].sg_count); - } -} - -/* - * asc_prt_hex() - * - * Print hexadecimal output in 4 byte groupings 32 bytes - * or 8 double-words per line. - */ -static void asc_prt_hex(char *f, uchar *s, int l) -{ - int i; - int j; - int k; - int m; - - printk("%s: (%d bytes)\n", f, l); - - for (i = 0; i < l; i += 32) { - - /* Display a maximum of 8 double-words per line. */ - if ((k = (l - i) / 4) >= 8) { - k = 8; - m = 0; - } else { - m = (l - i) % 4; - } - - for (j = 0; j < k; j++) { - printk(" %2.2X%2.2X%2.2X%2.2X", - (unsigned)s[i + (j * 4)], - (unsigned)s[i + (j * 4) + 1], - (unsigned)s[i + (j * 4) + 2], - (unsigned)s[i + (j * 4) + 3]); - } - - switch (m) { - case 0: - default: - break; - case 1: - printk(" %2.2X", (unsigned)s[i + (j * 4)]); - break; - case 2: - printk(" %2.2X%2.2X", - (unsigned)s[i + (j * 4)], - (unsigned)s[i + (j * 4) + 1]); - break; - case 3: - printk(" %2.2X%2.2X%2.2X", - (unsigned)s[i + (j * 4) + 1], - (unsigned)s[i + (j * 4) + 2], - (unsigned)s[i + (j * 4) + 3]); - break; - } - - printk("\n"); - } -} -#endif /* ADVANSYS_DEBUG */ - -static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base) -{ - PortAddr eisa_cfg_iop; - - eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | - (PortAddr) (ASC_EISA_CFG_IOP_MASK); - return (inpw(eisa_cfg_iop)); -} - -static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) -{ - ushort cfg_lsw; - - if (AscGetChipScsiID(iop_base) == new_host_id) { - return (new_host_id); - } - cfg_lsw = AscGetChipCfgLsw(iop_base); - cfg_lsw &= 0xF8FF; - cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8); - AscSetChipCfgLsw(iop_base, cfg_lsw); - return (AscGetChipScsiID(iop_base)); -} - -static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base) -{ - unsigned char sc; - - AscSetBank(iop_base, 1); - sc = inp(iop_base + IOP_REG_SC); - AscSetBank(iop_base, 0); - return sc; -} - -static unsigned char __devinit -AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) -{ - if (bus_type & ASC_IS_EISA) { - PortAddr eisa_iop; - unsigned char revision; - eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | - (PortAddr) ASC_EISA_REV_IOP_MASK; - revision = inp(eisa_iop); - return ASC_CHIP_MIN_VER_EISA - 1 + revision; - } - return AscGetChipVerNo(iop_base); -} - -static ASC_DCNT -AscLoadMicroCode(PortAddr iop_base, - ushort s_addr, uchar *mcode_buf, ushort mcode_size) -{ - ASC_DCNT chksum; - ushort mcode_word_size; - ushort mcode_chksum; - - /* Write the microcode buffer starting at LRAM address 0. */ - mcode_word_size = (ushort)(mcode_size >> 1); - AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); - AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); - - chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); - ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum); - mcode_chksum = (ushort)AscMemSumLramWord(iop_base, - (ushort)ASC_CODE_SEC_BEG, - (ushort)((mcode_size - - s_addr - (ushort) - ASC_CODE_SEC_BEG) / - 2)); - ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n", - (ulong)mcode_chksum); - AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); - AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); - return (chksum); -} - -static int AscFindSignature(PortAddr iop_base) -{ - ushort sig_word; - - ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n", - iop_base, AscGetChipSignatureByte(iop_base)); - if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) { - ASC_DBG2(1, - "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n", - iop_base, AscGetChipSignatureWord(iop_base)); - sig_word = AscGetChipSignatureWord(iop_base); - if ((sig_word == (ushort)ASC_1000_ID0W) || - (sig_word == (ushort)ASC_1000_ID0W_FIX)) { - return (1); - } - } - return (0); -} - -static void __devinit AscToggleIRQAct(PortAddr iop_base) -{ - AscSetChipStatus(iop_base, CIW_IRQ_ACT); - AscSetChipStatus(iop_base, 0); - return; -} - -static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type) -{ - ushort cfg_lsw; - uchar chip_irq; - - if ((bus_type & ASC_IS_EISA) != 0) { - cfg_lsw = AscGetEisaChipCfg(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10); - if ((chip_irq == 13) || (chip_irq > 15)) { - return (0); - } - return (chip_irq); - } - if ((bus_type & ASC_IS_VL) != 0) { - cfg_lsw = AscGetChipCfgLsw(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07)); - if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) { - return (0); - } - return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1))); - } - cfg_lsw = AscGetChipCfgLsw(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03)); - if (chip_irq == 3) - chip_irq += (uchar)2; - return ((uchar)(chip_irq + ASC_MIN_IRQ_NO)); -} - -static uchar __devinit -AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) -{ - ushort cfg_lsw; - - if ((bus_type & ASC_IS_VL) != 0) { - if (irq_no != 0) { - if ((irq_no < ASC_MIN_IRQ_NO) - || (irq_no > ASC_MAX_IRQ_NO)) { - irq_no = 0; - } else { - irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1)); - } - } - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3); - cfg_lsw |= (ushort)0x0010; - AscSetChipCfgLsw(iop_base, cfg_lsw); - AscToggleIRQAct(iop_base); - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0); - cfg_lsw |= (ushort)((irq_no & 0x07) << 2); - AscSetChipCfgLsw(iop_base, cfg_lsw); - AscToggleIRQAct(iop_base); - return (AscGetChipIRQ(iop_base, bus_type)); - } - if ((bus_type & (ASC_IS_ISA)) != 0) { - if (irq_no == 15) - irq_no -= (uchar)2; - irq_no -= (uchar)ASC_MIN_IRQ_NO; - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3); - cfg_lsw |= (ushort)((irq_no & 0x03) << 2); - AscSetChipCfgLsw(iop_base, cfg_lsw); - return (AscGetChipIRQ(iop_base, bus_type)); - } - return (0); -} - -#ifdef CONFIG_ISA -static void __devinit AscEnableIsaDma(uchar dma_channel) -{ - if (dma_channel < 4) { - outp(0x000B, (ushort)(0xC0 | dma_channel)); - outp(0x000A, dma_channel); - } else if (dma_channel < 8) { - outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); - outp(0x00D4, (ushort)(dma_channel - 4)); - } - return; -} -#endif /* CONFIG_ISA */ - -static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) -{ - EXT_MSG ext_msg; - EXT_MSG out_msg; - ushort halt_q_addr; - int sdtr_accept; - ushort int_halt_code; - ASC_SCSI_BIT_ID_TYPE scsi_busy; - ASC_SCSI_BIT_ID_TYPE target_id; - PortAddr iop_base; - uchar tag_code; - uchar q_status; - uchar halt_qp; - uchar sdtr_data; - uchar target_ix; - uchar q_cntl, tid_no; - uchar cur_dvc_qng; - uchar asyn_sdtr; - uchar scsi_status; - asc_board_t *boardp; - - BUG_ON(!asc_dvc->drv_ptr); - boardp = asc_dvc->drv_ptr; - - iop_base = asc_dvc->iop_base; - int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W); - - halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B); - halt_q_addr = ASC_QNO_TO_QADDR(halt_qp); - target_ix = AscReadLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_TARGET_IX)); - q_cntl = AscReadLramByte(iop_base, - (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL)); - tid_no = ASC_TIX_TO_TID(target_ix); - target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no); - if (asc_dvc->pci_fix_asyn_xfer & target_id) { - asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB; - } else { - asyn_sdtr = 0; - } - if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) { - if (asc_dvc->pci_fix_asyn_xfer & target_id) { - AscSetChipSDTR(iop_base, 0, tid_no); - boardp->sdtr_data[tid_no] = 0; - } - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) { - if (asc_dvc->pci_fix_asyn_xfer & target_id) { - AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); - boardp->sdtr_data[tid_no] = asyn_sdtr; - } - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { - AscMemWordCopyPtrFromLram(iop_base, - ASCV_MSGIN_BEG, - (uchar *)&ext_msg, - sizeof(EXT_MSG) >> 1); - - if (ext_msg.msg_type == EXTENDED_MESSAGE && - ext_msg.msg_req == EXTENDED_SDTR && - ext_msg.msg_len == MS_SDTR_LEN) { - sdtr_accept = TRUE; - if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { - - sdtr_accept = FALSE; - ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; - } - if ((ext_msg.xfer_period < - asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]) - || (ext_msg.xfer_period > - asc_dvc->sdtr_period_tbl[asc_dvc-> - max_sdtr_index])) { - sdtr_accept = FALSE; - ext_msg.xfer_period = - asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]; - } - if (sdtr_accept) { - sdtr_data = - AscCalSDTRData(asc_dvc, ext_msg.xfer_period, - ext_msg.req_ack_offset); - if ((sdtr_data == 0xFF)) { - - q_cntl |= QC_MSG_OUT; - asc_dvc->init_sdtr &= ~target_id; - asc_dvc->sdtr_done &= ~target_id; - AscSetChipSDTR(iop_base, asyn_sdtr, - tid_no); - boardp->sdtr_data[tid_no] = asyn_sdtr; - } - } - if (ext_msg.req_ack_offset == 0) { - - q_cntl &= ~QC_MSG_OUT; - asc_dvc->init_sdtr &= ~target_id; - asc_dvc->sdtr_done &= ~target_id; - AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); - } else { - if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { - - q_cntl &= ~QC_MSG_OUT; - asc_dvc->sdtr_done |= target_id; - asc_dvc->init_sdtr |= target_id; - asc_dvc->pci_fix_asyn_xfer &= - ~target_id; - sdtr_data = - AscCalSDTRData(asc_dvc, - ext_msg.xfer_period, - ext_msg. - req_ack_offset); - AscSetChipSDTR(iop_base, sdtr_data, - tid_no); - boardp->sdtr_data[tid_no] = sdtr_data; - } else { - - q_cntl |= QC_MSG_OUT; - AscMsgOutSDTR(asc_dvc, - ext_msg.xfer_period, - ext_msg.req_ack_offset); - asc_dvc->pci_fix_asyn_xfer &= - ~target_id; - sdtr_data = - AscCalSDTRData(asc_dvc, - ext_msg.xfer_period, - ext_msg. - req_ack_offset); - AscSetChipSDTR(iop_base, sdtr_data, - tid_no); - boardp->sdtr_data[tid_no] = sdtr_data; - asc_dvc->sdtr_done |= target_id; - asc_dvc->init_sdtr |= target_id; - } - } - - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_CNTL), - q_cntl); - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else if (ext_msg.msg_type == EXTENDED_MESSAGE && - ext_msg.msg_req == EXTENDED_WDTR && - ext_msg.msg_len == MS_WDTR_LEN) { - - ext_msg.wdtr_width = 0; - AscMemWordCopyPtrToLram(iop_base, - ASCV_MSGOUT_BEG, - (uchar *)&ext_msg, - sizeof(EXT_MSG) >> 1); - q_cntl |= QC_MSG_OUT; - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_CNTL), - q_cntl); - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else { - - ext_msg.msg_type = MESSAGE_REJECT; - AscMemWordCopyPtrToLram(iop_base, - ASCV_MSGOUT_BEG, - (uchar *)&ext_msg, - sizeof(EXT_MSG) >> 1); - q_cntl |= QC_MSG_OUT; - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_CNTL), - q_cntl); - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } - } else if (int_halt_code == ASC_HALT_CHK_CONDITION) { - - q_cntl |= QC_REQ_SENSE; - - if ((asc_dvc->init_sdtr & target_id) != 0) { - - asc_dvc->sdtr_done &= ~target_id; - - sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); - q_cntl |= QC_MSG_OUT; - AscMsgOutSDTR(asc_dvc, - asc_dvc-> - sdtr_period_tbl[(sdtr_data >> 4) & - (uchar)(asc_dvc-> - max_sdtr_index - - 1)], - (uchar)(sdtr_data & (uchar) - ASC_SYN_MAX_OFFSET)); - } - - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_CNTL), q_cntl); - - tag_code = AscReadLramByte(iop_base, - (ushort)(halt_q_addr + (ushort) - ASC_SCSIQ_B_TAG_CODE)); - tag_code &= 0xDC; - if ((asc_dvc->pci_fix_asyn_xfer & target_id) - && !(asc_dvc->pci_fix_asyn_xfer_always & target_id) - ) { - - tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT - | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX); - - } - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_TAG_CODE), - tag_code); - - q_status = AscReadLramByte(iop_base, - (ushort)(halt_q_addr + (ushort) - ASC_SCSIQ_B_STATUS)); - q_status |= (QS_READY | QS_BUSY); - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_STATUS), - q_status); - - scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B); - scsi_busy &= ~target_id; - AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy); - - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) { - - AscMemWordCopyPtrFromLram(iop_base, - ASCV_MSGOUT_BEG, - (uchar *)&out_msg, - sizeof(EXT_MSG) >> 1); - - if ((out_msg.msg_type == EXTENDED_MESSAGE) && - (out_msg.msg_len == MS_SDTR_LEN) && - (out_msg.msg_req == EXTENDED_SDTR)) { - - asc_dvc->init_sdtr &= ~target_id; - asc_dvc->sdtr_done &= ~target_id; - AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); - boardp->sdtr_data[tid_no] = asyn_sdtr; - } - q_cntl &= ~QC_MSG_OUT; - AscWriteLramByte(iop_base, - (ushort)(halt_q_addr + - (ushort)ASC_SCSIQ_B_CNTL), q_cntl); - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) { - - scsi_status = AscReadLramByte(iop_base, - (ushort)((ushort)halt_q_addr + - (ushort) - ASC_SCSIQ_SCSI_STATUS)); - cur_dvc_qng = - AscReadLramByte(iop_base, - (ushort)((ushort)ASC_QADR_BEG + - (ushort)target_ix)); - if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) { - - scsi_busy = AscReadLramByte(iop_base, - (ushort)ASCV_SCSIBUSY_B); - scsi_busy |= target_id; - AscWriteLramByte(iop_base, - (ushort)ASCV_SCSIBUSY_B, scsi_busy); - asc_dvc->queue_full_or_busy |= target_id; - - if (scsi_status == SAM_STAT_TASK_SET_FULL) { - if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) { - cur_dvc_qng -= 1; - asc_dvc->max_dvc_qng[tid_no] = - cur_dvc_qng; - - AscWriteLramByte(iop_base, - (ushort)((ushort) - ASCV_MAX_DVC_QNG_BEG - + (ushort) - tid_no), - cur_dvc_qng); - - /* - * Set the device queue depth to the - * number of active requests when the - * QUEUE FULL condition was encountered. - */ - boardp->queue_full |= target_id; - boardp->queue_full_cnt[tid_no] = - cur_dvc_qng; - } - } - } - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } -#if CC_VERY_LONG_SG_LIST - else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) { - uchar q_no; - ushort q_addr; - uchar sg_wk_q_no; - uchar first_sg_wk_q_no; - ASC_SCSI_Q *scsiq; /* Ptr to driver request. */ - ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */ - ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */ - ushort sg_list_dwords; - ushort sg_entry_cnt; - uchar next_qp; - int i; - - q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP); - if (q_no == ASC_QLINK_END) - return 0; - - q_addr = ASC_QNO_TO_QADDR(q_no); - - /* - * Convert the request's SRB pointer to a host ASC_SCSI_REQ - * structure pointer using a macro provided by the driver. - * The ASC_SCSI_REQ pointer provides a pointer to the - * host ASC_SG_HEAD structure. - */ - /* Read request's SRB pointer. */ - scsiq = (ASC_SCSI_Q *) - ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base, - (ushort) - (q_addr + - ASC_SCSIQ_D_SRBPTR)))); - - /* - * Get request's first and working SG queue. - */ - sg_wk_q_no = AscReadLramByte(iop_base, - (ushort)(q_addr + - ASC_SCSIQ_B_SG_WK_QP)); - - first_sg_wk_q_no = AscReadLramByte(iop_base, - (ushort)(q_addr + - ASC_SCSIQ_B_FIRST_SG_WK_QP)); - - /* - * Reset request's working SG queue back to the - * first SG queue. - */ - AscWriteLramByte(iop_base, - (ushort)(q_addr + - (ushort)ASC_SCSIQ_B_SG_WK_QP), - first_sg_wk_q_no); - - sg_head = scsiq->sg_head; - - /* - * Set sg_entry_cnt to the number of SG elements - * that will be completed on this interrupt. - * - * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1 - * SG elements. The data_cnt and data_addr fields which - * add 1 to the SG element capacity are not used when - * restarting SG handling after a halt. - */ - if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) { - sg_entry_cnt = ASC_MAX_SG_LIST - 1; - - /* - * Keep track of remaining number of SG elements that - * will need to be handled on the next interrupt. - */ - scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); - } else { - sg_entry_cnt = scsiq->remain_sg_entry_cnt; - scsiq->remain_sg_entry_cnt = 0; - } - - /* - * Copy SG elements into the list of allocated SG queues. - * - * Last index completed is saved in scsiq->next_sg_index. - */ - next_qp = first_sg_wk_q_no; - q_addr = ASC_QNO_TO_QADDR(next_qp); - scsi_sg_q.sg_head_qp = q_no; - scsi_sg_q.cntl = QCSG_SG_XFER_LIST; - for (i = 0; i < sg_head->queue_cnt; i++) { - scsi_sg_q.seq_no = i + 1; - if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { - sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2); - sg_entry_cnt -= ASC_SG_LIST_PER_Q; - /* - * After very first SG queue RISC FW uses next - * SG queue first element then checks sg_list_cnt - * against zero and then decrements, so set - * sg_list_cnt 1 less than number of SG elements - * in each SG queue. - */ - scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1; - scsi_sg_q.sg_cur_list_cnt = - ASC_SG_LIST_PER_Q - 1; - } else { - /* - * This is the last SG queue in the list of - * allocated SG queues. If there are more - * SG elements than will fit in the allocated - * queues, then set the QCSG_SG_XFER_MORE flag. - */ - if (scsiq->remain_sg_entry_cnt != 0) { - scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; - } else { - scsi_sg_q.cntl |= QCSG_SG_XFER_END; - } - /* equals sg_entry_cnt * 2 */ - sg_list_dwords = sg_entry_cnt << 1; - scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1; - scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1; - sg_entry_cnt = 0; - } - - scsi_sg_q.q_no = next_qp; - AscMemWordCopyPtrToLram(iop_base, - q_addr + ASC_SCSIQ_SGHD_CPY_BEG, - (uchar *)&scsi_sg_q, - sizeof(ASC_SG_LIST_Q) >> 1); - - AscMemDWordCopyPtrToLram(iop_base, - q_addr + ASC_SGQ_LIST_BEG, - (uchar *)&sg_head-> - sg_list[scsiq->next_sg_index], - sg_list_dwords); - - scsiq->next_sg_index += ASC_SG_LIST_PER_Q; - - /* - * If the just completed SG queue contained the - * last SG element, then no more SG queues need - * to be written. - */ - if (scsi_sg_q.cntl & QCSG_SG_XFER_END) { - break; - } - - next_qp = AscReadLramByte(iop_base, - (ushort)(q_addr + - ASC_SCSIQ_B_FWD)); - q_addr = ASC_QNO_TO_QADDR(next_qp); - } - - /* - * Clear the halt condition so the RISC will be restarted - * after the return. - */ - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - return (0); - } -#endif /* CC_VERY_LONG_SG_LIST */ - return (0); -} - -static uchar -_AscCopyLramScsiDoneQ(PortAddr iop_base, - ushort q_addr, - ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count) -{ - ushort _val; - uchar sg_queue_cnt; - - DvcGetQinfo(iop_base, - q_addr + ASC_SCSIQ_DONE_INFO_BEG, - (uchar *)scsiq, - (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2); - - _val = AscReadLramWord(iop_base, - (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS)); - scsiq->q_status = (uchar)_val; - scsiq->q_no = (uchar)(_val >> 8); - _val = AscReadLramWord(iop_base, - (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL)); - scsiq->cntl = (uchar)_val; - sg_queue_cnt = (uchar)(_val >> 8); - _val = AscReadLramWord(iop_base, - (ushort)(q_addr + - (ushort)ASC_SCSIQ_B_SENSE_LEN)); - scsiq->sense_len = (uchar)_val; - scsiq->extra_bytes = (uchar)(_val >> 8); - - /* - * Read high word of remain bytes from alternate location. - */ - scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base, - (ushort)(q_addr + - (ushort) - ASC_SCSIQ_W_ALT_DC1))) - << 16); - /* - * Read low word of remain bytes from original location. - */ - scsiq->remain_bytes += AscReadLramWord(iop_base, - (ushort)(q_addr + (ushort) - ASC_SCSIQ_DW_REMAIN_XFER_CNT)); - - scsiq->remain_bytes &= max_dma_count; - return (sg_queue_cnt); -} - -static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) -{ - uchar next_qp; - uchar n_q_used; - uchar sg_list_qp; - uchar sg_queue_cnt; - uchar q_cnt; - uchar done_q_tail; - uchar tid_no; - ASC_SCSI_BIT_ID_TYPE scsi_busy; - ASC_SCSI_BIT_ID_TYPE target_id; - PortAddr iop_base; - ushort q_addr; - ushort sg_q_addr; - uchar cur_target_qng; - ASC_QDONE_INFO scsiq_buf; - ASC_QDONE_INFO *scsiq; - int false_overrun; - - iop_base = asc_dvc->iop_base; - n_q_used = 1; - scsiq = (ASC_QDONE_INFO *)&scsiq_buf; - done_q_tail = (uchar)AscGetVarDoneQTail(iop_base); - q_addr = ASC_QNO_TO_QADDR(done_q_tail); - next_qp = AscReadLramByte(iop_base, - (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD)); - if (next_qp != ASC_QLINK_END) { - AscPutVarDoneQTail(iop_base, next_qp); - q_addr = ASC_QNO_TO_QADDR(next_qp); - sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, - asc_dvc->max_dma_count); - AscWriteLramByte(iop_base, - (ushort)(q_addr + - (ushort)ASC_SCSIQ_B_STATUS), - (uchar)(scsiq-> - q_status & (uchar)~(QS_READY | - QS_ABORTED))); - tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix); - target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix); - if ((scsiq->cntl & QC_SG_HEAD) != 0) { - sg_q_addr = q_addr; - sg_list_qp = next_qp; - for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) { - sg_list_qp = AscReadLramByte(iop_base, - (ushort)(sg_q_addr - + (ushort) - ASC_SCSIQ_B_FWD)); - sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp); - if (sg_list_qp == ASC_QLINK_END) { - AscSetLibErrorCode(asc_dvc, - ASCQ_ERR_SG_Q_LINKS); - scsiq->d3.done_stat = QD_WITH_ERROR; - scsiq->d3.host_stat = - QHSTA_D_QDONE_SG_LIST_CORRUPTED; - goto FATAL_ERR_QDONE; - } - AscWriteLramByte(iop_base, - (ushort)(sg_q_addr + (ushort) - ASC_SCSIQ_B_STATUS), - QS_FREE); - } - n_q_used = sg_queue_cnt + 1; - AscPutVarDoneQTail(iop_base, sg_list_qp); - } - if (asc_dvc->queue_full_or_busy & target_id) { - cur_target_qng = AscReadLramByte(iop_base, - (ushort)((ushort) - ASC_QADR_BEG - + (ushort) - scsiq->d2. - target_ix)); - if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) { - scsi_busy = AscReadLramByte(iop_base, (ushort) - ASCV_SCSIBUSY_B); - scsi_busy &= ~target_id; - AscWriteLramByte(iop_base, - (ushort)ASCV_SCSIBUSY_B, - scsi_busy); - asc_dvc->queue_full_or_busy &= ~target_id; - } - } - if (asc_dvc->cur_total_qng >= n_q_used) { - asc_dvc->cur_total_qng -= n_q_used; - if (asc_dvc->cur_dvc_qng[tid_no] != 0) { - asc_dvc->cur_dvc_qng[tid_no]--; - } - } else { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG); - scsiq->d3.done_stat = QD_WITH_ERROR; - goto FATAL_ERR_QDONE; - } - if ((scsiq->d2.srb_ptr == 0UL) || - ((scsiq->q_status & QS_ABORTED) != 0)) { - return (0x11); - } else if (scsiq->q_status == QS_DONE) { - false_overrun = FALSE; - if (scsiq->extra_bytes != 0) { - scsiq->remain_bytes += - (ADV_DCNT)scsiq->extra_bytes; - } - if (scsiq->d3.done_stat == QD_WITH_ERROR) { - if (scsiq->d3.host_stat == - QHSTA_M_DATA_OVER_RUN) { - if ((scsiq-> - cntl & (QC_DATA_IN | QC_DATA_OUT)) - == 0) { - scsiq->d3.done_stat = - QD_NO_ERROR; - scsiq->d3.host_stat = - QHSTA_NO_ERROR; - } else if (false_overrun) { - scsiq->d3.done_stat = - QD_NO_ERROR; - scsiq->d3.host_stat = - QHSTA_NO_ERROR; - } - } else if (scsiq->d3.host_stat == - QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) { - AscStopChip(iop_base); - AscSetChipControl(iop_base, - (uchar)(CC_SCSI_RESET - | CC_HALT)); - udelay(60); - AscSetChipControl(iop_base, CC_HALT); - AscSetChipStatus(iop_base, - CIW_CLR_SCSI_RESET_INT); - AscSetChipStatus(iop_base, 0); - AscSetChipControl(iop_base, 0); - } - } - if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { - asc_isr_callback(asc_dvc, scsiq); - } else { - if ((AscReadLramByte(iop_base, - (ushort)(q_addr + (ushort) - ASC_SCSIQ_CDB_BEG)) - == START_STOP)) { - asc_dvc->unit_not_ready &= ~target_id; - if (scsiq->d3.done_stat != QD_NO_ERROR) { - asc_dvc->start_motor &= - ~target_id; - } - } - } - return (1); - } else { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); - FATAL_ERR_QDONE: - if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { - asc_isr_callback(asc_dvc, scsiq); - } - return (0x80); - } - } - return (0); -} - -static int AscISR(ASC_DVC_VAR *asc_dvc) -{ - ASC_CS_TYPE chipstat; - PortAddr iop_base; - ushort saved_ram_addr; - uchar ctrl_reg; - uchar saved_ctrl_reg; - int int_pending; - int status; - uchar host_flag; - - iop_base = asc_dvc->iop_base; - int_pending = FALSE; - - if (AscIsIntPending(iop_base) == 0) { - return int_pending; - } - - if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) { - return (ERR); - } - if (asc_dvc->in_critical_cnt != 0) { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); - return (ERR); - } - if (asc_dvc->is_in_int) { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); - return (ERR); - } - asc_dvc->is_in_int = TRUE; - ctrl_reg = AscGetChipControl(iop_base); - saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET | - CC_SINGLE_STEP | CC_DIAG | CC_TEST)); - chipstat = AscGetChipStatus(iop_base); - if (chipstat & CSW_SCSI_RESET_LATCH) { - if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) { - int i = 10; - int_pending = TRUE; - asc_dvc->sdtr_done = 0; - saved_ctrl_reg &= (uchar)(~CC_HALT); - while ((AscGetChipStatus(iop_base) & - CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { - mdelay(100); - } - AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); - AscSetChipControl(iop_base, CC_HALT); - AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); - AscSetChipStatus(iop_base, 0); - chipstat = AscGetChipStatus(iop_base); - } - } - saved_ram_addr = AscGetChipLramAddr(iop_base); - host_flag = AscReadLramByte(iop_base, - ASCV_HOST_FLAG_B) & - (uchar)(~ASC_HOST_FLAG_IN_ISR); - AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, - (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR)); - if ((chipstat & CSW_INT_PENDING) - || (int_pending) - ) { - AscAckInterrupt(iop_base); - int_pending = TRUE; - if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) { - if (AscIsrChipHalted(asc_dvc) == ERR) { - goto ISR_REPORT_QDONE_FATAL_ERROR; - } else { - saved_ctrl_reg &= (uchar)(~CC_HALT); - } - } else { - ISR_REPORT_QDONE_FATAL_ERROR: - if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) { - while (((status = - AscIsrQDone(asc_dvc)) & 0x01) != 0) { - } - } else { - do { - if ((status = - AscIsrQDone(asc_dvc)) == 1) { - break; - } - } while (status == 0x11); - } - if ((status & 0x80) != 0) - int_pending = ERR; - } - } - AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); - AscSetChipLramAddr(iop_base, saved_ram_addr); - AscSetChipControl(iop_base, saved_ctrl_reg); - asc_dvc->is_in_int = FALSE; - return (int_pending); -} - -/* Microcode buffer is kept after initialization for error recovery. */ -static uchar _asc_mcode_buf[] = { - 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04, - 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, - 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, - 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, - 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, - 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, - 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, - 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, - 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04, - 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88, - 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, - 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, - 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, - 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6, - 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, - 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, - 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, - 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23, - 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, - 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, - 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, - 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01, - 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, - 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, - 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23, - 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, - 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, - 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, - 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84, - 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, - 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, - 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, - 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, - 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, - 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, - 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, - 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82, - 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95, - 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, - 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, - 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23, - 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, - 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, - 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, - 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02, - 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02, - 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, - 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, - 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, - 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82, - 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, - 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, - 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6, - 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6, - 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, - 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, - 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01, - 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, - 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, - 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, - 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83, - 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33, - 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, - 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, - 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00, - 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03, - 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, - 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, - 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95, - 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42, - 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, - 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, - 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84, - 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, - 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, - 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, - 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4, - 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, - 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, - 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, - 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84, - 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, - 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, - 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, - 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, - 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, - 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, - 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, - 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00, - 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98, - 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, - 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, - 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62, - 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23, - 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, - 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, - 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95, - 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, - 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, - 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, - 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01, - 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, - 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, - 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, - 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05, - 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, - 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, - 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, - 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63, - 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, - 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, - 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, - 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85, - 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, - 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, - 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, - 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87, - 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, - 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, - 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, - 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60, - 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, - 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, - 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, - 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33, - 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, - 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, - 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, - 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, - 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, - 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, - 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, - 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06, - 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, - 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, - 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, - 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33, - 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, - 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, - 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, - 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88, - 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, - 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, - 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, - 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, - 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, - 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, - 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, - 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, - 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, - 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, - 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, - 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, - 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, - 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, - 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, - 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, - 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, - 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, - 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, - 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, - 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, - 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, - 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, - 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01, - 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, - 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, - 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, - 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88, - 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, - 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, - 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, - 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, - 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, - 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, - 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, - 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73, - 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, - 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, - 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, - 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23, - 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, -}; - -static ushort _asc_mcode_size = sizeof(_asc_mcode_buf); -static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL; - -#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 -static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { - INQUIRY, - REQUEST_SENSE, - READ_CAPACITY, - READ_TOC, - MODE_SELECT, - MODE_SENSE, - MODE_SELECT_10, - MODE_SENSE_10, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - 0xFF -}; - -static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) -{ - PortAddr iop_base; - int sta; - int n_q_required; - int disable_syn_offset_one_fix; - int i; - ASC_PADDR addr; - ushort sg_entry_cnt = 0; - ushort sg_entry_cnt_minus_one = 0; - uchar target_ix; - uchar tid_no; - uchar sdtr_data; - uchar extra_bytes; - uchar scsi_cmd; - uchar disable_cmd; - ASC_SG_HEAD *sg_head; - ASC_DCNT data_cnt; - - iop_base = asc_dvc->iop_base; - sg_head = scsiq->sg_head; - if (asc_dvc->err_code != 0) - return (ERR); - scsiq->q1.q_no = 0; - if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { - scsiq->q1.extra_bytes = 0; - } - sta = 0; - target_ix = scsiq->q2.target_ix; - tid_no = ASC_TIX_TO_TID(target_ix); - n_q_required = 1; - if (scsiq->cdbptr[0] == REQUEST_SENSE) { - if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { - asc_dvc->sdtr_done &= ~scsiq->q1.target_id; - sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); - AscMsgOutSDTR(asc_dvc, - asc_dvc-> - sdtr_period_tbl[(sdtr_data >> 4) & - (uchar)(asc_dvc-> - max_sdtr_index - - 1)], - (uchar)(sdtr_data & (uchar) - ASC_SYN_MAX_OFFSET)); - scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); - } - } - if (asc_dvc->in_critical_cnt != 0) { - AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); - return (ERR); - } - asc_dvc->in_critical_cnt++; - if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { - if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { - asc_dvc->in_critical_cnt--; - return (ERR); - } -#if !CC_VERY_LONG_SG_LIST - if (sg_entry_cnt > ASC_MAX_SG_LIST) { - asc_dvc->in_critical_cnt--; - return (ERR); - } -#endif /* !CC_VERY_LONG_SG_LIST */ - if (sg_entry_cnt == 1) { - scsiq->q1.data_addr = - (ADV_PADDR)sg_head->sg_list[0].addr; - scsiq->q1.data_cnt = - (ADV_DCNT)sg_head->sg_list[0].bytes; - scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); - } - sg_entry_cnt_minus_one = sg_entry_cnt - 1; - } - scsi_cmd = scsiq->cdbptr[0]; - disable_syn_offset_one_fix = FALSE; - if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && - !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { - if (scsiq->q1.cntl & QC_SG_HEAD) { - data_cnt = 0; - for (i = 0; i < sg_entry_cnt; i++) { - data_cnt += - (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i]. - bytes); - } - } else { - data_cnt = le32_to_cpu(scsiq->q1.data_cnt); - } - if (data_cnt != 0UL) { - if (data_cnt < 512UL) { - disable_syn_offset_one_fix = TRUE; - } else { - for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; - i++) { - disable_cmd = - _syn_offset_one_disable_cmd[i]; - if (disable_cmd == 0xFF) { - break; - } - if (scsi_cmd == disable_cmd) { - disable_syn_offset_one_fix = - TRUE; - break; - } - } - } - } - } - if (disable_syn_offset_one_fix) { - scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; - scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | - ASC_TAG_FLAG_DISABLE_DISCONNECT); - } else { - scsiq->q2.tag_code &= 0x27; - } - if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { - if (asc_dvc->bug_fix_cntl) { - if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { - if ((scsi_cmd == READ_6) || - (scsi_cmd == READ_10)) { - addr = - (ADV_PADDR)le32_to_cpu(sg_head-> - sg_list - [sg_entry_cnt_minus_one]. - addr) + - (ADV_DCNT)le32_to_cpu(sg_head-> - sg_list - [sg_entry_cnt_minus_one]. - bytes); - extra_bytes = - (uchar)((ushort)addr & 0x0003); - if ((extra_bytes != 0) - && - ((scsiq->q2. - tag_code & - ASC_TAG_FLAG_EXTRA_BYTES) - == 0)) { - scsiq->q2.tag_code |= - ASC_TAG_FLAG_EXTRA_BYTES; - scsiq->q1.extra_bytes = - extra_bytes; - data_cnt = - le32_to_cpu(sg_head-> - sg_list - [sg_entry_cnt_minus_one]. - bytes); - data_cnt -= - (ASC_DCNT) extra_bytes; - sg_head-> - sg_list - [sg_entry_cnt_minus_one]. - bytes = - cpu_to_le32(data_cnt); - } - } - } - } - sg_head->entry_to_copy = sg_head->entry_cnt; -#if CC_VERY_LONG_SG_LIST - /* - * Set the sg_entry_cnt to the maximum possible. The rest of - * the SG elements will be copied when the RISC completes the - * SG elements that fit and halts. - */ - if (sg_entry_cnt > ASC_MAX_SG_LIST) { - sg_entry_cnt = ASC_MAX_SG_LIST; - } -#endif /* CC_VERY_LONG_SG_LIST */ - n_q_required = AscSgListToQueue(sg_entry_cnt); - if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= - (uint) n_q_required) - || ((scsiq->q1.cntl & QC_URGENT) != 0)) { - if ((sta = - AscSendScsiQueue(asc_dvc, scsiq, - n_q_required)) == 1) { - asc_dvc->in_critical_cnt--; - return (sta); - } - } - } else { - if (asc_dvc->bug_fix_cntl) { - if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { - if ((scsi_cmd == READ_6) || - (scsi_cmd == READ_10)) { - addr = - le32_to_cpu(scsiq->q1.data_addr) + - le32_to_cpu(scsiq->q1.data_cnt); - extra_bytes = - (uchar)((ushort)addr & 0x0003); - if ((extra_bytes != 0) - && - ((scsiq->q2. - tag_code & - ASC_TAG_FLAG_EXTRA_BYTES) - == 0)) { - data_cnt = - le32_to_cpu(scsiq->q1. - data_cnt); - if (((ushort)data_cnt & 0x01FF) - == 0) { - scsiq->q2.tag_code |= - ASC_TAG_FLAG_EXTRA_BYTES; - data_cnt -= (ASC_DCNT) - extra_bytes; - scsiq->q1.data_cnt = - cpu_to_le32 - (data_cnt); - scsiq->q1.extra_bytes = - extra_bytes; - } - } - } - } - } - n_q_required = 1; - if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || - ((scsiq->q1.cntl & QC_URGENT) != 0)) { - if ((sta = AscSendScsiQueue(asc_dvc, scsiq, - n_q_required)) == 1) { - asc_dvc->in_critical_cnt--; - return (sta); - } - } - } - asc_dvc->in_critical_cnt--; - return (sta); -} - -static int -AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required) -{ - PortAddr iop_base; - uchar free_q_head; - uchar next_qp; - uchar tid_no; - uchar target_ix; - int sta; - - iop_base = asc_dvc->iop_base; - target_ix = scsiq->q2.target_ix; - tid_no = ASC_TIX_TO_TID(target_ix); - sta = 0; - free_q_head = (uchar)AscGetVarFreeQHead(iop_base); - if (n_q_required > 1) { - next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head, - (uchar)n_q_required); - if (next_qp != ASC_QLINK_END) { - asc_dvc->last_q_shortage = 0; - scsiq->sg_head->queue_cnt = n_q_required - 1; - scsiq->q1.q_no = free_q_head; - sta = AscPutReadySgListQueue(asc_dvc, scsiq, - free_q_head); - } - } else if (n_q_required == 1) { - next_qp = AscAllocFreeQueue(iop_base, free_q_head); - if (next_qp != ASC_QLINK_END) { - scsiq->q1.q_no = free_q_head; - sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head); - } - } - if (sta == 1) { - AscPutVarFreeQHead(iop_base, next_qp); - asc_dvc->cur_total_qng += (uchar)(n_q_required); - asc_dvc->cur_dvc_qng[tid_no]++; - } - return sta; -} - -static int AscSgListToQueue(int sg_list) -{ - int n_sg_list_qs; - - n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); - if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) - n_sg_list_qs++; - return (n_sg_list_qs + 1); -} - -static uint -AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs) -{ - uint cur_used_qs; - uint cur_free_qs; - ASC_SCSI_BIT_ID_TYPE target_id; - uchar tid_no; - - target_id = ASC_TIX_TO_TARGET_ID(target_ix); - tid_no = ASC_TIX_TO_TID(target_ix); - if ((asc_dvc->unit_not_ready & target_id) || - (asc_dvc->queue_full_or_busy & target_id)) { - return (0); - } - if (n_qs == 1) { - cur_used_qs = (uint) asc_dvc->cur_total_qng + - (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q; - } else { - cur_used_qs = (uint) asc_dvc->cur_total_qng + - (uint) ASC_MIN_FREE_Q; - } - if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) { - cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; - if (asc_dvc->cur_dvc_qng[tid_no] >= - asc_dvc->max_dvc_qng[tid_no]) { - return (0); - } - return (cur_free_qs); - } - if (n_qs > 1) { - if ((n_qs > asc_dvc->last_q_shortage) - && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) { - asc_dvc->last_q_shortage = n_qs; - } - } - return (0); -} - -static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) -{ - ushort q_addr; - uchar tid_no; - uchar sdtr_data; - uchar syn_period_ix; - uchar syn_offset; - PortAddr iop_base; - - iop_base = asc_dvc->iop_base; - if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) && - ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) { - tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix); - sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); - syn_period_ix = - (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1); - syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET; - AscMsgOutSDTR(asc_dvc, - asc_dvc->sdtr_period_tbl[syn_period_ix], - syn_offset); - scsiq->q1.cntl |= QC_MSG_OUT; - } - q_addr = ASC_QNO_TO_QADDR(q_no); - if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { - scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; - } - scsiq->q1.status = QS_FREE; - AscMemWordCopyPtrToLram(iop_base, - q_addr + ASC_SCSIQ_CDB_BEG, - (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1); - - DvcPutScsiQ(iop_base, - q_addr + ASC_SCSIQ_CPY_BEG, - (uchar *)&scsiq->q1.cntl, - ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1); - AscWriteLramWord(iop_base, - (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS), - (ushort)(((ushort)scsiq->q1. - q_no << 8) | (ushort)QS_READY)); - return (1); -} - -static int -AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) -{ - int sta; - int i; - ASC_SG_HEAD *sg_head; - ASC_SG_LIST_Q scsi_sg_q; - ASC_DCNT saved_data_addr; - ASC_DCNT saved_data_cnt; - PortAddr iop_base; - ushort sg_list_dwords; - ushort sg_index; - ushort sg_entry_cnt; - ushort q_addr; - uchar next_qp; - - iop_base = asc_dvc->iop_base; - sg_head = scsiq->sg_head; - saved_data_addr = scsiq->q1.data_addr; - saved_data_cnt = scsiq->q1.data_cnt; - scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr; - scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes; -#if CC_VERY_LONG_SG_LIST - /* - * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST - * then not all SG elements will fit in the allocated queues. - * The rest of the SG elements will be copied when the RISC - * completes the SG elements that fit and halts. - */ - if (sg_head->entry_cnt > ASC_MAX_SG_LIST) { - /* - * Set sg_entry_cnt to be the number of SG elements that - * will fit in the allocated SG queues. It is minus 1, because - * the first SG element is handled above. ASC_MAX_SG_LIST is - * already inflated by 1 to account for this. For example it - * may be 50 which is 1 + 7 queues * 7 SG elements. - */ - sg_entry_cnt = ASC_MAX_SG_LIST - 1; - - /* - * Keep track of remaining number of SG elements that will - * need to be handled from a_isr.c. - */ - scsiq->remain_sg_entry_cnt = - sg_head->entry_cnt - ASC_MAX_SG_LIST; - } else { -#endif /* CC_VERY_LONG_SG_LIST */ - /* - * Set sg_entry_cnt to be the number of SG elements that - * will fit in the allocated SG queues. It is minus 1, because - * the first SG element is handled above. - */ - sg_entry_cnt = sg_head->entry_cnt - 1; -#if CC_VERY_LONG_SG_LIST - } -#endif /* CC_VERY_LONG_SG_LIST */ - if (sg_entry_cnt != 0) { - scsiq->q1.cntl |= QC_SG_HEAD; - q_addr = ASC_QNO_TO_QADDR(q_no); - sg_index = 1; - scsiq->q1.sg_queue_cnt = sg_head->queue_cnt; - scsi_sg_q.sg_head_qp = q_no; - scsi_sg_q.cntl = QCSG_SG_XFER_LIST; - for (i = 0; i < sg_head->queue_cnt; i++) { - scsi_sg_q.seq_no = i + 1; - if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { - sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2); - sg_entry_cnt -= ASC_SG_LIST_PER_Q; - if (i == 0) { - scsi_sg_q.sg_list_cnt = - ASC_SG_LIST_PER_Q; - scsi_sg_q.sg_cur_list_cnt = - ASC_SG_LIST_PER_Q; - } else { - scsi_sg_q.sg_list_cnt = - ASC_SG_LIST_PER_Q - 1; - scsi_sg_q.sg_cur_list_cnt = - ASC_SG_LIST_PER_Q - 1; - } - } else { -#if CC_VERY_LONG_SG_LIST - /* - * This is the last SG queue in the list of - * allocated SG queues. If there are more - * SG elements than will fit in the allocated - * queues, then set the QCSG_SG_XFER_MORE flag. - */ - if (sg_head->entry_cnt > ASC_MAX_SG_LIST) { - scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; - } else { -#endif /* CC_VERY_LONG_SG_LIST */ - scsi_sg_q.cntl |= QCSG_SG_XFER_END; -#if CC_VERY_LONG_SG_LIST - } -#endif /* CC_VERY_LONG_SG_LIST */ - sg_list_dwords = sg_entry_cnt << 1; - if (i == 0) { - scsi_sg_q.sg_list_cnt = sg_entry_cnt; - scsi_sg_q.sg_cur_list_cnt = - sg_entry_cnt; - } else { - scsi_sg_q.sg_list_cnt = - sg_entry_cnt - 1; - scsi_sg_q.sg_cur_list_cnt = - sg_entry_cnt - 1; - } - sg_entry_cnt = 0; - } - next_qp = AscReadLramByte(iop_base, - (ushort)(q_addr + - ASC_SCSIQ_B_FWD)); - scsi_sg_q.q_no = next_qp; - q_addr = ASC_QNO_TO_QADDR(next_qp); - AscMemWordCopyPtrToLram(iop_base, - q_addr + ASC_SCSIQ_SGHD_CPY_BEG, - (uchar *)&scsi_sg_q, - sizeof(ASC_SG_LIST_Q) >> 1); - AscMemDWordCopyPtrToLram(iop_base, - q_addr + ASC_SGQ_LIST_BEG, - (uchar *)&sg_head-> - sg_list[sg_index], - sg_list_dwords); - sg_index += ASC_SG_LIST_PER_Q; - scsiq->next_sg_index = sg_index; - } - } else { - scsiq->q1.cntl &= ~QC_SG_HEAD; - } - sta = AscPutReadyQueue(asc_dvc, scsiq, q_no); - scsiq->q1.data_addr = saved_data_addr; - scsiq->q1.data_cnt = saved_data_cnt; - return (sta); -} - -static int -AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data) -{ - int sta = FALSE; - - if (AscHostReqRiscHalt(iop_base)) { - sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); - AscStartChip(iop_base); - return (sta); - } - return (sta); -} - -static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data) -{ - ASC_SCSI_BIT_ID_TYPE org_id; - int i; - int sta = TRUE; - - AscSetBank(iop_base, 1); - org_id = AscReadChipDvcID(iop_base); - for (i = 0; i <= ASC_MAX_TID; i++) { - if (org_id == (0x01 << i)) - break; - } - org_id = (ASC_SCSI_BIT_ID_TYPE) i; - AscWriteChipDvcID(iop_base, id); - if (AscReadChipDvcID(iop_base) == (0x01 << id)) { - AscSetBank(iop_base, 0); - AscSetChipSyn(iop_base, sdtr_data); - if (AscGetChipSyn(iop_base) != sdtr_data) { - sta = FALSE; - } - } else { - sta = FALSE; - } - AscSetBank(iop_base, 1); - AscWriteChipDvcID(iop_base, org_id); - AscSetBank(iop_base, 0); - return (sta); -} - -static ushort AscInitLram(ASC_DVC_VAR *asc_dvc) -{ - uchar i; - ushort s_addr; - PortAddr iop_base; - ushort warn_code; - - iop_base = asc_dvc->iop_base; - warn_code = 0; - AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, - (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) * - 64) >> 1) - ); - i = ASC_MIN_ACTIVE_QNO; - s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), - (uchar)(i + 1)); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), - (uchar)(asc_dvc->max_total_qng)); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), - (uchar)i); - i++; - s_addr += ASC_QBLK_SIZE; - for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), - (uchar)(i + 1)); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), - (uchar)(i - 1)); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), - (uchar)i); - } - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), - (uchar)ASC_QLINK_END); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), - (uchar)(asc_dvc->max_total_qng - 1)); - AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), - (uchar)asc_dvc->max_total_qng); - i++; - s_addr += ASC_QBLK_SIZE; - for (; i <= (uchar)(asc_dvc->max_total_qng + 3); - i++, s_addr += ASC_QBLK_SIZE) { - AscWriteLramByte(iop_base, - (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i); - AscWriteLramByte(iop_base, - (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i); - AscWriteLramByte(iop_base, - (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i); - } - return (warn_code); -} - -static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) -{ - PortAddr iop_base; - int i; - ushort lram_addr; - - iop_base = asc_dvc->iop_base; - AscPutRiscVarFreeQHead(iop_base, 1); - AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); - AscPutVarFreeQHead(iop_base, 1); - AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); - AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, - (uchar)((int)asc_dvc->max_total_qng + 1)); - AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, - (uchar)((int)asc_dvc->max_total_qng + 2)); - AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B, - asc_dvc->max_total_qng); - AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); - AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); - AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); - AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); - AscPutQDoneInProgress(iop_base, 0); - lram_addr = ASC_QADR_BEG; - for (i = 0; i < 32; i++, lram_addr += 2) { - AscWriteLramWord(iop_base, lram_addr, 0); - } -} - -static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code) -{ - if (asc_dvc->err_code == 0) { - asc_dvc->err_code = err_code; - AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, - err_code); - } - return (err_code); -} - -static uchar -AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset) -{ - EXT_MSG sdtr_buf; - uchar sdtr_period_index; - PortAddr iop_base; - - iop_base = asc_dvc->iop_base; - sdtr_buf.msg_type = EXTENDED_MESSAGE; - sdtr_buf.msg_len = MS_SDTR_LEN; - sdtr_buf.msg_req = EXTENDED_SDTR; - sdtr_buf.xfer_period = sdtr_period; - sdtr_offset &= ASC_SYN_MAX_OFFSET; - sdtr_buf.req_ack_offset = sdtr_offset; - if ((sdtr_period_index = - AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <= - asc_dvc->max_sdtr_index) { - AscMemWordCopyPtrToLram(iop_base, - ASCV_MSGOUT_BEG, - (uchar *)&sdtr_buf, - sizeof(EXT_MSG) >> 1); - return ((sdtr_period_index << 4) | sdtr_offset); - } else { - - sdtr_buf.req_ack_offset = 0; - AscMemWordCopyPtrToLram(iop_base, - ASCV_MSGOUT_BEG, - (uchar *)&sdtr_buf, - sizeof(EXT_MSG) >> 1); - return (0); - } -} - -static uchar -AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) -{ - uchar byte; - uchar sdtr_period_ix; - - sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); - if ((sdtr_period_ix > asc_dvc->max_sdtr_index) - ) { - return (0xFF); - } - byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); - return (byte); -} - -static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no) -{ - AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); - AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); - return; -} - -static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) -{ - uchar *period_table; - int max_index; - int min_index; - int i; - - period_table = asc_dvc->sdtr_period_tbl; - max_index = (int)asc_dvc->max_sdtr_index; - min_index = (int)asc_dvc->host_init_sdtr_index; - if ((syn_time <= period_table[max_index])) { - for (i = min_index; i < (max_index - 1); i++) { - if (syn_time <= period_table[i]) { - return ((uchar)i); - } - } - return ((uchar)max_index); - } else { - return ((uchar)(max_index + 1)); - } -} - -static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head) -{ - ushort q_addr; - uchar next_qp; - uchar q_status; - - q_addr = ASC_QNO_TO_QADDR(free_q_head); - q_status = (uchar)AscReadLramByte(iop_base, - (ushort)(q_addr + - ASC_SCSIQ_B_STATUS)); - next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD)); - if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) { - return (next_qp); - } - return (ASC_QLINK_END); -} - -static uchar -AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q) -{ - uchar i; - - for (i = 0; i < n_free_q; i++) { - if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head)) - == ASC_QLINK_END) { - return (ASC_QLINK_END); - } - } - return (free_q_head); -} - -static int AscHostReqRiscHalt(PortAddr iop_base) -{ - int count = 0; - int sta = 0; - uchar saved_stop_code; - - if (AscIsChipHalted(iop_base)) - return (1); - saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); - AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, - ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP); - do { - if (AscIsChipHalted(iop_base)) { - sta = 1; - break; - } - mdelay(100); - } while (count++ < 20); - AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); - return (sta); -} - -static int AscStopQueueExe(PortAddr iop_base) -{ - int count = 0; - - if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { - AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, - ASC_STOP_REQ_RISC_STOP); - do { - if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & - ASC_STOP_ACK_RISC_STOP) { - return (1); - } - mdelay(100); - } while (count++ < 20); - } - return (0); -} - -static int AscStartChip(PortAddr iop_base) -{ - AscSetChipControl(iop_base, 0); - if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { - return (0); - } - return (1); -} - -static int AscStopChip(PortAddr iop_base) -{ - uchar cc_val; - - cc_val = - AscGetChipControl(iop_base) & - (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); - AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT)); - AscSetChipIH(iop_base, INS_HALT); - AscSetChipIH(iop_base, INS_RFLAG_WTM); - if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { - return (0); - } - return (1); -} - -static int AscIsChipHalted(PortAddr iop_base) -{ - if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { - if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { - return (1); - } - } - return (0); -} - -static void AscSetChipIH(PortAddr iop_base, ushort ins_code) -{ - AscSetBank(iop_base, 1); - AscWriteChipIH(iop_base, ins_code); - AscSetBank(iop_base, 0); - return; -} - -static void AscAckInterrupt(PortAddr iop_base) -{ - uchar host_flag; - uchar risc_flag; - ushort loop; - - loop = 0; - do { - risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); - if (loop++ > 0x7FFF) { - break; - } - } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); - host_flag = - AscReadLramByte(iop_base, - ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); - AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, - (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT)); - AscSetChipStatus(iop_base, CIW_INT_ACK); - loop = 0; - while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { - AscSetChipStatus(iop_base, CIW_INT_ACK); - if (loop++ > 3) { - break; - } - } - AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); - return; -} - -static void AscDisableInterrupt(PortAddr iop_base) -{ - ushort cfg; - - cfg = AscGetChipCfgLsw(iop_base); - AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); - return; -} - -static void AscEnableInterrupt(PortAddr iop_base) -{ - ushort cfg; - - cfg = AscGetChipCfgLsw(iop_base); - AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); - return; -} - -static void AscSetBank(PortAddr iop_base, uchar bank) -{ - uchar val; - - val = AscGetChipControl(iop_base) & - (~ - (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | - CC_CHIP_RESET)); - if (bank == 1) { - val |= CC_BANK_ONE; - } else if (bank == 2) { - val |= CC_DIAG | CC_BANK_ONE; - } else { - val &= ~CC_BANK_ONE; - } - AscSetChipControl(iop_base, val); - return; -} - -static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) -{ - PortAddr iop_base; - int i = 10; - - iop_base = asc_dvc->iop_base; - while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) - && (i-- > 0)) { - mdelay(100); - } - AscStopChip(iop_base); - AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); - udelay(60); - AscSetChipIH(iop_base, INS_RFLAG_WTM); - AscSetChipIH(iop_base, INS_HALT); - AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); - AscSetChipControl(iop_base, CC_HALT); - mdelay(200); - AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); - AscSetChipStatus(iop_base, 0); - return (AscIsChipHalted(iop_base)); -} - -static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type) -{ - if (bus_type & ASC_IS_ISA) - return ASC_MAX_ISA_DMA_COUNT; - else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) - return ASC_MAX_VL_DMA_COUNT; - return ASC_MAX_PCI_DMA_COUNT; -} - -#ifdef CONFIG_ISA -static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base) -{ - ushort channel; - - channel = AscGetChipCfgLsw(iop_base) & 0x0003; - if (channel == 0x03) - return (0); - else if (channel == 0x00) - return (7); - return (channel + 4); -} - -static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) -{ - ushort cfg_lsw; - uchar value; - - if ((dma_channel >= 5) && (dma_channel <= 7)) { - if (dma_channel == 7) - value = 0x00; - else - value = dma_channel - 4; - cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC; - cfg_lsw |= value; - AscSetChipCfgLsw(iop_base, cfg_lsw); - return (AscGetIsaDmaChannel(iop_base)); - } - return (0); -} - -static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) -{ - speed_value &= 0x07; - AscSetBank(iop_base, 1); - AscWriteChipDmaSpeed(iop_base, speed_value); - AscSetBank(iop_base, 0); - return (AscGetIsaDmaSpeed(iop_base)); -} - -static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) -{ - uchar speed_value; - - AscSetBank(iop_base, 1); - speed_value = AscReadChipDmaSpeed(iop_base); - speed_value &= 0x07; - AscSetBank(iop_base, 0); - return (speed_value); -} -#endif /* CONFIG_ISA */ - -static int __devinit AscInitGetConfig(asc_board_t *boardp) -{ - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; - unsigned short warn_code = 0; - - asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; - if (asc_dvc->err_code != 0) - return asc_dvc->err_code; - - if (AscFindSignature(asc_dvc->iop_base)) { - warn_code |= AscInitAscDvcVar(asc_dvc); - warn_code |= AscInitFromEEP(asc_dvc); - asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; - if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) - asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; - } else { - asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; - } - - switch (warn_code) { - case 0: /* No error */ - break; - case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port address " - "modified\n", boardp->id); - break; - case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); - break; - case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); - break; - case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n", - boardp->id); - break; - case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled " - "w/o disconnects\n", boardp->id); - break; - default: - ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); - break; - } - - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } - - return asc_dvc->err_code; -} - -static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp) -{ - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; - PortAddr iop_base = asc_dvc->iop_base; - unsigned short cfg_msw; - unsigned short warn_code = 0; - - asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; - if (asc_dvc->err_code != 0) - return asc_dvc->err_code; - if (!AscFindSignature(asc_dvc->iop_base)) { - asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; - return asc_dvc->err_code; - } - - cfg_msw = AscGetChipCfgMsw(iop_base); - if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { - cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; - warn_code |= ASC_WARN_CFG_MSW_RECOVER; - AscSetChipCfgMsw(iop_base, cfg_msw); - } - if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != - asc_dvc->cfg->cmd_qng_enabled) { - asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; - warn_code |= ASC_WARN_CMD_QNG_CONFLICT; - } - if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { - warn_code |= ASC_WARN_AUTO_CONFIG; - } - if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { - if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) - != asc_dvc->irq_no) { - asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; - } - } -#ifdef CONFIG_PCI - if (asc_dvc->bus_type & ASC_IS_PCI) { - cfg_msw &= 0xFFC0; - AscSetChipCfgMsw(iop_base, cfg_msw); - if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { - } else { - if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || - (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { - asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; - asc_dvc->bug_fix_cntl |= - ASC_BUG_FIX_ASYN_USE_SYN; - } - } - } else -#endif /* CONFIG_PCI */ - if (asc_dvc->bus_type == ASC_IS_ISAPNP) { - if (AscGetChipVersion(iop_base, asc_dvc->bus_type) - == ASC_CHIP_VER_ASYN_BUG) { - asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; - } - } - if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != - asc_dvc->cfg->chip_scsi_id) { - asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; - } -#ifdef CONFIG_ISA - if (asc_dvc->bus_type & ASC_IS_ISA) { - AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); - AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); - } -#endif /* CONFIG_ISA */ - - asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; - - switch (warn_code) { - case 0: /* No error. */ - break; - case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port address " - "modified\n", boardp->id); - break; - case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); - break; - case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); - break; - case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n", - boardp->id); - break; - case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o " - "disconnects\n", - boardp->id); - break; - default: - ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); - break; - } - - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } - - return asc_dvc->err_code; -} - -static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) -{ - ushort warn_code; - PortAddr iop_base; - - iop_base = asc_dvc->iop_base; - warn_code = 0; - if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && - !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { - AscResetChipAndScsiBus(asc_dvc); - mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ - } - asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; - if (asc_dvc->err_code != 0) - return (UW_ERR); - if (!AscFindSignature(asc_dvc->iop_base)) { - asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; - return (warn_code); - } - AscDisableInterrupt(iop_base); - warn_code |= AscInitLram(asc_dvc); - if (asc_dvc->err_code != 0) - return (UW_ERR); - ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n", - (ulong)_asc_mcode_chksum); - if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, - _asc_mcode_size) != _asc_mcode_chksum) { - asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; - return (warn_code); - } - warn_code |= AscInitMicroCodeVar(asc_dvc); - asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; - AscEnableInterrupt(iop_base); - return (warn_code); -} - -static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) -{ - int i; - PortAddr iop_base; - ushort warn_code; - uchar chip_version; - - iop_base = asc_dvc->iop_base; - warn_code = 0; - asc_dvc->err_code = 0; - if ((asc_dvc->bus_type & - (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) { - asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE; - } - AscSetChipControl(iop_base, CC_HALT); - AscSetChipStatus(iop_base, 0); - asc_dvc->bug_fix_cntl = 0; - asc_dvc->pci_fix_asyn_xfer = 0; - asc_dvc->pci_fix_asyn_xfer_always = 0; - /* asc_dvc->init_state initalized in AscInitGetConfig(). */ - asc_dvc->sdtr_done = 0; - asc_dvc->cur_total_qng = 0; - asc_dvc->is_in_int = 0; - asc_dvc->in_critical_cnt = 0; - asc_dvc->last_q_shortage = 0; - asc_dvc->use_tagged_qng = 0; - asc_dvc->no_scam = 0; - asc_dvc->unit_not_ready = 0; - asc_dvc->queue_full_or_busy = 0; - asc_dvc->redo_scam = 0; - asc_dvc->res2 = 0; - asc_dvc->host_init_sdtr_index = 0; - asc_dvc->cfg->can_tagged_qng = 0; - asc_dvc->cfg->cmd_qng_enabled = 0; - asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; - asc_dvc->init_sdtr = 0; - asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG; - asc_dvc->scsi_reset_wait = 3; - asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET; - asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type); - asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; - asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; - asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; - asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; - asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | - ASC_LIB_VERSION_MINOR; - chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); - asc_dvc->cfg->chip_version = chip_version; - asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; - asc_dvc->max_sdtr_index = 7; - if ((asc_dvc->bus_type & ASC_IS_PCI) && - (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { - asc_dvc->bus_type = ASC_IS_PCI_ULTRA; - asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; - asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; - asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; - asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; - asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; - asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; - asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; - asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; - asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; - asc_dvc->max_sdtr_index = 15; - if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { - AscSetExtraControl(iop_base, - (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); - } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) { - AscSetExtraControl(iop_base, - (SEC_ACTIVE_NEGATE | - SEC_ENABLE_FILTER)); - } - } - if (asc_dvc->bus_type == ASC_IS_PCI) { - AscSetExtraControl(iop_base, - (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); - } - - asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; -#ifdef CONFIG_ISA - if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { - if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) { - AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); - asc_dvc->bus_type = ASC_IS_ISAPNP; - } - asc_dvc->cfg->isa_dma_channel = - (uchar)AscGetIsaDmaChannel(iop_base); - } -#endif /* CONFIG_ISA */ - for (i = 0; i <= ASC_MAX_TID; i++) { - asc_dvc->cur_dvc_qng[i] = 0; - asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG; - asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L; - asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L; - asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; - } - return (warn_code); -} - -static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) -{ - ASCEEP_CONFIG eep_config_buf; - ASCEEP_CONFIG *eep_config; - PortAddr iop_base; - ushort chksum; - ushort warn_code; - ushort cfg_msw, cfg_lsw; - int i; - int write_eep = 0; - - iop_base = asc_dvc->iop_base; - warn_code = 0; - AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); - AscStopQueueExe(iop_base); - if ((AscStopChip(iop_base) == FALSE) || - (AscGetChipScsiCtrl(iop_base) != 0)) { - asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; - AscResetChipAndScsiBus(asc_dvc); - mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ - } - if (AscIsChipHalted(iop_base) == FALSE) { - asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; - return (warn_code); - } - AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); - if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { - asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; - return (warn_code); - } - eep_config = (ASCEEP_CONFIG *)&eep_config_buf; - cfg_msw = AscGetChipCfgMsw(iop_base); - cfg_lsw = AscGetChipCfgLsw(iop_base); - if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { - cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; - warn_code |= ASC_WARN_CFG_MSW_RECOVER; - AscSetChipCfgMsw(iop_base, cfg_msw); - } - chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); - ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum); - if (chksum == 0) { - chksum = 0xaa55; - } - if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { - warn_code |= ASC_WARN_AUTO_CONFIG; - if (asc_dvc->cfg->chip_version == 3) { - if (eep_config->cfg_lsw != cfg_lsw) { - warn_code |= ASC_WARN_EEPROM_RECOVER; - eep_config->cfg_lsw = - AscGetChipCfgLsw(iop_base); - } - if (eep_config->cfg_msw != cfg_msw) { - warn_code |= ASC_WARN_EEPROM_RECOVER; - eep_config->cfg_msw = - AscGetChipCfgMsw(iop_base); - } - } - } - eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; - eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; - ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n", - eep_config->chksum); - if (chksum != eep_config->chksum) { - if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == - ASC_CHIP_VER_PCI_ULTRA_3050) { - ASC_DBG(1, - "AscInitFromEEP: chksum error ignored; EEPROM-less board\n"); - eep_config->init_sdtr = 0xFF; - eep_config->disc_enable = 0xFF; - eep_config->start_motor = 0xFF; - eep_config->use_cmd_qng = 0; - eep_config->max_total_qng = 0xF0; - eep_config->max_tag_qng = 0x20; - eep_config->cntl = 0xBFFF; - ASC_EEP_SET_CHIP_ID(eep_config, 7); - eep_config->no_scam = 0; - eep_config->adapter_info[0] = 0; - eep_config->adapter_info[1] = 0; - eep_config->adapter_info[2] = 0; - eep_config->adapter_info[3] = 0; - eep_config->adapter_info[4] = 0; - /* Indicate EEPROM-less board. */ - eep_config->adapter_info[5] = 0xBB; - } else { - ASC_PRINT - ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n"); - write_eep = 1; - warn_code |= ASC_WARN_EEPROM_CHKSUM; - } - } - asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr; - asc_dvc->cfg->disc_enable = eep_config->disc_enable; - asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; - asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config); - asc_dvc->start_motor = eep_config->start_motor; - asc_dvc->dvc_cntl = eep_config->cntl; - asc_dvc->no_scam = eep_config->no_scam; - asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; - asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; - asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; - asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; - asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; - asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; - if (!AscTestExternalLram(asc_dvc)) { - if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == - ASC_IS_PCI_ULTRA)) { - eep_config->max_total_qng = - ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; - eep_config->max_tag_qng = - ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; - } else { - eep_config->cfg_msw |= 0x0800; - cfg_msw |= 0x0800; - AscSetChipCfgMsw(iop_base, cfg_msw); - eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; - eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; - } - } else { - } - if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { - eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; - } - if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { - eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; - } - if (eep_config->max_tag_qng > eep_config->max_total_qng) { - eep_config->max_tag_qng = eep_config->max_total_qng; - } - if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { - eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; - } - asc_dvc->max_total_qng = eep_config->max_total_qng; - if ((eep_config->use_cmd_qng & eep_config->disc_enable) != - eep_config->use_cmd_qng) { - eep_config->disc_enable = eep_config->use_cmd_qng; - warn_code |= ASC_WARN_CMD_QNG_CONFLICT; - } - if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { - asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); - } - ASC_EEP_SET_CHIP_ID(eep_config, - ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); - asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); - if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && - !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { - asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; - } - - for (i = 0; i <= ASC_MAX_TID; i++) { - asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; - asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; - asc_dvc->cfg->sdtr_period_offset[i] = - (uchar)(ASC_DEF_SDTR_OFFSET | - (asc_dvc->host_init_sdtr_index << 4)); - } - eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); - if (write_eep) { - if ((i = - AscSetEEPConfig(iop_base, eep_config, - asc_dvc->bus_type)) != 0) { - ASC_PRINT1 - ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", - i); - } else { - ASC_PRINT - ("AscInitFromEEP: Successfully re-wrote EEPROM.\n"); - } - } - return (warn_code); -} - -static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) -{ - int i; - ushort warn_code; - PortAddr iop_base; - ASC_PADDR phy_addr; - ASC_DCNT phy_size; - - iop_base = asc_dvc->iop_base; - warn_code = 0; - for (i = 0; i <= ASC_MAX_TID; i++) { - AscPutMCodeInitSDTRAtID(iop_base, i, - asc_dvc->cfg->sdtr_period_offset[i] - ); - } - - AscInitQLinkVar(asc_dvc); - AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, - asc_dvc->cfg->disc_enable); - AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, - ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); - - /* Align overrun buffer on an 8 byte boundary. */ - phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); - phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); - AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, - (uchar *)&phy_addr, 1); - phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); - AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, - (uchar *)&phy_size, 1); - - asc_dvc->cfg->mcode_date = - AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W); - asc_dvc->cfg->mcode_version = - AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W); - - AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); - if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { - asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; - return (warn_code); - } - if (AscStartChip(iop_base) != 1) { - asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; - return (warn_code); - } - - return (warn_code); -} - -static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) -{ - PortAddr iop_base; - ushort q_addr; - ushort saved_word; - int sta; - - iop_base = asc_dvc->iop_base; - sta = 0; - q_addr = ASC_QNO_TO_QADDR(241); - saved_word = AscReadLramWord(iop_base, q_addr); - AscSetChipLramAddr(iop_base, q_addr); - AscSetChipLramData(iop_base, 0x55AA); - mdelay(10); - AscSetChipLramAddr(iop_base, q_addr); - if (AscGetChipLramData(iop_base) == 0x55AA) { - sta = 1; - AscWriteLramWord(iop_base, q_addr, saved_word); - } - return (sta); -} - -static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) -{ - uchar read_back; - int retry; - - retry = 0; - while (TRUE) { - AscSetChipEEPCmd(iop_base, cmd_reg); - mdelay(1); - read_back = AscGetChipEEPCmd(iop_base); - if (read_back == cmd_reg) { - return (1); - } - if (retry++ > ASC_EEP_MAX_RETRY) { - return (0); - } - } -} - -static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) -{ - ushort read_back; - int retry; - - retry = 0; - while (TRUE) { - AscSetChipEEPData(iop_base, data_reg); - mdelay(1); - read_back = AscGetChipEEPData(iop_base); - if (read_back == data_reg) { - return (1); - } - if (retry++ > ASC_EEP_MAX_RETRY) { - return (0); - } - } -} - -static void __devinit AscWaitEEPRead(void) -{ - mdelay(1); - return; -} - -static void __devinit AscWaitEEPWrite(void) -{ - mdelay(20); - return; -} - -static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr) -{ - ushort read_wval; - uchar cmd_reg; - - AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); - AscWaitEEPRead(); - cmd_reg = addr | ASC_EEP_CMD_READ; - AscWriteEEPCmdReg(iop_base, cmd_reg); - AscWaitEEPRead(); - read_wval = AscGetChipEEPData(iop_base); - AscWaitEEPRead(); - return (read_wval); -} - -static ushort __devinit -AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) -{ - ushort read_wval; - - read_wval = AscReadEEPWord(iop_base, addr); - if (read_wval != word_val) { - AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE); - AscWaitEEPRead(); - AscWriteEEPDataReg(iop_base, word_val); - AscWaitEEPRead(); - AscWriteEEPCmdReg(iop_base, - (uchar)((uchar)ASC_EEP_CMD_WRITE | addr)); - AscWaitEEPWrite(); - AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); - AscWaitEEPRead(); - return (AscReadEEPWord(iop_base, addr)); - } - return (read_wval); -} - -static ushort __devinit -AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) -{ - ushort wval; - ushort sum; - ushort *wbuf; - int cfg_beg; - int cfg_end; - int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; - int s_addr; - - wbuf = (ushort *)cfg_buf; - sum = 0; - /* Read two config words; Byte-swapping done by AscReadEEPWord(). */ - for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { - *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); - sum += *wbuf; - } - if (bus_type & ASC_IS_VL) { - cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; - cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; - } else { - cfg_beg = ASC_EEP_DVC_CFG_BEG; - cfg_end = ASC_EEP_MAX_DVC_ADDR; - } - for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { - wval = AscReadEEPWord(iop_base, (uchar)s_addr); - if (s_addr <= uchar_end_in_config) { - /* - * Swap all char fields - must unswap bytes already swapped - * by AscReadEEPWord(). - */ - *wbuf = le16_to_cpu(wval); - } else { - /* Don't swap word field at the end - cntl field. */ - *wbuf = wval; - } - sum += wval; /* Checksum treats all EEPROM data as words. */ - } - /* - * Read the checksum word which will be compared against 'sum' - * by the caller. Word field already swapped. - */ - *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); - return (sum); -} - -static int __devinit -AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) -{ - int n_error; - ushort *wbuf; - ushort word; - ushort sum; - int s_addr; - int cfg_beg; - int cfg_end; - int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; - - wbuf = (ushort *)cfg_buf; - n_error = 0; - sum = 0; - /* Write two config words; AscWriteEEPWord() will swap bytes. */ - for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { - sum += *wbuf; - if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) { - n_error++; - } - } - if (bus_type & ASC_IS_VL) { - cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; - cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; - } else { - cfg_beg = ASC_EEP_DVC_CFG_BEG; - cfg_end = ASC_EEP_MAX_DVC_ADDR; - } - for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { - if (s_addr <= uchar_end_in_config) { - /* - * This is a char field. Swap char fields before they are - * swapped again by AscWriteEEPWord(). - */ - word = cpu_to_le16(*wbuf); - if (word != - AscWriteEEPWord(iop_base, (uchar)s_addr, word)) { - n_error++; - } - } else { - /* Don't swap word field at the end - cntl field. */ - if (*wbuf != - AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) { - n_error++; - } - } - sum += *wbuf; /* Checksum calculated from word values. */ - } - /* Write checksum word. It will be swapped by AscWriteEEPWord(). */ - *wbuf = sum; - if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) { - n_error++; - } - - /* Read EEPROM back again. */ - wbuf = (ushort *)cfg_buf; - /* - * Read two config words; Byte-swapping done by AscReadEEPWord(). - */ - for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { - if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) { - n_error++; - } - } - if (bus_type & ASC_IS_VL) { - cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; - cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; - } else { - cfg_beg = ASC_EEP_DVC_CFG_BEG; - cfg_end = ASC_EEP_MAX_DVC_ADDR; - } - for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { - if (s_addr <= uchar_end_in_config) { - /* - * Swap all char fields. Must unswap bytes already swapped - * by AscReadEEPWord(). - */ - word = - le16_to_cpu(AscReadEEPWord - (iop_base, (uchar)s_addr)); - } else { - /* Don't swap word field at the end - cntl field. */ - word = AscReadEEPWord(iop_base, (uchar)s_addr); - } - if (*wbuf != word) { - n_error++; - } - } - /* Read checksum; Byte swapping not needed. */ - if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) { - n_error++; - } - return (n_error); -} - -static int __devinit -AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) -{ - int retry; - int n_error; - - retry = 0; - while (TRUE) { - if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf, - bus_type)) == 0) { - break; - } - if (++retry > ASC_EEP_MAX_RETRY) { - break; - } - } - return (n_error); -} - -static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev) -{ - char type = sdev->type; - ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id; - - if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)) - return; - if (asc_dvc->init_sdtr & tid_bits) - return; - - if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0)) - asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; - - asc_dvc->pci_fix_asyn_xfer |= tid_bits; - if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) || - (type == TYPE_ROM) || (type == TYPE_TAPE)) - asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; - - if (asc_dvc->pci_fix_asyn_xfer & tid_bits) - AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id, - ASYN_SDTR_DATA_FIX_PCI_REV_AB); -} - -static uchar AscReadLramByte(PortAddr iop_base, ushort addr) -{ - uchar byte_data; - ushort word_data; - - if (isodd_word(addr)) { - AscSetChipLramAddr(iop_base, addr - 1); - word_data = AscGetChipLramData(iop_base); - byte_data = (uchar)((word_data >> 8) & 0xFF); - } else { - AscSetChipLramAddr(iop_base, addr); - word_data = AscGetChipLramData(iop_base); - byte_data = (uchar)(word_data & 0xFF); - } - return (byte_data); -} - -static ushort AscReadLramWord(PortAddr iop_base, ushort addr) -{ - ushort word_data; - - AscSetChipLramAddr(iop_base, addr); - word_data = AscGetChipLramData(iop_base); - return (word_data); -} - -#if CC_VERY_LONG_SG_LIST -static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr) -{ - ushort val_low, val_high; - ASC_DCNT dword_data; - - AscSetChipLramAddr(iop_base, addr); - val_low = AscGetChipLramData(iop_base); - val_high = AscGetChipLramData(iop_base); - dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low; - return (dword_data); -} -#endif /* CC_VERY_LONG_SG_LIST */ - -static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) -{ - AscSetChipLramAddr(iop_base, addr); - AscSetChipLramData(iop_base, word_val); - return; -} - -static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) -{ - ushort word_data; - - if (isodd_word(addr)) { - addr--; - word_data = AscReadLramWord(iop_base, addr); - word_data &= 0x00FF; - word_data |= (((ushort)byte_val << 8) & 0xFF00); - } else { - word_data = AscReadLramWord(iop_base, addr); - word_data &= 0xFF00; - word_data |= ((ushort)byte_val & 0x00FF); - } - AscWriteLramWord(iop_base, addr, word_data); - return; -} - -/* - * Copy 2 bytes to LRAM. - * - * The source data is assumed to be in little-endian order in memory - * and is maintained in little-endian order when written to LRAM. - */ -static void -AscMemWordCopyPtrToLram(PortAddr iop_base, - ushort s_addr, uchar *s_buffer, int words) -{ - int i; - - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < 2 * words; i += 2) { - /* - * On a little-endian system the second argument below - * produces a little-endian ushort which is written to - * LRAM in little-endian order. On a big-endian system - * the second argument produces a big-endian ushort which - * is "transparently" byte-swapped by outpw() and written - * in little-endian order to LRAM. - */ - outpw(iop_base + IOP_RAM_DATA, - ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); - } - return; -} - -/* - * Copy 4 bytes to LRAM. - * - * The source data is assumed to be in little-endian order in memory - * and is maintained in little-endian order when writen to LRAM. - */ -static void -AscMemDWordCopyPtrToLram(PortAddr iop_base, - ushort s_addr, uchar *s_buffer, int dwords) -{ - int i; - - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < 4 * dwords; i += 4) { - outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ - outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ - } - return; -} - -/* - * Copy 2 bytes from LRAM. - * - * The source data is assumed to be in little-endian order in LRAM - * and is maintained in little-endian order when written to memory. - */ -static void -AscMemWordCopyPtrFromLram(PortAddr iop_base, - ushort s_addr, uchar *d_buffer, int words) -{ - int i; - ushort word; - - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < 2 * words; i += 2) { - word = inpw(iop_base + IOP_RAM_DATA); - d_buffer[i] = word & 0xff; - d_buffer[i + 1] = (word >> 8) & 0xff; - } - return; -} - -static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) -{ - ASC_DCNT sum; - int i; - - sum = 0L; - for (i = 0; i < words; i++, s_addr += 2) { - sum += AscReadLramWord(iop_base, s_addr); - } - return (sum); -} - -static void -AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) -{ - int i; - - AscSetChipLramAddr(iop_base, s_addr); - for (i = 0; i < words; i++) { - AscSetChipLramData(iop_base, set_wval); - } - return; -} +static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf); +static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL; /* Microcode buffer is kept after initialization for error recovery. */ static unsigned char _adv_asc3550_buf[] = { @@ -10683,2728 +6491,6514 @@ static unsigned char _adv_asc38C1600_buf[] = { 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, }; -static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ -static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */ +static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ +static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */ + +static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) +{ + PortAddr iop_base; + int i; + ushort lram_addr; + + iop_base = asc_dvc->iop_base; + AscPutRiscVarFreeQHead(iop_base, 1); + AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); + AscPutVarFreeQHead(iop_base, 1); + AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); + AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, + (uchar)((int)asc_dvc->max_total_qng + 1)); + AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, + (uchar)((int)asc_dvc->max_total_qng + 2)); + AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B, + asc_dvc->max_total_qng); + AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); + AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); + AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); + AscPutQDoneInProgress(iop_base, 0); + lram_addr = ASC_QADR_BEG; + for (i = 0; i < 32; i++, lram_addr += 2) { + AscWriteLramWord(iop_base, lram_addr, 0); + } +} + +static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) +{ + int i; + ushort warn_code; + PortAddr iop_base; + ASC_PADDR phy_addr; + ASC_DCNT phy_size; + + iop_base = asc_dvc->iop_base; + warn_code = 0; + for (i = 0; i <= ASC_MAX_TID; i++) { + AscPutMCodeInitSDTRAtID(iop_base, i, + asc_dvc->cfg->sdtr_period_offset[i]); + } + + AscInitQLinkVar(asc_dvc); + AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, + asc_dvc->cfg->disc_enable); + AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, + ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); + + /* Align overrun buffer on an 8 byte boundary. */ + phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); + phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); + AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, + (uchar *)&phy_addr, 1); + phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); + AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, + (uchar *)&phy_size, 1); + + asc_dvc->cfg->mcode_date = + AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W); + asc_dvc->cfg->mcode_version = + AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W); + + AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); + if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { + asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; + return warn_code; + } + if (AscStartChip(iop_base) != 1) { + asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; + return warn_code; + } + + return warn_code; +} + +static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) +{ + ushort warn_code; + PortAddr iop_base; + + iop_base = asc_dvc->iop_base; + warn_code = 0; + if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && + !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { + AscResetChipAndScsiBus(asc_dvc); + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ + } + asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; + if (asc_dvc->err_code != 0) + return UW_ERR; + if (!AscFindSignature(asc_dvc->iop_base)) { + asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; + return warn_code; + } + AscDisableInterrupt(iop_base); + warn_code |= AscInitLram(asc_dvc); + if (asc_dvc->err_code != 0) + return UW_ERR; + ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n", + (ulong)_asc_mcode_chksum); + if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, + _asc_mcode_size) != _asc_mcode_chksum) { + asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + return warn_code; + } + warn_code |= AscInitMicroCodeVar(asc_dvc); + asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; + AscEnableInterrupt(iop_base); + return warn_code; +} + +/* + * Load the Microcode + * + * Write the microcode image to RISC memory starting at address 0. + * + * The microcode is stored compressed in the following format: + * + * 254 word (508 byte) table indexed by byte code followed + * by the following byte codes: + * + * 1-Byte Code: + * 00: Emit word 0 in table. + * 01: Emit word 1 in table. + * . + * FD: Emit word 253 in table. + * + * Multi-Byte Code: + * FE WW WW: (3 byte code) Word to emit is the next word WW WW. + * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. + * + * Returns 0 or an error if the checksum doesn't match + */ +static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, + int memsize, int chksum) +{ + int i, j, end, len = 0; + ADV_DCNT sum; + + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); + + for (i = 253 * 2; i < size; i++) { + if (buf[i] == 0xff) { + unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; + for (j = 0; j < buf[i + 1]; j++) { + AdvWriteWordAutoIncLram(iop_base, word); + len += 2; + } + i += 3; + } else if (buf[i] == 0xfe) { + unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; + AdvWriteWordAutoIncLram(iop_base, word); + i += 2; + len += 2; + } else { + unsigned char off = buf[i] * 2; + unsigned short word = (buf[off + 1] << 8) | buf[off]; + AdvWriteWordAutoIncLram(iop_base, word); + len += 2; + } + } + + end = len; + + while (len < memsize) { + AdvWriteWordAutoIncLram(iop_base, 0); + len += 2; + } + + /* Verify the microcode checksum. */ + sum = 0; + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); + + for (len = 0; len < end; len += 2) { + sum += AdvReadWordAutoIncLram(iop_base); + } + + if (sum != chksum) + return ASC_IERR_MCODE_CHKSUM; + + return 0; +} + +/* + * DvcGetPhyAddr() + * + * Return the physical address of 'vaddr' and set '*lenp' to the + * number of physically contiguous bytes that follow 'vaddr'. + * 'flag' indicates the type of structure whose physical address + * is being translated. + * + * Note: Because Linux currently doesn't page the kernel and all + * kernel buffers are physically contiguous, leave '*lenp' unchanged. + */ +ADV_PADDR +DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, + uchar *vaddr, ADV_SDCNT *lenp, int flag) +{ + ADV_PADDR paddr = virt_to_bus(vaddr); + + ASC_DBG4(4, "DvcGetPhyAddr: vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n", + vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr); + + return paddr; +} + +static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) +{ + ADV_CARR_T *carrp; + ADV_SDCNT buf_size; + ADV_PADDR carr_paddr; + + BUG_ON(!asc_dvc->carrier_buf); + + carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); + asc_dvc->carr_freelist = NULL; + if (carrp == asc_dvc->carrier_buf) { + buf_size = ADV_CARRIER_BUFSIZE; + } else { + buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); + } + + do { + /* Get physical address of the carrier 'carrp'. */ + ADV_DCNT contig_len = sizeof(ADV_CARR_T); + carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, + (uchar *)carrp, + (ADV_SDCNT *)&contig_len, + ADV_IS_CARRIER_FLAG)); + + buf_size -= sizeof(ADV_CARR_T); + + /* + * If the current carrier is not physically contiguous, then + * maybe there was a page crossing. Try the next carrier + * aligned start address. + */ + if (contig_len < sizeof(ADV_CARR_T)) { + carrp++; + continue; + } + + carrp->carr_pa = carr_paddr; + carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); + + /* + * Insert the carrier at the beginning of the freelist. + */ + carrp->next_vpa = + cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); + asc_dvc->carr_freelist = carrp; + + carrp++; + } while (buf_size > 0); +} + +/* + * Send an idle command to the chip and wait for completion. + * + * Command completion is polled for once per microsecond. + * + * The function can be called from anywhere including an interrupt handler. + * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() + * functions to prevent reentrancy. + * + * Return Values: + * ADV_TRUE - command completed successfully + * ADV_FALSE - command failed + * ADV_ERROR - command timed out + */ +static int +AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, + ushort idle_cmd, ADV_DCNT idle_cmd_parameter) +{ + int result; + ADV_DCNT i, j; + AdvPortAddr iop_base; + + iop_base = asc_dvc->iop_base; + + /* + * Clear the idle command status which is set by the microcode + * to a non-zero value to indicate when the command is completed. + * The non-zero result is one of the IDLE_CMD_STATUS_* values + */ + AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0); + + /* + * Write the idle command value after the idle command parameter + * has been written to avoid a race condition. If the order is not + * followed, the microcode may process the idle command before the + * parameters have been written to LRAM. + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER, + cpu_to_le32(idle_cmd_parameter)); + AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); + + /* + * Tickle the RISC to tell it to process the idle command. + */ + AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B); + if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { + /* + * Clear the tickle value. In the ASC-3550 the RISC flag + * command 'clr_tickle_b' does not work unless the host + * value is cleared. + */ + AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); + } + + /* Wait for up to 100 millisecond for the idle command to timeout. */ + for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { + /* Poll once each microsecond for command completion. */ + for (j = 0; j < SCSI_US_PER_MSEC; j++) { + AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, + result); + if (result != 0) + return result; + udelay(1); + } + } + + BUG(); /* The idle command should never timeout. */ + return ADV_ERROR; +} + +/* + * Reset SCSI Bus and purge all outstanding requests. + * + * Return Value: + * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. + * ADV_FALSE(0) - Microcode command failed. + * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC + * may be hung which requires driver recovery. + */ +static int AdvResetSB(ADV_DVC_VAR *asc_dvc) +{ + int status; + + /* + * Send the SCSI Bus Reset idle start idle command which asserts + * the SCSI Bus Reset signal. + */ + status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L); + if (status != ADV_TRUE) { + return status; + } + + /* + * Delay for the specified SCSI Bus Reset hold time. + * + * The hold time delay is done on the host because the RISC has no + * microsecond accurate timer. + */ + udelay(ASC_SCSI_RESET_HOLD_TIME_US); + + /* + * Send the SCSI Bus Reset end idle command which de-asserts + * the SCSI Bus Reset signal and purges any pending requests. + */ + status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L); + if (status != ADV_TRUE) { + return status; + } + + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ + + return status; +} + +/* + * Initialize the ASC-3550. + * + * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + * + * Needed after initialization for error recovery. + */ +static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) +{ + AdvPortAddr iop_base; + ushort warn_code; + int begin_addr; + int end_addr; + ushort code_sum; + int word; + int i; + ushort scsi_cfg1; + uchar tid; + ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ + ushort wdtr_able = 0, sdtr_able, tagqng_able; + uchar max_cmd[ADV_MAX_TID + 1]; + + /* If there is already an error, don't continue. */ + if (asc_dvc->err_code != 0) + return ADV_ERROR; + + /* + * The caller must set 'chip_type' to ADV_CHIP_ASC3550. + */ + if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { + asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; + return ADV_ERROR; + } + + warn_code = 0; + iop_base = asc_dvc->iop_base; + + /* + * Save the RISC memory BIOS region before writing the microcode. + * The BIOS may already be loaded and using its RISC LRAM region + * so its region must be saved and restored. + * + * Note: This code makes the assumption, which is currently true, + * that a chip reset does not clear RISC LRAM. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Save current per TID negotiated values. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) { + ushort bios_version, major, minor; + + bios_version = + bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2]; + major = (bios_version >> 12) & 0xF; + minor = (bios_version >> 8) & 0xF; + if (major < 3 || (major == 3 && minor == 1)) { + /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ + AdvReadWordLram(iop_base, 0x120, wdtr_able); + } else { + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + } + } + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, + _adv_asc3550_size, ADV_3550_MEMSIZE, + _adv_asc3550_chksum); + if (asc_dvc->err_code) + return ADV_ERROR; + + /* + * Restore the RISC memory BIOS region. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Calculate and write the microcode code checksum to the microcode + * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + */ + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); + AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); + code_sum = 0; + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); + for (word = begin_addr; word < end_addr; word += 2) { + code_sum += AdvReadWordAutoIncLram(iop_base); + } + AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); + + /* + * Read and save microcode version and date. + */ + AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, + asc_dvc->cfg->mcode_date); + AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, + asc_dvc->cfg->mcode_version); + + /* + * Set the chip type to indicate the ASC3550. + */ + AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); + + /* + * If the PCI Configuration Command Register "Parity Error Response + * Control" Bit was clear (0), then set the microcode variable + * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode + * to ignore DMA parity errors. + */ + if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { + AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + word |= CONTROL_FLAG_IGNORE_PERR; + AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + } + + /* + * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO + * threshold of 128 bytes. This register is only accessible to the host. + */ + AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, + START_CTL_EMFU | READ_CMD_MRM); + + /* + * Microcode operating variables for WDTR, SDTR, and command tag + * queuing will be set in slave_configure() based on what a + * device reports it is capable of in Inquiry byte 7. + * + * If SCSI Bus Resets have been disabled, then directly set + * SDTR and WDTR from the EEPROM configuration. This will allow + * the BIOS and warm boot to work without a SCSI bus hang on + * the Inquiry caused by host and target mismatched DTR values. + * Without the SCSI Bus Reset, before an Inquiry a device can't + * be assumed to be in Asynchronous, Narrow mode. + */ + if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, + asc_dvc->wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, + asc_dvc->sdtr_able); + } + + /* + * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID + * bitmask. These values determine the maximum SDTR speed negotiated + * with a device. + * + * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them + * without determining here whether the device supports SDTR. + * + * 4-bit speed SDTR speed name + * =========== =============== + * 0000b (0x0) SDTR disabled + * 0001b (0x1) 5 Mhz + * 0010b (0x2) 10 Mhz + * 0011b (0x3) 20 Mhz (Ultra) + * 0100b (0x4) 40 Mhz (LVD/Ultra2) + * 0101b (0x5) 80 Mhz (LVD2/Ultra3) + * 0110b (0x6) Undefined + * . + * 1111b (0xF) Undefined + */ + word = 0; + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) { + /* Set Ultra speed for TID 'tid'. */ + word |= (0x3 << (4 * (tid % 4))); + } else { + /* Set Fast speed for TID 'tid'. */ + word |= (0x2 << (4 * (tid % 4))); + } + if (tid == 3) { /* Check if done with sdtr_speed1. */ + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word); + word = 0; + } else if (tid == 7) { /* Check if done with sdtr_speed2. */ + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word); + word = 0; + } else if (tid == 11) { /* Check if done with sdtr_speed3. */ + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word); + word = 0; + } else if (tid == 15) { /* Check if done with sdtr_speed4. */ + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word); + /* End of loop. */ + } + } + + /* + * Set microcode operating variable for the disconnect per TID bitmask. + */ + AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, + asc_dvc->cfg->disc_enable); + + /* + * Set SCSI_CFG0 Microcode Default Value. + * + * The microcode will set the SCSI_CFG0 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, + PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | + asc_dvc->chip_scsi_id); + + /* + * Determine SCSI_CFG1 Microcode Default Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + + /* Read current SCSI_CFG1 Register value. */ + scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + + /* + * If all three connectors are in use, return an error. + */ + if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || + (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { + asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; + return ADV_ERROR; + } + + /* + * If the internal narrow cable is reversed all of the SCSI_CTRL + * register signals will be set. Check for and return an error if + * this condition is found. + */ + if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { + asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; + return ADV_ERROR; + } + + /* + * If this is a differential board and a single-ended device + * is attached to one of the connectors, return an error. + */ + if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) { + asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; + return ADV_ERROR; + } + + /* + * If automatic termination control is enabled, then set the + * termination value based on a table listed in a_condor.h. + * + * If manual termination was specified with an EEPROM setting + * then 'termination' was set-up in AdvInitFrom3550EEPROM() and + * is ready to be 'ored' into SCSI_CFG1. + */ + if (asc_dvc->cfg->termination == 0) { + /* + * The software always controls termination by setting TERM_CTL_SEL. + * If TERM_CTL_SEL were set to 0, the hardware would set termination. + */ + asc_dvc->cfg->termination |= TERM_CTL_SEL; + + switch (scsi_cfg1 & CABLE_DETECT) { + /* TERM_CTL_H: on, TERM_CTL_L: on */ + case 0x3: + case 0x7: + case 0xB: + case 0xD: + case 0xE: + case 0xF: + asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); + break; + + /* TERM_CTL_H: on, TERM_CTL_L: off */ + case 0x1: + case 0x5: + case 0x9: + case 0xA: + case 0xC: + asc_dvc->cfg->termination |= TERM_CTL_H; + break; + + /* TERM_CTL_H: off, TERM_CTL_L: off */ + case 0x2: + case 0x6: + break; + } + } + + /* + * Clear any set TERM_CTL_H and TERM_CTL_L bits. + */ + scsi_cfg1 &= ~TERM_CTL; + + /* + * Invert the TERM_CTL_H and TERM_CTL_L bits and then + * set 'scsi_cfg1'. The TERM_POL bit does not need to be + * referenced, because the hardware internally inverts + * the Termination High and Low bits if TERM_POL is set. + */ + scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); + + /* + * Set SCSI_CFG1 Microcode Default Value + * + * Set filter value and possibly modified termination control + * bits in the Microcode SCSI_CFG1 Register Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, + FLTR_DISABLE | scsi_cfg1); + + /* + * Set MEM_CFG Microcode Default Value + * + * The microcode will set the MEM_CFG register using this value + * after it is started below. + * + * MEM_CFG may be accessed as a word or byte, but only bits 0-7 + * are defined. + * + * ASC-3550 has 8KB internal memory. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, + BIOS_EN | RAM_SZ_8KB); + + /* + * Set SEL_MASK Microcode Default Value + * + * The microcode will set the SEL_MASK register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, + ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); + + AdvBuildCarrierFreelist(asc_dvc); + + /* + * Set-up the Host->RISC Initiator Command Queue (ICQ). + */ + + if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + + /* + * The first command issued will be placed in the stopper carrier. + */ + asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC ICQ physical address start value. + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); + + /* + * Set-up the RISC->Host Initiator Response Queue (IRQ). + */ + if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); + + /* + * The first command completed by the RISC will be placed in + * the stopper. + * + * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is + * completed the RISC will set the ASC_RQ_STOPPER bit. + */ + asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC IRQ physical address start value. + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); + asc_dvc->carr_pending_cnt = 0; + + AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, + (ADV_INTR_ENABLE_HOST_INTR | + ADV_INTR_ENABLE_GLOBAL_INTR)); + + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); + AdvWriteWordRegister(iop_base, IOPW_PC, word); + + /* finally, finally, gentlemen, start your engine */ + AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); + + /* + * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus + * Resets should be performed. The RISC has to be running + * to issue a SCSI Bus Reset. + */ + if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { + /* + * If the BIOS Signature is present in memory, restore the + * BIOS Handshake Configuration Table and do not perform + * a SCSI Bus Reset. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == + 0x55AA) { + /* + * Restore per TID negotiated values. + */ + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, + tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvWriteByteLram(iop_base, + ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + } else { + if (AdvResetSB(asc_dvc) != ADV_TRUE) { + warn_code = ASC_WARN_BUSRESET_ERROR; + } + } + } + + return warn_code; +} + +/* + * Initialize the ASC-38C0800. + * + * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + * + * Needed after initialization for error recovery. + */ +static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) +{ + AdvPortAddr iop_base; + ushort warn_code; + int begin_addr; + int end_addr; + ushort code_sum; + int word; + int i; + ushort scsi_cfg1; + uchar byte; + uchar tid; + ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ + ushort wdtr_able, sdtr_able, tagqng_able; + uchar max_cmd[ADV_MAX_TID + 1]; + + /* If there is already an error, don't continue. */ + if (asc_dvc->err_code != 0) + return ADV_ERROR; + + /* + * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. + */ + if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) { + asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; + return ADV_ERROR; + } + + warn_code = 0; + iop_base = asc_dvc->iop_base; + + /* + * Save the RISC memory BIOS region before writing the microcode. + * The BIOS may already be loaded and using its RISC LRAM region + * so its region must be saved and restored. + * + * Note: This code makes the assumption, which is currently true, + * that a chip reset does not clear RISC LRAM. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Save current per TID negotiated values. + */ + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + /* + * RAM BIST (RAM Built-In Self Test) + * + * Address : I/O base + offset 0x38h register (byte). + * Function: Bit 7-6(RW) : RAM mode + * Normal Mode : 0x00 + * Pre-test Mode : 0x40 + * RAM Test Mode : 0x80 + * Bit 5 : unused + * Bit 4(RO) : Done bit + * Bit 3-0(RO) : Status + * Host Error : 0x08 + * Int_RAM Error : 0x04 + * RISC Error : 0x02 + * SCSI Error : 0x01 + * No Error : 0x00 + * + * Note: RAM BIST code should be put right here, before loading the + * microcode and after saving the RISC memory BIOS region. + */ + + /* + * LRAM Pre-test + * + * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. + * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return + * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset + * to NORMAL_MODE, return an error too. + */ + for (i = 0; i < 2; i++) { + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); + mdelay(10); /* Wait for 10ms before reading back. */ + byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 + || (byte & 0x0F) != PRE_TEST_VALUE) { + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; + return ADV_ERROR; + } + + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); + mdelay(10); /* Wait for 10ms before reading back. */ + if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) + != NORMAL_VALUE) { + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; + return ADV_ERROR; + } + } + + /* + * LRAM Test - It takes about 1.5 ms to run through the test. + * + * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. + * If Done bit not set or Status not 0, save register byte, set the + * err_code, and return an error. + */ + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); + mdelay(10); /* Wait for 10ms before checking status. */ + + byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { + /* Get here if Done bit not set or Status not 0. */ + asc_dvc->bist_err_code = byte; /* for BIOS display message */ + asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; + return ADV_ERROR; + } + + /* We need to reset back to normal mode after LRAM test passes. */ + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); + + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, + _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, + _adv_asc38C0800_chksum); + if (asc_dvc->err_code) + return ADV_ERROR; + + /* + * Restore the RISC memory BIOS region. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Calculate and write the microcode code checksum to the microcode + * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + */ + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); + AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); + code_sum = 0; + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); + for (word = begin_addr; word < end_addr; word += 2) { + code_sum += AdvReadWordAutoIncLram(iop_base); + } + AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); + + /* + * Read microcode version and date. + */ + AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, + asc_dvc->cfg->mcode_date); + AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, + asc_dvc->cfg->mcode_version); + + /* + * Set the chip type to indicate the ASC38C0800. + */ + AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); + + /* + * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. + * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current + * cable detection and then we are able to read C_DET[3:0]. + * + * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 + * Microcode Default Value' section below. + */ + scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, + scsi_cfg1 | DIS_TERM_DRV); + + /* + * If the PCI Configuration Command Register "Parity Error Response + * Control" Bit was clear (0), then set the microcode variable + * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode + * to ignore DMA parity errors. + */ + if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { + AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + word |= CONTROL_FLAG_IGNORE_PERR; + AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + } + + /* + * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] + * bits for the default FIFO threshold. + * + * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. + * + * For DMA Errata #4 set the BC_THRESH_ENB bit. + */ + AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, + BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | + READ_CMD_MRM); + + /* + * Microcode operating variables for WDTR, SDTR, and command tag + * queuing will be set in slave_configure() based on what a + * device reports it is capable of in Inquiry byte 7. + * + * If SCSI Bus Resets have been disabled, then directly set + * SDTR and WDTR from the EEPROM configuration. This will allow + * the BIOS and warm boot to work without a SCSI bus hang on + * the Inquiry caused by host and target mismatched DTR values. + * Without the SCSI Bus Reset, before an Inquiry a device can't + * be assumed to be in Asynchronous, Narrow mode. + */ + if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, + asc_dvc->wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, + asc_dvc->sdtr_able); + } + + /* + * Set microcode operating variables for DISC and SDTR_SPEED1, + * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM + * configuration values. + * + * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them + * without determining here whether the device supports SDTR. + */ + AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, + asc_dvc->cfg->disc_enable); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); + + /* + * Set SCSI_CFG0 Microcode Default Value. + * + * The microcode will set the SCSI_CFG0 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, + PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | + asc_dvc->chip_scsi_id); + + /* + * Determine SCSI_CFG1 Microcode Default Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + + /* Read current SCSI_CFG1 Register value. */ + scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + + /* + * If the internal narrow cable is reversed all of the SCSI_CTRL + * register signals will be set. Check for and return an error if + * this condition is found. + */ + if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { + asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; + return ADV_ERROR; + } + + /* + * All kind of combinations of devices attached to one of four + * connectors are acceptable except HVD device attached. For example, + * LVD device can be attached to SE connector while SE device attached + * to LVD connector. If LVD device attached to SE connector, it only + * runs up to Ultra speed. + * + * If an HVD device is attached to one of LVD connectors, return an + * error. However, there is no way to detect HVD device attached to + * SE connectors. + */ + if (scsi_cfg1 & HVD) { + asc_dvc->err_code = ASC_IERR_HVD_DEVICE; + return ADV_ERROR; + } + + /* + * If either SE or LVD automatic termination control is enabled, then + * set the termination value based on a table listed in a_condor.h. + * + * If manual termination was specified with an EEPROM setting then + * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready + * to be 'ored' into SCSI_CFG1. + */ + if ((asc_dvc->cfg->termination & TERM_SE) == 0) { + /* SE automatic termination control is enabled. */ + switch (scsi_cfg1 & C_DET_SE) { + /* TERM_SE_HI: on, TERM_SE_LO: on */ + case 0x1: + case 0x2: + case 0x3: + asc_dvc->cfg->termination |= TERM_SE; + break; + + /* TERM_SE_HI: on, TERM_SE_LO: off */ + case 0x0: + asc_dvc->cfg->termination |= TERM_SE_HI; + break; + } + } + + if ((asc_dvc->cfg->termination & TERM_LVD) == 0) { + /* LVD automatic termination control is enabled. */ + switch (scsi_cfg1 & C_DET_LVD) { + /* TERM_LVD_HI: on, TERM_LVD_LO: on */ + case 0x4: + case 0x8: + case 0xC: + asc_dvc->cfg->termination |= TERM_LVD; + break; + + /* TERM_LVD_HI: off, TERM_LVD_LO: off */ + case 0x0: + break; + } + } + + /* + * Clear any set TERM_SE and TERM_LVD bits. + */ + scsi_cfg1 &= (~TERM_SE & ~TERM_LVD); + + /* + * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. + */ + scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); + + /* + * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE + * bits and set possibly modified termination control bits in the + * Microcode SCSI_CFG1 Register Value. + */ + scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); + + /* + * Set SCSI_CFG1 Microcode Default Value + * + * Set possibly modified termination control and reset DIS_TERM_DRV + * bits in the Microcode SCSI_CFG1 Register Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); + + /* + * Set MEM_CFG Microcode Default Value + * + * The microcode will set the MEM_CFG register using this value + * after it is started below. + * + * MEM_CFG may be accessed as a word or byte, but only bits 0-7 + * are defined. + * + * ASC-38C0800 has 16KB internal memory. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, + BIOS_EN | RAM_SZ_16KB); + + /* + * Set SEL_MASK Microcode Default Value + * + * The microcode will set the SEL_MASK register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, + ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); + + AdvBuildCarrierFreelist(asc_dvc); + + /* + * Set-up the Host->RISC Initiator Command Queue (ICQ). + */ + + if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + + /* + * The first command issued will be placed in the stopper carrier. + */ + asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC ICQ physical address start value. + * carr_pa is LE, must be native before write + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); + + /* + * Set-up the RISC->Host Initiator Response Queue (IRQ). + */ + if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); + + /* + * The first command completed by the RISC will be placed in + * the stopper. + * + * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is + * completed the RISC will set the ASC_RQ_STOPPER bit. + */ + asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC IRQ physical address start value. + * + * carr_pa is LE, must be native before write * + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); + asc_dvc->carr_pending_cnt = 0; + + AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, + (ADV_INTR_ENABLE_HOST_INTR | + ADV_INTR_ENABLE_GLOBAL_INTR)); + + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); + AdvWriteWordRegister(iop_base, IOPW_PC, word); + + /* finally, finally, gentlemen, start your engine */ + AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); + + /* + * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus + * Resets should be performed. The RISC has to be running + * to issue a SCSI Bus Reset. + */ + if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { + /* + * If the BIOS Signature is present in memory, restore the + * BIOS Handshake Configuration Table and do not perform + * a SCSI Bus Reset. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == + 0x55AA) { + /* + * Restore per TID negotiated values. + */ + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, + tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvWriteByteLram(iop_base, + ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + } else { + if (AdvResetSB(asc_dvc) != ADV_TRUE) { + warn_code = ASC_WARN_BUSRESET_ERROR; + } + } + } + + return warn_code; +} + +/* + * Initialize the ASC-38C1600. + * + * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + * + * Needed after initialization for error recovery. + */ +static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) +{ + AdvPortAddr iop_base; + ushort warn_code; + int begin_addr; + int end_addr; + ushort code_sum; + long word; + int i; + ushort scsi_cfg1; + uchar byte; + uchar tid; + ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ + ushort wdtr_able, sdtr_able, ppr_able, tagqng_able; + uchar max_cmd[ASC_MAX_TID + 1]; + + /* If there is already an error, don't continue. */ + if (asc_dvc->err_code != 0) { + return ADV_ERROR; + } + + /* + * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600. + */ + if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { + asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; + return ADV_ERROR; + } + + warn_code = 0; + iop_base = asc_dvc->iop_base; + + /* + * Save the RISC memory BIOS region before writing the microcode. + * The BIOS may already be loaded and using its RISC LRAM region + * so its region must be saved and restored. + * + * Note: This code makes the assumption, which is currently true, + * that a chip reset does not clear RISC LRAM. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Save current per TID negotiated values. + */ + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ASC_MAX_TID; tid++) { + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + /* + * RAM BIST (Built-In Self Test) + * + * Address : I/O base + offset 0x38h register (byte). + * Function: Bit 7-6(RW) : RAM mode + * Normal Mode : 0x00 + * Pre-test Mode : 0x40 + * RAM Test Mode : 0x80 + * Bit 5 : unused + * Bit 4(RO) : Done bit + * Bit 3-0(RO) : Status + * Host Error : 0x08 + * Int_RAM Error : 0x04 + * RISC Error : 0x02 + * SCSI Error : 0x01 + * No Error : 0x00 + * + * Note: RAM BIST code should be put right here, before loading the + * microcode and after saving the RISC memory BIOS region. + */ + + /* + * LRAM Pre-test + * + * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. + * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return + * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset + * to NORMAL_MODE, return an error too. + */ + for (i = 0; i < 2; i++) { + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); + mdelay(10); /* Wait for 10ms before reading back. */ + byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 + || (byte & 0x0F) != PRE_TEST_VALUE) { + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; + return ADV_ERROR; + } + + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); + mdelay(10); /* Wait for 10ms before reading back. */ + if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) + != NORMAL_VALUE) { + asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; + return ADV_ERROR; + } + } + + /* + * LRAM Test - It takes about 1.5 ms to run through the test. + * + * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. + * If Done bit not set or Status not 0, save register byte, set the + * err_code, and return an error. + */ + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); + mdelay(10); /* Wait for 10ms before checking status. */ + + byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { + /* Get here if Done bit not set or Status not 0. */ + asc_dvc->bist_err_code = byte; /* for BIOS display message */ + asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; + return ADV_ERROR; + } + + /* We need to reset back to normal mode after LRAM test passes. */ + AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); + + asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, + _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, + _adv_asc38C1600_chksum); + if (asc_dvc->err_code) + return ADV_ERROR; + + /* + * Restore the RISC memory BIOS region. + */ + for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { + AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + + /* + * Calculate and write the microcode code checksum to the microcode + * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + */ + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); + AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); + code_sum = 0; + AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); + for (word = begin_addr; word < end_addr; word += 2) { + code_sum += AdvReadWordAutoIncLram(iop_base); + } + AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); + + /* + * Read microcode version and date. + */ + AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, + asc_dvc->cfg->mcode_date); + AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, + asc_dvc->cfg->mcode_version); + + /* + * Set the chip type to indicate the ASC38C1600. + */ + AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600); + + /* + * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. + * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current + * cable detection and then we are able to read C_DET[3:0]. + * + * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 + * Microcode Default Value' section below. + */ + scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, + scsi_cfg1 | DIS_TERM_DRV); + + /* + * If the PCI Configuration Command Register "Parity Error Response + * Control" Bit was clear (0), then set the microcode variable + * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode + * to ignore DMA parity errors. + */ + if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { + AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + word |= CONTROL_FLAG_IGNORE_PERR; + AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + } + + /* + * If the BIOS control flag AIPP (Asynchronous Information + * Phase Protection) disable bit is not set, then set the firmware + * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable + * AIPP checking and encoding. + */ + if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) { + AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + word |= CONTROL_FLAG_ENABLE_AIPP; + AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + } + + /* + * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4], + * and START_CTL_TH [3:2]. + */ + AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, + FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); + + /* + * Microcode operating variables for WDTR, SDTR, and command tag + * queuing will be set in slave_configure() based on what a + * device reports it is capable of in Inquiry byte 7. + * + * If SCSI Bus Resets have been disabled, then directly set + * SDTR and WDTR from the EEPROM configuration. This will allow + * the BIOS and warm boot to work without a SCSI bus hang on + * the Inquiry caused by host and target mismatched DTR values. + * Without the SCSI Bus Reset, before an Inquiry a device can't + * be assumed to be in Asynchronous, Narrow mode. + */ + if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, + asc_dvc->wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, + asc_dvc->sdtr_able); + } + + /* + * Set microcode operating variables for DISC and SDTR_SPEED1, + * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM + * configuration values. + * + * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them + * without determining here whether the device supports SDTR. + */ + AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, + asc_dvc->cfg->disc_enable); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); + + /* + * Set SCSI_CFG0 Microcode Default Value. + * + * The microcode will set the SCSI_CFG0 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, + PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | + asc_dvc->chip_scsi_id); + + /* + * Calculate SCSI_CFG1 Microcode Default Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + * + * Each ASC-38C1600 function has only two cable detect bits. + * The bus mode override bits are in IOPB_SOFT_OVER_WR. + */ + scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + + /* + * If the cable is reversed all of the SCSI_CTRL register signals + * will be set. Check for and return an error if this condition is + * found. + */ + if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { + asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; + return ADV_ERROR; + } + + /* + * Each ASC-38C1600 function has two connectors. Only an HVD device + * can not be connected to either connector. An LVD device or SE device + * may be connected to either connecor. If an SE device is connected, + * then at most Ultra speed (20 Mhz) can be used on both connectors. + * + * If an HVD device is attached, return an error. + */ + if (scsi_cfg1 & HVD) { + asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; + return ADV_ERROR; + } + + /* + * Each function in the ASC-38C1600 uses only the SE cable detect and + * termination because there are two connectors for each function. Each + * function may use either LVD or SE mode. Corresponding the SE automatic + * termination control EEPROM bits are used for each function. Each + * function has its own EEPROM. If SE automatic control is enabled for + * the function, then set the termination value based on a table listed + * in a_condor.h. + * + * If manual termination is specified in the EEPROM for the function, + * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is + * ready to be 'ored' into SCSI_CFG1. + */ + if ((asc_dvc->cfg->termination & TERM_SE) == 0) { + struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); + /* SE automatic termination control is enabled. */ + switch (scsi_cfg1 & C_DET_SE) { + /* TERM_SE_HI: on, TERM_SE_LO: on */ + case 0x1: + case 0x2: + case 0x3: + asc_dvc->cfg->termination |= TERM_SE; + break; + + case 0x0: + if (PCI_FUNC(pdev->devfn) == 0) { + /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ + } else { + /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ + asc_dvc->cfg->termination |= TERM_SE_HI; + } + break; + } + } + + /* + * Clear any set TERM_SE bits. + */ + scsi_cfg1 &= ~TERM_SE; + + /* + * Invert the TERM_SE bits and then set 'scsi_cfg1'. + */ + scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE); + + /* + * Clear Big Endian and Terminator Polarity bits and set possibly + * modified termination control bits in the Microcode SCSI_CFG1 + * Register Value. + * + * Big Endian bit is not used even on big endian machines. + */ + scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL); + + /* + * Set SCSI_CFG1 Microcode Default Value + * + * Set possibly modified termination control bits in the Microcode + * SCSI_CFG1 Register Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); + + /* + * Set MEM_CFG Microcode Default Value + * + * The microcode will set the MEM_CFG register using this value + * after it is started below. + * + * MEM_CFG may be accessed as a word or byte, but only bits 0-7 + * are defined. + * + * ASC-38C1600 has 32KB internal memory. + * + * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come + * out a special 16K Adv Library and Microcode version. After the issue + * resolved, we should turn back to the 32K support. Both a_condor.h and + * mcode.sas files also need to be updated. + * + * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, + * BIOS_EN | RAM_SZ_32KB); + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, + BIOS_EN | RAM_SZ_16KB); + + /* + * Set SEL_MASK Microcode Default Value + * + * The microcode will set the SEL_MASK register using this value + * after it is started below. + */ + AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, + ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); + + AdvBuildCarrierFreelist(asc_dvc); + + /* + * Set-up the Host->RISC Initiator Command Queue (ICQ). + */ + if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + + /* + * The first command issued will be placed in the stopper carrier. + */ + asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC ICQ physical address start value. Initialize the + * COMMA register to the same value otherwise the RISC will + * prematurely detect a command is available. + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); + AdvWriteDWordRegister(iop_base, IOPDW_COMMA, + le32_to_cpu(asc_dvc->icq_sp->carr_pa)); + + /* + * Set-up the RISC->Host Initiator Response Queue (IRQ). + */ + if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { + asc_dvc->err_code |= ASC_IERR_NO_CARRIER; + return ADV_ERROR; + } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); + + /* + * The first command completed by the RISC will be placed in + * the stopper. + * + * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is + * completed the RISC will set the ASC_RQ_STOPPER bit. + */ + asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + + /* + * Set RISC IRQ physical address start value. + */ + AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); + asc_dvc->carr_pending_cnt = 0; + + AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, + (ADV_INTR_ENABLE_HOST_INTR | + ADV_INTR_ENABLE_GLOBAL_INTR)); + AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); + AdvWriteWordRegister(iop_base, IOPW_PC, word); + + /* finally, finally, gentlemen, start your engine */ + AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); + + /* + * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus + * Resets should be performed. The RISC has to be running + * to issue a SCSI Bus Reset. + */ + if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { + /* + * If the BIOS Signature is present in memory, restore the + * per TID microcode operating variables. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == + 0x55AA) { + /* + * Restore per TID negotiated values. + */ + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, + tagqng_able); + for (tid = 0; tid <= ASC_MAX_TID; tid++) { + AdvWriteByteLram(iop_base, + ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + } else { + if (AdvResetSB(asc_dvc) != ADV_TRUE) { + warn_code = ASC_WARN_BUSRESET_ERROR; + } + } + } + + return warn_code; +} + +/* + * Reset chip and SCSI Bus. + * + * Return Value: + * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. + * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. + */ +static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) +{ + int status; + ushort wdtr_able, sdtr_able, tagqng_able; + ushort ppr_able = 0; + uchar tid, max_cmd[ADV_MAX_TID + 1]; + AdvPortAddr iop_base; + ushort bios_sig; + + iop_base = asc_dvc->iop_base; + + /* + * Save current per TID negotiated values. + */ + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { + AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); + } + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + /* + * Force the AdvInitAsc3550/38C0800Driver() function to + * perform a SCSI Bus Reset by clearing the BIOS signature word. + * The initialization functions assumes a SCSI Bus Reset is not + * needed if the BIOS signature word is present. + */ + AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); + AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0); + + /* + * Stop chip and reset it. + */ + AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); + AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); + mdelay(100); + AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, + ADV_CTRL_REG_CMD_WR_IO_REG); + + /* + * Reset Adv Library error code, if any, and try + * re-initializing the chip. + */ + asc_dvc->err_code = 0; + if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { + status = AdvInitAsc38C1600Driver(asc_dvc); + } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { + status = AdvInitAsc38C0800Driver(asc_dvc); + } else { + status = AdvInitAsc3550Driver(asc_dvc); + } + + /* Translate initialization return value to status value. */ + if (status == 0) { + status = ADV_TRUE; + } else { + status = ADV_FALSE; + } + + /* + * Restore the BIOS signature word. + */ + AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); + + /* + * Restore per TID negotiated values. + */ + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); + if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { + AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); + } + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + return status; +} + +/* + * adv_async_callback() - Adv Library asynchronous event callback function. + */ +static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) +{ + switch (code) { + case ADV_ASYNC_SCSI_BUS_RESET_DET: + /* + * The firmware detected a SCSI Bus reset. + */ + ASC_DBG(0, + "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n"); + break; + + case ADV_ASYNC_RDMA_FAILURE: + /* + * Handle RDMA failure by resetting the SCSI Bus and + * possibly the chip if it is unresponsive. Log the error + * with a unique code. + */ + ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n"); + AdvResetChipAndSB(adv_dvc_varp); + break; + + case ADV_HOST_SCSI_BUS_RESET: + /* + * Host generated SCSI bus reset occurred. + */ + ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n"); + break; + + default: + ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code); + break; + } +} + +/* + * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). + * + * Callback function for the Wide SCSI Adv Library. + */ +static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) +{ + asc_board_t *boardp; + adv_req_t *reqp; + adv_sgblk_t *sgblkp; + struct scsi_cmnd *scp; + struct Scsi_Host *shost; + ADV_DCNT resid_cnt; + + ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", + (ulong)adv_dvc_varp, (ulong)scsiqp); + ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); + + /* + * Get the adv_req_t structure for the command that has been + * completed. The adv_req_t structure actually contains the + * completed ADV_SCSI_REQ_Q structure. + */ + reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr); + ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp); + if (reqp == NULL) { + ASC_PRINT("adv_isr_callback: reqp is NULL\n"); + return; + } + + /* + * Get the struct scsi_cmnd structure and Scsi_Host structure for the + * command that has been completed. + * + * Note: The adv_req_t request structure and adv_sgblk_t structure, + * if any, are dropped, because a board structure pointer can not be + * determined. + */ + scp = reqp->cmndp; + ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp); + if (scp == NULL) { + ASC_PRINT + ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); + return; + } + ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); + + shost = scp->device->host; + ASC_STATS(shost, callback); + ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); + + boardp = ASC_BOARDP(shost); + BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); + + /* + * 'done_status' contains the command's ending status. + */ + switch (scsiqp->done_status) { + case QD_NO_ERROR: + ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); + scp->result = 0; + + /* + * Check for an underrun condition. + * + * If there was no error and an underrun condition, then + * then return the number of underrun bytes. + */ + resid_cnt = le32_to_cpu(scsiqp->data_cnt); + if (scp->request_bufflen != 0 && resid_cnt != 0 && + resid_cnt <= scp->request_bufflen) { + ASC_DBG1(1, + "adv_isr_callback: underrun condition %lu bytes\n", + (ulong)resid_cnt); + scp->resid = resid_cnt; + } + break; + + case QD_WITH_ERROR: + ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); + switch (scsiqp->host_status) { + case QHSTA_NO_ERROR: + if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { + ASC_DBG(2, + "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); + ASC_DBG_PRT_SENSE(2, scp->sense_buffer, + sizeof(scp->sense_buffer)); + /* + * Note: The 'status_byte()' macro used by + * target drivers defined in scsi.h shifts the + * status byte returned by host drivers right + * by 1 bit. This is why target drivers also + * use right shifted status byte definitions. + * For instance target drivers use + * CHECK_CONDITION, defined to 0x1, instead of + * the SCSI defined check condition value of + * 0x2. Host drivers are supposed to return + * the status byte as it is defined by SCSI. + */ + scp->result = DRIVER_BYTE(DRIVER_SENSE) | + STATUS_BYTE(scsiqp->scsi_status); + } else { + scp->result = STATUS_BYTE(scsiqp->scsi_status); + } + break; + + default: + /* Some other QHSTA error occurred. */ + ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n", + scsiqp->host_status); + scp->result = HOST_BYTE(DID_BAD_TARGET); + break; + } + break; + + case QD_ABORTED_BY_HOST: + ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); + scp->result = + HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); + break; + + default: + ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", + scsiqp->done_status); + scp->result = + HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); + break; + } + + /* + * If the 'init_tidmask' bit isn't already set for the target and the + * current request finished normally, then set the bit for the target + * to indicate that a device is present. + */ + if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && + scsiqp->done_status == QD_NO_ERROR && + scsiqp->host_status == QHSTA_NO_ERROR) { + boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); + } + + asc_scsi_done(scp); + + /* + * Free all 'adv_sgblk_t' structures allocated for the request. + */ + while ((sgblkp = reqp->sgblkp) != NULL) { + /* Remove 'sgblkp' from the request list. */ + reqp->sgblkp = sgblkp->next_sgblkp; + + /* Add 'sgblkp' to the board free list. */ + sgblkp->next_sgblkp = boardp->adv_sgblkp; + boardp->adv_sgblkp = sgblkp; + } + + /* + * Free the adv_req_t structure used with the command by adding + * it back to the board free list. + */ + reqp->next_reqp = boardp->adv_reqp; + boardp->adv_reqp = reqp; + + ASC_DBG(1, "adv_isr_callback: done\n"); + + return; +} + +/* + * Adv Library Interrupt Service Routine + * + * This function is called by a driver's interrupt service routine. + * The function disables and re-enables interrupts. + * + * When a microcode idle command is completed, the ADV_DVC_VAR + * 'idle_cmd_done' field is set to ADV_TRUE. + * + * Note: AdvISR() can be called when interrupts are disabled or even + * when there is no hardware interrupt condition present. It will + * always check for completed idle commands and microcode requests. + * This is an important feature that shouldn't be changed because it + * allows commands to be completed from polling mode loops. + * + * Return: + * ADV_TRUE(1) - interrupt was pending + * ADV_FALSE(0) - no interrupt was pending + */ +static int AdvISR(ADV_DVC_VAR *asc_dvc) +{ + AdvPortAddr iop_base; + uchar int_stat; + ushort target_bit; + ADV_CARR_T *free_carrp; + ADV_VADDR irq_next_vpa; + ADV_SCSI_REQ_Q *scsiq; + + iop_base = asc_dvc->iop_base; + + /* Reading the register clears the interrupt. */ + int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); + + if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | + ADV_INTR_STATUS_INTRC)) == 0) { + return ADV_FALSE; + } + + /* + * Notify the driver of an asynchronous microcode condition by + * calling the adv_async_callback function. The function + * is passed the microcode ASC_MC_INTRB_CODE byte value. + */ + if (int_stat & ADV_INTR_STATUS_INTRB) { + uchar intrb_code; + + AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code); + + if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || + asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { + if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && + asc_dvc->carr_pending_cnt != 0) { + AdvWriteByteRegister(iop_base, IOPB_TICKLE, + ADV_TICKLE_A); + if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { + AdvWriteByteRegister(iop_base, + IOPB_TICKLE, + ADV_TICKLE_NOP); + } + } + } + + adv_async_callback(asc_dvc, intrb_code); + } + + /* + * Check if the IRQ stopper carrier contains a completed request. + */ + while (((irq_next_vpa = + le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) { + /* + * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure. + * The RISC will have set 'areq_vpa' to a virtual address. + * + * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr + * field to the carrier ADV_CARR_T.areq_vpa field. The conversion + * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' + * in AdvExeScsiQueue(). + */ + scsiq = (ADV_SCSI_REQ_Q *) + ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa)); + + /* + * Request finished with good status and the queue was not + * DMAed to host memory by the firmware. Set all status fields + * to indicate good status. + */ + if ((irq_next_vpa & ASC_RQ_GOOD) != 0) { + scsiq->done_status = QD_NO_ERROR; + scsiq->host_status = scsiq->scsi_status = 0; + scsiq->data_cnt = 0L; + } + + /* + * Advance the stopper pointer to the next carrier + * ignoring the lower four bits. Free the previous + * stopper carrier. + */ + free_carrp = asc_dvc->irq_sp; + asc_dvc->irq_sp = (ADV_CARR_T *) + ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa)); + + free_carrp->next_vpa = + cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); + asc_dvc->carr_freelist = free_carrp; + asc_dvc->carr_pending_cnt--; + + target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); + + /* + * Clear request microcode control flag. + */ + scsiq->cntl = 0; + + /* + * Notify the driver of the completed request by passing + * the ADV_SCSI_REQ_Q pointer to its callback function. + */ + scsiq->a_flag |= ADV_SCSIQ_DONE; + adv_isr_callback(asc_dvc, scsiq); + /* + * Note: After the driver callback function is called, 'scsiq' + * can no longer be referenced. + * + * Fall through and continue processing other completed + * requests... + */ + } + return ADV_TRUE; +} + +static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code) +{ + if (asc_dvc->err_code == 0) { + asc_dvc->err_code = err_code; + AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, + err_code); + } + return err_code; +} + +static void AscAckInterrupt(PortAddr iop_base) +{ + uchar host_flag; + uchar risc_flag; + ushort loop; + + loop = 0; + do { + risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); + if (loop++ > 0x7FFF) { + break; + } + } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); + host_flag = + AscReadLramByte(iop_base, + ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); + AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, + (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT)); + AscSetChipStatus(iop_base, CIW_INT_ACK); + loop = 0; + while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { + AscSetChipStatus(iop_base, CIW_INT_ACK); + if (loop++ > 3) { + break; + } + } + AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); + return; +} + +static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) +{ + uchar *period_table; + int max_index; + int min_index; + int i; + + period_table = asc_dvc->sdtr_period_tbl; + max_index = (int)asc_dvc->max_sdtr_index; + min_index = (int)asc_dvc->host_init_sdtr_index; + if ((syn_time <= period_table[max_index])) { + for (i = min_index; i < (max_index - 1); i++) { + if (syn_time <= period_table[i]) { + return (uchar)i; + } + } + return (uchar)max_index; + } else { + return (uchar)(max_index + 1); + } +} + +static uchar +AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset) +{ + EXT_MSG sdtr_buf; + uchar sdtr_period_index; + PortAddr iop_base; + + iop_base = asc_dvc->iop_base; + sdtr_buf.msg_type = EXTENDED_MESSAGE; + sdtr_buf.msg_len = MS_SDTR_LEN; + sdtr_buf.msg_req = EXTENDED_SDTR; + sdtr_buf.xfer_period = sdtr_period; + sdtr_offset &= ASC_SYN_MAX_OFFSET; + sdtr_buf.req_ack_offset = sdtr_offset; + sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period); + if (sdtr_period_index <= asc_dvc->max_sdtr_index) { + AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG, + (uchar *)&sdtr_buf, + sizeof(EXT_MSG) >> 1); + return ((sdtr_period_index << 4) | sdtr_offset); + } else { + sdtr_buf.req_ack_offset = 0; + AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG, + (uchar *)&sdtr_buf, + sizeof(EXT_MSG) >> 1); + return 0; + } +} + +static uchar +AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) +{ + uchar byte; + uchar sdtr_period_ix; + + sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); + if (sdtr_period_ix > asc_dvc->max_sdtr_index) { + return 0xFF; + } + byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); + return byte; +} + +static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data) +{ + ASC_SCSI_BIT_ID_TYPE org_id; + int i; + int sta = TRUE; + + AscSetBank(iop_base, 1); + org_id = AscReadChipDvcID(iop_base); + for (i = 0; i <= ASC_MAX_TID; i++) { + if (org_id == (0x01 << i)) + break; + } + org_id = (ASC_SCSI_BIT_ID_TYPE) i; + AscWriteChipDvcID(iop_base, id); + if (AscReadChipDvcID(iop_base) == (0x01 << id)) { + AscSetBank(iop_base, 0); + AscSetChipSyn(iop_base, sdtr_data); + if (AscGetChipSyn(iop_base) != sdtr_data) { + sta = FALSE; + } + } else { + sta = FALSE; + } + AscSetBank(iop_base, 1); + AscWriteChipDvcID(iop_base, org_id); + AscSetBank(iop_base, 0); + return (sta); +} + +static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no) +{ + AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); + AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); +} + +static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) +{ + EXT_MSG ext_msg; + EXT_MSG out_msg; + ushort halt_q_addr; + int sdtr_accept; + ushort int_halt_code; + ASC_SCSI_BIT_ID_TYPE scsi_busy; + ASC_SCSI_BIT_ID_TYPE target_id; + PortAddr iop_base; + uchar tag_code; + uchar q_status; + uchar halt_qp; + uchar sdtr_data; + uchar target_ix; + uchar q_cntl, tid_no; + uchar cur_dvc_qng; + uchar asyn_sdtr; + uchar scsi_status; + asc_board_t *boardp; + + BUG_ON(!asc_dvc->drv_ptr); + boardp = asc_dvc->drv_ptr; + + iop_base = asc_dvc->iop_base; + int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W); + + halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B); + halt_q_addr = ASC_QNO_TO_QADDR(halt_qp); + target_ix = AscReadLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_TARGET_IX)); + q_cntl = AscReadLramByte(iop_base, + (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL)); + tid_no = ASC_TIX_TO_TID(target_ix); + target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no); + if (asc_dvc->pci_fix_asyn_xfer & target_id) { + asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB; + } else { + asyn_sdtr = 0; + } + if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) { + if (asc_dvc->pci_fix_asyn_xfer & target_id) { + AscSetChipSDTR(iop_base, 0, tid_no); + boardp->sdtr_data[tid_no] = 0; + } + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) { + if (asc_dvc->pci_fix_asyn_xfer & target_id) { + AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); + boardp->sdtr_data[tid_no] = asyn_sdtr; + } + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { + AscMemWordCopyPtrFromLram(iop_base, + ASCV_MSGIN_BEG, + (uchar *)&ext_msg, + sizeof(EXT_MSG) >> 1); + + if (ext_msg.msg_type == EXTENDED_MESSAGE && + ext_msg.msg_req == EXTENDED_SDTR && + ext_msg.msg_len == MS_SDTR_LEN) { + sdtr_accept = TRUE; + if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { + + sdtr_accept = FALSE; + ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; + } + if ((ext_msg.xfer_period < + asc_dvc->sdtr_period_tbl[asc_dvc-> + host_init_sdtr_index]) + || (ext_msg.xfer_period > + asc_dvc->sdtr_period_tbl[asc_dvc-> + max_sdtr_index])) { + sdtr_accept = FALSE; + ext_msg.xfer_period = + asc_dvc->sdtr_period_tbl[asc_dvc-> + host_init_sdtr_index]; + } + if (sdtr_accept) { + sdtr_data = + AscCalSDTRData(asc_dvc, ext_msg.xfer_period, + ext_msg.req_ack_offset); + if ((sdtr_data == 0xFF)) { + + q_cntl |= QC_MSG_OUT; + asc_dvc->init_sdtr &= ~target_id; + asc_dvc->sdtr_done &= ~target_id; + AscSetChipSDTR(iop_base, asyn_sdtr, + tid_no); + boardp->sdtr_data[tid_no] = asyn_sdtr; + } + } + if (ext_msg.req_ack_offset == 0) { + + q_cntl &= ~QC_MSG_OUT; + asc_dvc->init_sdtr &= ~target_id; + asc_dvc->sdtr_done &= ~target_id; + AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); + } else { + if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { + + q_cntl &= ~QC_MSG_OUT; + asc_dvc->sdtr_done |= target_id; + asc_dvc->init_sdtr |= target_id; + asc_dvc->pci_fix_asyn_xfer &= + ~target_id; + sdtr_data = + AscCalSDTRData(asc_dvc, + ext_msg.xfer_period, + ext_msg. + req_ack_offset); + AscSetChipSDTR(iop_base, sdtr_data, + tid_no); + boardp->sdtr_data[tid_no] = sdtr_data; + } else { + + q_cntl |= QC_MSG_OUT; + AscMsgOutSDTR(asc_dvc, + ext_msg.xfer_period, + ext_msg.req_ack_offset); + asc_dvc->pci_fix_asyn_xfer &= + ~target_id; + sdtr_data = + AscCalSDTRData(asc_dvc, + ext_msg.xfer_period, + ext_msg. + req_ack_offset); + AscSetChipSDTR(iop_base, sdtr_data, + tid_no); + boardp->sdtr_data[tid_no] = sdtr_data; + asc_dvc->sdtr_done |= target_id; + asc_dvc->init_sdtr |= target_id; + } + } + + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_CNTL), + q_cntl); + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else if (ext_msg.msg_type == EXTENDED_MESSAGE && + ext_msg.msg_req == EXTENDED_WDTR && + ext_msg.msg_len == MS_WDTR_LEN) { + + ext_msg.wdtr_width = 0; + AscMemWordCopyPtrToLram(iop_base, + ASCV_MSGOUT_BEG, + (uchar *)&ext_msg, + sizeof(EXT_MSG) >> 1); + q_cntl |= QC_MSG_OUT; + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_CNTL), + q_cntl); + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else { + + ext_msg.msg_type = MESSAGE_REJECT; + AscMemWordCopyPtrToLram(iop_base, + ASCV_MSGOUT_BEG, + (uchar *)&ext_msg, + sizeof(EXT_MSG) >> 1); + q_cntl |= QC_MSG_OUT; + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_CNTL), + q_cntl); + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } + } else if (int_halt_code == ASC_HALT_CHK_CONDITION) { + + q_cntl |= QC_REQ_SENSE; + + if ((asc_dvc->init_sdtr & target_id) != 0) { + + asc_dvc->sdtr_done &= ~target_id; + + sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); + q_cntl |= QC_MSG_OUT; + AscMsgOutSDTR(asc_dvc, + asc_dvc-> + sdtr_period_tbl[(sdtr_data >> 4) & + (uchar)(asc_dvc-> + max_sdtr_index - + 1)], + (uchar)(sdtr_data & (uchar) + ASC_SYN_MAX_OFFSET)); + } + + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_CNTL), q_cntl); + + tag_code = AscReadLramByte(iop_base, + (ushort)(halt_q_addr + (ushort) + ASC_SCSIQ_B_TAG_CODE)); + tag_code &= 0xDC; + if ((asc_dvc->pci_fix_asyn_xfer & target_id) + && !(asc_dvc->pci_fix_asyn_xfer_always & target_id) + ) { + + tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT + | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX); + + } + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_TAG_CODE), + tag_code); + + q_status = AscReadLramByte(iop_base, + (ushort)(halt_q_addr + (ushort) + ASC_SCSIQ_B_STATUS)); + q_status |= (QS_READY | QS_BUSY); + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_STATUS), + q_status); + + scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B); + scsi_busy &= ~target_id; + AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy); + + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) { + + AscMemWordCopyPtrFromLram(iop_base, + ASCV_MSGOUT_BEG, + (uchar *)&out_msg, + sizeof(EXT_MSG) >> 1); + + if ((out_msg.msg_type == EXTENDED_MESSAGE) && + (out_msg.msg_len == MS_SDTR_LEN) && + (out_msg.msg_req == EXTENDED_SDTR)) { + + asc_dvc->init_sdtr &= ~target_id; + asc_dvc->sdtr_done &= ~target_id; + AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); + boardp->sdtr_data[tid_no] = asyn_sdtr; + } + q_cntl &= ~QC_MSG_OUT; + AscWriteLramByte(iop_base, + (ushort)(halt_q_addr + + (ushort)ASC_SCSIQ_B_CNTL), q_cntl); + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) { + + scsi_status = AscReadLramByte(iop_base, + (ushort)((ushort)halt_q_addr + + (ushort) + ASC_SCSIQ_SCSI_STATUS)); + cur_dvc_qng = + AscReadLramByte(iop_base, + (ushort)((ushort)ASC_QADR_BEG + + (ushort)target_ix)); + if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) { + + scsi_busy = AscReadLramByte(iop_base, + (ushort)ASCV_SCSIBUSY_B); + scsi_busy |= target_id; + AscWriteLramByte(iop_base, + (ushort)ASCV_SCSIBUSY_B, scsi_busy); + asc_dvc->queue_full_or_busy |= target_id; + + if (scsi_status == SAM_STAT_TASK_SET_FULL) { + if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) { + cur_dvc_qng -= 1; + asc_dvc->max_dvc_qng[tid_no] = + cur_dvc_qng; + + AscWriteLramByte(iop_base, + (ushort)((ushort) + ASCV_MAX_DVC_QNG_BEG + + (ushort) + tid_no), + cur_dvc_qng); + + /* + * Set the device queue depth to the + * number of active requests when the + * QUEUE FULL condition was encountered. + */ + boardp->queue_full |= target_id; + boardp->queue_full_cnt[tid_no] = + cur_dvc_qng; + } + } + } + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } +#if CC_VERY_LONG_SG_LIST + else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) { + uchar q_no; + ushort q_addr; + uchar sg_wk_q_no; + uchar first_sg_wk_q_no; + ASC_SCSI_Q *scsiq; /* Ptr to driver request. */ + ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */ + ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */ + ushort sg_list_dwords; + ushort sg_entry_cnt; + uchar next_qp; + int i; + + q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP); + if (q_no == ASC_QLINK_END) + return 0; + + q_addr = ASC_QNO_TO_QADDR(q_no); + + /* + * Convert the request's SRB pointer to a host ASC_SCSI_REQ + * structure pointer using a macro provided by the driver. + * The ASC_SCSI_REQ pointer provides a pointer to the + * host ASC_SG_HEAD structure. + */ + /* Read request's SRB pointer. */ + scsiq = (ASC_SCSI_Q *) + ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base, + (ushort) + (q_addr + + ASC_SCSIQ_D_SRBPTR)))); + + /* + * Get request's first and working SG queue. + */ + sg_wk_q_no = AscReadLramByte(iop_base, + (ushort)(q_addr + + ASC_SCSIQ_B_SG_WK_QP)); + + first_sg_wk_q_no = AscReadLramByte(iop_base, + (ushort)(q_addr + + ASC_SCSIQ_B_FIRST_SG_WK_QP)); + + /* + * Reset request's working SG queue back to the + * first SG queue. + */ + AscWriteLramByte(iop_base, + (ushort)(q_addr + + (ushort)ASC_SCSIQ_B_SG_WK_QP), + first_sg_wk_q_no); + + sg_head = scsiq->sg_head; + + /* + * Set sg_entry_cnt to the number of SG elements + * that will be completed on this interrupt. + * + * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1 + * SG elements. The data_cnt and data_addr fields which + * add 1 to the SG element capacity are not used when + * restarting SG handling after a halt. + */ + if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) { + sg_entry_cnt = ASC_MAX_SG_LIST - 1; + + /* + * Keep track of remaining number of SG elements that + * will need to be handled on the next interrupt. + */ + scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); + } else { + sg_entry_cnt = scsiq->remain_sg_entry_cnt; + scsiq->remain_sg_entry_cnt = 0; + } + + /* + * Copy SG elements into the list of allocated SG queues. + * + * Last index completed is saved in scsiq->next_sg_index. + */ + next_qp = first_sg_wk_q_no; + q_addr = ASC_QNO_TO_QADDR(next_qp); + scsi_sg_q.sg_head_qp = q_no; + scsi_sg_q.cntl = QCSG_SG_XFER_LIST; + for (i = 0; i < sg_head->queue_cnt; i++) { + scsi_sg_q.seq_no = i + 1; + if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { + sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2); + sg_entry_cnt -= ASC_SG_LIST_PER_Q; + /* + * After very first SG queue RISC FW uses next + * SG queue first element then checks sg_list_cnt + * against zero and then decrements, so set + * sg_list_cnt 1 less than number of SG elements + * in each SG queue. + */ + scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1; + scsi_sg_q.sg_cur_list_cnt = + ASC_SG_LIST_PER_Q - 1; + } else { + /* + * This is the last SG queue in the list of + * allocated SG queues. If there are more + * SG elements than will fit in the allocated + * queues, then set the QCSG_SG_XFER_MORE flag. + */ + if (scsiq->remain_sg_entry_cnt != 0) { + scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; + } else { + scsi_sg_q.cntl |= QCSG_SG_XFER_END; + } + /* equals sg_entry_cnt * 2 */ + sg_list_dwords = sg_entry_cnt << 1; + scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1; + scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1; + sg_entry_cnt = 0; + } + + scsi_sg_q.q_no = next_qp; + AscMemWordCopyPtrToLram(iop_base, + q_addr + ASC_SCSIQ_SGHD_CPY_BEG, + (uchar *)&scsi_sg_q, + sizeof(ASC_SG_LIST_Q) >> 1); + + AscMemDWordCopyPtrToLram(iop_base, + q_addr + ASC_SGQ_LIST_BEG, + (uchar *)&sg_head-> + sg_list[scsiq->next_sg_index], + sg_list_dwords); + + scsiq->next_sg_index += ASC_SG_LIST_PER_Q; + + /* + * If the just completed SG queue contained the + * last SG element, then no more SG queues need + * to be written. + */ + if (scsi_sg_q.cntl & QCSG_SG_XFER_END) { + break; + } + + next_qp = AscReadLramByte(iop_base, + (ushort)(q_addr + + ASC_SCSIQ_B_FWD)); + q_addr = ASC_QNO_TO_QADDR(next_qp); + } + + /* + * Clear the halt condition so the RISC will be restarted + * after the return. + */ + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); + return (0); + } +#endif /* CC_VERY_LONG_SG_LIST */ + return (0); +} /* - * EEPROM Configuration. + * void + * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) * - * All drivers should use this structure to set the default EEPROM - * configuration. The BIOS now uses this structure when it is built. - * Additional structure information can be found in a_condor.h where - * the structure is defined. + * Calling/Exit State: + * none * - * The *_Field_IsChar structs are needed to correct for endianness. - * These values are read from the board 16 bits at a time directly - * into the structs. Because some fields are char, the values will be - * in the wrong order. The *_Field_IsChar tells when to flip the - * bytes. Data read and written to PCI memory is automatically swapped - * on big-endian platforms so char fields read as words are actually being - * unswapped on big-endian platforms. + * Description: + * Input an ASC_QDONE_INFO structure from the chip */ -static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = { - ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ - 0x0000, /* cfg_msw */ - 0xFFFF, /* disc_enable */ - 0xFFFF, /* wdtr_able */ - 0xFFFF, /* sdtr_able */ - 0xFFFF, /* start_motor */ - 0xFFFF, /* tagqng_able */ - 0xFFFF, /* bios_scan */ - 0, /* scam_tolerant */ - 7, /* adapter_scsi_id */ - 0, /* bios_boot_delay */ - 3, /* scsi_reset_delay */ - 0, /* bios_id_lun */ - 0, /* termination */ - 0, /* reserved1 */ - 0xFFE7, /* bios_ctrl */ - 0xFFFF, /* ultra_able */ - 0, /* reserved2 */ - ASC_DEF_MAX_HOST_QNG, /* max_host_qng */ - ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ - 0, /* dvc_cntl */ - 0, /* bug_fix */ - 0, /* serial_number_word1 */ - 0, /* serial_number_word2 */ - 0, /* serial_number_word3 */ - 0, /* check_sum */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , /* oem_name[16] */ - 0, /* dvc_err_code */ - 0, /* adv_err_code */ - 0, /* adv_err_addr */ - 0, /* saved_dvc_err_code */ - 0, /* saved_adv_err_code */ - 0, /* saved_adv_err_addr */ - 0 /* num_of_err */ -}; +static void +DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) +{ + int i; + ushort word; + + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < 2 * words; i += 2) { + if (i == 10) { + continue; + } + word = inpw(iop_base + IOP_RAM_DATA); + inbuf[i] = word & 0xff; + inbuf[i + 1] = (word >> 8) & 0xff; + } + ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words); +} + +static uchar +_AscCopyLramScsiDoneQ(PortAddr iop_base, + ushort q_addr, + ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count) +{ + ushort _val; + uchar sg_queue_cnt; + + DvcGetQinfo(iop_base, + q_addr + ASC_SCSIQ_DONE_INFO_BEG, + (uchar *)scsiq, + (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2); + + _val = AscReadLramWord(iop_base, + (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS)); + scsiq->q_status = (uchar)_val; + scsiq->q_no = (uchar)(_val >> 8); + _val = AscReadLramWord(iop_base, + (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL)); + scsiq->cntl = (uchar)_val; + sg_queue_cnt = (uchar)(_val >> 8); + _val = AscReadLramWord(iop_base, + (ushort)(q_addr + + (ushort)ASC_SCSIQ_B_SENSE_LEN)); + scsiq->sense_len = (uchar)_val; + scsiq->extra_bytes = (uchar)(_val >> 8); + + /* + * Read high word of remain bytes from alternate location. + */ + scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base, + (ushort)(q_addr + + (ushort) + ASC_SCSIQ_W_ALT_DC1))) + << 16); + /* + * Read low word of remain bytes from original location. + */ + scsiq->remain_bytes += AscReadLramWord(iop_base, + (ushort)(q_addr + (ushort) + ASC_SCSIQ_DW_REMAIN_XFER_CNT)); + + scsiq->remain_bytes &= max_dma_count; + return sg_queue_cnt; +} + +/* + * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). + * + * Interrupt callback function for the Narrow SCSI Asc Library. + */ +static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) +{ + asc_board_t *boardp; + struct scsi_cmnd *scp; + struct Scsi_Host *shost; + + ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", + (ulong)asc_dvc_varp, (ulong)qdonep); + ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); + + /* + * Get the struct scsi_cmnd structure and Scsi_Host structure for the + * command that has been completed. + */ + scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); + ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp); + + if (scp == NULL) { + ASC_PRINT("asc_isr_callback: scp is NULL\n"); + return; + } + ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); + + shost = scp->device->host; + ASC_STATS(shost, callback); + ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); + + boardp = ASC_BOARDP(shost); + BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); + + /* + * 'qdonep' contains the command's ending status. + */ + switch (qdonep->d3.done_stat) { + case QD_NO_ERROR: + ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); + scp->result = 0; + + /* + * Check for an underrun condition. + * + * If there was no error and an underrun condition, then + * return the number of underrun bytes. + */ + if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && + qdonep->remain_bytes <= scp->request_bufflen) { + ASC_DBG1(1, + "asc_isr_callback: underrun condition %u bytes\n", + (unsigned)qdonep->remain_bytes); + scp->resid = qdonep->remain_bytes; + } + break; + + case QD_WITH_ERROR: + ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); + switch (qdonep->d3.host_stat) { + case QHSTA_NO_ERROR: + if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { + ASC_DBG(2, + "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); + ASC_DBG_PRT_SENSE(2, scp->sense_buffer, + sizeof(scp->sense_buffer)); + /* + * Note: The 'status_byte()' macro used by + * target drivers defined in scsi.h shifts the + * status byte returned by host drivers right + * by 1 bit. This is why target drivers also + * use right shifted status byte definitions. + * For instance target drivers use + * CHECK_CONDITION, defined to 0x1, instead of + * the SCSI defined check condition value of + * 0x2. Host drivers are supposed to return + * the status byte as it is defined by SCSI. + */ + scp->result = DRIVER_BYTE(DRIVER_SENSE) | + STATUS_BYTE(qdonep->d3.scsi_stat); + } else { + scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); + } + break; + + default: + /* QHSTA error occurred */ + ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n", + qdonep->d3.host_stat); + scp->result = HOST_BYTE(DID_BAD_TARGET); + break; + } + break; + + case QD_ABORTED_BY_HOST: + ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); + scp->result = + HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3. + scsi_msg) | + STATUS_BYTE(qdonep->d3.scsi_stat); + break; + + default: + ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", + qdonep->d3.done_stat); + scp->result = + HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3. + scsi_msg) | + STATUS_BYTE(qdonep->d3.scsi_stat); + break; + } + + /* + * If the 'init_tidmask' bit isn't already set for the target and the + * current request finished normally, then set the bit for the target + * to indicate that a device is present. + */ + if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && + qdonep->d3.done_stat == QD_NO_ERROR && + qdonep->d3.host_stat == QHSTA_NO_ERROR) { + boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); + } -static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = { - 0, /* cfg_lsw */ - 0, /* cfg_msw */ - 0, /* -disc_enable */ - 0, /* wdtr_able */ - 0, /* sdtr_able */ - 0, /* start_motor */ - 0, /* tagqng_able */ - 0, /* bios_scan */ - 0, /* scam_tolerant */ - 1, /* adapter_scsi_id */ - 1, /* bios_boot_delay */ - 1, /* scsi_reset_delay */ - 1, /* bios_id_lun */ - 1, /* termination */ - 1, /* reserved1 */ - 0, /* bios_ctrl */ - 0, /* ultra_able */ - 0, /* reserved2 */ - 1, /* max_host_qng */ - 1, /* max_dvc_qng */ - 0, /* dvc_cntl */ - 0, /* bug_fix */ - 0, /* serial_number_word1 */ - 0, /* serial_number_word2 */ - 0, /* serial_number_word3 */ - 0, /* check_sum */ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , /* oem_name[16] */ - 0, /* dvc_err_code */ - 0, /* adv_err_code */ - 0, /* adv_err_addr */ - 0, /* saved_dvc_err_code */ - 0, /* saved_adv_err_code */ - 0, /* saved_adv_err_addr */ - 0 /* num_of_err */ -}; + asc_scsi_done(scp); -static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = { - ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ - 0x0000, /* 01 cfg_msw */ - 0xFFFF, /* 02 disc_enable */ - 0xFFFF, /* 03 wdtr_able */ - 0x4444, /* 04 sdtr_speed1 */ - 0xFFFF, /* 05 start_motor */ - 0xFFFF, /* 06 tagqng_able */ - 0xFFFF, /* 07 bios_scan */ - 0, /* 08 scam_tolerant */ - 7, /* 09 adapter_scsi_id */ - 0, /* bios_boot_delay */ - 3, /* 10 scsi_reset_delay */ - 0, /* bios_id_lun */ - 0, /* 11 termination_se */ - 0, /* termination_lvd */ - 0xFFE7, /* 12 bios_ctrl */ - 0x4444, /* 13 sdtr_speed2 */ - 0x4444, /* 14 sdtr_speed3 */ - ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ - ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ - 0, /* 16 dvc_cntl */ - 0x4444, /* 17 sdtr_speed4 */ - 0, /* 18 serial_number_word1 */ - 0, /* 19 serial_number_word2 */ - 0, /* 20 serial_number_word3 */ - 0, /* 21 check_sum */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , /* 22-29 oem_name[16] */ - 0, /* 30 dvc_err_code */ - 0, /* 31 adv_err_code */ - 0, /* 32 adv_err_addr */ - 0, /* 33 saved_dvc_err_code */ - 0, /* 34 saved_adv_err_code */ - 0, /* 35 saved_adv_err_addr */ - 0, /* 36 reserved */ - 0, /* 37 reserved */ - 0, /* 38 reserved */ - 0, /* 39 reserved */ - 0, /* 40 reserved */ - 0, /* 41 reserved */ - 0, /* 42 reserved */ - 0, /* 43 reserved */ - 0, /* 44 reserved */ - 0, /* 45 reserved */ - 0, /* 46 reserved */ - 0, /* 47 reserved */ - 0, /* 48 reserved */ - 0, /* 49 reserved */ - 0, /* 50 reserved */ - 0, /* 51 reserved */ - 0, /* 52 reserved */ - 0, /* 53 reserved */ - 0, /* 54 reserved */ - 0, /* 55 reserved */ - 0, /* 56 cisptr_lsw */ - 0, /* 57 cisprt_msw */ - PCI_VENDOR_ID_ASP, /* 58 subsysvid */ - PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */ - 0, /* 60 reserved */ - 0, /* 61 reserved */ - 0, /* 62 reserved */ - 0 /* 63 reserved */ -}; + return; +} + +static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) +{ + uchar next_qp; + uchar n_q_used; + uchar sg_list_qp; + uchar sg_queue_cnt; + uchar q_cnt; + uchar done_q_tail; + uchar tid_no; + ASC_SCSI_BIT_ID_TYPE scsi_busy; + ASC_SCSI_BIT_ID_TYPE target_id; + PortAddr iop_base; + ushort q_addr; + ushort sg_q_addr; + uchar cur_target_qng; + ASC_QDONE_INFO scsiq_buf; + ASC_QDONE_INFO *scsiq; + int false_overrun; + + iop_base = asc_dvc->iop_base; + n_q_used = 1; + scsiq = (ASC_QDONE_INFO *)&scsiq_buf; + done_q_tail = (uchar)AscGetVarDoneQTail(iop_base); + q_addr = ASC_QNO_TO_QADDR(done_q_tail); + next_qp = AscReadLramByte(iop_base, + (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD)); + if (next_qp != ASC_QLINK_END) { + AscPutVarDoneQTail(iop_base, next_qp); + q_addr = ASC_QNO_TO_QADDR(next_qp); + sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, + asc_dvc->max_dma_count); + AscWriteLramByte(iop_base, + (ushort)(q_addr + + (ushort)ASC_SCSIQ_B_STATUS), + (uchar)(scsiq-> + q_status & (uchar)~(QS_READY | + QS_ABORTED))); + tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix); + target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix); + if ((scsiq->cntl & QC_SG_HEAD) != 0) { + sg_q_addr = q_addr; + sg_list_qp = next_qp; + for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) { + sg_list_qp = AscReadLramByte(iop_base, + (ushort)(sg_q_addr + + (ushort) + ASC_SCSIQ_B_FWD)); + sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp); + if (sg_list_qp == ASC_QLINK_END) { + AscSetLibErrorCode(asc_dvc, + ASCQ_ERR_SG_Q_LINKS); + scsiq->d3.done_stat = QD_WITH_ERROR; + scsiq->d3.host_stat = + QHSTA_D_QDONE_SG_LIST_CORRUPTED; + goto FATAL_ERR_QDONE; + } + AscWriteLramByte(iop_base, + (ushort)(sg_q_addr + (ushort) + ASC_SCSIQ_B_STATUS), + QS_FREE); + } + n_q_used = sg_queue_cnt + 1; + AscPutVarDoneQTail(iop_base, sg_list_qp); + } + if (asc_dvc->queue_full_or_busy & target_id) { + cur_target_qng = AscReadLramByte(iop_base, + (ushort)((ushort) + ASC_QADR_BEG + + (ushort) + scsiq->d2. + target_ix)); + if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) { + scsi_busy = AscReadLramByte(iop_base, (ushort) + ASCV_SCSIBUSY_B); + scsi_busy &= ~target_id; + AscWriteLramByte(iop_base, + (ushort)ASCV_SCSIBUSY_B, + scsi_busy); + asc_dvc->queue_full_or_busy &= ~target_id; + } + } + if (asc_dvc->cur_total_qng >= n_q_used) { + asc_dvc->cur_total_qng -= n_q_used; + if (asc_dvc->cur_dvc_qng[tid_no] != 0) { + asc_dvc->cur_dvc_qng[tid_no]--; + } + } else { + AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG); + scsiq->d3.done_stat = QD_WITH_ERROR; + goto FATAL_ERR_QDONE; + } + if ((scsiq->d2.srb_ptr == 0UL) || + ((scsiq->q_status & QS_ABORTED) != 0)) { + return (0x11); + } else if (scsiq->q_status == QS_DONE) { + false_overrun = FALSE; + if (scsiq->extra_bytes != 0) { + scsiq->remain_bytes += + (ADV_DCNT)scsiq->extra_bytes; + } + if (scsiq->d3.done_stat == QD_WITH_ERROR) { + if (scsiq->d3.host_stat == + QHSTA_M_DATA_OVER_RUN) { + if ((scsiq-> + cntl & (QC_DATA_IN | QC_DATA_OUT)) + == 0) { + scsiq->d3.done_stat = + QD_NO_ERROR; + scsiq->d3.host_stat = + QHSTA_NO_ERROR; + } else if (false_overrun) { + scsiq->d3.done_stat = + QD_NO_ERROR; + scsiq->d3.host_stat = + QHSTA_NO_ERROR; + } + } else if (scsiq->d3.host_stat == + QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) { + AscStopChip(iop_base); + AscSetChipControl(iop_base, + (uchar)(CC_SCSI_RESET + | CC_HALT)); + udelay(60); + AscSetChipControl(iop_base, CC_HALT); + AscSetChipStatus(iop_base, + CIW_CLR_SCSI_RESET_INT); + AscSetChipStatus(iop_base, 0); + AscSetChipControl(iop_base, 0); + } + } + if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { + asc_isr_callback(asc_dvc, scsiq); + } else { + if ((AscReadLramByte(iop_base, + (ushort)(q_addr + (ushort) + ASC_SCSIQ_CDB_BEG)) + == START_STOP)) { + asc_dvc->unit_not_ready &= ~target_id; + if (scsiq->d3.done_stat != QD_NO_ERROR) { + asc_dvc->start_motor &= + ~target_id; + } + } + } + return (1); + } else { + AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); + FATAL_ERR_QDONE: + if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { + asc_isr_callback(asc_dvc, scsiq); + } + return (0x80); + } + } + return (0); +} -static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = { - 0, /* 00 cfg_lsw */ - 0, /* 01 cfg_msw */ - 0, /* 02 disc_enable */ - 0, /* 03 wdtr_able */ - 0, /* 04 sdtr_speed1 */ - 0, /* 05 start_motor */ - 0, /* 06 tagqng_able */ - 0, /* 07 bios_scan */ - 0, /* 08 scam_tolerant */ - 1, /* 09 adapter_scsi_id */ - 1, /* bios_boot_delay */ - 1, /* 10 scsi_reset_delay */ - 1, /* bios_id_lun */ - 1, /* 11 termination_se */ - 1, /* termination_lvd */ - 0, /* 12 bios_ctrl */ - 0, /* 13 sdtr_speed2 */ - 0, /* 14 sdtr_speed3 */ - 1, /* 15 max_host_qng */ - 1, /* max_dvc_qng */ - 0, /* 16 dvc_cntl */ - 0, /* 17 sdtr_speed4 */ - 0, /* 18 serial_number_word1 */ - 0, /* 19 serial_number_word2 */ - 0, /* 20 serial_number_word3 */ - 0, /* 21 check_sum */ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , /* 22-29 oem_name[16] */ - 0, /* 30 dvc_err_code */ - 0, /* 31 adv_err_code */ - 0, /* 32 adv_err_addr */ - 0, /* 33 saved_dvc_err_code */ - 0, /* 34 saved_adv_err_code */ - 0, /* 35 saved_adv_err_addr */ - 0, /* 36 reserved */ - 0, /* 37 reserved */ - 0, /* 38 reserved */ - 0, /* 39 reserved */ - 0, /* 40 reserved */ - 0, /* 41 reserved */ - 0, /* 42 reserved */ - 0, /* 43 reserved */ - 0, /* 44 reserved */ - 0, /* 45 reserved */ - 0, /* 46 reserved */ - 0, /* 47 reserved */ - 0, /* 48 reserved */ - 0, /* 49 reserved */ - 0, /* 50 reserved */ - 0, /* 51 reserved */ - 0, /* 52 reserved */ - 0, /* 53 reserved */ - 0, /* 54 reserved */ - 0, /* 55 reserved */ - 0, /* 56 cisptr_lsw */ - 0, /* 57 cisprt_msw */ - 0, /* 58 subsysvid */ - 0, /* 59 subsysid */ - 0, /* 60 reserved */ - 0, /* 61 reserved */ - 0, /* 62 reserved */ - 0 /* 63 reserved */ -}; +static int AscISR(ASC_DVC_VAR *asc_dvc) +{ + ASC_CS_TYPE chipstat; + PortAddr iop_base; + ushort saved_ram_addr; + uchar ctrl_reg; + uchar saved_ctrl_reg; + int int_pending; + int status; + uchar host_flag; -static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = { - ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ - 0x0000, /* 01 cfg_msw */ - 0xFFFF, /* 02 disc_enable */ - 0xFFFF, /* 03 wdtr_able */ - 0x5555, /* 04 sdtr_speed1 */ - 0xFFFF, /* 05 start_motor */ - 0xFFFF, /* 06 tagqng_able */ - 0xFFFF, /* 07 bios_scan */ - 0, /* 08 scam_tolerant */ - 7, /* 09 adapter_scsi_id */ - 0, /* bios_boot_delay */ - 3, /* 10 scsi_reset_delay */ - 0, /* bios_id_lun */ - 0, /* 11 termination_se */ - 0, /* termination_lvd */ - 0xFFE7, /* 12 bios_ctrl */ - 0x5555, /* 13 sdtr_speed2 */ - 0x5555, /* 14 sdtr_speed3 */ - ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ - ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ - 0, /* 16 dvc_cntl */ - 0x5555, /* 17 sdtr_speed4 */ - 0, /* 18 serial_number_word1 */ - 0, /* 19 serial_number_word2 */ - 0, /* 20 serial_number_word3 */ - 0, /* 21 check_sum */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , /* 22-29 oem_name[16] */ - 0, /* 30 dvc_err_code */ - 0, /* 31 adv_err_code */ - 0, /* 32 adv_err_addr */ - 0, /* 33 saved_dvc_err_code */ - 0, /* 34 saved_adv_err_code */ - 0, /* 35 saved_adv_err_addr */ - 0, /* 36 reserved */ - 0, /* 37 reserved */ - 0, /* 38 reserved */ - 0, /* 39 reserved */ - 0, /* 40 reserved */ - 0, /* 41 reserved */ - 0, /* 42 reserved */ - 0, /* 43 reserved */ - 0, /* 44 reserved */ - 0, /* 45 reserved */ - 0, /* 46 reserved */ - 0, /* 47 reserved */ - 0, /* 48 reserved */ - 0, /* 49 reserved */ - 0, /* 50 reserved */ - 0, /* 51 reserved */ - 0, /* 52 reserved */ - 0, /* 53 reserved */ - 0, /* 54 reserved */ - 0, /* 55 reserved */ - 0, /* 56 cisptr_lsw */ - 0, /* 57 cisprt_msw */ - PCI_VENDOR_ID_ASP, /* 58 subsysvid */ - PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */ - 0, /* 60 reserved */ - 0, /* 61 reserved */ - 0, /* 62 reserved */ - 0 /* 63 reserved */ -}; + iop_base = asc_dvc->iop_base; + int_pending = FALSE; -static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = { - 0, /* 00 cfg_lsw */ - 0, /* 01 cfg_msw */ - 0, /* 02 disc_enable */ - 0, /* 03 wdtr_able */ - 0, /* 04 sdtr_speed1 */ - 0, /* 05 start_motor */ - 0, /* 06 tagqng_able */ - 0, /* 07 bios_scan */ - 0, /* 08 scam_tolerant */ - 1, /* 09 adapter_scsi_id */ - 1, /* bios_boot_delay */ - 1, /* 10 scsi_reset_delay */ - 1, /* bios_id_lun */ - 1, /* 11 termination_se */ - 1, /* termination_lvd */ - 0, /* 12 bios_ctrl */ - 0, /* 13 sdtr_speed2 */ - 0, /* 14 sdtr_speed3 */ - 1, /* 15 max_host_qng */ - 1, /* max_dvc_qng */ - 0, /* 16 dvc_cntl */ - 0, /* 17 sdtr_speed4 */ - 0, /* 18 serial_number_word1 */ - 0, /* 19 serial_number_word2 */ - 0, /* 20 serial_number_word3 */ - 0, /* 21 check_sum */ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , /* 22-29 oem_name[16] */ - 0, /* 30 dvc_err_code */ - 0, /* 31 adv_err_code */ - 0, /* 32 adv_err_addr */ - 0, /* 33 saved_dvc_err_code */ - 0, /* 34 saved_adv_err_code */ - 0, /* 35 saved_adv_err_addr */ - 0, /* 36 reserved */ - 0, /* 37 reserved */ - 0, /* 38 reserved */ - 0, /* 39 reserved */ - 0, /* 40 reserved */ - 0, /* 41 reserved */ - 0, /* 42 reserved */ - 0, /* 43 reserved */ - 0, /* 44 reserved */ - 0, /* 45 reserved */ - 0, /* 46 reserved */ - 0, /* 47 reserved */ - 0, /* 48 reserved */ - 0, /* 49 reserved */ - 0, /* 50 reserved */ - 0, /* 51 reserved */ - 0, /* 52 reserved */ - 0, /* 53 reserved */ - 0, /* 54 reserved */ - 0, /* 55 reserved */ - 0, /* 56 cisptr_lsw */ - 0, /* 57 cisprt_msw */ - 0, /* 58 subsysvid */ - 0, /* 59 subsysid */ - 0, /* 60 reserved */ - 0, /* 61 reserved */ - 0, /* 62 reserved */ - 0 /* 63 reserved */ -}; + if (AscIsIntPending(iop_base) == 0) + return int_pending; + + if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) { + return ERR; + } + if (asc_dvc->in_critical_cnt != 0) { + AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); + return ERR; + } + if (asc_dvc->is_in_int) { + AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); + return ERR; + } + asc_dvc->is_in_int = TRUE; + ctrl_reg = AscGetChipControl(iop_base); + saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET | + CC_SINGLE_STEP | CC_DIAG | CC_TEST)); + chipstat = AscGetChipStatus(iop_base); + if (chipstat & CSW_SCSI_RESET_LATCH) { + if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) { + int i = 10; + int_pending = TRUE; + asc_dvc->sdtr_done = 0; + saved_ctrl_reg &= (uchar)(~CC_HALT); + while ((AscGetChipStatus(iop_base) & + CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { + mdelay(100); + } + AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); + AscSetChipControl(iop_base, CC_HALT); + AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); + AscSetChipStatus(iop_base, 0); + chipstat = AscGetChipStatus(iop_base); + } + } + saved_ram_addr = AscGetChipLramAddr(iop_base); + host_flag = AscReadLramByte(iop_base, + ASCV_HOST_FLAG_B) & + (uchar)(~ASC_HOST_FLAG_IN_ISR); + AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, + (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR)); + if ((chipstat & CSW_INT_PENDING) || (int_pending)) { + AscAckInterrupt(iop_base); + int_pending = TRUE; + if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) { + if (AscIsrChipHalted(asc_dvc) == ERR) { + goto ISR_REPORT_QDONE_FATAL_ERROR; + } else { + saved_ctrl_reg &= (uchar)(~CC_HALT); + } + } else { + ISR_REPORT_QDONE_FATAL_ERROR: + if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) { + while (((status = + AscIsrQDone(asc_dvc)) & 0x01) != 0) { + } + } else { + do { + if ((status = + AscIsrQDone(asc_dvc)) == 1) { + break; + } + } while (status == 0x11); + } + if ((status & 0x80) != 0) + int_pending = ERR; + } + } + AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); + AscSetChipLramAddr(iop_base, saved_ram_addr); + AscSetChipControl(iop_base, saved_ctrl_reg); + asc_dvc->is_in_int = FALSE; + return int_pending; +} -#ifdef CONFIG_PCI /* - * Initialize the ADV_DVC_VAR structure. + * advansys_reset() * - * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * Reset the bus associated with the command 'scp'. * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. + * This function runs its own thread. Interrupts must be blocked but + * sleeping is allowed and no locking other than for host structures is + * required. Returns SUCCESS or FAILED. */ -static int __devinit -AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp) +static int advansys_reset(struct scsi_cmnd *scp) { - ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; - unsigned short warn_code = 0; - AdvPortAddr iop_base = asc_dvc->iop_base; - u16 cmd; + struct Scsi_Host *shost; + asc_board_t *boardp; + ASC_DVC_VAR *asc_dvc_varp; + ADV_DVC_VAR *adv_dvc_varp; + ulong flags; int status; + int ret = SUCCESS; - asc_dvc->err_code = 0; - - /* - * Save the state of the PCI Configuration Command Register - * "Parity Error Response Control" Bit. If the bit is clear (0), - * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore - * DMA parity errors. - */ - asc_dvc->cfg->control_flag = 0; - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if ((cmd & PCI_COMMAND_PARITY) == 0) - asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; + ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp); - asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | - ADV_LIB_VERSION_MINOR; - asc_dvc->cfg->chip_version = - AdvGetChipVersion(iop_base, asc_dvc->bus_type); +#ifdef ADVANSYS_STATS + if (scp->device->host != NULL) { + ASC_STATS(scp->device->host, reset); + } +#endif /* ADVANSYS_STATS */ - ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n", - (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), - (ushort)ADV_CHIP_ID_BYTE); + if ((shost = scp->device->host) == NULL) { + scp->result = HOST_BYTE(DID_ERROR); + return FAILED; + } - ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n", - (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), - (ushort)ADV_CHIP_ID_WORD); + boardp = ASC_BOARDP(shost); + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n", + boardp->id); /* - * Reset the chip to start and allow register writes. + * Check for re-entrancy. */ - if (AdvFindSignature(iop_base) == 0) { - asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; - return ADV_ERROR; - } else { + spin_lock_irqsave(&boardp->lock, flags); + if (boardp->flags & ASC_HOST_IN_RESET) { + spin_unlock_irqrestore(&boardp->lock, flags); + return FAILED; + } + boardp->flags |= ASC_HOST_IN_RESET; + spin_unlock_irqrestore(&boardp->lock, flags); + + if (ASC_NARROW_BOARD(boardp)) { /* - * The caller must set 'chip_type' to a valid setting. + * Narrow Board */ - if (asc_dvc->chip_type != ADV_CHIP_ASC3550 && - asc_dvc->chip_type != ADV_CHIP_ASC38C0800 && - asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { - asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; - return ADV_ERROR; - } + asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; /* - * Reset Chip. + * Reset the chip and SCSI bus. */ - AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, - ADV_CTRL_REG_CMD_RESET); - mdelay(100); - AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, - ADV_CTRL_REG_CMD_WR_IO_REG); + ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); + status = AscInitAsc1000Driver(asc_dvc_varp); - if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - status = AdvInitFrom38C1600EEP(asc_dvc); - } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { - status = AdvInitFrom38C0800EEP(asc_dvc); + /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ + if (asc_dvc_varp->err_code) { + ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " + "error: 0x%x\n", boardp->id, + asc_dvc_varp->err_code); + ret = FAILED; + } else if (status) { + ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " + "warning: 0x%x\n", boardp->id, status); } else { - status = AdvInitFrom3550EEP(asc_dvc); + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "successful.\n", boardp->id); } - warn_code |= status; - } - - if (warn_code != 0) { - ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", - boardp->id, warn_code); - } - - if (asc_dvc->err_code) { - ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n", - boardp->id, asc_dvc->err_code); - } - - return asc_dvc->err_code; -} -#endif - -static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) -{ - ADV_CARR_T *carrp; - ADV_SDCNT buf_size; - ADV_PADDR carr_paddr; - BUG_ON(!asc_dvc->carrier_buf); + ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); + spin_lock_irqsave(&boardp->lock, flags); - carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); - asc_dvc->carr_freelist = NULL; - if (carrp == asc_dvc->carrier_buf) { - buf_size = ADV_CARRIER_BUFSIZE; } else { - buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); - } - - do { - /* Get physical address of the carrier 'carrp'. */ - ADV_DCNT contig_len = sizeof(ADV_CARR_T); - carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, - (uchar *)carrp, - (ADV_SDCNT *)&contig_len, - ADV_IS_CARRIER_FLAG)); - - buf_size -= sizeof(ADV_CARR_T); - /* - * If the current carrier is not physically contiguous, then - * maybe there was a page crossing. Try the next carrier - * aligned start address. + * Wide Board + * + * If the suggest reset bus flags are set, then reset the bus. + * Otherwise only reset the device. */ - if (contig_len < sizeof(ADV_CARR_T)) { - carrp++; - continue; - } - - carrp->carr_pa = carr_paddr; - carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); + adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; /* - * Insert the carrier at the beginning of the freelist. + * Reset the target's SCSI bus. */ - carrp->next_vpa = - cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); - asc_dvc->carr_freelist = carrp; - - carrp++; - } while (buf_size > 0); -} - -/* - * Load the Microcode - * - * Write the microcode image to RISC memory starting at address 0. - * - * The microcode is stored compressed in the following format: - * - * 254 word (508 byte) table indexed by byte code followed - * by the following byte codes: - * - * 1-Byte Code: - * 00: Emit word 0 in table. - * 01: Emit word 1 in table. - * . - * FD: Emit word 253 in table. - * - * Multi-Byte Code: - * FE WW WW: (3 byte code) Word to emit is the next word WW WW. - * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. - * - * Returns 0 or an error if the checksum doesn't match - */ -static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, - int memsize, int chksum) -{ - int i, j, end, len = 0; - ADV_DCNT sum; - - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); - - for (i = 253 * 2; i < size; i++) { - if (buf[i] == 0xff) { - unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; - for (j = 0; j < buf[i + 1]; j++) { - AdvWriteWordAutoIncLram(iop_base, word); - len += 2; - } - i += 3; - } else if (buf[i] == 0xfe) { - unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; - AdvWriteWordAutoIncLram(iop_base, word); - i += 2; - len += 2; - } else { - unsigned char off = buf[i] * 2; - unsigned short word = (buf[off + 1] << 8) | buf[off]; - AdvWriteWordAutoIncLram(iop_base, word); - len += 2; + ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); + switch (AdvResetChipAndSB(adv_dvc_varp)) { + case ASC_TRUE: + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "successful.\n", boardp->id); + break; + case ASC_FALSE: + default: + ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " + "error.\n", boardp->id); + ret = FAILED; + break; } + spin_lock_irqsave(&boardp->lock, flags); + AdvISR(adv_dvc_varp); } + /* Board lock is held. */ - end = len; - - while (len < memsize) { - AdvWriteWordAutoIncLram(iop_base, 0); - len += 2; - } - - /* Verify the microcode checksum. */ - sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); + /* Save the time of the most recently completed reset. */ + boardp->last_reset = jiffies; - for (len = 0; len < end; len += 2) { - sum += AdvReadWordAutoIncLram(iop_base); - } + /* Clear reset flag. */ + boardp->flags &= ~ASC_HOST_IN_RESET; + spin_unlock_irqrestore(&boardp->lock, flags); - if (sum != chksum) - return ASC_IERR_MCODE_CHKSUM; + ASC_DBG1(1, "advansys_reset: ret %d\n", ret); - return 0; + return ret; } /* - * Initialize the ASC-3550. - * - * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * advansys_biosparam() * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. + * Translate disk drive geometry if the "BIOS greater than 1 GB" + * support is enabled for a drive. * - * Needed after initialization for error recovery. + * ip (information pointer) is an int array with the following definition: + * ip[0]: heads + * ip[1]: sectors + * ip[2]: cylinders */ -static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) +static int +advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int ip[]) { - AdvPortAddr iop_base; - ushort warn_code; - int begin_addr; - int end_addr; - ushort code_sum; - int word; - int i; - ushort scsi_cfg1; - uchar tid; - ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ - ushort wdtr_able = 0, sdtr_able, tagqng_able; - uchar max_cmd[ADV_MAX_TID + 1]; - - /* If there is already an error, don't continue. */ - if (asc_dvc->err_code != 0) - return ADV_ERROR; + asc_board_t *boardp; - /* - * The caller must set 'chip_type' to ADV_CHIP_ASC3550. - */ - if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { - asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; - return ADV_ERROR; + ASC_DBG(1, "advansys_biosparam: begin\n"); + ASC_STATS(sdev->host, biosparam); + boardp = ASC_BOARDP(sdev->host); + if (ASC_NARROW_BOARD(boardp)) { + if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & + ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { + ip[0] = 255; + ip[1] = 63; + } else { + ip[0] = 64; + ip[1] = 32; + } + } else { + if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & + BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) { + ip[0] = 255; + ip[1] = 63; + } else { + ip[0] = 64; + ip[1] = 32; + } } + ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); + ASC_DBG(1, "advansys_biosparam: end\n"); + return 0; +} - warn_code = 0; - iop_base = asc_dvc->iop_base; +/* + * First-level interrupt handler. + * + * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host. + */ +static irqreturn_t advansys_interrupt(int irq, void *dev_id) +{ + unsigned long flags; + struct Scsi_Host *shost = dev_id; + asc_board_t *boardp = ASC_BOARDP(shost); + irqreturn_t result = IRQ_NONE; - /* - * Save the RISC memory BIOS region before writing the microcode. - * The BIOS may already be loaded and using its RISC LRAM region - * so its region must be saved and restored. - * - * Note: This code makes the assumption, which is currently true, - * that a chip reset does not clear RISC LRAM. - */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); + ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); + spin_lock_irqsave(&boardp->lock, flags); + if (ASC_NARROW_BOARD(boardp)) { + if (AscIsIntPending(shost->io_port)) { + result = IRQ_HANDLED; + ASC_STATS(shost, interrupt); + ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); + AscISR(&boardp->dvc_var.asc_dvc_var); + } + } else { + ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); + if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { + result = IRQ_HANDLED; + ASC_STATS(shost, interrupt); + } } + spin_unlock_irqrestore(&boardp->lock, flags); - /* - * Save current per TID negotiated values. - */ - if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) { - ushort bios_version, major, minor; + ASC_DBG(1, "advansys_interrupt: end\n"); + return result; +} - bios_version = - bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2]; - major = (bios_version >> 12) & 0xF; - minor = (bios_version >> 8) & 0xF; - if (major < 3 || (major == 3 && minor == 1)) { - /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ - AdvReadWordLram(iop_base, 0x120, wdtr_able); - } else { - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); +static int AscHostReqRiscHalt(PortAddr iop_base) +{ + int count = 0; + int sta = 0; + uchar saved_stop_code; + + if (AscIsChipHalted(iop_base)) + return (1); + saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); + AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, + ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP); + do { + if (AscIsChipHalted(iop_base)) { + sta = 1; + break; } - } - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); - } + mdelay(100); + } while (count++ < 20); + AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); + return (sta); +} - asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, - _adv_asc3550_size, ADV_3550_MEMSIZE, - _adv_asc3550_chksum); - if (asc_dvc->err_code) - return ADV_ERROR; +static int +AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data) +{ + int sta = FALSE; - /* - * Restore the RISC memory BIOS region. - */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); + if (AscHostReqRiscHalt(iop_base)) { + sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); + AscStartChip(iop_base); } + return sta; +} - /* - * Calculate and write the microcode code checksum to the microcode - * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). - */ - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); - AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); - code_sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); - for (word = begin_addr; word < end_addr; word += 2) { - code_sum += AdvReadWordAutoIncLram(iop_base); - } - AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); +static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev) +{ + char type = sdev->type; + ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id; - /* - * Read and save microcode version and date. - */ - AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, - asc_dvc->cfg->mcode_date); - AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, - asc_dvc->cfg->mcode_version); + if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)) + return; + if (asc_dvc->init_sdtr & tid_bits) + return; - /* - * Set the chip type to indicate the ASC3550. - */ - AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); + if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0)) + asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; - /* - * If the PCI Configuration Command Register "Parity Error Response - * Control" Bit was clear (0), then set the microcode variable - * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode - * to ignore DMA parity errors. - */ - if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { - AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - word |= CONTROL_FLAG_IGNORE_PERR; - AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - } + asc_dvc->pci_fix_asyn_xfer |= tid_bits; + if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) || + (type == TYPE_ROM) || (type == TYPE_TAPE)) + asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; + + if (asc_dvc->pci_fix_asyn_xfer & tid_bits) + AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id, + ASYN_SDTR_DATA_FIX_PCI_REV_AB); +} - /* - * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO - * threshold of 128 bytes. This register is only accessible to the host. - */ - AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, - START_CTL_EMFU | READ_CMD_MRM); +static void +advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc) +{ + ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id; + ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng; - /* - * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in slave_configure() based on what a - * device reports it is capable of in Inquiry byte 7. - * - * If SCSI Bus Resets have been disabled, then directly set - * SDTR and WDTR from the EEPROM configuration. This will allow - * the BIOS and warm boot to work without a SCSI bus hang on - * the Inquiry caused by host and target mismatched DTR values. - * Without the SCSI Bus Reset, before an Inquiry a device can't - * be assumed to be in Asynchronous, Narrow mode. - */ - if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, - asc_dvc->wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, - asc_dvc->sdtr_able); + if (sdev->lun == 0) { + ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr; + if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) { + asc_dvc->init_sdtr |= tid_bit; + } else { + asc_dvc->init_sdtr &= ~tid_bit; + } + + if (orig_init_sdtr != asc_dvc->init_sdtr) + AscAsyncFix(asc_dvc, sdev); } - /* - * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, - * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID - * bitmask. These values determine the maximum SDTR speed negotiated - * with a device. - * - * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, - * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them - * without determining here whether the device supports SDTR. - * - * 4-bit speed SDTR speed name - * =========== =============== - * 0000b (0x0) SDTR disabled - * 0001b (0x1) 5 Mhz - * 0010b (0x2) 10 Mhz - * 0011b (0x3) 20 Mhz (Ultra) - * 0100b (0x4) 40 Mhz (LVD/Ultra2) - * 0101b (0x5) 80 Mhz (LVD2/Ultra3) - * 0110b (0x6) Undefined - * . - * 1111b (0xF) Undefined - */ - word = 0; - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) { - /* Set Ultra speed for TID 'tid'. */ - word |= (0x3 << (4 * (tid % 4))); - } else { - /* Set Fast speed for TID 'tid'. */ - word |= (0x2 << (4 * (tid % 4))); + if (sdev->tagged_supported) { + if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) { + if (sdev->lun == 0) { + asc_dvc->cfg->can_tagged_qng |= tid_bit; + asc_dvc->use_tagged_qng |= tid_bit; + } + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, + asc_dvc->max_dvc_qng[sdev->id]); } - if (tid == 3) { /* Check if done with sdtr_speed1. */ - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word); - word = 0; - } else if (tid == 7) { /* Check if done with sdtr_speed2. */ - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word); - word = 0; - } else if (tid == 11) { /* Check if done with sdtr_speed3. */ - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word); - word = 0; - } else if (tid == 15) { /* Check if done with sdtr_speed4. */ - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word); - /* End of loop. */ + } else { + if (sdev->lun == 0) { + asc_dvc->cfg->can_tagged_qng &= ~tid_bit; + asc_dvc->use_tagged_qng &= ~tid_bit; } + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); } - /* - * Set microcode operating variable for the disconnect per TID bitmask. - */ - AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, - asc_dvc->cfg->disc_enable); + if ((sdev->lun == 0) && + (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) { + AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, + asc_dvc->cfg->disc_enable); + AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, + asc_dvc->use_tagged_qng); + AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, + asc_dvc->cfg->can_tagged_qng); - /* - * Set SCSI_CFG0 Microcode Default Value. - * - * The microcode will set the SCSI_CFG0 register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, - PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | - asc_dvc->chip_scsi_id); + asc_dvc->max_dvc_qng[sdev->id] = + asc_dvc->cfg->max_tag_qng[sdev->id]; + AscWriteLramByte(asc_dvc->iop_base, + (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id), + asc_dvc->max_dvc_qng[sdev->id]); + } +} - /* - * Determine SCSI_CFG1 Microcode Default Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. - */ +/* + * Wide Transfers + * + * If the EEPROM enabled WDTR for the device and the device supports wide + * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and + * write the new value to the microcode. + */ +static void +advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask) +{ + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); + if ((cfg_word & tidmask) != 0) + return; - /* Read current SCSI_CFG1 Register value. */ - scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); /* - * If all three connectors are in use, return an error. + * Clear the microcode SDTR and WDTR negotiation done indicators for + * the target to cause it to negotiate with the new setting set above. + * WDTR when accepted causes the target to enter asynchronous mode, so + * SDTR must be negotiated. */ - if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || - (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { - asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; - return ADV_ERROR; - } + AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); +} - /* - * If the internal narrow cable is reversed all of the SCSI_CTRL - * register signals will be set. Check for and return an error if - * this condition is found. - */ - if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { - asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; - return ADV_ERROR; - } +/* + * Synchronous Transfers + * + * If the EEPROM enabled SDTR for the device and the device + * supports synchronous transfers, then turn on the device's + * 'sdtr_able' bit. Write the new value to the microcode. + */ +static void +advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask) +{ + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); + if ((cfg_word & tidmask) != 0) + return; - /* - * If this is a differential board and a single-ended device - * is attached to one of the connectors, return an error. - */ - if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) { - asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; - return ADV_ERROR; - } + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); /* - * If automatic termination control is enabled, then set the - * termination value based on a table listed in a_condor.h. - * - * If manual termination was specified with an EEPROM setting - * then 'termination' was set-up in AdvInitFrom3550EEPROM() and - * is ready to be 'ored' into SCSI_CFG1. + * Clear the microcode "SDTR negotiation" done indicator for the + * target to cause it to negotiate with the new setting set above. */ - if (asc_dvc->cfg->termination == 0) { - /* - * The software always controls termination by setting TERM_CTL_SEL. - * If TERM_CTL_SEL were set to 0, the hardware would set termination. - */ - asc_dvc->cfg->termination |= TERM_CTL_SEL; + AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); + cfg_word &= ~tidmask; + AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); +} - switch (scsi_cfg1 & CABLE_DETECT) { - /* TERM_CTL_H: on, TERM_CTL_L: on */ - case 0x3: - case 0x7: - case 0xB: - case 0xD: - case 0xE: - case 0xF: - asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); - break; +/* + * PPR (Parallel Protocol Request) Capable + * + * If the device supports DT mode, then it must be PPR capable. + * The PPR message will be used in place of the SDTR and WDTR + * messages to negotiate synchronous speed and offset, transfer + * width, and protocol options. + */ +static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc, + AdvPortAddr iop_base, unsigned short tidmask) +{ + AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); + adv_dvc->ppr_able |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); +} - /* TERM_CTL_H: on, TERM_CTL_L: off */ - case 0x1: - case 0x5: - case 0x9: - case 0xA: - case 0xC: - asc_dvc->cfg->termination |= TERM_CTL_H; - break; +static void +advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) +{ + AdvPortAddr iop_base = adv_dvc->iop_base; + unsigned short tidmask = 1 << sdev->id; + + if (sdev->lun == 0) { + /* + * Handle WDTR, SDTR, and Tag Queuing. If the feature + * is enabled in the EEPROM and the device supports the + * feature, then enable it in the microcode. + */ - /* TERM_CTL_H: off, TERM_CTL_L: off */ - case 0x2: - case 0x6: - break; + if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr) + advansys_wide_enable_wdtr(iop_base, tidmask); + if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr) + advansys_wide_enable_sdtr(iop_base, tidmask); + if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr) + advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask); + + /* + * Tag Queuing is disabled for the BIOS which runs in polled + * mode and would see no benefit from Tag Queuing. Also by + * disabling Tag Queuing in the BIOS devices with Tag Queuing + * bugs will at least work with the BIOS. + */ + if ((adv_dvc->tagqng_able & tidmask) && + sdev->tagged_supported) { + unsigned short cfg_word; + AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); + cfg_word |= tidmask; + AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, + cfg_word); + AdvWriteByteLram(iop_base, + ASC_MC_NUMBER_OF_MAX_CMD + sdev->id, + adv_dvc->max_dvc_qng); } } - /* - * Clear any set TERM_CTL_H and TERM_CTL_L bits. - */ - scsi_cfg1 &= ~TERM_CTL; - - /* - * Invert the TERM_CTL_H and TERM_CTL_L bits and then - * set 'scsi_cfg1'. The TERM_POL bit does not need to be - * referenced, because the hardware internally inverts - * the Termination High and Low bits if TERM_POL is set. - */ - scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); - - /* - * Set SCSI_CFG1 Microcode Default Value - * - * Set filter value and possibly modified termination control - * bits in the Microcode SCSI_CFG1 Register Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, - FLTR_DISABLE | scsi_cfg1); + if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) { + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, + adv_dvc->max_dvc_qng); + } else { + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); + } +} - /* - * Set MEM_CFG Microcode Default Value - * - * The microcode will set the MEM_CFG register using this value - * after it is started below. - * - * MEM_CFG may be accessed as a word or byte, but only bits 0-7 - * are defined. - * - * ASC-3550 has 8KB internal memory. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, - BIOS_EN | RAM_SZ_8KB); +/* + * Set the number of commands to queue per device for the + * specified host adapter. + */ +static int advansys_slave_configure(struct scsi_device *sdev) +{ + asc_board_t *boardp = ASC_BOARDP(sdev->host); + boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; /* - * Set SEL_MASK Microcode Default Value - * - * The microcode will set the SEL_MASK register using this value - * after it is started below. + * Save a pointer to the sdev and set its initial/maximum + * queue depth. Only save the pointer for a lun0 dev though. */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, - ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); - - AdvBuildCarrierFreelist(asc_dvc); + if (sdev->lun == 0) + boardp->device[sdev->id] = sdev; - /* - * Set-up the Host->RISC Initiator Command Queue (ICQ). - */ + if (ASC_NARROW_BOARD(boardp)) + advansys_narrow_slave_configure(sdev, + &boardp->dvc_var.asc_dvc_var); + else + advansys_wide_slave_configure(sdev, + &boardp->dvc_var.adv_dvc_var); - if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; - } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + return 0; +} +/* + * Build a request structure for the Asc Library (Narrow Board). + * + * The global structures 'asc_scsi_q' and 'asc_sg_head' are + * used to build the request. + * + * If an error occurs, then return ASC_ERROR. + */ +static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) +{ /* - * The first command issued will be placed in the stopper carrier. + * Mutually exclusive access is required to 'asc_scsi_q' and + * 'asc_sg_head' until after the request is started. */ - asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); /* - * Set RISC ICQ physical address start value. + * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); + asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); /* - * Set-up the RISC->Host Initiator Response Queue (IRQ). + * Build the ASC_SCSI_Q request. */ - if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; - } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); + asc_scsi_q.cdbptr = &scp->cmnd[0]; + asc_scsi_q.q2.cdb_len = scp->cmd_len; + asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); + asc_scsi_q.q1.target_lun = scp->device->lun; + asc_scsi_q.q2.target_ix = + ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); + asc_scsi_q.q1.sense_addr = + cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); + asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); /* - * The first command completed by the RISC will be placed in - * the stopper. + * If there are any outstanding requests for the current target, + * then every 255th request send an ORDERED request. This heuristic + * tries to retain the benefit of request sorting while preventing + * request starvation. 255 is the max number of tags or pending commands + * a device may have outstanding. + * + * The request count is incremented below for every successfully + * started request. * - * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is - * completed the RISC will set the ASC_RQ_STOPPER bit. */ - asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && + (boardp->reqcnt[scp->device->id] % 255) == 0) { + asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; + } else { + asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; + } /* - * Set RISC IRQ physical address start value. + * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather + * buffer command. */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); - asc_dvc->carr_pending_cnt = 0; + if (scp->use_sg == 0) { + /* + * CDB request of single contiguous buffer. + */ + ASC_STATS(scp->device->host, cont_cnt); + scp->SCp.dma_handle = scp->request_bufflen ? + dma_map_single(boardp->dev, scp->request_buffer, + scp->request_bufflen, + scp->sc_data_direction) : 0; + asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); + asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); + ASC_STATS_ADD(scp->device->host, cont_xfer, + ASC_CEILING(scp->request_bufflen, 512)); + asc_scsi_q.q1.sg_queue_cnt = 0; + asc_scsi_q.sg_head = NULL; + } else { + /* + * CDB scatter-gather request list. + */ + int sgcnt; + int use_sg; + struct scatterlist *slp; - AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, - (ADV_INTR_ENABLE_HOST_INTR | - ADV_INTR_ENABLE_GLOBAL_INTR)); + slp = (struct scatterlist *)scp->request_buffer; + use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); - AdvWriteWordRegister(iop_base, IOPW_PC, word); + if (use_sg > scp->device->host->sg_tablesize) { + ASC_PRINT3("asc_build_req: board %d: use_sg %d > " + "sg_tablesize %d\n", boardp->id, use_sg, + scp->device->host->sg_tablesize); + dma_unmap_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); + scp->result = HOST_BYTE(DID_ERROR); + return ASC_ERROR; + } - /* finally, finally, gentlemen, start your engine */ - AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); + ASC_STATS(scp->device->host, sg_cnt); - /* - * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus - * Resets should be performed. The RISC has to be running - * to issue a SCSI Bus Reset. - */ - if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { /* - * If the BIOS Signature is present in memory, restore the - * BIOS Handshake Configuration Table and do not perform - * a SCSI Bus Reset. + * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q + * structure to point to it. */ - if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == - 0x55AA) { - /* - * Restore per TID negotiated values. - */ - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, - tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvWriteByteLram(iop_base, - ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); - } - } else { - if (AdvResetSB(asc_dvc) != ADV_TRUE) { - warn_code = ASC_WARN_BUSRESET_ERROR; - } + memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); + + asc_scsi_q.q1.cntl |= QC_SG_HEAD; + asc_scsi_q.sg_head = &asc_sg_head; + asc_scsi_q.q1.data_cnt = 0; + asc_scsi_q.q1.data_addr = 0; + /* This is a byte value, otherwise it would need to be swapped. */ + asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; + ASC_STATS_ADD(scp->device->host, sg_elem, + asc_sg_head.entry_cnt); + + /* + * Convert scatter-gather list into ASC_SG_HEAD list. + */ + for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { + asc_sg_head.sg_list[sgcnt].addr = + cpu_to_le32(sg_dma_address(slp)); + asc_sg_head.sg_list[sgcnt].bytes = + cpu_to_le32(sg_dma_len(slp)); + ASC_STATS_ADD(scp->device->host, sg_xfer, + ASC_CEILING(sg_dma_len(slp), 512)); } } - return warn_code; + ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); + ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); + + return ASC_NOERROR; } /* - * Initialize the ASC-38C0800. - * - * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * Build scatter-gather list for Adv Library (Wide Board). * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. + * Additional ADV_SG_BLOCK structures will need to be allocated + * if the total number of scatter-gather elements exceeds + * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are + * assumed to be physically contiguous. * - * Needed after initialization for error recovery. + * Return: + * ADV_SUCCESS(1) - SG List successfully created + * ADV_ERROR(-1) - SG List creation failed */ -static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) +static int +adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, + int use_sg) { - AdvPortAddr iop_base; - ushort warn_code; - int begin_addr; - int end_addr; - ushort code_sum; - int word; + adv_sgblk_t *sgblkp; + ADV_SCSI_REQ_Q *scsiqp; + struct scatterlist *slp; + int sg_elem_cnt; + ADV_SG_BLOCK *sg_block, *prev_sg_block; + ADV_PADDR sg_block_paddr; int i; - ushort scsi_cfg1; - uchar byte; - uchar tid; - ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ - ushort wdtr_able, sdtr_able, tagqng_able; - uchar max_cmd[ADV_MAX_TID + 1]; - /* If there is already an error, don't continue. */ - if (asc_dvc->err_code != 0) - return ADV_ERROR; + scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); + slp = (struct scatterlist *)scp->request_buffer; + sg_elem_cnt = use_sg; + prev_sg_block = NULL; + reqp->sgblkp = NULL; - /* - * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. - */ - if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) { - asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; - return ADV_ERROR; - } + for (;;) { + /* + * Allocate a 'adv_sgblk_t' structure from the board free + * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK + * (15) scatter-gather elements. + */ + if ((sgblkp = boardp->adv_sgblkp) == NULL) { + ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); + ASC_STATS(scp->device->host, adv_build_nosg); - warn_code = 0; - iop_base = asc_dvc->iop_base; + /* + * Allocation failed. Free 'adv_sgblk_t' structures + * already allocated for the request. + */ + while ((sgblkp = reqp->sgblkp) != NULL) { + /* Remove 'sgblkp' from the request list. */ + reqp->sgblkp = sgblkp->next_sgblkp; - /* - * Save the RISC memory BIOS region before writing the microcode. - * The BIOS may already be loaded and using its RISC LRAM region - * so its region must be saved and restored. - * - * Note: This code makes the assumption, which is currently true, - * that a chip reset does not clear RISC LRAM. - */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); - } + /* Add 'sgblkp' to the board free list. */ + sgblkp->next_sgblkp = boardp->adv_sgblkp; + boardp->adv_sgblkp = sgblkp; + } + return ASC_BUSY; + } - /* - * Save current per TID negotiated values. - */ - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); - } + /* Complete 'adv_sgblk_t' board allocation. */ + boardp->adv_sgblkp = sgblkp->next_sgblkp; + sgblkp->next_sgblkp = NULL; - /* - * RAM BIST (RAM Built-In Self Test) - * - * Address : I/O base + offset 0x38h register (byte). - * Function: Bit 7-6(RW) : RAM mode - * Normal Mode : 0x00 - * Pre-test Mode : 0x40 - * RAM Test Mode : 0x80 - * Bit 5 : unused - * Bit 4(RO) : Done bit - * Bit 3-0(RO) : Status - * Host Error : 0x08 - * Int_RAM Error : 0x04 - * RISC Error : 0x02 - * SCSI Error : 0x01 - * No Error : 0x00 - * - * Note: RAM BIST code should be put right here, before loading the - * microcode and after saving the RISC memory BIOS region. - */ + /* + * Get 8 byte aligned virtual and physical addresses + * for the allocated ADV_SG_BLOCK structure. + */ + sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); + sg_block_paddr = virt_to_bus(sg_block); - /* - * LRAM Pre-test - * - * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. - * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return - * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset - * to NORMAL_MODE, return an error too. - */ - for (i = 0; i < 2; i++) { - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); - mdelay(10); /* Wait for 10ms before reading back. */ - byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); - if ((byte & RAM_TEST_DONE) == 0 - || (byte & 0x0F) != PRE_TEST_VALUE) { - asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; - return ADV_ERROR; - } + /* + * Check if this is the first 'adv_sgblk_t' for the + * request. + */ + if (reqp->sgblkp == NULL) { + /* Request's first scatter-gather block. */ + reqp->sgblkp = sgblkp; - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - mdelay(10); /* Wait for 10ms before reading back. */ - if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) - != NORMAL_VALUE) { - asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; - return ADV_ERROR; + /* + * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical + * address pointers. + */ + scsiqp->sg_list_ptr = sg_block; + scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr); + } else { + /* Request's second or later scatter-gather block. */ + sgblkp->next_sgblkp = reqp->sgblkp; + reqp->sgblkp = sgblkp; + + /* + * Point the previous ADV_SG_BLOCK structure to + * the newly allocated ADV_SG_BLOCK structure. + */ + prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); } - } - /* - * LRAM Test - It takes about 1.5 ms to run through the test. - * - * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. - * If Done bit not set or Status not 0, save register byte, set the - * err_code, and return an error. - */ - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); - mdelay(10); /* Wait for 10ms before checking status. */ + for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { + sg_block->sg_list[i].sg_addr = + cpu_to_le32(sg_dma_address(slp)); + sg_block->sg_list[i].sg_count = + cpu_to_le32(sg_dma_len(slp)); + ASC_STATS_ADD(scp->device->host, sg_xfer, + ASC_CEILING(sg_dma_len(slp), 512)); - byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); - if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { - /* Get here if Done bit not set or Status not 0. */ - asc_dvc->bist_err_code = byte; /* for BIOS display message */ - asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; - return ADV_ERROR; + if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ + sg_block->sg_cnt = i + 1; + sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */ + return ADV_SUCCESS; + } + slp++; + } + sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; + prev_sg_block = sg_block; } +} - /* We need to reset back to normal mode after LRAM test passes. */ - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - - asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, - _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, - _adv_asc38C0800_chksum); - if (asc_dvc->err_code) - return ADV_ERROR; +/* + * Build a request structure for the Adv Library (Wide Board). + * + * If an adv_req_t can not be allocated to issue the request, + * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. + * + * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the + * microcode for DMA addresses or math operations are byte swapped + * to little-endian order. + */ +static int +adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, + ADV_SCSI_REQ_Q **adv_scsiqpp) +{ + adv_req_t *reqp; + ADV_SCSI_REQ_Q *scsiqp; + int i; + int ret; /* - * Restore the RISC memory BIOS region. + * Allocate an adv_req_t structure from the board to execute + * the command. */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); + if (boardp->adv_reqp == NULL) { + ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); + ASC_STATS(scp->device->host, adv_build_noreq); + return ASC_BUSY; + } else { + reqp = boardp->adv_reqp; + boardp->adv_reqp = reqp->next_reqp; + reqp->next_reqp = NULL; } /* - * Calculate and write the microcode code checksum to the microcode - * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. */ - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); - AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); - code_sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); - for (word = begin_addr; word < end_addr; word += 2) { - code_sum += AdvReadWordAutoIncLram(iop_base); - } - AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); + scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); /* - * Read microcode version and date. + * Initialize the structure. */ - AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, - asc_dvc->cfg->mcode_date); - AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, - asc_dvc->cfg->mcode_version); + scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0; /* - * Set the chip type to indicate the ASC38C0800. + * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. */ - AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); + scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp); /* - * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. - * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current - * cable detection and then we are able to read C_DET[3:0]. - * - * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 - * Microcode Default Value' section below. + * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. */ - scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); - AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, - scsi_cfg1 | DIS_TERM_DRV); + reqp->cmndp = scp; /* - * If the PCI Configuration Command Register "Parity Error Response - * Control" Bit was clear (0), then set the microcode variable - * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode - * to ignore DMA parity errors. + * Build the ADV_SCSI_REQ_Q request. */ - if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { - AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - word |= CONTROL_FLAG_IGNORE_PERR; - AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); + + /* Set CDB length and copy it to the request structure. */ + scsiqp->cdb_len = scp->cmd_len; + /* Copy first 12 CDB bytes to cdb[]. */ + for (i = 0; i < scp->cmd_len && i < 12; i++) { + scsiqp->cdb[i] = scp->cmnd[i]; + } + /* Copy last 4 CDB bytes, if present, to cdb16[]. */ + for (; i < scp->cmd_len; i++) { + scsiqp->cdb16[i - 12] = scp->cmnd[i]; } - /* - * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] - * bits for the default FIFO threshold. - * - * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. - * - * For DMA Errata #4 set the BC_THRESH_ENB bit. - */ - AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, - BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | - READ_CMD_MRM); + scsiqp->target_id = scp->device->id; + scsiqp->target_lun = scp->device->lun; + + scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); + scsiqp->sense_len = sizeof(scp->sense_buffer); /* - * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in slave_configure() based on what a - * device reports it is capable of in Inquiry byte 7. - * - * If SCSI Bus Resets have been disabled, then directly set - * SDTR and WDTR from the EEPROM configuration. This will allow - * the BIOS and warm boot to work without a SCSI bus hang on - * the Inquiry caused by host and target mismatched DTR values. - * Without the SCSI Bus Reset, before an Inquiry a device can't - * be assumed to be in Asynchronous, Narrow mode. + * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather + * buffer command. */ - if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, - asc_dvc->wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, - asc_dvc->sdtr_able); + + scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); + scsiqp->vdata_addr = scp->request_buffer; + scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); + + if (scp->use_sg == 0) { + /* + * CDB request of single contiguous buffer. + */ + reqp->sgblkp = NULL; + scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); + if (scp->request_bufflen) { + scsiqp->vdata_addr = scp->request_buffer; + scp->SCp.dma_handle = + dma_map_single(boardp->dev, scp->request_buffer, + scp->request_bufflen, + scp->sc_data_direction); + } else { + scsiqp->vdata_addr = NULL; + scp->SCp.dma_handle = 0; + } + scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); + scsiqp->sg_list_ptr = NULL; + scsiqp->sg_real_addr = 0; + ASC_STATS(scp->device->host, cont_cnt); + ASC_STATS_ADD(scp->device->host, cont_xfer, + ASC_CEILING(scp->request_bufflen, 512)); + } else { + /* + * CDB scatter-gather request list. + */ + struct scatterlist *slp; + int use_sg; + + slp = (struct scatterlist *)scp->request_buffer; + use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); + + if (use_sg > ADV_MAX_SG_LIST) { + ASC_PRINT3("adv_build_req: board %d: use_sg %d > " + "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg, + scp->device->host->sg_tablesize); + dma_unmap_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); + scp->result = HOST_BYTE(DID_ERROR); + + /* + * Free the 'adv_req_t' structure by adding it back + * to the board free list. + */ + reqp->next_reqp = boardp->adv_reqp; + boardp->adv_reqp = reqp; + + return ASC_ERROR; + } + + ret = adv_get_sglist(boardp, reqp, scp, use_sg); + if (ret != ADV_SUCCESS) { + /* + * Free the adv_req_t structure by adding it back to + * the board free list. + */ + reqp->next_reqp = boardp->adv_reqp; + boardp->adv_reqp = reqp; + + return ret; + } + + ASC_STATS(scp->device->host, sg_cnt); + ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); } - /* - * Set microcode operating variables for DISC and SDTR_SPEED1, - * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM - * configuration values. - * - * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, - * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them - * without determining here whether the device supports SDTR. - */ - AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, - asc_dvc->cfg->disc_enable); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); + ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); + ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); - /* - * Set SCSI_CFG0 Microcode Default Value. - * - * The microcode will set the SCSI_CFG0 register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, - PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | - asc_dvc->chip_scsi_id); + *adv_scsiqpp = scsiqp; - /* - * Determine SCSI_CFG1 Microcode Default Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. - */ + return ASC_NOERROR; +} + +static int AscSgListToQueue(int sg_list) +{ + int n_sg_list_qs; + + n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); + if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) + n_sg_list_qs++; + return n_sg_list_qs + 1; +} + +static uint +AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs) +{ + uint cur_used_qs; + uint cur_free_qs; + ASC_SCSI_BIT_ID_TYPE target_id; + uchar tid_no; + + target_id = ASC_TIX_TO_TARGET_ID(target_ix); + tid_no = ASC_TIX_TO_TID(target_ix); + if ((asc_dvc->unit_not_ready & target_id) || + (asc_dvc->queue_full_or_busy & target_id)) { + return 0; + } + if (n_qs == 1) { + cur_used_qs = (uint) asc_dvc->cur_total_qng + + (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q; + } else { + cur_used_qs = (uint) asc_dvc->cur_total_qng + + (uint) ASC_MIN_FREE_Q; + } + if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) { + cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; + if (asc_dvc->cur_dvc_qng[tid_no] >= + asc_dvc->max_dvc_qng[tid_no]) { + return 0; + } + return cur_free_qs; + } + if (n_qs > 1) { + if ((n_qs > asc_dvc->last_q_shortage) + && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) { + asc_dvc->last_q_shortage = n_qs; + } + } + return 0; +} + +static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head) +{ + ushort q_addr; + uchar next_qp; + uchar q_status; + + q_addr = ASC_QNO_TO_QADDR(free_q_head); + q_status = (uchar)AscReadLramByte(iop_base, + (ushort)(q_addr + + ASC_SCSIQ_B_STATUS)); + next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD)); + if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) + return next_qp; + return ASC_QLINK_END; +} + +static uchar +AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q) +{ + uchar i; - /* Read current SCSI_CFG1 Register value. */ - scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + for (i = 0; i < n_free_q; i++) { + free_q_head = AscAllocFreeQueue(iop_base, free_q_head); + if (free_q_head == ASC_QLINK_END) + break; + } + return free_q_head; +} - /* - * If the internal narrow cable is reversed all of the SCSI_CTRL - * register signals will be set. Check for and return an error if - * this condition is found. - */ - if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { - asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; - return ADV_ERROR; +/* + * void + * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) + * + * Calling/Exit State: + * none + * + * Description: + * Output an ASC_SCSI_Q structure to the chip + */ +static void +DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) +{ + int i; + + ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words); + AscSetChipLramAddr(iop_base, s_addr); + for (i = 0; i < 2 * words; i += 2) { + if (i == 4 || i == 20) { + continue; + } + outpw(iop_base + IOP_RAM_DATA, + ((ushort)outbuf[i + 1] << 8) | outbuf[i]); } +} - /* - * All kind of combinations of devices attached to one of four - * connectors are acceptable except HVD device attached. For example, - * LVD device can be attached to SE connector while SE device attached - * to LVD connector. If LVD device attached to SE connector, it only - * runs up to Ultra speed. - * - * If an HVD device is attached to one of LVD connectors, return an - * error. However, there is no way to detect HVD device attached to - * SE connectors. - */ - if (scsi_cfg1 & HVD) { - asc_dvc->err_code = ASC_IERR_HVD_DEVICE; - return ADV_ERROR; +static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) +{ + ushort q_addr; + uchar tid_no; + uchar sdtr_data; + uchar syn_period_ix; + uchar syn_offset; + PortAddr iop_base; + + iop_base = asc_dvc->iop_base; + if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) && + ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) { + tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix); + sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); + syn_period_ix = + (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1); + syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET; + AscMsgOutSDTR(asc_dvc, + asc_dvc->sdtr_period_tbl[syn_period_ix], + syn_offset); + scsiq->q1.cntl |= QC_MSG_OUT; + } + q_addr = ASC_QNO_TO_QADDR(q_no); + if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) { + scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; } + scsiq->q1.status = QS_FREE; + AscMemWordCopyPtrToLram(iop_base, + q_addr + ASC_SCSIQ_CDB_BEG, + (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1); + + DvcPutScsiQ(iop_base, + q_addr + ASC_SCSIQ_CPY_BEG, + (uchar *)&scsiq->q1.cntl, + ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1); + AscWriteLramWord(iop_base, + (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS), + (ushort)(((ushort)scsiq->q1. + q_no << 8) | (ushort)QS_READY)); + return 1; +} + +static int +AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) +{ + int sta; + int i; + ASC_SG_HEAD *sg_head; + ASC_SG_LIST_Q scsi_sg_q; + ASC_DCNT saved_data_addr; + ASC_DCNT saved_data_cnt; + PortAddr iop_base; + ushort sg_list_dwords; + ushort sg_index; + ushort sg_entry_cnt; + ushort q_addr; + uchar next_qp; + iop_base = asc_dvc->iop_base; + sg_head = scsiq->sg_head; + saved_data_addr = scsiq->q1.data_addr; + saved_data_cnt = scsiq->q1.data_cnt; + scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr; + scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes; +#if CC_VERY_LONG_SG_LIST /* - * If either SE or LVD automatic termination control is enabled, then - * set the termination value based on a table listed in a_condor.h. - * - * If manual termination was specified with an EEPROM setting then - * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready - * to be 'ored' into SCSI_CFG1. + * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST + * then not all SG elements will fit in the allocated queues. + * The rest of the SG elements will be copied when the RISC + * completes the SG elements that fit and halts. */ - if ((asc_dvc->cfg->termination & TERM_SE) == 0) { - /* SE automatic termination control is enabled. */ - switch (scsi_cfg1 & C_DET_SE) { - /* TERM_SE_HI: on, TERM_SE_LO: on */ - case 0x1: - case 0x2: - case 0x3: - asc_dvc->cfg->termination |= TERM_SE; - break; + if (sg_head->entry_cnt > ASC_MAX_SG_LIST) { + /* + * Set sg_entry_cnt to be the number of SG elements that + * will fit in the allocated SG queues. It is minus 1, because + * the first SG element is handled above. ASC_MAX_SG_LIST is + * already inflated by 1 to account for this. For example it + * may be 50 which is 1 + 7 queues * 7 SG elements. + */ + sg_entry_cnt = ASC_MAX_SG_LIST - 1; - /* TERM_SE_HI: on, TERM_SE_LO: off */ - case 0x0: - asc_dvc->cfg->termination |= TERM_SE_HI; - break; + /* + * Keep track of remaining number of SG elements that will + * need to be handled from a_isr.c. + */ + scsiq->remain_sg_entry_cnt = + sg_head->entry_cnt - ASC_MAX_SG_LIST; + } else { +#endif /* CC_VERY_LONG_SG_LIST */ + /* + * Set sg_entry_cnt to be the number of SG elements that + * will fit in the allocated SG queues. It is minus 1, because + * the first SG element is handled above. + */ + sg_entry_cnt = sg_head->entry_cnt - 1; +#if CC_VERY_LONG_SG_LIST + } +#endif /* CC_VERY_LONG_SG_LIST */ + if (sg_entry_cnt != 0) { + scsiq->q1.cntl |= QC_SG_HEAD; + q_addr = ASC_QNO_TO_QADDR(q_no); + sg_index = 1; + scsiq->q1.sg_queue_cnt = sg_head->queue_cnt; + scsi_sg_q.sg_head_qp = q_no; + scsi_sg_q.cntl = QCSG_SG_XFER_LIST; + for (i = 0; i < sg_head->queue_cnt; i++) { + scsi_sg_q.seq_no = i + 1; + if (sg_entry_cnt > ASC_SG_LIST_PER_Q) { + sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2); + sg_entry_cnt -= ASC_SG_LIST_PER_Q; + if (i == 0) { + scsi_sg_q.sg_list_cnt = + ASC_SG_LIST_PER_Q; + scsi_sg_q.sg_cur_list_cnt = + ASC_SG_LIST_PER_Q; + } else { + scsi_sg_q.sg_list_cnt = + ASC_SG_LIST_PER_Q - 1; + scsi_sg_q.sg_cur_list_cnt = + ASC_SG_LIST_PER_Q - 1; + } + } else { +#if CC_VERY_LONG_SG_LIST + /* + * This is the last SG queue in the list of + * allocated SG queues. If there are more + * SG elements than will fit in the allocated + * queues, then set the QCSG_SG_XFER_MORE flag. + */ + if (sg_head->entry_cnt > ASC_MAX_SG_LIST) { + scsi_sg_q.cntl |= QCSG_SG_XFER_MORE; + } else { +#endif /* CC_VERY_LONG_SG_LIST */ + scsi_sg_q.cntl |= QCSG_SG_XFER_END; +#if CC_VERY_LONG_SG_LIST + } +#endif /* CC_VERY_LONG_SG_LIST */ + sg_list_dwords = sg_entry_cnt << 1; + if (i == 0) { + scsi_sg_q.sg_list_cnt = sg_entry_cnt; + scsi_sg_q.sg_cur_list_cnt = + sg_entry_cnt; + } else { + scsi_sg_q.sg_list_cnt = + sg_entry_cnt - 1; + scsi_sg_q.sg_cur_list_cnt = + sg_entry_cnt - 1; + } + sg_entry_cnt = 0; + } + next_qp = AscReadLramByte(iop_base, + (ushort)(q_addr + + ASC_SCSIQ_B_FWD)); + scsi_sg_q.q_no = next_qp; + q_addr = ASC_QNO_TO_QADDR(next_qp); + AscMemWordCopyPtrToLram(iop_base, + q_addr + ASC_SCSIQ_SGHD_CPY_BEG, + (uchar *)&scsi_sg_q, + sizeof(ASC_SG_LIST_Q) >> 1); + AscMemDWordCopyPtrToLram(iop_base, + q_addr + ASC_SGQ_LIST_BEG, + (uchar *)&sg_head-> + sg_list[sg_index], + sg_list_dwords); + sg_index += ASC_SG_LIST_PER_Q; + scsiq->next_sg_index = sg_index; } + } else { + scsiq->q1.cntl &= ~QC_SG_HEAD; } + sta = AscPutReadyQueue(asc_dvc, scsiq, q_no); + scsiq->q1.data_addr = saved_data_addr; + scsiq->q1.data_cnt = saved_data_cnt; + return (sta); +} - if ((asc_dvc->cfg->termination & TERM_LVD) == 0) { - /* LVD automatic termination control is enabled. */ - switch (scsi_cfg1 & C_DET_LVD) { - /* TERM_LVD_HI: on, TERM_LVD_LO: on */ - case 0x4: - case 0x8: - case 0xC: - asc_dvc->cfg->termination |= TERM_LVD; - break; +static int +AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required) +{ + PortAddr iop_base; + uchar free_q_head; + uchar next_qp; + uchar tid_no; + uchar target_ix; + int sta; - /* TERM_LVD_HI: off, TERM_LVD_LO: off */ - case 0x0: - break; + iop_base = asc_dvc->iop_base; + target_ix = scsiq->q2.target_ix; + tid_no = ASC_TIX_TO_TID(target_ix); + sta = 0; + free_q_head = (uchar)AscGetVarFreeQHead(iop_base); + if (n_q_required > 1) { + next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head, + (uchar)n_q_required); + if (next_qp != ASC_QLINK_END) { + asc_dvc->last_q_shortage = 0; + scsiq->sg_head->queue_cnt = n_q_required - 1; + scsiq->q1.q_no = free_q_head; + sta = AscPutReadySgListQueue(asc_dvc, scsiq, + free_q_head); + } + } else if (n_q_required == 1) { + next_qp = AscAllocFreeQueue(iop_base, free_q_head); + if (next_qp != ASC_QLINK_END) { + scsiq->q1.q_no = free_q_head; + sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head); } } - - /* - * Clear any set TERM_SE and TERM_LVD bits. - */ - scsi_cfg1 &= (~TERM_SE & ~TERM_LVD); - - /* - * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. - */ - scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); - - /* - * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE - * bits and set possibly modified termination control bits in the - * Microcode SCSI_CFG1 Register Value. - */ - scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); - - /* - * Set SCSI_CFG1 Microcode Default Value - * - * Set possibly modified termination control and reset DIS_TERM_DRV - * bits in the Microcode SCSI_CFG1 Register Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); - - /* - * Set MEM_CFG Microcode Default Value - * - * The microcode will set the MEM_CFG register using this value - * after it is started below. - * - * MEM_CFG may be accessed as a word or byte, but only bits 0-7 - * are defined. - * - * ASC-38C0800 has 16KB internal memory. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, - BIOS_EN | RAM_SZ_16KB); - - /* - * Set SEL_MASK Microcode Default Value - * - * The microcode will set the SEL_MASK register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, - ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); - - AdvBuildCarrierFreelist(asc_dvc); - - /* - * Set-up the Host->RISC Initiator Command Queue (ICQ). - */ - - if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; + if (sta == 1) { + AscPutVarFreeQHead(iop_base, next_qp); + asc_dvc->cur_total_qng += n_q_required; + asc_dvc->cur_dvc_qng[tid_no]++; } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + return sta; +} - /* - * The first command issued will be placed in the stopper carrier. - */ - asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); +#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 +static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { + INQUIRY, + REQUEST_SENSE, + READ_CAPACITY, + READ_TOC, + MODE_SELECT, + MODE_SENSE, + MODE_SELECT_10, + MODE_SENSE_10, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF +}; - /* - * Set RISC ICQ physical address start value. - * carr_pa is LE, must be native before write - */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); +static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) +{ + PortAddr iop_base; + int sta; + int n_q_required; + int disable_syn_offset_one_fix; + int i; + ASC_PADDR addr; + ushort sg_entry_cnt = 0; + ushort sg_entry_cnt_minus_one = 0; + uchar target_ix; + uchar tid_no; + uchar sdtr_data; + uchar extra_bytes; + uchar scsi_cmd; + uchar disable_cmd; + ASC_SG_HEAD *sg_head; + ASC_DCNT data_cnt; - /* - * Set-up the RISC->Host Initiator Response Queue (IRQ). - */ - if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; + iop_base = asc_dvc->iop_base; + sg_head = scsiq->sg_head; + if (asc_dvc->err_code != 0) + return (ERR); + scsiq->q1.q_no = 0; + if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { + scsiq->q1.extra_bytes = 0; } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); - - /* - * The first command completed by the RISC will be placed in - * the stopper. - * - * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is - * completed the RISC will set the ASC_RQ_STOPPER bit. - */ - asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); - - /* - * Set RISC IRQ physical address start value. - * - * carr_pa is LE, must be native before write * - */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); - asc_dvc->carr_pending_cnt = 0; - - AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, - (ADV_INTR_ENABLE_HOST_INTR | - ADV_INTR_ENABLE_GLOBAL_INTR)); - - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); - AdvWriteWordRegister(iop_base, IOPW_PC, word); - - /* finally, finally, gentlemen, start your engine */ - AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); - - /* - * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus - * Resets should be performed. The RISC has to be running - * to issue a SCSI Bus Reset. - */ - if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { + sta = 0; + target_ix = scsiq->q2.target_ix; + tid_no = ASC_TIX_TO_TID(target_ix); + n_q_required = 1; + if (scsiq->cdbptr[0] == REQUEST_SENSE) { + if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { + asc_dvc->sdtr_done &= ~scsiq->q1.target_id; + sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); + AscMsgOutSDTR(asc_dvc, + asc_dvc-> + sdtr_period_tbl[(sdtr_data >> 4) & + (uchar)(asc_dvc-> + max_sdtr_index - + 1)], + (uchar)(sdtr_data & (uchar) + ASC_SYN_MAX_OFFSET)); + scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); + } + } + if (asc_dvc->in_critical_cnt != 0) { + AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); + return (ERR); + } + asc_dvc->in_critical_cnt++; + if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { + if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { + asc_dvc->in_critical_cnt--; + return (ERR); + } +#if !CC_VERY_LONG_SG_LIST + if (sg_entry_cnt > ASC_MAX_SG_LIST) { + asc_dvc->in_critical_cnt--; + return (ERR); + } +#endif /* !CC_VERY_LONG_SG_LIST */ + if (sg_entry_cnt == 1) { + scsiq->q1.data_addr = + (ADV_PADDR)sg_head->sg_list[0].addr; + scsiq->q1.data_cnt = + (ADV_DCNT)sg_head->sg_list[0].bytes; + scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); + } + sg_entry_cnt_minus_one = sg_entry_cnt - 1; + } + scsi_cmd = scsiq->cdbptr[0]; + disable_syn_offset_one_fix = FALSE; + if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && + !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { + if (scsiq->q1.cntl & QC_SG_HEAD) { + data_cnt = 0; + for (i = 0; i < sg_entry_cnt; i++) { + data_cnt += + (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i]. + bytes); + } + } else { + data_cnt = le32_to_cpu(scsiq->q1.data_cnt); + } + if (data_cnt != 0UL) { + if (data_cnt < 512UL) { + disable_syn_offset_one_fix = TRUE; + } else { + for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; + i++) { + disable_cmd = + _syn_offset_one_disable_cmd[i]; + if (disable_cmd == 0xFF) { + break; + } + if (scsi_cmd == disable_cmd) { + disable_syn_offset_one_fix = + TRUE; + break; + } + } + } + } + } + if (disable_syn_offset_one_fix) { + scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; + scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | + ASC_TAG_FLAG_DISABLE_DISCONNECT); + } else { + scsiq->q2.tag_code &= 0x27; + } + if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { + if (asc_dvc->bug_fix_cntl) { + if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { + if ((scsi_cmd == READ_6) || + (scsi_cmd == READ_10)) { + addr = + (ADV_PADDR)le32_to_cpu(sg_head-> + sg_list + [sg_entry_cnt_minus_one]. + addr) + + (ADV_DCNT)le32_to_cpu(sg_head-> + sg_list + [sg_entry_cnt_minus_one]. + bytes); + extra_bytes = + (uchar)((ushort)addr & 0x0003); + if ((extra_bytes != 0) + && + ((scsiq->q2. + tag_code & + ASC_TAG_FLAG_EXTRA_BYTES) + == 0)) { + scsiq->q2.tag_code |= + ASC_TAG_FLAG_EXTRA_BYTES; + scsiq->q1.extra_bytes = + extra_bytes; + data_cnt = + le32_to_cpu(sg_head-> + sg_list + [sg_entry_cnt_minus_one]. + bytes); + data_cnt -= + (ASC_DCNT) extra_bytes; + sg_head-> + sg_list + [sg_entry_cnt_minus_one]. + bytes = + cpu_to_le32(data_cnt); + } + } + } + } + sg_head->entry_to_copy = sg_head->entry_cnt; +#if CC_VERY_LONG_SG_LIST /* - * If the BIOS Signature is present in memory, restore the - * BIOS Handshake Configuration Table and do not perform - * a SCSI Bus Reset. + * Set the sg_entry_cnt to the maximum possible. The rest of + * the SG elements will be copied when the RISC completes the + * SG elements that fit and halts. */ - if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == - 0x55AA) { - /* - * Restore per TID negotiated values. - */ - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, - tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvWriteByteLram(iop_base, - ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); + if (sg_entry_cnt > ASC_MAX_SG_LIST) { + sg_entry_cnt = ASC_MAX_SG_LIST; + } +#endif /* CC_VERY_LONG_SG_LIST */ + n_q_required = AscSgListToQueue(sg_entry_cnt); + if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= + (uint) n_q_required) + || ((scsiq->q1.cntl & QC_URGENT) != 0)) { + if ((sta = + AscSendScsiQueue(asc_dvc, scsiq, + n_q_required)) == 1) { + asc_dvc->in_critical_cnt--; + return (sta); } - } else { - if (AdvResetSB(asc_dvc) != ADV_TRUE) { - warn_code = ASC_WARN_BUSRESET_ERROR; + } + } else { + if (asc_dvc->bug_fix_cntl) { + if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { + if ((scsi_cmd == READ_6) || + (scsi_cmd == READ_10)) { + addr = + le32_to_cpu(scsiq->q1.data_addr) + + le32_to_cpu(scsiq->q1.data_cnt); + extra_bytes = + (uchar)((ushort)addr & 0x0003); + if ((extra_bytes != 0) + && + ((scsiq->q2. + tag_code & + ASC_TAG_FLAG_EXTRA_BYTES) + == 0)) { + data_cnt = + le32_to_cpu(scsiq->q1. + data_cnt); + if (((ushort)data_cnt & 0x01FF) + == 0) { + scsiq->q2.tag_code |= + ASC_TAG_FLAG_EXTRA_BYTES; + data_cnt -= (ASC_DCNT) + extra_bytes; + scsiq->q1.data_cnt = + cpu_to_le32 + (data_cnt); + scsiq->q1.extra_bytes = + extra_bytes; + } + } + } + } + } + n_q_required = 1; + if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || + ((scsiq->q1.cntl & QC_URGENT) != 0)) { + if ((sta = AscSendScsiQueue(asc_dvc, scsiq, + n_q_required)) == 1) { + asc_dvc->in_critical_cnt--; + return (sta); } } } - - return warn_code; + asc_dvc->in_critical_cnt--; + return (sta); } /* - * Initialize the ASC-38C1600. - * - * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. - * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. + * AdvExeScsiQueue() - Send a request to the RISC microcode program. * - * Needed after initialization for error recovery. - */ -static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) -{ - AdvPortAddr iop_base; - ushort warn_code; - int begin_addr; - int end_addr; - ushort code_sum; - long word; - int i; - ushort scsi_cfg1; - uchar byte; - uchar tid; - ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ - ushort wdtr_able, sdtr_able, ppr_able, tagqng_able; - uchar max_cmd[ASC_MAX_TID + 1]; - - /* If there is already an error, don't continue. */ - if (asc_dvc->err_code != 0) { - return ADV_ERROR; - } - - /* - * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600. - */ - if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { - asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; - return ADV_ERROR; - } - - warn_code = 0; - iop_base = asc_dvc->iop_base; - - /* - * Save the RISC memory BIOS region before writing the microcode. - * The BIOS may already be loaded and using its RISC LRAM region - * so its region must be saved and restored. - * - * Note: This code makes the assumption, which is currently true, - * that a chip reset does not clear RISC LRAM. - */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); - } - - /* - * Save current per TID negotiated values. - */ - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - for (tid = 0; tid <= ASC_MAX_TID; tid++) { - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); - } - - /* - * RAM BIST (Built-In Self Test) - * - * Address : I/O base + offset 0x38h register (byte). - * Function: Bit 7-6(RW) : RAM mode - * Normal Mode : 0x00 - * Pre-test Mode : 0x40 - * RAM Test Mode : 0x80 - * Bit 5 : unused - * Bit 4(RO) : Done bit - * Bit 3-0(RO) : Status - * Host Error : 0x08 - * Int_RAM Error : 0x04 - * RISC Error : 0x02 - * SCSI Error : 0x01 - * No Error : 0x00 - * - * Note: RAM BIST code should be put right here, before loading the - * microcode and after saving the RISC memory BIOS region. - */ - - /* - * LRAM Pre-test - * - * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. - * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return - * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset - * to NORMAL_MODE, return an error too. - */ - for (i = 0; i < 2; i++) { - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); - mdelay(10); /* Wait for 10ms before reading back. */ - byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); - if ((byte & RAM_TEST_DONE) == 0 - || (byte & 0x0F) != PRE_TEST_VALUE) { - asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; - return ADV_ERROR; - } - - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - mdelay(10); /* Wait for 10ms before reading back. */ - if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) - != NORMAL_VALUE) { - asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; - return ADV_ERROR; - } - } + * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q, + * add the carrier to the ICQ (Initiator Command Queue), and tickle the + * RISC to notify it a new command is ready to be executed. + * + * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be + * set to SCSI_MAX_RETRY. + * + * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode + * for DMA addresses or math operations are byte swapped to little-endian + * order. + * + * Return: + * ADV_SUCCESS(1) - The request was successfully queued. + * ADV_BUSY(0) - Resource unavailable; Retry again after pending + * request completes. + * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure + * host IC error. + */ +static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) +{ + AdvPortAddr iop_base; + ADV_DCNT req_size; + ADV_PADDR req_paddr; + ADV_CARR_T *new_carrp; /* - * LRAM Test - It takes about 1.5 ms to run through the test. - * - * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. - * If Done bit not set or Status not 0, save register byte, set the - * err_code, and return an error. + * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. */ - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); - mdelay(10); /* Wait for 10ms before checking status. */ - - byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); - if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { - /* Get here if Done bit not set or Status not 0. */ - asc_dvc->bist_err_code = byte; /* for BIOS display message */ - asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; + if (scsiq->target_id > ADV_MAX_TID) { + scsiq->host_status = QHSTA_M_INVALID_DEVICE; + scsiq->done_status = QD_WITH_ERROR; return ADV_ERROR; } - /* We need to reset back to normal mode after LRAM test passes. */ - AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); - - asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, - _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, - _adv_asc38C1600_chksum); - if (asc_dvc->err_code) - return ADV_ERROR; + iop_base = asc_dvc->iop_base; /* - * Restore the RISC memory BIOS region. + * Allocate a carrier ensuring at least one carrier always + * remains on the freelist and initialize fields. */ - for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { - AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), - bios_mem[i]); + if ((new_carrp = asc_dvc->carr_freelist) == NULL) { + return ADV_BUSY; } + asc_dvc->carr_freelist = (ADV_CARR_T *) + ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa)); + asc_dvc->carr_pending_cnt++; /* - * Calculate and write the microcode code checksum to the microcode - * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + * Set the carrier to be a stopper by setting 'next_vpa' + * to the stopper value. The current stopper will be changed + * below to point to the new stopper. */ - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); - AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); - code_sum = 0; - AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); - for (word = begin_addr; word < end_addr; word += 2) { - code_sum += AdvReadWordAutoIncLram(iop_base); - } - AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); + new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); /* - * Read microcode version and date. + * Clear the ADV_SCSI_REQ_Q done flag. */ - AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, - asc_dvc->cfg->mcode_date); - AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, - asc_dvc->cfg->mcode_version); + scsiq->a_flag &= ~ADV_SCSIQ_DONE; - /* - * Set the chip type to indicate the ASC38C1600. - */ - AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600); + req_size = sizeof(ADV_SCSI_REQ_Q); + req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq, + (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG); - /* - * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. - * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current - * cable detection and then we are able to read C_DET[3:0]. - * - * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 - * Microcode Default Value' section below. - */ - scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); - AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, - scsi_cfg1 | DIS_TERM_DRV); + BUG_ON(req_paddr & 31); + BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q)); + + /* Wait for assertion before making little-endian */ + req_paddr = cpu_to_le32(req_paddr); + /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */ + scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq)); + scsiq->scsiq_rptr = req_paddr; + + scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp)); /* - * If the PCI Configuration Command Register "Parity Error Response - * Control" Bit was clear (0), then set the microcode variable - * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode - * to ignore DMA parity errors. + * Every ADV_CARR_T.carr_pa is byte swapped to little-endian + * order during initialization. */ - if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { - AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - word |= CONTROL_FLAG_IGNORE_PERR; - AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - } + scsiq->carr_pa = asc_dvc->icq_sp->carr_pa; /* - * If the BIOS control flag AIPP (Asynchronous Information - * Phase Protection) disable bit is not set, then set the firmware - * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable - * AIPP checking and encoding. + * Use the current stopper to send the ADV_SCSI_REQ_Q command to + * the microcode. The newly allocated stopper will become the new + * stopper. */ - if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) { - AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - word |= CONTROL_FLAG_ENABLE_AIPP; - AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); - } + asc_dvc->icq_sp->areq_vpa = req_paddr; /* - * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4], - * and START_CTL_TH [3:2]. + * Set the 'next_vpa' pointer for the old stopper to be the + * physical address of the new stopper. The RISC can only + * follow physical addresses. */ - AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, - FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); + asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa; /* - * Microcode operating variables for WDTR, SDTR, and command tag - * queuing will be set in slave_configure() based on what a - * device reports it is capable of in Inquiry byte 7. - * - * If SCSI Bus Resets have been disabled, then directly set - * SDTR and WDTR from the EEPROM configuration. This will allow - * the BIOS and warm boot to work without a SCSI bus hang on - * the Inquiry caused by host and target mismatched DTR values. - * Without the SCSI Bus Reset, before an Inquiry a device can't - * be assumed to be in Asynchronous, Narrow mode. + * Set the host adapter stopper pointer to point to the new carrier. */ - if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, - asc_dvc->wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, - asc_dvc->sdtr_able); + asc_dvc->icq_sp = new_carrp; + + if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || + asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { + /* + * Tickle the RISC to tell it to read its Command Queue Head pointer. + */ + AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); + if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { + /* + * Clear the tickle value. In the ASC-3550 the RISC flag + * command 'clr_tickle_a' does not work unless the host + * value is cleared. + */ + AdvWriteByteRegister(iop_base, IOPB_TICKLE, + ADV_TICKLE_NOP); + } + } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { + /* + * Notify the RISC a carrier is ready by writing the physical + * address of the new carrier stopper to the COMMA register. + */ + AdvWriteDWordRegister(iop_base, IOPDW_COMMA, + le32_to_cpu(new_carrp->carr_pa)); } - /* - * Set microcode operating variables for DISC and SDTR_SPEED1, - * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM - * configuration values. - * - * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, - * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them - * without determining here whether the device supports SDTR. - */ - AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, - asc_dvc->cfg->disc_enable); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); + return ADV_SUCCESS; +} + +/* + * Execute a single 'Scsi_Cmnd'. + * + * The function 'done' is called when the request has been completed. + * + * Scsi_Cmnd: + * + * host - board controlling device + * device - device to send command + * target - target of device + * lun - lun of device + * cmd_len - length of SCSI CDB + * cmnd - buffer for SCSI 8, 10, or 12 byte CDB + * use_sg - if non-zero indicates scatter-gather request with use_sg elements + * + * if (use_sg == 0) { + * request_buffer - buffer address for request + * request_bufflen - length of request buffer + * } else { + * request_buffer - pointer to scatterlist structure + * } + * + * sense_buffer - sense command buffer + * + * result (4 bytes of an int): + * Byte Meaning + * 0 SCSI Status Byte Code + * 1 SCSI One Byte Message Code + * 2 Host Error Code + * 3 Mid-Level Error Code + * + * host driver fields: + * SCp - Scsi_Pointer used for command processing status + * scsi_done - used to save caller's done function + * host_scribble - used for pointer to another struct scsi_cmnd + * + * If this function returns ASC_NOERROR the request will be completed + * from the interrupt handler. + * + * If this function returns ASC_ERROR the host error code has been set, + * and the called must call asc_scsi_done. + * + * If ASC_BUSY is returned the request will be returned to the midlayer + * and re-tried later. + */ +static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) +{ + asc_board_t *boardp; + ASC_DVC_VAR *asc_dvc_varp; + ADV_DVC_VAR *adv_dvc_varp; + ADV_SCSI_REQ_Q *adv_scsiqp; + struct scsi_device *device; + int ret; + + ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", + (ulong)scp, (ulong)scp->scsi_done); - /* - * Set SCSI_CFG0 Microcode Default Value. - * - * The microcode will set the SCSI_CFG0 register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, - PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | - asc_dvc->chip_scsi_id); + boardp = ASC_BOARDP(scp->device->host); + device = boardp->device[scp->device->id]; - /* - * Calculate SCSI_CFG1 Microcode Default Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. - * - * Each ASC-38C1600 function has only two cable detect bits. - * The bus mode override bits are in IOPB_SOFT_OVER_WR. - */ - scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); + if (ASC_NARROW_BOARD(boardp)) { + /* + * Build and execute Narrow Board request. + */ - /* - * If the cable is reversed all of the SCSI_CTRL register signals - * will be set. Check for and return an error if this condition is - * found. - */ - if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { - asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; - return ADV_ERROR; - } + asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; - /* - * Each ASC-38C1600 function has two connectors. Only an HVD device - * can not be connected to either connector. An LVD device or SE device - * may be connected to either connecor. If an SE device is connected, - * then at most Ultra speed (20 Mhz) can be used on both connectors. - * - * If an HVD device is attached, return an error. - */ - if (scsi_cfg1 & HVD) { - asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; - return ADV_ERROR; - } + /* + * Build Asc Library request structure using the + * global structures 'asc_scsi_req' and 'asc_sg_head'. + * + * If an error is returned, then the request has been + * queued on the board done queue. It will be completed + * by the caller. + * + * asc_build_req() can not return ASC_BUSY. + */ + if (asc_build_req(boardp, scp) == ASC_ERROR) { + ASC_STATS(scp->device->host, build_error); + return ASC_ERROR; + } - /* - * Each function in the ASC-38C1600 uses only the SE cable detect and - * termination because there are two connectors for each function. Each - * function may use either LVD or SE mode. Corresponding the SE automatic - * termination control EEPROM bits are used for each function. Each - * function has its own EEPROM. If SE automatic control is enabled for - * the function, then set the termination value based on a table listed - * in a_condor.h. - * - * If manual termination is specified in the EEPROM for the function, - * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is - * ready to be 'ored' into SCSI_CFG1. - */ - if ((asc_dvc->cfg->termination & TERM_SE) == 0) { - struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); - /* SE automatic termination control is enabled. */ - switch (scsi_cfg1 & C_DET_SE) { - /* TERM_SE_HI: on, TERM_SE_LO: on */ - case 0x1: - case 0x2: - case 0x3: - asc_dvc->cfg->termination |= TERM_SE; + switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { + case ASC_NOERROR: + ASC_STATS(scp->device->host, exe_noerror); + /* + * Increment monotonically increasing per device + * successful request counter. Wrapping doesn't matter. + */ + boardp->reqcnt[scp->device->id]++; + ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), " + "ASC_NOERROR\n"); + break; + case ASC_BUSY: + ASC_STATS(scp->device->host, exe_busy); break; + case ASC_ERROR: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", + boardp->id, asc_dvc_varp->err_code); + ASC_STATS(scp->device->host, exe_error); + scp->result = HOST_BYTE(DID_ERROR); + break; + default: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AscExeScsiQueue() unknown, err_code 0x%x\n", + boardp->id, asc_dvc_varp->err_code); + ASC_STATS(scp->device->host, exe_unknown); + scp->result = HOST_BYTE(DID_ERROR); + break; + } + } else { + /* + * Build and execute Wide Board request. + */ + adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; - case 0x0: - if (PCI_FUNC(pdev->devfn) == 0) { - /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ - } else { - /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ - asc_dvc->cfg->termination |= TERM_SE_HI; - } + /* + * Build and get a pointer to an Adv Library request structure. + * + * If the request is successfully built then send it below, + * otherwise return with an error. + */ + switch (adv_build_req(boardp, scp, &adv_scsiqp)) { + case ASC_NOERROR: + ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_NOERROR\n"); + break; + case ASC_BUSY: + ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_BUSY\n"); + /* + * The asc_stats fields 'adv_build_noreq' and + * 'adv_build_nosg' count wide board busy conditions. + * They are updated in adv_build_req and + * adv_get_sglist, respectively. + */ + return ASC_BUSY; + case ASC_ERROR: + default: + ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " + "ASC_ERROR\n"); + ASC_STATS(scp->device->host, build_error); + return ASC_ERROR; + } + + switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { + case ASC_NOERROR: + ASC_STATS(scp->device->host, exe_noerror); + /* + * Increment monotonically increasing per device + * successful request counter. Wrapping doesn't matter. + */ + boardp->reqcnt[scp->device->id]++; + ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), " + "ASC_NOERROR\n"); + break; + case ASC_BUSY: + ASC_STATS(scp->device->host, exe_busy); + break; + case ASC_ERROR: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", + boardp->id, adv_dvc_varp->err_code); + ASC_STATS(scp->device->host, exe_error); + scp->result = HOST_BYTE(DID_ERROR); + break; + default: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " + "AdvExeScsiQueue() unknown, err_code 0x%x\n", + boardp->id, adv_dvc_varp->err_code); + ASC_STATS(scp->device->host, exe_unknown); + scp->result = HOST_BYTE(DID_ERROR); break; } } - /* - * Clear any set TERM_SE bits. - */ - scsi_cfg1 &= ~TERM_SE; + ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); + return ret; +} - /* - * Invert the TERM_SE bits and then set 'scsi_cfg1'. - */ - scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE); +/* + * advansys_queuecommand() - interrupt-driven I/O entrypoint. + * + * This function always returns 0. Command return status is saved + * in the 'scp' result field. + */ +static int +advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +{ + struct Scsi_Host *shost = scp->device->host; + asc_board_t *boardp = ASC_BOARDP(shost); + unsigned long flags; + int asc_res, result = 0; - /* - * Clear Big Endian and Terminator Polarity bits and set possibly - * modified termination control bits in the Microcode SCSI_CFG1 - * Register Value. - * - * Big Endian bit is not used even on big endian machines. - */ - scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL); + ASC_STATS(shost, queuecommand); + scp->scsi_done = done; /* - * Set SCSI_CFG1 Microcode Default Value - * - * Set possibly modified termination control bits in the Microcode - * SCSI_CFG1 Register Value. - * - * The microcode will set the SCSI_CFG1 register using this value - * after it is started below. + * host_lock taken by mid-level prior to call, but need + * to protect against own ISR */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); + spin_lock_irqsave(&boardp->lock, flags); + asc_res = asc_execute_scsi_cmnd(scp); + spin_unlock_irqrestore(&boardp->lock, flags); + + switch (asc_res) { + case ASC_NOERROR: + break; + case ASC_BUSY: + result = SCSI_MLQUEUE_HOST_BUSY; + break; + case ASC_ERROR: + default: + asc_scsi_done(scp); + break; + } + + return result; +} + +static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base) +{ + PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | + (PortAddr) (ASC_EISA_CFG_IOP_MASK); + return inpw(eisa_cfg_iop); +} + +/* + * Return the BIOS address of the adapter at the specified + * I/O port and with the specified bus type. + */ +static unsigned short __devinit +AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type) +{ + unsigned short cfg_lsw; + unsigned short bios_addr; /* - * Set MEM_CFG Microcode Default Value - * - * The microcode will set the MEM_CFG register using this value - * after it is started below. - * - * MEM_CFG may be accessed as a word or byte, but only bits 0-7 - * are defined. - * - * ASC-38C1600 has 32KB internal memory. - * - * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come - * out a special 16K Adv Library and Microcode version. After the issue - * resolved, we should turn back to the 32K support. Both a_condor.h and - * mcode.sas files also need to be updated. - * - * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, - * BIOS_EN | RAM_SZ_32KB); + * The PCI BIOS is re-located by the motherboard BIOS. Because + * of this the driver can not determine where a PCI BIOS is + * loaded and executes. */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, - BIOS_EN | RAM_SZ_16KB); + if (bus_type & ASC_IS_PCI) + return 0; - /* - * Set SEL_MASK Microcode Default Value - * - * The microcode will set the SEL_MASK register using this value - * after it is started below. - */ - AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, - ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); + if ((bus_type & ASC_IS_EISA) != 0) { + cfg_lsw = AscGetEisaChipCfg(iop_base); + cfg_lsw &= 0x000F; + bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE; + return bios_addr; + } - AdvBuildCarrierFreelist(asc_dvc); + cfg_lsw = AscGetChipCfgLsw(iop_base); /* - * Set-up the Host->RISC Initiator Command Queue (ICQ). + * ISA PnP uses the top bit as the 32K BIOS flag */ - if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; + if (bus_type == ASC_IS_ISAPNP) + cfg_lsw &= 0x7FFF; + bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE; + return bios_addr; +} + +static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) +{ + ushort cfg_lsw; + + if (AscGetChipScsiID(iop_base) == new_host_id) { + return (new_host_id); } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); + cfg_lsw = AscGetChipCfgLsw(iop_base); + cfg_lsw &= 0xF8FF; + cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8); + AscSetChipCfgLsw(iop_base, cfg_lsw); + return (AscGetChipScsiID(iop_base)); +} - /* - * The first command issued will be placed in the stopper carrier. - */ - asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); +static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base) +{ + unsigned char sc; - /* - * Set RISC ICQ physical address start value. Initialize the - * COMMA register to the same value otherwise the RISC will - * prematurely detect a command is available. - */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); - AdvWriteDWordRegister(iop_base, IOPDW_COMMA, - le32_to_cpu(asc_dvc->icq_sp->carr_pa)); + AscSetBank(iop_base, 1); + sc = inp(iop_base + IOP_REG_SC); + AscSetBank(iop_base, 0); + return sc; +} - /* - * Set-up the RISC->Host Initiator Response Queue (IRQ). - */ - if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { - asc_dvc->err_code |= ASC_IERR_NO_CARRIER; - return ADV_ERROR; +static unsigned char __devinit +AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) +{ + if (bus_type & ASC_IS_EISA) { + PortAddr eisa_iop; + unsigned char revision; + eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | + (PortAddr) ASC_EISA_REV_IOP_MASK; + revision = inp(eisa_iop); + return ASC_CHIP_MIN_VER_EISA - 1 + revision; } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); + return AscGetChipVerNo(iop_base); +} - /* - * The first command completed by the RISC will be placed in - * the stopper. - * - * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is - * completed the RISC will set the ASC_RQ_STOPPER bit. - */ - asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); +static void __devinit AscToggleIRQAct(PortAddr iop_base) +{ + AscSetChipStatus(iop_base, CIW_IRQ_ACT); + AscSetChipStatus(iop_base, 0); + return; +} - /* - * Set RISC IRQ physical address start value. - */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); - asc_dvc->carr_pending_cnt = 0; +static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type) +{ + ushort cfg_lsw; + uchar chip_irq; - AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, - (ADV_INTR_ENABLE_HOST_INTR | - ADV_INTR_ENABLE_GLOBAL_INTR)); - AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); - AdvWriteWordRegister(iop_base, IOPW_PC, word); + if ((bus_type & ASC_IS_EISA) != 0) { + cfg_lsw = AscGetEisaChipCfg(iop_base); + chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10); + if ((chip_irq == 13) || (chip_irq > 15)) { + return (0); + } + return (chip_irq); + } + if ((bus_type & ASC_IS_VL) != 0) { + cfg_lsw = AscGetChipCfgLsw(iop_base); + chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07)); + if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) { + return (0); + } + return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1))); + } + cfg_lsw = AscGetChipCfgLsw(iop_base); + chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03)); + if (chip_irq == 3) + chip_irq += (uchar)2; + return ((uchar)(chip_irq + ASC_MIN_IRQ_NO)); +} - /* finally, finally, gentlemen, start your engine */ - AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); +static uchar __devinit +AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) +{ + ushort cfg_lsw; - /* - * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus - * Resets should be performed. The RISC has to be running - * to issue a SCSI Bus Reset. - */ - if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { - /* - * If the BIOS Signature is present in memory, restore the - * per TID microcode operating variables. - */ - if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == - 0x55AA) { - /* - * Restore per TID negotiated values. - */ - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, - tagqng_able); - for (tid = 0; tid <= ASC_MAX_TID; tid++) { - AdvWriteByteLram(iop_base, - ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); - } - } else { - if (AdvResetSB(asc_dvc) != ADV_TRUE) { - warn_code = ASC_WARN_BUSRESET_ERROR; + if ((bus_type & ASC_IS_VL) != 0) { + if (irq_no != 0) { + if ((irq_no < ASC_MIN_IRQ_NO) + || (irq_no > ASC_MAX_IRQ_NO)) { + irq_no = 0; + } else { + irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1)); } } + cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3); + cfg_lsw |= (ushort)0x0010; + AscSetChipCfgLsw(iop_base, cfg_lsw); + AscToggleIRQAct(iop_base); + cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0); + cfg_lsw |= (ushort)((irq_no & 0x07) << 2); + AscSetChipCfgLsw(iop_base, cfg_lsw); + AscToggleIRQAct(iop_base); + return (AscGetChipIRQ(iop_base, bus_type)); + } + if ((bus_type & (ASC_IS_ISA)) != 0) { + if (irq_no == 15) + irq_no -= (uchar)2; + irq_no -= (uchar)ASC_MIN_IRQ_NO; + cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3); + cfg_lsw |= (ushort)((irq_no & 0x03) << 2); + AscSetChipCfgLsw(iop_base, cfg_lsw); + return (AscGetChipIRQ(iop_base, bus_type)); } + return (0); +} - return warn_code; +#ifdef CONFIG_ISA +static void __devinit AscEnableIsaDma(uchar dma_channel) +{ + if (dma_channel < 4) { + outp(0x000B, (ushort)(0xC0 | dma_channel)); + outp(0x000A, dma_channel); + } else if (dma_channel < 8) { + outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); + outp(0x00D4, (ushort)(dma_channel - 4)); + } + return; +} +#endif /* CONFIG_ISA */ + +static int AscStopQueueExe(PortAddr iop_base) +{ + int count = 0; + + if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { + AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, + ASC_STOP_REQ_RISC_STOP); + do { + if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & + ASC_STOP_ACK_RISC_STOP) { + return (1); + } + mdelay(100); + } while (count++ < 20); + } + return (0); +} + +static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type) +{ + if (bus_type & ASC_IS_ISA) + return ASC_MAX_ISA_DMA_COUNT; + else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) + return ASC_MAX_VL_DMA_COUNT; + return ASC_MAX_PCI_DMA_COUNT; } -/* - * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and - * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while - * all of this is done. - * - * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. - * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. - * - * Note: Chip is stopped on entry. - */ -static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) +#ifdef CONFIG_ISA +static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base) { - AdvPortAddr iop_base; - ushort warn_code; - ADVEEP_3550_CONFIG eep_config; + ushort channel; - iop_base = asc_dvc->iop_base; + channel = AscGetChipCfgLsw(iop_base) & 0x0003; + if (channel == 0x03) + return (0); + else if (channel == 0x00) + return (7); + return (channel + 4); +} - warn_code = 0; +static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) +{ + ushort cfg_lsw; + uchar value; - /* - * Read the board's EEPROM configuration. - * - * Set default values if a bad checksum is found. - */ - if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) { - warn_code |= ASC_WARN_EEPROM_CHKSUM; + if ((dma_channel >= 5) && (dma_channel <= 7)) { + if (dma_channel == 7) + value = 0x00; + else + value = dma_channel - 4; + cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC; + cfg_lsw |= value; + AscSetChipCfgLsw(iop_base, cfg_lsw); + return (AscGetIsaDmaChannel(iop_base)); + } + return 0; +} - /* - * Set EEPROM default values. - */ - memcpy(&eep_config, &Default_3550_EEPROM_Config, - sizeof(ADVEEP_3550_CONFIG)); +static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) +{ + uchar speed_value; - /* - * Assume the 6 byte board serial number that was read from - * EEPROM is correct even if the EEPROM checksum failed. - */ - eep_config.serial_number_word3 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); + AscSetBank(iop_base, 1); + speed_value = AscReadChipDmaSpeed(iop_base); + speed_value &= 0x07; + AscSetBank(iop_base, 0); + return speed_value; +} - eep_config.serial_number_word2 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); +static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) +{ + speed_value &= 0x07; + AscSetBank(iop_base, 1); + AscWriteChipDmaSpeed(iop_base, speed_value); + AscSetBank(iop_base, 0); + return AscGetIsaDmaSpeed(iop_base); +} +#endif /* CONFIG_ISA */ - eep_config.serial_number_word1 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); +static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) +{ + int i; + PortAddr iop_base; + ushort warn_code; + uchar chip_version; - AdvSet3550EEPConfig(iop_base, &eep_config); + iop_base = asc_dvc->iop_base; + warn_code = 0; + asc_dvc->err_code = 0; + if ((asc_dvc->bus_type & + (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) { + asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE; } - /* - * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the - * EEPROM configuration that was read. - * - * This is the mapping of EEPROM fields to Adv Library fields. - */ - asc_dvc->wdtr_able = eep_config.wdtr_able; - asc_dvc->sdtr_able = eep_config.sdtr_able; - asc_dvc->ultra_able = eep_config.ultra_able; - asc_dvc->tagqng_able = eep_config.tagqng_able; - asc_dvc->cfg->disc_enable = eep_config.disc_enable; - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; - asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); - asc_dvc->start_motor = eep_config.start_motor; - asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; - asc_dvc->bios_ctrl = eep_config.bios_ctrl; - asc_dvc->no_scam = eep_config.scam_tolerant; - asc_dvc->cfg->serial1 = eep_config.serial_number_word1; - asc_dvc->cfg->serial2 = eep_config.serial_number_word2; - asc_dvc->cfg->serial3 = eep_config.serial_number_word3; - - /* - * Set the host maximum queuing (max. 253, min. 16) and the per device - * maximum queuing (max. 63, min. 4). - */ - if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_host_qng == 0) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else { - eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + AscSetChipControl(iop_base, CC_HALT); + AscSetChipStatus(iop_base, 0); + asc_dvc->bug_fix_cntl = 0; + asc_dvc->pci_fix_asyn_xfer = 0; + asc_dvc->pci_fix_asyn_xfer_always = 0; + /* asc_dvc->init_state initalized in AscInitGetConfig(). */ + asc_dvc->sdtr_done = 0; + asc_dvc->cur_total_qng = 0; + asc_dvc->is_in_int = 0; + asc_dvc->in_critical_cnt = 0; + asc_dvc->last_q_shortage = 0; + asc_dvc->use_tagged_qng = 0; + asc_dvc->no_scam = 0; + asc_dvc->unit_not_ready = 0; + asc_dvc->queue_full_or_busy = 0; + asc_dvc->redo_scam = 0; + asc_dvc->res2 = 0; + asc_dvc->host_init_sdtr_index = 0; + asc_dvc->cfg->can_tagged_qng = 0; + asc_dvc->cfg->cmd_qng_enabled = 0; + asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; + asc_dvc->init_sdtr = 0; + asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG; + asc_dvc->scsi_reset_wait = 3; + asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET; + asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type); + asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; + asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; + asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; + asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; + asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | + ASC_LIB_VERSION_MINOR; + chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); + asc_dvc->cfg->chip_version = chip_version; + asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; + asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; + asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; + asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; + asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; + asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; + asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; + asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; + asc_dvc->max_sdtr_index = 7; + if ((asc_dvc->bus_type & ASC_IS_PCI) && + (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { + asc_dvc->bus_type = ASC_IS_PCI_ULTRA; + asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; + asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; + asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; + asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; + asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; + asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; + asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; + asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; + asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; + asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; + asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; + asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; + asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; + asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; + asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; + asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; + asc_dvc->max_sdtr_index = 15; + if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { + AscSetExtraControl(iop_base, + (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); + } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) { + AscSetExtraControl(iop_base, + (SEC_ACTIVE_NEGATE | + SEC_ENABLE_FILTER)); } } + if (asc_dvc->bus_type == ASC_IS_PCI) { + AscSetExtraControl(iop_base, + (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE)); + } - if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; - } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_dvc_qng == 0) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; - } else { - eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; +#ifdef CONFIG_ISA + if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { + if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) { + AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); + asc_dvc->bus_type = ASC_IS_ISAPNP; } + asc_dvc->cfg->isa_dma_channel = + (uchar)AscGetIsaDmaChannel(iop_base); } - - /* - * If 'max_dvc_qng' is greater than 'max_host_qng', then - * set 'max_dvc_qng' to 'max_host_qng'. - */ - if (eep_config.max_dvc_qng > eep_config.max_host_qng) { - eep_config.max_dvc_qng = eep_config.max_host_qng; +#endif /* CONFIG_ISA */ + for (i = 0; i <= ASC_MAX_TID; i++) { + asc_dvc->cur_dvc_qng[i] = 0; + asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG; + asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L; + asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L; + asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; } + return warn_code; +} - /* - * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' - * values based on possibly adjusted EEPROM values. - */ - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; - - /* - * If the EEPROM 'termination' field is set to automatic (0), then set - * the ADV_DVC_CFG 'termination' field to automatic also. - * - * If the termination is specified with a non-zero 'termination' - * value check that a legal value is set and set the ADV_DVC_CFG - * 'termination' field appropriately. - */ - if (eep_config.termination == 0) { - asc_dvc->cfg->termination = 0; /* auto termination */ - } else { - /* Enable manual control with low off / high off. */ - if (eep_config.termination == 1) { - asc_dvc->cfg->termination = TERM_CTL_SEL; - - /* Enable manual control with low off / high on. */ - } else if (eep_config.termination == 2) { - asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H; +static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) +{ + int retry; - /* Enable manual control with low on / high on. */ - } else if (eep_config.termination == 3) { - asc_dvc->cfg->termination = - TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L; - } else { - /* - * The EEPROM 'termination' field contains a bad value. Use - * automatic termination instead. - */ - asc_dvc->cfg->termination = 0; - warn_code |= ASC_WARN_EEPROM_TERMINATION; - } + for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) { + unsigned char read_back; + AscSetChipEEPCmd(iop_base, cmd_reg); + mdelay(1); + read_back = AscGetChipEEPCmd(iop_base); + if (read_back == cmd_reg) + return 1; } + return 0; +} - return warn_code; +static void __devinit AscWaitEEPRead(void) +{ + mdelay(1); } -/* - * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and - * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while - * all of this is done. - * - * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. - * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. - * - * Note: Chip is stopped on entry. - */ -static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) +static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr) { - AdvPortAddr iop_base; - ushort warn_code; - ADVEEP_38C0800_CONFIG eep_config; - uchar tid, termination; - ushort sdtr_speed = 0; + ushort read_wval; + uchar cmd_reg; - iop_base = asc_dvc->iop_base; + AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); + AscWaitEEPRead(); + cmd_reg = addr | ASC_EEP_CMD_READ; + AscWriteEEPCmdReg(iop_base, cmd_reg); + AscWaitEEPRead(); + read_wval = AscGetChipEEPData(iop_base); + AscWaitEEPRead(); + return read_wval; +} - warn_code = 0; +static ushort __devinit +AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) +{ + ushort wval; + ushort sum; + ushort *wbuf; + int cfg_beg; + int cfg_end; + int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; + int s_addr; + wbuf = (ushort *)cfg_buf; + sum = 0; + /* Read two config words; Byte-swapping done by AscReadEEPWord(). */ + for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { + *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); + sum += *wbuf; + } + if (bus_type & ASC_IS_VL) { + cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; + cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; + } else { + cfg_beg = ASC_EEP_DVC_CFG_BEG; + cfg_end = ASC_EEP_MAX_DVC_ADDR; + } + for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { + wval = AscReadEEPWord(iop_base, (uchar)s_addr); + if (s_addr <= uchar_end_in_config) { + /* + * Swap all char fields - must unswap bytes already swapped + * by AscReadEEPWord(). + */ + *wbuf = le16_to_cpu(wval); + } else { + /* Don't swap word field at the end - cntl field. */ + *wbuf = wval; + } + sum += wval; /* Checksum treats all EEPROM data as words. */ + } /* - * Read the board's EEPROM configuration. - * - * Set default values if a bad checksum is found. + * Read the checksum word which will be compared against 'sum' + * by the caller. Word field already swapped. */ - if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != - eep_config.check_sum) { - warn_code |= ASC_WARN_EEPROM_CHKSUM; + *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); + return sum; +} - /* - * Set EEPROM default values. - */ - memcpy(&eep_config, &Default_38C0800_EEPROM_Config, - sizeof(ADVEEP_38C0800_CONFIG)); +static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) +{ + PortAddr iop_base; + ushort q_addr; + ushort saved_word; + int sta; - /* - * Assume the 6 byte board serial number that was read from - * EEPROM is correct even if the EEPROM checksum failed. - */ - eep_config.serial_number_word3 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); + iop_base = asc_dvc->iop_base; + sta = 0; + q_addr = ASC_QNO_TO_QADDR(241); + saved_word = AscReadLramWord(iop_base, q_addr); + AscSetChipLramAddr(iop_base, q_addr); + AscSetChipLramData(iop_base, 0x55AA); + mdelay(10); + AscSetChipLramAddr(iop_base, q_addr); + if (AscGetChipLramData(iop_base) == 0x55AA) { + sta = 1; + AscWriteLramWord(iop_base, q_addr, saved_word); + } + return (sta); +} - eep_config.serial_number_word2 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); +static void __devinit AscWaitEEPWrite(void) +{ + mdelay(20); + return; +} - eep_config.serial_number_word1 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); +static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) +{ + ushort read_back; + int retry; - AdvSet38C0800EEPConfig(iop_base, &eep_config); + retry = 0; + while (TRUE) { + AscSetChipEEPData(iop_base, data_reg); + mdelay(1); + read_back = AscGetChipEEPData(iop_base); + if (read_back == data_reg) { + return (1); + } + if (retry++ > ASC_EEP_MAX_RETRY) { + return (0); + } } - /* - * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the - * EEPROM configuration that was read. - * - * This is the mapping of EEPROM fields to Adv Library fields. - */ - asc_dvc->wdtr_able = eep_config.wdtr_able; - asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; - asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; - asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; - asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; - asc_dvc->tagqng_able = eep_config.tagqng_able; - asc_dvc->cfg->disc_enable = eep_config.disc_enable; - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; - asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); - asc_dvc->start_motor = eep_config.start_motor; - asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; - asc_dvc->bios_ctrl = eep_config.bios_ctrl; - asc_dvc->no_scam = eep_config.scam_tolerant; - asc_dvc->cfg->serial1 = eep_config.serial_number_word1; - asc_dvc->cfg->serial2 = eep_config.serial_number_word2; - asc_dvc->cfg->serial3 = eep_config.serial_number_word3; +} - /* - * For every Target ID if any of its 'sdtr_speed[1234]' bits - * are set, then set an 'sdtr_able' bit for it. - */ - asc_dvc->sdtr_able = 0; - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - if (tid == 0) { - sdtr_speed = asc_dvc->sdtr_speed1; - } else if (tid == 4) { - sdtr_speed = asc_dvc->sdtr_speed2; - } else if (tid == 8) { - sdtr_speed = asc_dvc->sdtr_speed3; - } else if (tid == 12) { - sdtr_speed = asc_dvc->sdtr_speed4; +static ushort __devinit +AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) +{ + ushort read_wval; + + read_wval = AscReadEEPWord(iop_base, addr); + if (read_wval != word_val) { + AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE); + AscWaitEEPRead(); + AscWriteEEPDataReg(iop_base, word_val); + AscWaitEEPRead(); + AscWriteEEPCmdReg(iop_base, + (uchar)((uchar)ASC_EEP_CMD_WRITE | addr)); + AscWaitEEPWrite(); + AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); + AscWaitEEPRead(); + return (AscReadEEPWord(iop_base, addr)); + } + return (read_wval); +} + +static int __devinit +AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) +{ + int n_error; + ushort *wbuf; + ushort word; + ushort sum; + int s_addr; + int cfg_beg; + int cfg_end; + int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; + + wbuf = (ushort *)cfg_buf; + n_error = 0; + sum = 0; + /* Write two config words; AscWriteEEPWord() will swap bytes. */ + for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { + sum += *wbuf; + if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) { + n_error++; } - if (sdtr_speed & ADV_MAX_TID) { - asc_dvc->sdtr_able |= (1 << tid); + } + if (bus_type & ASC_IS_VL) { + cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; + cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; + } else { + cfg_beg = ASC_EEP_DVC_CFG_BEG; + cfg_end = ASC_EEP_MAX_DVC_ADDR; + } + for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { + if (s_addr <= uchar_end_in_config) { + /* + * This is a char field. Swap char fields before they are + * swapped again by AscWriteEEPWord(). + */ + word = cpu_to_le16(*wbuf); + if (word != + AscWriteEEPWord(iop_base, (uchar)s_addr, word)) { + n_error++; + } + } else { + /* Don't swap word field at the end - cntl field. */ + if (*wbuf != + AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) { + n_error++; + } } - sdtr_speed >>= 4; + sum += *wbuf; /* Checksum calculated from word values. */ + } + /* Write checksum word. It will be swapped by AscWriteEEPWord(). */ + *wbuf = sum; + if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) { + n_error++; } + /* Read EEPROM back again. */ + wbuf = (ushort *)cfg_buf; /* - * Set the host maximum queuing (max. 253, min. 16) and the per device - * maximum queuing (max. 63, min. 4). + * Read two config words; Byte-swapping done by AscReadEEPWord(). */ - if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_host_qng == 0) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else { - eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { + if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) { + n_error++; } } - - if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; - } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_dvc_qng == 0) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + if (bus_type & ASC_IS_VL) { + cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; + cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; + } else { + cfg_beg = ASC_EEP_DVC_CFG_BEG; + cfg_end = ASC_EEP_MAX_DVC_ADDR; + } + for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { + if (s_addr <= uchar_end_in_config) { + /* + * Swap all char fields. Must unswap bytes already swapped + * by AscReadEEPWord(). + */ + word = + le16_to_cpu(AscReadEEPWord + (iop_base, (uchar)s_addr)); } else { - eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + /* Don't swap word field at the end - cntl field. */ + word = AscReadEEPWord(iop_base, (uchar)s_addr); + } + if (*wbuf != word) { + n_error++; } } - - /* - * If 'max_dvc_qng' is greater than 'max_host_qng', then - * set 'max_dvc_qng' to 'max_host_qng'. - */ - if (eep_config.max_dvc_qng > eep_config.max_host_qng) { - eep_config.max_dvc_qng = eep_config.max_host_qng; + /* Read checksum; Byte swapping not needed. */ + if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) { + n_error++; } + return n_error; +} - /* - * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' - * values based on possibly adjusted EEPROM values. - */ - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; +static int __devinit +AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) +{ + int retry; + int n_error; - /* - * If the EEPROM 'termination' field is set to automatic (0), then set - * the ADV_DVC_CFG 'termination' field to automatic also. - * - * If the termination is specified with a non-zero 'termination' - * value check that a legal value is set and set the ADV_DVC_CFG - * 'termination' field appropriately. - */ - if (eep_config.termination_se == 0) { - termination = 0; /* auto termination for SE */ - } else { - /* Enable manual control with low off / high off. */ - if (eep_config.termination_se == 1) { - termination = 0; + retry = 0; + while (TRUE) { + if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf, + bus_type)) == 0) { + break; + } + if (++retry > ASC_EEP_MAX_RETRY) { + break; + } + } + return n_error; +} - /* Enable manual control with low off / high on. */ - } else if (eep_config.termination_se == 2) { - termination = TERM_SE_HI; +static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) +{ + ASCEEP_CONFIG eep_config_buf; + ASCEEP_CONFIG *eep_config; + PortAddr iop_base; + ushort chksum; + ushort warn_code; + ushort cfg_msw, cfg_lsw; + int i; + int write_eep = 0; - /* Enable manual control with low on / high on. */ - } else if (eep_config.termination_se == 3) { - termination = TERM_SE; + iop_base = asc_dvc->iop_base; + warn_code = 0; + AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); + AscStopQueueExe(iop_base); + if ((AscStopChip(iop_base) == FALSE) || + (AscGetChipScsiCtrl(iop_base) != 0)) { + asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; + AscResetChipAndScsiBus(asc_dvc); + mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ + } + if (AscIsChipHalted(iop_base) == FALSE) { + asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; + return (warn_code); + } + AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); + if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { + asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; + return (warn_code); + } + eep_config = (ASCEEP_CONFIG *)&eep_config_buf; + cfg_msw = AscGetChipCfgMsw(iop_base); + cfg_lsw = AscGetChipCfgLsw(iop_base); + if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { + cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; + warn_code |= ASC_WARN_CFG_MSW_RECOVER; + AscSetChipCfgMsw(iop_base, cfg_msw); + } + chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); + ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum); + if (chksum == 0) { + chksum = 0xaa55; + } + if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { + warn_code |= ASC_WARN_AUTO_CONFIG; + if (asc_dvc->cfg->chip_version == 3) { + if (eep_config->cfg_lsw != cfg_lsw) { + warn_code |= ASC_WARN_EEPROM_RECOVER; + eep_config->cfg_lsw = + AscGetChipCfgLsw(iop_base); + } + if (eep_config->cfg_msw != cfg_msw) { + warn_code |= ASC_WARN_EEPROM_RECOVER; + eep_config->cfg_msw = + AscGetChipCfgMsw(iop_base); + } + } + } + eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; + eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; + ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n", + eep_config->chksum); + if (chksum != eep_config->chksum) { + if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == + ASC_CHIP_VER_PCI_ULTRA_3050) { + ASC_DBG(1, + "AscInitFromEEP: chksum error ignored; EEPROM-less board\n"); + eep_config->init_sdtr = 0xFF; + eep_config->disc_enable = 0xFF; + eep_config->start_motor = 0xFF; + eep_config->use_cmd_qng = 0; + eep_config->max_total_qng = 0xF0; + eep_config->max_tag_qng = 0x20; + eep_config->cntl = 0xBFFF; + ASC_EEP_SET_CHIP_ID(eep_config, 7); + eep_config->no_scam = 0; + eep_config->adapter_info[0] = 0; + eep_config->adapter_info[1] = 0; + eep_config->adapter_info[2] = 0; + eep_config->adapter_info[3] = 0; + eep_config->adapter_info[4] = 0; + /* Indicate EEPROM-less board. */ + eep_config->adapter_info[5] = 0xBB; } else { - /* - * The EEPROM 'termination_se' field contains a bad value. - * Use automatic termination instead. - */ - termination = 0; - warn_code |= ASC_WARN_EEPROM_TERMINATION; + ASC_PRINT + ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n"); + write_eep = 1; + warn_code |= ASC_WARN_EEPROM_CHKSUM; + } + } + asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr; + asc_dvc->cfg->disc_enable = eep_config->disc_enable; + asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; + asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config); + asc_dvc->start_motor = eep_config->start_motor; + asc_dvc->dvc_cntl = eep_config->cntl; + asc_dvc->no_scam = eep_config->no_scam; + asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; + asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; + asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; + asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; + asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; + asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; + if (!AscTestExternalLram(asc_dvc)) { + if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == + ASC_IS_PCI_ULTRA)) { + eep_config->max_total_qng = + ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; + eep_config->max_tag_qng = + ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; + } else { + eep_config->cfg_msw |= 0x0800; + cfg_msw |= 0x0800; + AscSetChipCfgMsw(iop_base, cfg_msw); + eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; + eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; } + } else { + } + if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { + eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; + } + if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { + eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; + } + if (eep_config->max_tag_qng > eep_config->max_total_qng) { + eep_config->max_tag_qng = eep_config->max_total_qng; + } + if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { + eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; + } + asc_dvc->max_total_qng = eep_config->max_total_qng; + if ((eep_config->use_cmd_qng & eep_config->disc_enable) != + eep_config->use_cmd_qng) { + eep_config->disc_enable = eep_config->use_cmd_qng; + warn_code |= ASC_WARN_CMD_QNG_CONFLICT; + } + if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { + asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); + } + ASC_EEP_SET_CHIP_ID(eep_config, + ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); + asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); + if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && + !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { + asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; } - if (eep_config.termination_lvd == 0) { - asc_dvc->cfg->termination = termination; /* auto termination for LVD */ - } else { - /* Enable manual control with low off / high off. */ - if (eep_config.termination_lvd == 1) { - asc_dvc->cfg->termination = termination; - - /* Enable manual control with low off / high on. */ - } else if (eep_config.termination_lvd == 2) { - asc_dvc->cfg->termination = termination | TERM_LVD_HI; - - /* Enable manual control with low on / high on. */ - } else if (eep_config.termination_lvd == 3) { - asc_dvc->cfg->termination = termination | TERM_LVD; + for (i = 0; i <= ASC_MAX_TID; i++) { + asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; + asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; + asc_dvc->cfg->sdtr_period_offset[i] = + (uchar)(ASC_DEF_SDTR_OFFSET | + (asc_dvc->host_init_sdtr_index << 4)); + } + eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); + if (write_eep) { + if ((i = AscSetEEPConfig(iop_base, eep_config, + asc_dvc->bus_type)) != 0) { + ASC_PRINT1 + ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", + i); } else { - /* - * The EEPROM 'termination_lvd' field contains a bad value. - * Use automatic termination instead. - */ - asc_dvc->cfg->termination = termination; - warn_code |= ASC_WARN_EEPROM_TERMINATION; + ASC_PRINT + ("AscInitFromEEP: Successfully re-wrote EEPROM.\n"); } } - - return warn_code; + return (warn_code); } -/* - * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and - * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while - * all of this is done. - * - * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. - * - * For a non-fatal error return a warning code. If there are no warnings - * then 0 is returned. - * - * Note: Chip is stopped on entry. - */ -static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) +static int __devinit AscInitGetConfig(asc_board_t *boardp) { - AdvPortAddr iop_base; - ushort warn_code; - ADVEEP_38C1600_CONFIG eep_config; - uchar tid, termination; - ushort sdtr_speed = 0; + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + unsigned short warn_code = 0; - iop_base = asc_dvc->iop_base; + asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; + if (asc_dvc->err_code != 0) + return asc_dvc->err_code; - warn_code = 0; + if (AscFindSignature(asc_dvc->iop_base)) { + warn_code |= AscInitAscDvcVar(asc_dvc); + warn_code |= AscInitFromEEP(asc_dvc); + asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; + if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) + asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; + } else { + asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; + } - /* - * Read the board's EEPROM configuration. - * - * Set default values if a bad checksum is found. - */ - if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != - eep_config.check_sum) { - struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); - warn_code |= ASC_WARN_EEPROM_CHKSUM; + switch (warn_code) { + case 0: /* No error */ + break; + case ASC_WARN_IO_PORT_ROTATE: + ASC_PRINT1("AscInitGetConfig: board %d: I/O port address " + "modified\n", boardp->id); + break; + case ASC_WARN_AUTO_CONFIG: + ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment " + "switch enabled\n", boardp->id); + break; + case ASC_WARN_EEPROM_CHKSUM: + ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum " + "error\n", boardp->id); + break; + case ASC_WARN_IRQ_MODIFIED: + ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n", + boardp->id); + break; + case ASC_WARN_CMD_QNG_CONFLICT: + ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled " + "w/o disconnects\n", boardp->id); + break; + default: + ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: " + "0x%x\n", boardp->id, warn_code); + break; + } - /* - * Set EEPROM default values. - */ - memcpy(&eep_config, &Default_38C1600_EEPROM_Config, - sizeof(ADVEEP_38C1600_CONFIG)); + if (asc_dvc->err_code != 0) { + ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, " + "err_code 0x%x\n", boardp->id, asc_dvc->init_state, + asc_dvc->err_code); + } - if (PCI_FUNC(pdev->devfn) != 0) { - u8 ints; - /* - * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 - * and old Mac system booting problem. The Expansion - * ROM must be disabled in Function 1 for these systems - */ - eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE; - /* - * Clear the INTAB (bit 11) if the GPIO 0 input - * indicates the Function 1 interrupt line is wired - * to INTB. - * - * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: - * 1 - Function 1 interrupt line wired to INT A. - * 0 - Function 1 interrupt line wired to INT B. - * - * Note: Function 0 is always wired to INTA. - * Put all 5 GPIO bits in input mode and then read - * their input values. - */ - AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0); - ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA); - if ((ints & 0x01) == 0) - eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB; - } + return asc_dvc->err_code; +} - /* - * Assume the 6 byte board serial number that was read from - * EEPROM is correct even if the EEPROM checksum failed. - */ - eep_config.serial_number_word3 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); - eep_config.serial_number_word2 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); - eep_config.serial_number_word1 = - AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); +static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp) +{ + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + PortAddr iop_base = asc_dvc->iop_base; + unsigned short cfg_msw; + unsigned short warn_code = 0; - AdvSet38C1600EEPConfig(iop_base, &eep_config); + asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; + if (asc_dvc->err_code != 0) + return asc_dvc->err_code; + if (!AscFindSignature(asc_dvc->iop_base)) { + asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; + return asc_dvc->err_code; } - /* - * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the - * EEPROM configuration that was read. - * - * This is the mapping of EEPROM fields to Adv Library fields. - */ - asc_dvc->wdtr_able = eep_config.wdtr_able; - asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; - asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; - asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; - asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; - asc_dvc->ppr_able = 0; - asc_dvc->tagqng_able = eep_config.tagqng_able; - asc_dvc->cfg->disc_enable = eep_config.disc_enable; - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; - asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID); - asc_dvc->start_motor = eep_config.start_motor; - asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; - asc_dvc->bios_ctrl = eep_config.bios_ctrl; - asc_dvc->no_scam = eep_config.scam_tolerant; - - /* - * For every Target ID if any of its 'sdtr_speed[1234]' bits - * are set, then set an 'sdtr_able' bit for it. - */ - asc_dvc->sdtr_able = 0; - for (tid = 0; tid <= ASC_MAX_TID; tid++) { - if (tid == 0) { - sdtr_speed = asc_dvc->sdtr_speed1; - } else if (tid == 4) { - sdtr_speed = asc_dvc->sdtr_speed2; - } else if (tid == 8) { - sdtr_speed = asc_dvc->sdtr_speed3; - } else if (tid == 12) { - sdtr_speed = asc_dvc->sdtr_speed4; - } - if (sdtr_speed & ASC_MAX_TID) { - asc_dvc->sdtr_able |= (1 << tid); + cfg_msw = AscGetChipCfgMsw(iop_base); + if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { + cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; + warn_code |= ASC_WARN_CFG_MSW_RECOVER; + AscSetChipCfgMsw(iop_base, cfg_msw); + } + if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != + asc_dvc->cfg->cmd_qng_enabled) { + asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; + warn_code |= ASC_WARN_CMD_QNG_CONFLICT; + } + if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { + warn_code |= ASC_WARN_AUTO_CONFIG; + } + if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { + if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) + != asc_dvc->irq_no) { + asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; } - sdtr_speed >>= 4; } - - /* - * Set the host maximum queuing (max. 253, min. 16) and the per device - * maximum queuing (max. 63, min. 4). - */ - if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_host_qng == 0) { - eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; +#ifdef CONFIG_PCI + if (asc_dvc->bus_type & ASC_IS_PCI) { + cfg_msw &= 0xFFC0; + AscSetChipCfgMsw(iop_base, cfg_msw); + if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { } else { - eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || + (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { + asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; + asc_dvc->bug_fix_cntl |= + ASC_BUG_FIX_ASYN_USE_SYN; + } } - } - - if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; - } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { - /* If the value is zero, assume it is uninitialized. */ - if (eep_config.max_dvc_qng == 0) { - eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; - } else { - eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + } else +#endif /* CONFIG_PCI */ + if (asc_dvc->bus_type == ASC_IS_ISAPNP) { + if (AscGetChipVersion(iop_base, asc_dvc->bus_type) + == ASC_CHIP_VER_ASYN_BUG) { + asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; } } + if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != + asc_dvc->cfg->chip_scsi_id) { + asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; + } +#ifdef CONFIG_ISA + if (asc_dvc->bus_type & ASC_IS_ISA) { + AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); + AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); + } +#endif /* CONFIG_ISA */ - /* - * If 'max_dvc_qng' is greater than 'max_host_qng', then - * set 'max_dvc_qng' to 'max_host_qng'. - */ - if (eep_config.max_dvc_qng > eep_config.max_host_qng) { - eep_config.max_dvc_qng = eep_config.max_host_qng; + asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; + + switch (warn_code) { + case 0: /* No error. */ + break; + case ASC_WARN_IO_PORT_ROTATE: + ASC_PRINT1("AscInitSetConfig: board %d: I/O port address " + "modified\n", boardp->id); + break; + case ASC_WARN_AUTO_CONFIG: + ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment " + "switch enabled\n", boardp->id); + break; + case ASC_WARN_EEPROM_CHKSUM: + ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum " + "error\n", boardp->id); + break; + case ASC_WARN_IRQ_MODIFIED: + ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n", + boardp->id); + break; + case ASC_WARN_CMD_QNG_CONFLICT: + ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o " + "disconnects\n", + boardp->id); + break; + default: + ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: " + "0x%x\n", boardp->id, warn_code); + break; } - /* - * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng' - * values based on possibly adjusted EEPROM values. - */ - asc_dvc->max_host_qng = eep_config.max_host_qng; - asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; + if (asc_dvc->err_code != 0) { + ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, " + "err_code 0x%x\n", boardp->id, asc_dvc->init_state, + asc_dvc->err_code); + } - /* - * If the EEPROM 'termination' field is set to automatic (0), then set - * the ASC_DVC_CFG 'termination' field to automatic also. - * - * If the termination is specified with a non-zero 'termination' - * value check that a legal value is set and set the ASC_DVC_CFG - * 'termination' field appropriately. - */ - if (eep_config.termination_se == 0) { - termination = 0; /* auto termination for SE */ - } else { - /* Enable manual control with low off / high off. */ - if (eep_config.termination_se == 1) { - termination = 0; + return asc_dvc->err_code; +} - /* Enable manual control with low off / high on. */ - } else if (eep_config.termination_se == 2) { - termination = TERM_SE_HI; +/* + * EEPROM Configuration. + * + * All drivers should use this structure to set the default EEPROM + * configuration. The BIOS now uses this structure when it is built. + * Additional structure information can be found in a_condor.h where + * the structure is defined. + * + * The *_Field_IsChar structs are needed to correct for endianness. + * These values are read from the board 16 bits at a time directly + * into the structs. Because some fields are char, the values will be + * in the wrong order. The *_Field_IsChar tells when to flip the + * bytes. Data read and written to PCI memory is automatically swapped + * on big-endian platforms so char fields read as words are actually being + * unswapped on big-endian platforms. + */ +static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = { + ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ + 0x0000, /* cfg_msw */ + 0xFFFF, /* disc_enable */ + 0xFFFF, /* wdtr_able */ + 0xFFFF, /* sdtr_able */ + 0xFFFF, /* start_motor */ + 0xFFFF, /* tagqng_able */ + 0xFFFF, /* bios_scan */ + 0, /* scam_tolerant */ + 7, /* adapter_scsi_id */ + 0, /* bios_boot_delay */ + 3, /* scsi_reset_delay */ + 0, /* bios_id_lun */ + 0, /* termination */ + 0, /* reserved1 */ + 0xFFE7, /* bios_ctrl */ + 0xFFFF, /* ultra_able */ + 0, /* reserved2 */ + ASC_DEF_MAX_HOST_QNG, /* max_host_qng */ + ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ + 0, /* dvc_cntl */ + 0, /* bug_fix */ + 0, /* serial_number_word1 */ + 0, /* serial_number_word2 */ + 0, /* serial_number_word3 */ + 0, /* check_sum */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , /* oem_name[16] */ + 0, /* dvc_err_code */ + 0, /* adv_err_code */ + 0, /* adv_err_addr */ + 0, /* saved_dvc_err_code */ + 0, /* saved_adv_err_code */ + 0, /* saved_adv_err_addr */ + 0 /* num_of_err */ +}; - /* Enable manual control with low on / high on. */ - } else if (eep_config.termination_se == 3) { - termination = TERM_SE; - } else { - /* - * The EEPROM 'termination_se' field contains a bad value. - * Use automatic termination instead. - */ - termination = 0; - warn_code |= ASC_WARN_EEPROM_TERMINATION; - } - } +static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = { + 0, /* cfg_lsw */ + 0, /* cfg_msw */ + 0, /* -disc_enable */ + 0, /* wdtr_able */ + 0, /* sdtr_able */ + 0, /* start_motor */ + 0, /* tagqng_able */ + 0, /* bios_scan */ + 0, /* scam_tolerant */ + 1, /* adapter_scsi_id */ + 1, /* bios_boot_delay */ + 1, /* scsi_reset_delay */ + 1, /* bios_id_lun */ + 1, /* termination */ + 1, /* reserved1 */ + 0, /* bios_ctrl */ + 0, /* ultra_able */ + 0, /* reserved2 */ + 1, /* max_host_qng */ + 1, /* max_dvc_qng */ + 0, /* dvc_cntl */ + 0, /* bug_fix */ + 0, /* serial_number_word1 */ + 0, /* serial_number_word2 */ + 0, /* serial_number_word3 */ + 0, /* check_sum */ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + , /* oem_name[16] */ + 0, /* dvc_err_code */ + 0, /* adv_err_code */ + 0, /* adv_err_addr */ + 0, /* saved_dvc_err_code */ + 0, /* saved_adv_err_code */ + 0, /* saved_adv_err_addr */ + 0 /* num_of_err */ +}; - if (eep_config.termination_lvd == 0) { - asc_dvc->cfg->termination = termination; /* auto termination for LVD */ - } else { - /* Enable manual control with low off / high off. */ - if (eep_config.termination_lvd == 1) { - asc_dvc->cfg->termination = termination; +static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = { + ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ + 0x0000, /* 01 cfg_msw */ + 0xFFFF, /* 02 disc_enable */ + 0xFFFF, /* 03 wdtr_able */ + 0x4444, /* 04 sdtr_speed1 */ + 0xFFFF, /* 05 start_motor */ + 0xFFFF, /* 06 tagqng_able */ + 0xFFFF, /* 07 bios_scan */ + 0, /* 08 scam_tolerant */ + 7, /* 09 adapter_scsi_id */ + 0, /* bios_boot_delay */ + 3, /* 10 scsi_reset_delay */ + 0, /* bios_id_lun */ + 0, /* 11 termination_se */ + 0, /* termination_lvd */ + 0xFFE7, /* 12 bios_ctrl */ + 0x4444, /* 13 sdtr_speed2 */ + 0x4444, /* 14 sdtr_speed3 */ + ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ + ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ + 0, /* 16 dvc_cntl */ + 0x4444, /* 17 sdtr_speed4 */ + 0, /* 18 serial_number_word1 */ + 0, /* 19 serial_number_word2 */ + 0, /* 20 serial_number_word3 */ + 0, /* 21 check_sum */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , /* 22-29 oem_name[16] */ + 0, /* 30 dvc_err_code */ + 0, /* 31 adv_err_code */ + 0, /* 32 adv_err_addr */ + 0, /* 33 saved_dvc_err_code */ + 0, /* 34 saved_adv_err_code */ + 0, /* 35 saved_adv_err_addr */ + 0, /* 36 reserved */ + 0, /* 37 reserved */ + 0, /* 38 reserved */ + 0, /* 39 reserved */ + 0, /* 40 reserved */ + 0, /* 41 reserved */ + 0, /* 42 reserved */ + 0, /* 43 reserved */ + 0, /* 44 reserved */ + 0, /* 45 reserved */ + 0, /* 46 reserved */ + 0, /* 47 reserved */ + 0, /* 48 reserved */ + 0, /* 49 reserved */ + 0, /* 50 reserved */ + 0, /* 51 reserved */ + 0, /* 52 reserved */ + 0, /* 53 reserved */ + 0, /* 54 reserved */ + 0, /* 55 reserved */ + 0, /* 56 cisptr_lsw */ + 0, /* 57 cisprt_msw */ + PCI_VENDOR_ID_ASP, /* 58 subsysvid */ + PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */ + 0, /* 60 reserved */ + 0, /* 61 reserved */ + 0, /* 62 reserved */ + 0 /* 63 reserved */ +}; - /* Enable manual control with low off / high on. */ - } else if (eep_config.termination_lvd == 2) { - asc_dvc->cfg->termination = termination | TERM_LVD_HI; +static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = { + 0, /* 00 cfg_lsw */ + 0, /* 01 cfg_msw */ + 0, /* 02 disc_enable */ + 0, /* 03 wdtr_able */ + 0, /* 04 sdtr_speed1 */ + 0, /* 05 start_motor */ + 0, /* 06 tagqng_able */ + 0, /* 07 bios_scan */ + 0, /* 08 scam_tolerant */ + 1, /* 09 adapter_scsi_id */ + 1, /* bios_boot_delay */ + 1, /* 10 scsi_reset_delay */ + 1, /* bios_id_lun */ + 1, /* 11 termination_se */ + 1, /* termination_lvd */ + 0, /* 12 bios_ctrl */ + 0, /* 13 sdtr_speed2 */ + 0, /* 14 sdtr_speed3 */ + 1, /* 15 max_host_qng */ + 1, /* max_dvc_qng */ + 0, /* 16 dvc_cntl */ + 0, /* 17 sdtr_speed4 */ + 0, /* 18 serial_number_word1 */ + 0, /* 19 serial_number_word2 */ + 0, /* 20 serial_number_word3 */ + 0, /* 21 check_sum */ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + , /* 22-29 oem_name[16] */ + 0, /* 30 dvc_err_code */ + 0, /* 31 adv_err_code */ + 0, /* 32 adv_err_addr */ + 0, /* 33 saved_dvc_err_code */ + 0, /* 34 saved_adv_err_code */ + 0, /* 35 saved_adv_err_addr */ + 0, /* 36 reserved */ + 0, /* 37 reserved */ + 0, /* 38 reserved */ + 0, /* 39 reserved */ + 0, /* 40 reserved */ + 0, /* 41 reserved */ + 0, /* 42 reserved */ + 0, /* 43 reserved */ + 0, /* 44 reserved */ + 0, /* 45 reserved */ + 0, /* 46 reserved */ + 0, /* 47 reserved */ + 0, /* 48 reserved */ + 0, /* 49 reserved */ + 0, /* 50 reserved */ + 0, /* 51 reserved */ + 0, /* 52 reserved */ + 0, /* 53 reserved */ + 0, /* 54 reserved */ + 0, /* 55 reserved */ + 0, /* 56 cisptr_lsw */ + 0, /* 57 cisprt_msw */ + 0, /* 58 subsysvid */ + 0, /* 59 subsysid */ + 0, /* 60 reserved */ + 0, /* 61 reserved */ + 0, /* 62 reserved */ + 0 /* 63 reserved */ +}; - /* Enable manual control with low on / high on. */ - } else if (eep_config.termination_lvd == 3) { - asc_dvc->cfg->termination = termination | TERM_LVD; - } else { - /* - * The EEPROM 'termination_lvd' field contains a bad value. - * Use automatic termination instead. - */ - asc_dvc->cfg->termination = termination; - warn_code |= ASC_WARN_EEPROM_TERMINATION; - } - } +static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = { + ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ + 0x0000, /* 01 cfg_msw */ + 0xFFFF, /* 02 disc_enable */ + 0xFFFF, /* 03 wdtr_able */ + 0x5555, /* 04 sdtr_speed1 */ + 0xFFFF, /* 05 start_motor */ + 0xFFFF, /* 06 tagqng_able */ + 0xFFFF, /* 07 bios_scan */ + 0, /* 08 scam_tolerant */ + 7, /* 09 adapter_scsi_id */ + 0, /* bios_boot_delay */ + 3, /* 10 scsi_reset_delay */ + 0, /* bios_id_lun */ + 0, /* 11 termination_se */ + 0, /* termination_lvd */ + 0xFFE7, /* 12 bios_ctrl */ + 0x5555, /* 13 sdtr_speed2 */ + 0x5555, /* 14 sdtr_speed3 */ + ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ + ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ + 0, /* 16 dvc_cntl */ + 0x5555, /* 17 sdtr_speed4 */ + 0, /* 18 serial_number_word1 */ + 0, /* 19 serial_number_word2 */ + 0, /* 20 serial_number_word3 */ + 0, /* 21 check_sum */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + , /* 22-29 oem_name[16] */ + 0, /* 30 dvc_err_code */ + 0, /* 31 adv_err_code */ + 0, /* 32 adv_err_addr */ + 0, /* 33 saved_dvc_err_code */ + 0, /* 34 saved_adv_err_code */ + 0, /* 35 saved_adv_err_addr */ + 0, /* 36 reserved */ + 0, /* 37 reserved */ + 0, /* 38 reserved */ + 0, /* 39 reserved */ + 0, /* 40 reserved */ + 0, /* 41 reserved */ + 0, /* 42 reserved */ + 0, /* 43 reserved */ + 0, /* 44 reserved */ + 0, /* 45 reserved */ + 0, /* 46 reserved */ + 0, /* 47 reserved */ + 0, /* 48 reserved */ + 0, /* 49 reserved */ + 0, /* 50 reserved */ + 0, /* 51 reserved */ + 0, /* 52 reserved */ + 0, /* 53 reserved */ + 0, /* 54 reserved */ + 0, /* 55 reserved */ + 0, /* 56 cisptr_lsw */ + 0, /* 57 cisprt_msw */ + PCI_VENDOR_ID_ASP, /* 58 subsysvid */ + PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */ + 0, /* 60 reserved */ + 0, /* 61 reserved */ + 0, /* 62 reserved */ + 0 /* 63 reserved */ +}; - return warn_code; -} +static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = { + 0, /* 00 cfg_lsw */ + 0, /* 01 cfg_msw */ + 0, /* 02 disc_enable */ + 0, /* 03 wdtr_able */ + 0, /* 04 sdtr_speed1 */ + 0, /* 05 start_motor */ + 0, /* 06 tagqng_able */ + 0, /* 07 bios_scan */ + 0, /* 08 scam_tolerant */ + 1, /* 09 adapter_scsi_id */ + 1, /* bios_boot_delay */ + 1, /* 10 scsi_reset_delay */ + 1, /* bios_id_lun */ + 1, /* 11 termination_se */ + 1, /* termination_lvd */ + 0, /* 12 bios_ctrl */ + 0, /* 13 sdtr_speed2 */ + 0, /* 14 sdtr_speed3 */ + 1, /* 15 max_host_qng */ + 1, /* max_dvc_qng */ + 0, /* 16 dvc_cntl */ + 0, /* 17 sdtr_speed4 */ + 0, /* 18 serial_number_word1 */ + 0, /* 19 serial_number_word2 */ + 0, /* 20 serial_number_word3 */ + 0, /* 21 check_sum */ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + , /* 22-29 oem_name[16] */ + 0, /* 30 dvc_err_code */ + 0, /* 31 adv_err_code */ + 0, /* 32 adv_err_addr */ + 0, /* 33 saved_dvc_err_code */ + 0, /* 34 saved_adv_err_code */ + 0, /* 35 saved_adv_err_addr */ + 0, /* 36 reserved */ + 0, /* 37 reserved */ + 0, /* 38 reserved */ + 0, /* 39 reserved */ + 0, /* 40 reserved */ + 0, /* 41 reserved */ + 0, /* 42 reserved */ + 0, /* 43 reserved */ + 0, /* 44 reserved */ + 0, /* 45 reserved */ + 0, /* 46 reserved */ + 0, /* 47 reserved */ + 0, /* 48 reserved */ + 0, /* 49 reserved */ + 0, /* 50 reserved */ + 0, /* 51 reserved */ + 0, /* 52 reserved */ + 0, /* 53 reserved */ + 0, /* 54 reserved */ + 0, /* 55 reserved */ + 0, /* 56 cisptr_lsw */ + 0, /* 57 cisprt_msw */ + 0, /* 58 subsysvid */ + 0, /* 59 subsysid */ + 0, /* 60 reserved */ + 0, /* 61 reserved */ + 0, /* 62 reserved */ + 0 /* 63 reserved */ +}; +#ifdef CONFIG_PCI /* - * Read EEPROM configuration into the specified buffer. - * - * Return a checksum based on the EEPROM configuration read. + * Wait for EEPROM command to complete */ -static ushort __devinit -AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) +static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base) { - ushort wval, chksum; - ushort *wbuf; - int eep_addr; - ushort *charfields; - - charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; - wbuf = (ushort *)cfg_buf; - chksum = 0; - - for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; - eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { - wval = AdvReadEEPWord(iop_base, eep_addr); - chksum += wval; /* Checksum is calculated from word values. */ - if (*charfields++) { - *wbuf = le16_to_cpu(wval); - } else { - *wbuf = wval; - } - } - /* Read checksum word. */ - *wbuf = AdvReadEEPWord(iop_base, eep_addr); - wbuf++; - charfields++; + int eep_delay_ms; - /* Read rest of EEPROM not covered by the checksum. */ - for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; - eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { - *wbuf = AdvReadEEPWord(iop_base, eep_addr); - if (*charfields++) { - *wbuf = le16_to_cpu(*wbuf); + for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) { + if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & + ASC_EEP_CMD_DONE) { + break; } + mdelay(1); } - return chksum; + if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == + 0) + BUG(); } /* - * Read EEPROM configuration into the specified buffer. - * - * Return a checksum based on the EEPROM configuration read. + * Read the EEPROM from specified location */ -static ushort __devinit -AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) +static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) +{ + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, + ASC_EEP_CMD_READ | eep_word_addr); + AdvWaitEEPCmd(iop_base); + return AdvReadWordRegister(iop_base, IOPW_EE_DATA); +} + +/* + * Write the EEPROM from 'cfg_buf'. + */ +void __devinit +AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { - ushort wval, chksum; ushort *wbuf; - int eep_addr; + ushort addr, chksum; ushort *charfields; - charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; wbuf = (ushort *)cfg_buf; + charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; chksum = 0; - for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; - eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { - wval = AdvReadEEPWord(iop_base, eep_addr); - chksum += wval; /* Checksum is calculated from word values. */ + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); + AdvWaitEEPCmd(iop_base); + + /* + * Write EEPROM from word 0 to word 20. + */ + for (addr = ADV_EEP_DVC_CFG_BEGIN; + addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { + ushort word; + if (*charfields++) { - *wbuf = le16_to_cpu(wval); + word = cpu_to_le16(*wbuf); } else { - *wbuf = wval; + word = *wbuf; } + chksum += *wbuf; /* Checksum is calculated from word values. */ + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); + mdelay(ADV_EEP_DELAY_MS); } - /* Read checksum word. */ - *wbuf = AdvReadEEPWord(iop_base, eep_addr); + + /* + * Write EEPROM checksum at word 21. + */ + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); wbuf++; charfields++; - /* Read rest of EEPROM not covered by the checksum. */ - for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; - eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { - *wbuf = AdvReadEEPWord(iop_base, eep_addr); + /* + * Write EEPROM OEM name at words 22 to 29. + */ + for (addr = ADV_EEP_DVC_CTL_BEGIN; + addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { + ushort word; + if (*charfields++) { - *wbuf = le16_to_cpu(*wbuf); + word = cpu_to_le16(*wbuf); + } else { + word = *wbuf; } + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); } - return chksum; + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); + AdvWaitEEPCmd(iop_base); } /* - * Read EEPROM configuration into the specified buffer. - * - * Return a checksum based on the EEPROM configuration read. + * Write the EEPROM from 'cfg_buf'. */ -static ushort __devinit -AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) +void __devinit +AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) { - ushort wval, chksum; ushort *wbuf; - int eep_addr; ushort *charfields; + ushort addr, chksum; - charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; wbuf = (ushort *)cfg_buf; + charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; chksum = 0; - for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; - eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { - wval = AdvReadEEPWord(iop_base, eep_addr); - chksum += wval; /* Checksum is calculated from word values. */ + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); + AdvWaitEEPCmd(iop_base); + + /* + * Write EEPROM from word 0 to word 20. + */ + for (addr = ADV_EEP_DVC_CFG_BEGIN; + addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { + ushort word; + if (*charfields++) { - *wbuf = le16_to_cpu(wval); + word = cpu_to_le16(*wbuf); } else { - *wbuf = wval; + word = *wbuf; } + chksum += *wbuf; /* Checksum is calculated from word values. */ + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); + mdelay(ADV_EEP_DELAY_MS); } - /* Read checksum word. */ - *wbuf = AdvReadEEPWord(iop_base, eep_addr); + + /* + * Write EEPROM checksum at word 21. + */ + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); wbuf++; charfields++; - /* Read rest of EEPROM not covered by the checksum. */ - for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; - eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { - *wbuf = AdvReadEEPWord(iop_base, eep_addr); + /* + * Write EEPROM OEM name at words 22 to 29. + */ + for (addr = ADV_EEP_DVC_CTL_BEGIN; + addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { + ushort word; + if (*charfields++) { - *wbuf = le16_to_cpu(*wbuf); + word = cpu_to_le16(*wbuf); + } else { + word = *wbuf; } + AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iop_base); } - return chksum; -} - -/* - * Read the EEPROM from specified location - */ -static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) -{ - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, - ASC_EEP_CMD_READ | eep_word_addr); + AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); AdvWaitEEPCmd(iop_base); - return AdvReadWordRegister(iop_base, IOPW_EE_DATA); -} - -/* - * Wait for EEPROM command to complete - */ -static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base) -{ - int eep_delay_ms; - - for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) { - if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & - ASC_EEP_CMD_DONE) { - break; - } - mdelay(1); - } - if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == - 0) - BUG(); - return; } /* * Write the EEPROM from 'cfg_buf'. */ void __devinit -AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) +AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { ushort *wbuf; - ushort addr, chksum; ushort *charfields; + ushort addr, chksum; wbuf = (ushort *)cfg_buf; - charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; + charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; chksum = 0; AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); @@ -13458,610 +13052,829 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) } AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); AdvWaitEEPCmd(iop_base); - return; } /* - * Write the EEPROM from 'cfg_buf'. + * Read EEPROM configuration into the specified buffer. + * + * Return a checksum based on the EEPROM configuration read. */ -void __devinit -AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) +static ushort __devinit +AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { + ushort wval, chksum; ushort *wbuf; + int eep_addr; ushort *charfields; - ushort addr, chksum; + charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; wbuf = (ushort *)cfg_buf; - charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; chksum = 0; - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); - AdvWaitEEPCmd(iop_base); + for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; + eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { + wval = AdvReadEEPWord(iop_base, eep_addr); + chksum += wval; /* Checksum is calculated from word values. */ + if (*charfields++) { + *wbuf = le16_to_cpu(wval); + } else { + *wbuf = wval; + } + } + /* Read checksum word. */ + *wbuf = AdvReadEEPWord(iop_base, eep_addr); + wbuf++; + charfields++; - /* - * Write EEPROM from word 0 to word 20. - */ - for (addr = ADV_EEP_DVC_CFG_BEGIN; - addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { - ushort word; + /* Read rest of EEPROM not covered by the checksum. */ + for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; + eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { + *wbuf = AdvReadEEPWord(iop_base, eep_addr); + if (*charfields++) { + *wbuf = le16_to_cpu(*wbuf); + } + } + return chksum; +} + +/* + * Read EEPROM configuration into the specified buffer. + * + * Return a checksum based on the EEPROM configuration read. + */ +static ushort __devinit +AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) +{ + ushort wval, chksum; + ushort *wbuf; + int eep_addr; + ushort *charfields; + charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; + wbuf = (ushort *)cfg_buf; + chksum = 0; + + for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; + eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { + wval = AdvReadEEPWord(iop_base, eep_addr); + chksum += wval; /* Checksum is calculated from word values. */ if (*charfields++) { - word = cpu_to_le16(*wbuf); + *wbuf = le16_to_cpu(wval); } else { - word = *wbuf; + *wbuf = wval; } - chksum += *wbuf; /* Checksum is calculated from word values. */ - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); - mdelay(ADV_EEP_DELAY_MS); } - - /* - * Write EEPROM checksum at word 21. - */ - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); + /* Read checksum word. */ + *wbuf = AdvReadEEPWord(iop_base, eep_addr); wbuf++; charfields++; - /* - * Write EEPROM OEM name at words 22 to 29. - */ - for (addr = ADV_EEP_DVC_CTL_BEGIN; - addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { - ushort word; - + /* Read rest of EEPROM not covered by the checksum. */ + for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; + eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { + *wbuf = AdvReadEEPWord(iop_base, eep_addr); if (*charfields++) { - word = cpu_to_le16(*wbuf); - } else { - word = *wbuf; + *wbuf = le16_to_cpu(*wbuf); } - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); } - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); - AdvWaitEEPCmd(iop_base); - return; + return chksum; } /* - * Write the EEPROM from 'cfg_buf'. + * Read EEPROM configuration into the specified buffer. + * + * Return a checksum based on the EEPROM configuration read. */ -void __devinit -AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) +static ushort __devinit +AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { + ushort wval, chksum; ushort *wbuf; + int eep_addr; ushort *charfields; - ushort addr, chksum; - wbuf = (ushort *)cfg_buf; charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; + wbuf = (ushort *)cfg_buf; chksum = 0; - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); - AdvWaitEEPCmd(iop_base); - - /* - * Write EEPROM from word 0 to word 20. - */ - for (addr = ADV_EEP_DVC_CFG_BEGIN; - addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { - ushort word; - + for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; + eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { + wval = AdvReadEEPWord(iop_base, eep_addr); + chksum += wval; /* Checksum is calculated from word values. */ if (*charfields++) { - word = cpu_to_le16(*wbuf); + *wbuf = le16_to_cpu(wval); } else { - word = *wbuf; + *wbuf = wval; } - chksum += *wbuf; /* Checksum is calculated from word values. */ - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); - mdelay(ADV_EEP_DELAY_MS); } - - /* - * Write EEPROM checksum at word 21. - */ - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); + /* Read checksum word. */ + *wbuf = AdvReadEEPWord(iop_base, eep_addr); wbuf++; charfields++; - /* - * Write EEPROM OEM name at words 22 to 29. - */ - for (addr = ADV_EEP_DVC_CTL_BEGIN; - addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { - ushort word; - + /* Read rest of EEPROM not covered by the checksum. */ + for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; + eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { + *wbuf = AdvReadEEPWord(iop_base, eep_addr); if (*charfields++) { - word = cpu_to_le16(*wbuf); - } else { - word = *wbuf; + *wbuf = le16_to_cpu(*wbuf); } - AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE | addr); - AdvWaitEEPCmd(iop_base); } - AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); - AdvWaitEEPCmd(iop_base); - return; + return chksum; } /* - * AdvExeScsiQueue() - Send a request to the RISC microcode program. - * - * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q, - * add the carrier to the ICQ (Initiator Command Queue), and tickle the - * RISC to notify it a new command is ready to be executed. + * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and + * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while + * all of this is done. * - * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be - * set to SCSI_MAX_RETRY. + * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. * - * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode - * for DMA addresses or math operations are byte swapped to little-endian - * order. + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. * - * Return: - * ADV_SUCCESS(1) - The request was successfully queued. - * ADV_BUSY(0) - Resource unavailable; Retry again after pending - * request completes. - * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure - * host IC error. + * Note: Chip is stopped on entry. */ -static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) +static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; - ADV_DCNT req_size; - ADV_PADDR req_paddr; - ADV_CARR_T *new_carrp; - - /* - * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. - */ - if (scsiq->target_id > ADV_MAX_TID) { - scsiq->host_status = QHSTA_M_INVALID_DEVICE; - scsiq->done_status = QD_WITH_ERROR; - return ADV_ERROR; - } + ushort warn_code; + ADVEEP_3550_CONFIG eep_config; iop_base = asc_dvc->iop_base; - /* - * Allocate a carrier ensuring at least one carrier always - * remains on the freelist and initialize fields. - */ - if ((new_carrp = asc_dvc->carr_freelist) == NULL) { - return ADV_BUSY; - } - asc_dvc->carr_freelist = (ADV_CARR_T *) - ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa)); - asc_dvc->carr_pending_cnt++; + warn_code = 0; /* - * Set the carrier to be a stopper by setting 'next_vpa' - * to the stopper value. The current stopper will be changed - * below to point to the new stopper. + * Read the board's EEPROM configuration. + * + * Set default values if a bad checksum is found. */ - new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); + if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) { + warn_code |= ASC_WARN_EEPROM_CHKSUM; - /* - * Clear the ADV_SCSI_REQ_Q done flag. - */ - scsiq->a_flag &= ~ADV_SCSIQ_DONE; + /* + * Set EEPROM default values. + */ + memcpy(&eep_config, &Default_3550_EEPROM_Config, + sizeof(ADVEEP_3550_CONFIG)); - req_size = sizeof(ADV_SCSI_REQ_Q); - req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq, - (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG); + /* + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. + */ + eep_config.serial_number_word3 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); - BUG_ON(req_paddr & 31); - BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q)); + eep_config.serial_number_word2 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); - /* Wait for assertion before making little-endian */ - req_paddr = cpu_to_le32(req_paddr); + eep_config.serial_number_word1 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); - /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */ - scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq)); - scsiq->scsiq_rptr = req_paddr; + AdvSet3550EEPConfig(iop_base, &eep_config); + } + /* + * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the + * EEPROM configuration that was read. + * + * This is the mapping of EEPROM fields to Adv Library fields. + */ + asc_dvc->wdtr_able = eep_config.wdtr_able; + asc_dvc->sdtr_able = eep_config.sdtr_able; + asc_dvc->ultra_able = eep_config.ultra_able; + asc_dvc->tagqng_able = eep_config.tagqng_able; + asc_dvc->cfg->disc_enable = eep_config.disc_enable; + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; + asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); + asc_dvc->start_motor = eep_config.start_motor; + asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; + asc_dvc->bios_ctrl = eep_config.bios_ctrl; + asc_dvc->no_scam = eep_config.scam_tolerant; + asc_dvc->cfg->serial1 = eep_config.serial_number_word1; + asc_dvc->cfg->serial2 = eep_config.serial_number_word2; + asc_dvc->cfg->serial3 = eep_config.serial_number_word3; - scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp)); /* - * Every ADV_CARR_T.carr_pa is byte swapped to little-endian - * order during initialization. + * Set the host maximum queuing (max. 253, min. 16) and the per device + * maximum queuing (max. 63, min. 4). */ - scsiq->carr_pa = asc_dvc->icq_sp->carr_pa; + if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_host_qng == 0) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else { + eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + } + } + + if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_dvc_qng == 0) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else { + eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + } + } /* - * Use the current stopper to send the ADV_SCSI_REQ_Q command to - * the microcode. The newly allocated stopper will become the new - * stopper. + * If 'max_dvc_qng' is greater than 'max_host_qng', then + * set 'max_dvc_qng' to 'max_host_qng'. */ - asc_dvc->icq_sp->areq_vpa = req_paddr; + if (eep_config.max_dvc_qng > eep_config.max_host_qng) { + eep_config.max_dvc_qng = eep_config.max_host_qng; + } /* - * Set the 'next_vpa' pointer for the old stopper to be the - * physical address of the new stopper. The RISC can only - * follow physical addresses. + * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' + * values based on possibly adjusted EEPROM values. */ - asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa; + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; /* - * Set the host adapter stopper pointer to point to the new carrier. + * If the EEPROM 'termination' field is set to automatic (0), then set + * the ADV_DVC_CFG 'termination' field to automatic also. + * + * If the termination is specified with a non-zero 'termination' + * value check that a legal value is set and set the ADV_DVC_CFG + * 'termination' field appropriately. */ - asc_dvc->icq_sp = new_carrp; + if (eep_config.termination == 0) { + asc_dvc->cfg->termination = 0; /* auto termination */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination == 1) { + asc_dvc->cfg->termination = TERM_CTL_SEL; - if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || - asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { - /* - * Tickle the RISC to tell it to read its Command Queue Head pointer. - */ - AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); - if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination == 2) { + asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H; + + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination == 3) { + asc_dvc->cfg->termination = + TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L; + } else { /* - * Clear the tickle value. In the ASC-3550 the RISC flag - * command 'clr_tickle_a' does not work unless the host - * value is cleared. + * The EEPROM 'termination' field contains a bad value. Use + * automatic termination instead. */ - AdvWriteByteRegister(iop_base, IOPB_TICKLE, - ADV_TICKLE_NOP); + asc_dvc->cfg->termination = 0; + warn_code |= ASC_WARN_EEPROM_TERMINATION; } - } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - /* - * Notify the RISC a carrier is ready by writing the physical - * address of the new carrier stopper to the COMMA register. - */ - AdvWriteDWordRegister(iop_base, IOPDW_COMMA, - le32_to_cpu(new_carrp->carr_pa)); } - return ADV_SUCCESS; + return warn_code; } /* - * Reset SCSI Bus and purge all outstanding requests. + * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and + * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while + * all of this is done. * - * Return Value: - * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. - * ADV_FALSE(0) - Microcode command failed. - * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC - * may be hung which requires driver recovery. + * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + * + * Note: Chip is stopped on entry. */ -static int AdvResetSB(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) { - int status; + AdvPortAddr iop_base; + ushort warn_code; + ADVEEP_38C0800_CONFIG eep_config; + uchar tid, termination; + ushort sdtr_speed = 0; - /* - * Send the SCSI Bus Reset idle start idle command which asserts - * the SCSI Bus Reset signal. - */ - status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L); - if (status != ADV_TRUE) { - return status; - } + iop_base = asc_dvc->iop_base; - /* - * Delay for the specified SCSI Bus Reset hold time. - * - * The hold time delay is done on the host because the RISC has no - * microsecond accurate timer. - */ - udelay(ASC_SCSI_RESET_HOLD_TIME_US); + warn_code = 0; /* - * Send the SCSI Bus Reset end idle command which de-asserts - * the SCSI Bus Reset signal and purges any pending requests. + * Read the board's EEPROM configuration. + * + * Set default values if a bad checksum is found. */ - status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L); - if (status != ADV_TRUE) { - return status; - } + if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != + eep_config.check_sum) { + warn_code |= ASC_WARN_EEPROM_CHKSUM; - mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ + /* + * Set EEPROM default values. + */ + memcpy(&eep_config, &Default_38C0800_EEPROM_Config, + sizeof(ADVEEP_38C0800_CONFIG)); - return status; -} + /* + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. + */ + eep_config.serial_number_word3 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); -/* - * Reset chip and SCSI Bus. - * - * Return Value: - * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. - * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. - */ -static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) -{ - int status; - ushort wdtr_able, sdtr_able, tagqng_able; - ushort ppr_able = 0; - uchar tid, max_cmd[ADV_MAX_TID + 1]; - AdvPortAddr iop_base; - ushort bios_sig; + eep_config.serial_number_word2 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); - iop_base = asc_dvc->iop_base; + eep_config.serial_number_word1 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); - /* - * Save current per TID negotiated values. - */ - AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); - } - AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); + AdvSet38C0800EEPConfig(iop_base, &eep_config); } - /* - * Force the AdvInitAsc3550/38C0800Driver() function to - * perform a SCSI Bus Reset by clearing the BIOS signature word. - * The initialization functions assumes a SCSI Bus Reset is not - * needed if the BIOS signature word is present. + * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the + * EEPROM configuration that was read. + * + * This is the mapping of EEPROM fields to Adv Library fields. */ - AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); - AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0); + asc_dvc->wdtr_able = eep_config.wdtr_able; + asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; + asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; + asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; + asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; + asc_dvc->tagqng_able = eep_config.tagqng_able; + asc_dvc->cfg->disc_enable = eep_config.disc_enable; + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; + asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID); + asc_dvc->start_motor = eep_config.start_motor; + asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; + asc_dvc->bios_ctrl = eep_config.bios_ctrl; + asc_dvc->no_scam = eep_config.scam_tolerant; + asc_dvc->cfg->serial1 = eep_config.serial_number_word1; + asc_dvc->cfg->serial2 = eep_config.serial_number_word2; + asc_dvc->cfg->serial3 = eep_config.serial_number_word3; /* - * Stop chip and reset it. + * For every Target ID if any of its 'sdtr_speed[1234]' bits + * are set, then set an 'sdtr_able' bit for it. */ - AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); - AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); - mdelay(100); - AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, - ADV_CTRL_REG_CMD_WR_IO_REG); + asc_dvc->sdtr_able = 0; + for (tid = 0; tid <= ADV_MAX_TID; tid++) { + if (tid == 0) { + sdtr_speed = asc_dvc->sdtr_speed1; + } else if (tid == 4) { + sdtr_speed = asc_dvc->sdtr_speed2; + } else if (tid == 8) { + sdtr_speed = asc_dvc->sdtr_speed3; + } else if (tid == 12) { + sdtr_speed = asc_dvc->sdtr_speed4; + } + if (sdtr_speed & ADV_MAX_TID) { + asc_dvc->sdtr_able |= (1 << tid); + } + sdtr_speed >>= 4; + } /* - * Reset Adv Library error code, if any, and try - * re-initializing the chip. + * Set the host maximum queuing (max. 253, min. 16) and the per device + * maximum queuing (max. 63, min. 4). */ - asc_dvc->err_code = 0; - if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - status = AdvInitAsc38C1600Driver(asc_dvc); - } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { - status = AdvInitAsc38C0800Driver(asc_dvc); - } else { - status = AdvInitAsc3550Driver(asc_dvc); + if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_host_qng == 0) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else { + eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + } } - /* Translate initialization return value to status value. */ - if (status == 0) { - status = ADV_TRUE; - } else { - status = ADV_FALSE; + if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_dvc_qng == 0) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else { + eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + } + } + + /* + * If 'max_dvc_qng' is greater than 'max_host_qng', then + * set 'max_dvc_qng' to 'max_host_qng'. + */ + if (eep_config.max_dvc_qng > eep_config.max_host_qng) { + eep_config.max_dvc_qng = eep_config.max_host_qng; } /* - * Restore the BIOS signature word. + * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' + * values based on possibly adjusted EEPROM values. */ - AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; /* - * Restore per TID negotiated values. + * If the EEPROM 'termination' field is set to automatic (0), then set + * the ADV_DVC_CFG 'termination' field to automatic also. + * + * If the termination is specified with a non-zero 'termination' + * value check that a legal value is set and set the ADV_DVC_CFG + * 'termination' field appropriately. */ - AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); - AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); - if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { - AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); + if (eep_config.termination_se == 0) { + termination = 0; /* auto termination for SE */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_se == 1) { + termination = 0; + + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_se == 2) { + termination = TERM_SE_HI; + + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_se == 3) { + termination = TERM_SE; + } else { + /* + * The EEPROM 'termination_se' field contains a bad value. + * Use automatic termination instead. + */ + termination = 0; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } } - AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); - for (tid = 0; tid <= ADV_MAX_TID; tid++) { - AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, - max_cmd[tid]); + + if (eep_config.termination_lvd == 0) { + asc_dvc->cfg->termination = termination; /* auto termination for LVD */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_lvd == 1) { + asc_dvc->cfg->termination = termination; + + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_lvd == 2) { + asc_dvc->cfg->termination = termination | TERM_LVD_HI; + + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_lvd == 3) { + asc_dvc->cfg->termination = termination | TERM_LVD; + } else { + /* + * The EEPROM 'termination_lvd' field contains a bad value. + * Use automatic termination instead. + */ + asc_dvc->cfg->termination = termination; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } } - return status; + return warn_code; } /* - * Adv Library Interrupt Service Routine - * - * This function is called by a driver's interrupt service routine. - * The function disables and re-enables interrupts. + * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and + * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while + * all of this is done. * - * When a microcode idle command is completed, the ADV_DVC_VAR - * 'idle_cmd_done' field is set to ADV_TRUE. + * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. * - * Note: AdvISR() can be called when interrupts are disabled or even - * when there is no hardware interrupt condition present. It will - * always check for completed idle commands and microcode requests. - * This is an important feature that shouldn't be changed because it - * allows commands to be completed from polling mode loops. + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. * - * Return: - * ADV_TRUE(1) - interrupt was pending - * ADV_FALSE(0) - no interrupt was pending + * Note: Chip is stopped on entry. */ -static int AdvISR(ADV_DVC_VAR *asc_dvc) +static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; - uchar int_stat; - ushort target_bit; - ADV_CARR_T *free_carrp; - ADV_VADDR irq_next_vpa; - ADV_SCSI_REQ_Q *scsiq; + ushort warn_code; + ADVEEP_38C1600_CONFIG eep_config; + uchar tid, termination; + ushort sdtr_speed = 0; iop_base = asc_dvc->iop_base; - /* Reading the register clears the interrupt. */ - int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); + warn_code = 0; - if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | - ADV_INTR_STATUS_INTRC)) == 0) { - return ADV_FALSE; + /* + * Read the board's EEPROM configuration. + * + * Set default values if a bad checksum is found. + */ + if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != + eep_config.check_sum) { + struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); + warn_code |= ASC_WARN_EEPROM_CHKSUM; + + /* + * Set EEPROM default values. + */ + memcpy(&eep_config, &Default_38C1600_EEPROM_Config, + sizeof(ADVEEP_38C1600_CONFIG)); + + if (PCI_FUNC(pdev->devfn) != 0) { + u8 ints; + /* + * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 + * and old Mac system booting problem. The Expansion + * ROM must be disabled in Function 1 for these systems + */ + eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE; + /* + * Clear the INTAB (bit 11) if the GPIO 0 input + * indicates the Function 1 interrupt line is wired + * to INTB. + * + * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: + * 1 - Function 1 interrupt line wired to INT A. + * 0 - Function 1 interrupt line wired to INT B. + * + * Note: Function 0 is always wired to INTA. + * Put all 5 GPIO bits in input mode and then read + * their input values. + */ + AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0); + ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA); + if ((ints & 0x01) == 0) + eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB; + } + + /* + * Assume the 6 byte board serial number that was read from + * EEPROM is correct even if the EEPROM checksum failed. + */ + eep_config.serial_number_word3 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); + eep_config.serial_number_word2 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); + eep_config.serial_number_word1 = + AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); + + AdvSet38C1600EEPConfig(iop_base, &eep_config); } /* - * Notify the driver of an asynchronous microcode condition by - * calling the adv_async_callback function. The function - * is passed the microcode ASC_MC_INTRB_CODE byte value. + * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the + * EEPROM configuration that was read. + * + * This is the mapping of EEPROM fields to Adv Library fields. */ - if (int_stat & ADV_INTR_STATUS_INTRB) { - uchar intrb_code; + asc_dvc->wdtr_able = eep_config.wdtr_able; + asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1; + asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2; + asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3; + asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4; + asc_dvc->ppr_able = 0; + asc_dvc->tagqng_able = eep_config.tagqng_able; + asc_dvc->cfg->disc_enable = eep_config.disc_enable; + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; + asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID); + asc_dvc->start_motor = eep_config.start_motor; + asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay; + asc_dvc->bios_ctrl = eep_config.bios_ctrl; + asc_dvc->no_scam = eep_config.scam_tolerant; - AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code); + /* + * For every Target ID if any of its 'sdtr_speed[1234]' bits + * are set, then set an 'sdtr_able' bit for it. + */ + asc_dvc->sdtr_able = 0; + for (tid = 0; tid <= ASC_MAX_TID; tid++) { + if (tid == 0) { + sdtr_speed = asc_dvc->sdtr_speed1; + } else if (tid == 4) { + sdtr_speed = asc_dvc->sdtr_speed2; + } else if (tid == 8) { + sdtr_speed = asc_dvc->sdtr_speed3; + } else if (tid == 12) { + sdtr_speed = asc_dvc->sdtr_speed4; + } + if (sdtr_speed & ASC_MAX_TID) { + asc_dvc->sdtr_able |= (1 << tid); + } + sdtr_speed >>= 4; + } - if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || - asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { - if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && - asc_dvc->carr_pending_cnt != 0) { - AdvWriteByteRegister(iop_base, IOPB_TICKLE, - ADV_TICKLE_A); - if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { - AdvWriteByteRegister(iop_base, - IOPB_TICKLE, - ADV_TICKLE_NOP); - } - } + /* + * Set the host maximum queuing (max. 253, min. 16) and the per device + * maximum queuing (max. 63, min. 4). + */ + if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_host_qng == 0) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else { + eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; } + } - adv_async_callback(asc_dvc, intrb_code); + if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_dvc_qng == 0) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else { + eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + } + } + + /* + * If 'max_dvc_qng' is greater than 'max_host_qng', then + * set 'max_dvc_qng' to 'max_host_qng'. + */ + if (eep_config.max_dvc_qng > eep_config.max_host_qng) { + eep_config.max_dvc_qng = eep_config.max_host_qng; } /* - * Check if the IRQ stopper carrier contains a completed request. + * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng' + * values based on possibly adjusted EEPROM values. + */ + asc_dvc->max_host_qng = eep_config.max_host_qng; + asc_dvc->max_dvc_qng = eep_config.max_dvc_qng; + + /* + * If the EEPROM 'termination' field is set to automatic (0), then set + * the ASC_DVC_CFG 'termination' field to automatic also. + * + * If the termination is specified with a non-zero 'termination' + * value check that a legal value is set and set the ASC_DVC_CFG + * 'termination' field appropriately. */ - while (((irq_next_vpa = - le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) { - /* - * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure. - * The RISC will have set 'areq_vpa' to a virtual address. - * - * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr - * field to the carrier ADV_CARR_T.areq_vpa field. The conversion - * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' - * in AdvExeScsiQueue(). - */ - scsiq = (ADV_SCSI_REQ_Q *) - ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa)); - - /* - * Request finished with good status and the queue was not - * DMAed to host memory by the firmware. Set all status fields - * to indicate good status. - */ - if ((irq_next_vpa & ASC_RQ_GOOD) != 0) { - scsiq->done_status = QD_NO_ERROR; - scsiq->host_status = scsiq->scsi_status = 0; - scsiq->data_cnt = 0L; - } + if (eep_config.termination_se == 0) { + termination = 0; /* auto termination for SE */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_se == 1) { + termination = 0; - /* - * Advance the stopper pointer to the next carrier - * ignoring the lower four bits. Free the previous - * stopper carrier. - */ - free_carrp = asc_dvc->irq_sp; - asc_dvc->irq_sp = (ADV_CARR_T *) - ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa)); + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_se == 2) { + termination = TERM_SE_HI; - free_carrp->next_vpa = - cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); - asc_dvc->carr_freelist = free_carrp; - asc_dvc->carr_pending_cnt--; + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_se == 3) { + termination = TERM_SE; + } else { + /* + * The EEPROM 'termination_se' field contains a bad value. + * Use automatic termination instead. + */ + termination = 0; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } + } - target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); + if (eep_config.termination_lvd == 0) { + asc_dvc->cfg->termination = termination; /* auto termination for LVD */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_lvd == 1) { + asc_dvc->cfg->termination = termination; - /* - * Clear request microcode control flag. - */ - scsiq->cntl = 0; + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_lvd == 2) { + asc_dvc->cfg->termination = termination | TERM_LVD_HI; - /* - * Notify the driver of the completed request by passing - * the ADV_SCSI_REQ_Q pointer to its callback function. - */ - scsiq->a_flag |= ADV_SCSIQ_DONE; - adv_isr_callback(asc_dvc, scsiq); - /* - * Note: After the driver callback function is called, 'scsiq' - * can no longer be referenced. - * - * Fall through and continue processing other completed - * requests... - */ + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_lvd == 3) { + asc_dvc->cfg->termination = termination | TERM_LVD; + } else { + /* + * The EEPROM 'termination_lvd' field contains a bad value. + * Use automatic termination instead. + */ + asc_dvc->cfg->termination = termination; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } } - return ADV_TRUE; + + return warn_code; } /* - * Send an idle command to the chip and wait for completion. - * - * Command completion is polled for once per microsecond. + * Initialize the ADV_DVC_VAR structure. * - * The function can be called from anywhere including an interrupt handler. - * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() - * functions to prevent reentrancy. + * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. * - * Return Values: - * ADV_TRUE - command completed successfully - * ADV_FALSE - command failed - * ADV_ERROR - command timed out + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. */ -static int -AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, - ushort idle_cmd, ADV_DCNT idle_cmd_parameter) +static int __devinit +AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp) { - int result; - ADV_DCNT i, j; - AdvPortAddr iop_base; + ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; + unsigned short warn_code = 0; + AdvPortAddr iop_base = asc_dvc->iop_base; + u16 cmd; + int status; - iop_base = asc_dvc->iop_base; + asc_dvc->err_code = 0; /* - * Clear the idle command status which is set by the microcode - * to a non-zero value to indicate when the command is completed. - * The non-zero result is one of the IDLE_CMD_STATUS_* values + * Save the state of the PCI Configuration Command Register + * "Parity Error Response Control" Bit. If the bit is clear (0), + * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore + * DMA parity errors. */ - AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0); + asc_dvc->cfg->control_flag = 0; + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if ((cmd & PCI_COMMAND_PARITY) == 0) + asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; - /* - * Write the idle command value after the idle command parameter - * has been written to avoid a race condition. If the order is not - * followed, the microcode may process the idle command before the - * parameters have been written to LRAM. - */ - AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER, - cpu_to_le32(idle_cmd_parameter)); - AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); + asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | + ADV_LIB_VERSION_MINOR; + asc_dvc->cfg->chip_version = + AdvGetChipVersion(iop_base, asc_dvc->bus_type); + + ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n", + (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), + (ushort)ADV_CHIP_ID_BYTE); + + ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n", + (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), + (ushort)ADV_CHIP_ID_WORD); /* - * Tickle the RISC to tell it to process the idle command. + * Reset the chip to start and allow register writes. */ - AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B); - if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { + if (AdvFindSignature(iop_base) == 0) { + asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; + return ADV_ERROR; + } else { /* - * Clear the tickle value. In the ASC-3550 the RISC flag - * command 'clr_tickle_b' does not work unless the host - * value is cleared. + * The caller must set 'chip_type' to a valid setting. */ - AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); - } + if (asc_dvc->chip_type != ADV_CHIP_ASC3550 && + asc_dvc->chip_type != ADV_CHIP_ASC38C0800 && + asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { + asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; + return ADV_ERROR; + } - /* Wait for up to 100 millisecond for the idle command to timeout. */ - for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { - /* Poll once each microsecond for command completion. */ - for (j = 0; j < SCSI_US_PER_MSEC; j++) { - AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, - result); - if (result != 0) - return result; - udelay(1); + /* + * Reset Chip. + */ + AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, + ADV_CTRL_REG_CMD_RESET); + mdelay(100); + AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, + ADV_CTRL_REG_CMD_WR_IO_REG); + + if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { + status = AdvInitFrom38C1600EEP(asc_dvc); + } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { + status = AdvInitFrom38C0800EEP(asc_dvc); + } else { + status = AdvInitFrom3550EEP(asc_dvc); } + warn_code |= status; } - BUG(); /* The idle command should never timeout. */ - return ADV_ERROR; + if (warn_code != 0) { + ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", + boardp->id, warn_code); + } + + if (asc_dvc->err_code) { + ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n", + boardp->id, asc_dvc->err_code); + } + + return asc_dvc->err_code; } +#endif + +static struct scsi_host_template advansys_template = { + .proc_name = DRV_NAME, +#ifdef CONFIG_PROC_FS + .proc_info = advansys_proc_info, +#endif + .name = DRV_NAME, + .info = advansys_info, + .queuecommand = advansys_queuecommand, + .eh_bus_reset_handler = advansys_reset, + .bios_param = advansys_biosparam, + .slave_configure = advansys_slave_configure, + /* + * Because the driver may control an ISA adapter 'unchecked_isa_dma' + * must be set. The flag will be cleared in advansys_board_found + * for non-ISA adapters. + */ + .unchecked_isa_dma = 1, + /* + * All adapters controlled by this driver are capable of large + * scatter-gather lists. According to the mid-level SCSI documentation + * this obviates any performance gain provided by setting + * 'use_clustering'. But empirically while CPU utilization is increased + * by enabling clustering, I/O throughput increases as well. + */ + .use_clustering = ENABLE_CLUSTERING, +}; static int __devinit advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) -- cgit v1.1 From 6e8905f4a028bd07190fa5b2f90b5a35868c84d8 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:23 -0400 Subject: [SCSI] advansys: Remove array of scsi targets The driver was saving a scsi_device for each target, but wasn't doing anything useful with them. Just delete the array. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 4f047cc..737c0e4 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2514,7 +2514,6 @@ typedef struct asc_board { } dvc_cfg; ushort asc_n_io_port; /* Number I/O ports. */ ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ - struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */ ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */ @@ -10183,13 +10182,6 @@ static int advansys_slave_configure(struct scsi_device *sdev) asc_board_t *boardp = ASC_BOARDP(sdev->host); boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; - /* - * Save a pointer to the sdev and set its initial/maximum - * queue depth. Only save the pointer for a lun0 dev though. - */ - if (sdev->lun == 0) - boardp->device[sdev->id] = sdev; - if (ASC_NARROW_BOARD(boardp)) advansys_narrow_slave_configure(sdev, &boardp->dvc_var.asc_dvc_var); @@ -11343,14 +11335,12 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) ASC_DVC_VAR *asc_dvc_varp; ADV_DVC_VAR *adv_dvc_varp; ADV_SCSI_REQ_Q *adv_scsiqp; - struct scsi_device *device; int ret; ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", (ulong)scp, (ulong)scp->scsi_done); boardp = ASC_BOARDP(scp->device->host); - device = boardp->device[scp->device->id]; if (ASC_NARROW_BOARD(boardp)) { /* -- cgit v1.1 From 41d2493d3478942f891b21dff60951ff939c08d9 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:24 -0400 Subject: [SCSI] advansys: Restructure asc_execute_scsi_cmnd() The wide and narrow boards share identical handling of the return value, except for some trivial error messages. Move the handling to the common end of the function. Also move variable declarations to the arms of the `if' that they're used in and delete some pointless comments. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 131 ++++++++++++++---------------------------------- 1 file changed, 39 insertions(+), 92 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 737c0e4..3dd7856 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -11331,80 +11331,26 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) */ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) { - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; - ADV_DVC_VAR *adv_dvc_varp; - ADV_SCSI_REQ_Q *adv_scsiqp; - int ret; + int ret, err_code; + asc_board_t *boardp = ASC_BOARDP(scp->device->host); - ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", - (ulong)scp, (ulong)scp->scsi_done); - - boardp = ASC_BOARDP(scp->device->host); + ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp); if (ASC_NARROW_BOARD(boardp)) { - /* - * Build and execute Narrow Board request. - */ - - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; - /* - * Build Asc Library request structure using the - * global structures 'asc_scsi_req' and 'asc_sg_head'. - * - * If an error is returned, then the request has been - * queued on the board done queue. It will be completed - * by the caller. - * - * asc_build_req() can not return ASC_BUSY. - */ + /* asc_build_req() can not return ASC_BUSY. */ if (asc_build_req(boardp, scp) == ASC_ERROR) { ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } - switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { - case ASC_NOERROR: - ASC_STATS(scp->device->host, exe_noerror); - /* - * Increment monotonically increasing per device - * successful request counter. Wrapping doesn't matter. - */ - boardp->reqcnt[scp->device->id]++; - ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), " - "ASC_NOERROR\n"); - break; - case ASC_BUSY: - ASC_STATS(scp->device->host, exe_busy); - break; - case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_error); - scp->result = HOST_BYTE(DID_ERROR); - break; - default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AscExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_unknown); - scp->result = HOST_BYTE(DID_ERROR); - break; - } + ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q); + err_code = asc_dvc->err_code; } else { - /* - * Build and execute Wide Board request. - */ - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; + ADV_SCSI_REQ_Q *adv_scsiqp; - /* - * Build and get a pointer to an Adv Library request structure. - * - * If the request is successfully built then send it below, - * otherwise return with an error. - */ switch (adv_build_req(boardp, scp, &adv_scsiqp)) { case ASC_NOERROR: ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req " @@ -11428,35 +11374,36 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) return ASC_ERROR; } - switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { - case ASC_NOERROR: - ASC_STATS(scp->device->host, exe_noerror); - /* - * Increment monotonically increasing per device - * successful request counter. Wrapping doesn't matter. - */ - boardp->reqcnt[scp->device->id]++; - ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), " - "ASC_NOERROR\n"); - break; - case ASC_BUSY: - ASC_STATS(scp->device->host, exe_busy); - break; - case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_error); - scp->result = HOST_BYTE(DID_ERROR); - break; - default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " - "AdvExeScsiQueue() unknown, err_code 0x%x\n", - boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->device->host, exe_unknown); - scp->result = HOST_BYTE(DID_ERROR); - break; - } + ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp); + err_code = adv_dvc->err_code; + } + + switch (ret) { + case ASC_NOERROR: + ASC_STATS(scp->device->host, exe_noerror); + /* + * Increment monotonically increasing per device + * successful request counter. Wrapping doesn't matter. + */ + boardp->reqcnt[scp->device->id]++; + ASC_DBG(1, "asc_execute_scsi_cmnd: ExeScsiQueue(), " + "ASC_NOERROR\n"); + break; + case ASC_BUSY: + ASC_STATS(scp->device->host, exe_busy); + break; + case ASC_ERROR: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " + "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code); + ASC_STATS(scp->device->host, exe_error); + scp->result = HOST_BYTE(DID_ERROR); + break; + default: + ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " + "unknown, err_code 0x%x\n", boardp->id, err_code); + ASC_STATS(scp->device->host, exe_unknown); + scp->result = HOST_BYTE(DID_ERROR); + break; } ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); -- cgit v1.1 From 05848b6e66ee237c4496c2b49821d2622b0f677e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:25 -0400 Subject: [SCSI] advansys: Fix simultaneous calls to ->queuecommand The narrow board used two global structures to set up a command; unfortunately they weren't locked, so with two boards in the machine, one call to queuecommand could corrupt the data being used by the other call to queuecommand. Fix this by allocating asc_scsi_q on the stack (64 bytes) and using kmalloc for the asc_sg_head (2k) Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 88 ++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 3dd7856..fd4d669 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -380,7 +380,7 @@ typedef struct asc_sg_head { ushort queue_cnt; ushort entry_to_copy; ushort res; - ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; + ASC_SG_LIST sg_list[0]; } ASC_SG_HEAD; typedef struct asc_scsi_q { @@ -2559,12 +2559,6 @@ static int asc_board_count; /* Overrun buffer used by all narrow boards. */ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; -/* - * Global structures required to issue a command. - */ -static ASC_SCSI_Q asc_scsi_q = { {0} }; -static ASC_SG_HEAD asc_sg_head = { 0 }; - #ifdef ADVANSYS_DEBUG static int asc_dbglvl = 3; @@ -10192,39 +10186,28 @@ static int advansys_slave_configure(struct scsi_device *sdev) return 0; } -/* - * Build a request structure for the Asc Library (Narrow Board). - * - * The global structures 'asc_scsi_q' and 'asc_sg_head' are - * used to build the request. - * - * If an error occurs, then return ASC_ERROR. - */ -static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) +static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, + struct asc_scsi_q *asc_scsi_q) { - /* - * Mutually exclusive access is required to 'asc_scsi_q' and - * 'asc_sg_head' until after the request is started. - */ - memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); + memset(asc_scsi_q, 0, sizeof(*asc_scsi_q)); /* * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. */ - asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); + asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp); /* * Build the ASC_SCSI_Q request. */ - asc_scsi_q.cdbptr = &scp->cmnd[0]; - asc_scsi_q.q2.cdb_len = scp->cmd_len; - asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); - asc_scsi_q.q1.target_lun = scp->device->lun; - asc_scsi_q.q2.target_ix = + asc_scsi_q->cdbptr = &scp->cmnd[0]; + asc_scsi_q->q2.cdb_len = scp->cmd_len; + asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); + asc_scsi_q->q1.target_lun = scp->device->lun; + asc_scsi_q->q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); - asc_scsi_q.q1.sense_addr = + asc_scsi_q->q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); - asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); + asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer); /* * If there are any outstanding requests for the current target, @@ -10239,9 +10222,9 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) */ if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && (boardp->reqcnt[scp->device->id] % 255) == 0) { - asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; + asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG; } else { - asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; + asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG; } /* @@ -10257,12 +10240,12 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) dma_map_single(boardp->dev, scp->request_buffer, scp->request_bufflen, scp->sc_data_direction) : 0; - asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); - asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); + asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); + asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen); ASC_STATS_ADD(scp->device->host, cont_xfer, ASC_CEILING(scp->request_bufflen, 512)); - asc_scsi_q.q1.sg_queue_cnt = 0; - asc_scsi_q.sg_head = NULL; + asc_scsi_q->q1.sg_queue_cnt = 0; + asc_scsi_q->sg_head = NULL; } else { /* * CDB scatter-gather request list. @@ -10270,6 +10253,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) int sgcnt; int use_sg; struct scatterlist *slp; + struct asc_sg_head *asc_sg_head; slp = (struct scatterlist *)scp->request_buffer; use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, @@ -10287,28 +10271,31 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) ASC_STATS(scp->device->host, sg_cnt); - /* - * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q - * structure to point to it. - */ - memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); + asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) + + use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC); + if (!asc_sg_head) { + dma_unmap_sg(boardp->dev, slp, scp->use_sg, + scp->sc_data_direction); + scp->result = HOST_BYTE(DID_SOFT_ERROR); + return ASC_ERROR; + } - asc_scsi_q.q1.cntl |= QC_SG_HEAD; - asc_scsi_q.sg_head = &asc_sg_head; - asc_scsi_q.q1.data_cnt = 0; - asc_scsi_q.q1.data_addr = 0; + asc_scsi_q->q1.cntl |= QC_SG_HEAD; + asc_scsi_q->sg_head = asc_sg_head; + asc_scsi_q->q1.data_cnt = 0; + asc_scsi_q->q1.data_addr = 0; /* This is a byte value, otherwise it would need to be swapped. */ - asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; + asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg; ASC_STATS_ADD(scp->device->host, sg_elem, - asc_sg_head.entry_cnt); + asc_sg_head->entry_cnt); /* * Convert scatter-gather list into ASC_SG_HEAD list. */ for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { - asc_sg_head.sg_list[sgcnt].addr = + asc_sg_head->sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp)); - asc_sg_head.sg_list[sgcnt].bytes = + asc_sg_head->sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp)); ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512)); @@ -11338,14 +11325,17 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) if (ASC_NARROW_BOARD(boardp)) { ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + struct asc_scsi_q asc_scsi_q; /* asc_build_req() can not return ASC_BUSY. */ - if (asc_build_req(boardp, scp) == ASC_ERROR) { + ret = asc_build_req(boardp, scp, &asc_scsi_q); + if (ret == ASC_ERROR) { ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q); + kfree(asc_scsi_q.sg_head); err_code = asc_dvc->err_code; } else { ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; -- cgit v1.1 From 52fa07770921d9cbe815d3aff36702c88cdec978 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:26 -0400 Subject: [SCSI] advansys: Improve reset handler - Don't need to set ASC_HOST_IN_RESET any more - Don't need to test scp->device->host for NULL -- if it's NULL, we couldn't've been called. - Use scmd_printk instead of ASC_PRINT Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 83 +++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 61 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index fd4d669..52ea41d 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2229,7 +2229,6 @@ do { \ #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) /* asc_board_t flags */ -#define ASC_HOST_IN_RESET 0x01 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ #define ASC_SELECT_QUEUE_DEPTHS 0x08 @@ -9751,106 +9750,68 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) */ static int advansys_reset(struct scsi_cmnd *scp) { - struct Scsi_Host *shost; - asc_board_t *boardp; - ASC_DVC_VAR *asc_dvc_varp; - ADV_DVC_VAR *adv_dvc_varp; - ulong flags; + struct Scsi_Host *shost = scp->device->host; + struct asc_board *boardp = ASC_BOARDP(shost); + unsigned long flags; int status; int ret = SUCCESS; - ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp); + ASC_DBG1(1, "advansys_reset: 0x%p\n", scp); -#ifdef ADVANSYS_STATS - if (scp->device->host != NULL) { - ASC_STATS(scp->device->host, reset); - } -#endif /* ADVANSYS_STATS */ - - if ((shost = scp->device->host) == NULL) { - scp->result = HOST_BYTE(DID_ERROR); - return FAILED; - } + ASC_STATS(shost, reset); - boardp = ASC_BOARDP(shost); - - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n", - boardp->id); - /* - * Check for re-entrancy. - */ - spin_lock_irqsave(&boardp->lock, flags); - if (boardp->flags & ASC_HOST_IN_RESET) { - spin_unlock_irqrestore(&boardp->lock, flags); - return FAILED; - } - boardp->flags |= ASC_HOST_IN_RESET; - spin_unlock_irqrestore(&boardp->lock, flags); + scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n"); if (ASC_NARROW_BOARD(boardp)) { - /* - * Narrow Board - */ - asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; + ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; - /* - * Reset the chip and SCSI bus. - */ + /* Reset the chip and SCSI bus. */ ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); - status = AscInitAsc1000Driver(asc_dvc_varp); + status = AscInitAsc1000Driver(asc_dvc); /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ - if (asc_dvc_varp->err_code) { - ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " - "error: 0x%x\n", boardp->id, - asc_dvc_varp->err_code); + if (asc_dvc->err_code) { + scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " + "0x%x\n", asc_dvc->err_code); ret = FAILED; } else if (status) { - ASC_PRINT2("advansys_reset: board %d: SCSI bus reset " - "warning: 0x%x\n", boardp->id, status); + scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " + "0x%x\n", status); } else { - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "successful.\n", boardp->id); + scmd_printk(KERN_INFO, scp, "SCSI bus reset " + "successful\n"); } ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); spin_lock_irqsave(&boardp->lock, flags); - } else { /* - * Wide Board - * * If the suggest reset bus flags are set, then reset the bus. * Otherwise only reset the device. */ - adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; + ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; /* * Reset the target's SCSI bus. */ ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); - switch (AdvResetChipAndSB(adv_dvc_varp)) { + switch (AdvResetChipAndSB(adv_dvc)) { case ASC_TRUE: - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "successful.\n", boardp->id); + scmd_printk(KERN_INFO, scp, "SCSI bus reset " + "successful\n"); break; case ASC_FALSE: default: - ASC_PRINT1("advansys_reset: board %d: SCSI bus reset " - "error.\n", boardp->id); + scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n"); ret = FAILED; break; } spin_lock_irqsave(&boardp->lock, flags); - AdvISR(adv_dvc_varp); + AdvISR(adv_dvc); } - /* Board lock is held. */ /* Save the time of the most recently completed reset. */ boardp->last_reset = jiffies; - - /* Clear reset flag. */ - boardp->flags &= ~ASC_HOST_IN_RESET; spin_unlock_irqrestore(&boardp->lock, flags); ASC_DBG1(1, "advansys_reset: ret %d\n", ret); -- cgit v1.1 From ae002fec6906622aa96d01f8065ef90023660a68 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:27 -0400 Subject: [SCSI] advansys: Remove ASC_SELECT_QUEUE_DEPTHS It was only ever set; never tested, nor cleared. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 52ea41d..5e6bcf2 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2230,7 +2230,6 @@ do { \ /* asc_board_t flags */ #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ -#define ASC_SELECT_QUEUE_DEPTHS 0x08 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD) @@ -10135,7 +10134,6 @@ advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) static int advansys_slave_configure(struct scsi_device *sdev) { asc_board_t *boardp = ASC_BOARDP(sdev->host); - boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; if (ASC_NARROW_BOARD(boardp)) advansys_narrow_slave_configure(sdev, -- cgit v1.1 From 9a256fa50e9a9d6bd03e0d6e8eddce9dca4f15f2 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:28 -0400 Subject: [SCSI] advansys: Remove ASC_WIDE_BOARD predicate Replace it with !ASC_NARROW_BOARD Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 5e6bcf2..a5bb4e4 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2232,7 +2232,6 @@ do { \ #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) -#define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD) #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ @@ -4385,7 +4384,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, /* * Display Wide Board BIOS Information. */ - if (ASC_WIDE_BOARD(boardp)) { + if (!ASC_NARROW_BOARD(boardp)) { cp = boardp->prtbuf; cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); BUG_ON(cplen >= ASC_PRTBUF_SIZE); @@ -14432,7 +14431,7 @@ static int advansys_release(struct Scsi_Host *shost) ASC_DBG(1, "advansys_release: free_dma()\n"); free_dma(shost->dma_channel); } - if (ASC_WIDE_BOARD(boardp)) { + if (!ASC_NARROW_BOARD(boardp)) { iounmap(boardp->ioremap_addr); advansys_wide_free_mem(boardp); } -- cgit v1.1 From d361db483241489fc4b37cd168c2ce7940a7845b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:29 -0400 Subject: [SCSI] advansys: Sort out irq number mess The interrupt number was being stored in 4-5 different places, each with its own type, rules and usage. Fix this by keeping an unsigned int in the struct asc_board, and filling it in from the bus probe functions (since it's different for each of the four bus types). In order to do this, we have to allocate the Scsi_Host in the bus probe functions too. Then we can return an error from advansys_board_found, which requires a little rearranging of code (and removing of the err_code variable). Move the Wide Board flag setting into the PCI bus probe function. Split the AscGetChipIRQ function into three functions (one for each bus type that needs it) and add some commentary to explain what's going on. Also get rid of the AscSetChipIRQ function as we only ever set the interrupt number to the same value it already had. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 387 +++++++++++++++++++++++------------------------- 1 file changed, 189 insertions(+), 198 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index a5bb4e4..e2bd4c9 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -461,23 +461,13 @@ typedef struct asc_risc_sg_list_q { /* * Error code values are set in ASC_DVC_VAR 'err_code'. */ -#define ASC_IERR_WRITE_EEPROM 0x0001 #define ASC_IERR_MCODE_CHKSUM 0x0002 #define ASC_IERR_SET_PC_ADDR 0x0004 #define ASC_IERR_START_STOP_CHIP 0x0008 -#define ASC_IERR_IRQ_NO 0x0010 -#define ASC_IERR_SET_IRQ_NO 0x0020 -#define ASC_IERR_CHIP_VERSION 0x0040 #define ASC_IERR_SET_SCSI_ID 0x0080 -#define ASC_IERR_GET_PHY_ADDR 0x0100 #define ASC_IERR_BAD_SIGNATURE 0x0200 #define ASC_IERR_NO_BUS_TYPE 0x0400 -#define ASC_IERR_SCAM 0x0800 -#define ASC_IERR_SET_SDTR 0x1000 -#define ASC_IERR_RW_LRAM 0x8000 -#define ASC_MAX_IRQ_NO 15 -#define ASC_MIN_IRQ_NO 10 #define ASC_DEF_MAX_TOTAL_QNG (0xF0) #define ASC_MIN_TAG_Q_PER_DVC (0x04) #define ASC_MIN_FREE_Q (0x02) @@ -605,7 +595,6 @@ typedef struct asc_dvc_var { uchar max_total_qng; uchar cur_total_qng; uchar in_critical_cnt; - uchar irq_no; uchar last_q_shortage; ushort init_state; uchar cur_dvc_qng[ASC_MAX_TID + 1]; @@ -1711,11 +1700,9 @@ typedef struct adveep_38C1600_config { /* * Error code values are set in ADV_DVC_VAR 'err_code'. */ -#define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */ #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ -#define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */ #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ @@ -1919,7 +1906,6 @@ typedef struct adv_dvc_var { uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ uchar chip_no; /* should be assigned by caller */ uchar max_host_qng; /* maximum number of Q'ed command allowed */ - uchar irq_no; /* IRQ number */ ushort no_scam; /* scam_tolerant of EEPROM */ struct asc_board *drv_ptr; /* driver pointer to private structure */ uchar chip_scsi_id; /* chip SCSI target ID */ @@ -2501,6 +2487,7 @@ typedef struct asc_board { struct device *dev; int id; /* Board Id */ uint flags; /* Board flags */ + unsigned int irq; union { ASC_DVC_VAR asc_dvc_var; /* Narrow board */ ADV_DVC_VAR adv_dvc_var; /* Wide board */ @@ -2573,7 +2560,7 @@ static void asc_prt_scsi_host(struct Scsi_Host *s) s->host_busy, s->host_no, (unsigned)s->last_reset); printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", - (ulong)s->base, (ulong)s->io_port, s->irq); + (ulong)s->base, (ulong)s->io_port, boardp->irq); printk(" dma_channel %d, this_id %d, can_queue %d,\n", s->dma_channel, s->this_id, s->can_queue); @@ -2651,7 +2638,7 @@ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) (unsigned)h->init_state, (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer); - printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); + printk(" cfg 0x%lx\n", (ulong)h->cfg); } /* @@ -2749,9 +2736,8 @@ static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) (ulong)h->isr_callback, (unsigned)h->sdtr_able, (unsigned)h->wdtr_able); - printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", - (unsigned)h->start_motor, - (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no); + printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n", + (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, @@ -2958,7 +2944,7 @@ static const char *advansys_info(struct Scsi_Host *shost) ASC_VERSION, busname, (ulong)shost->io_port, (ulong)shost->io_port + ASC_IOADR_GAP - 1, - shost->irq, shost->dma_channel); + boardp->irq, shost->dma_channel); } else { if (asc_dvc_varp->bus_type & ASC_IS_VL) { busname = "VL"; @@ -2981,7 +2967,7 @@ static const char *advansys_info(struct Scsi_Host *shost) "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", ASC_VERSION, busname, (ulong)shost->io_port, (ulong)shost->io_port + ASC_IOADR_GAP - 1, - shost->irq); + boardp->irq); } } else { /* @@ -3002,7 +2988,7 @@ static const char *advansys_info(struct Scsi_Host *shost) sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, - (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, shost->irq); + (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq); } BUG_ON(strlen(info) >= ASC_INFO_SIZE); ASC_DBG(1, "advansys_info: end\n"); @@ -11479,77 +11465,6 @@ AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) return AscGetChipVerNo(iop_base); } -static void __devinit AscToggleIRQAct(PortAddr iop_base) -{ - AscSetChipStatus(iop_base, CIW_IRQ_ACT); - AscSetChipStatus(iop_base, 0); - return; -} - -static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type) -{ - ushort cfg_lsw; - uchar chip_irq; - - if ((bus_type & ASC_IS_EISA) != 0) { - cfg_lsw = AscGetEisaChipCfg(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10); - if ((chip_irq == 13) || (chip_irq > 15)) { - return (0); - } - return (chip_irq); - } - if ((bus_type & ASC_IS_VL) != 0) { - cfg_lsw = AscGetChipCfgLsw(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07)); - if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) { - return (0); - } - return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1))); - } - cfg_lsw = AscGetChipCfgLsw(iop_base); - chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03)); - if (chip_irq == 3) - chip_irq += (uchar)2; - return ((uchar)(chip_irq + ASC_MIN_IRQ_NO)); -} - -static uchar __devinit -AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) -{ - ushort cfg_lsw; - - if ((bus_type & ASC_IS_VL) != 0) { - if (irq_no != 0) { - if ((irq_no < ASC_MIN_IRQ_NO) - || (irq_no > ASC_MAX_IRQ_NO)) { - irq_no = 0; - } else { - irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1)); - } - } - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3); - cfg_lsw |= (ushort)0x0010; - AscSetChipCfgLsw(iop_base, cfg_lsw); - AscToggleIRQAct(iop_base); - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0); - cfg_lsw |= (ushort)((irq_no & 0x07) << 2); - AscSetChipCfgLsw(iop_base, cfg_lsw); - AscToggleIRQAct(iop_base); - return (AscGetChipIRQ(iop_base, bus_type)); - } - if ((bus_type & (ASC_IS_ISA)) != 0) { - if (irq_no == 15) - irq_no -= (uchar)2; - irq_no -= (uchar)ASC_MIN_IRQ_NO; - cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3); - cfg_lsw |= (ushort)((irq_no & 0x03) << 2); - AscSetChipCfgLsw(iop_base, cfg_lsw); - return (AscGetChipIRQ(iop_base, bus_type)); - } - return (0); -} - #ifdef CONFIG_ISA static void __devinit AscEnableIsaDma(uchar dma_channel) { @@ -12157,9 +12072,6 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) eep_config->disc_enable = eep_config->use_cmd_qng; warn_code |= ASC_WARN_CMD_QNG_CONFLICT; } - if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { - asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); - } ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); @@ -12276,12 +12188,6 @@ static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp) if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { warn_code |= ASC_WARN_AUTO_CONFIG; } - if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { - if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) - != asc_dvc->irq_no) { - asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; - } - } #ifdef CONFIG_PCI if (asc_dvc->bus_type & ASC_IS_PCI) { cfg_msw &= 0xFFC0; @@ -13879,49 +13785,19 @@ static void advansys_wide_free_mem(asc_board_t *boardp) } } -static struct Scsi_Host *__devinit -advansys_board_found(int iop, struct device *dev, int bus_type) +static int __devinit advansys_board_found(struct Scsi_Host *shost, + unsigned int iop, int bus_type) { - struct Scsi_Host *shost; - struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL; + struct pci_dev *pdev; asc_board_t *boardp; ASC_DVC_VAR *asc_dvc_varp = NULL; ADV_DVC_VAR *adv_dvc_varp = NULL; - int share_irq; - int warn_code, err_code; - int ret; - - /* - * Register the adapter, get its configuration, and - * initialize it. - */ - ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n"); - shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t)); - if (!shost) - return NULL; + int share_irq, warn_code, ret; - /* Initialize private per board data */ boardp = ASC_BOARDP(shost); - memset(boardp, 0, sizeof(asc_board_t)); boardp->id = asc_board_count++; spin_lock_init(&boardp->lock); - boardp->dev = dev; - - /* - * Handle both narrow and wide boards. - * - * If a Wide board was detected, set the board structure - * wide board flag. Set-up the board structure based on - * the board type. - */ -#ifdef CONFIG_PCI - if (bus_type == ASC_IS_PCI && - (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW || - pdev->device == PCI_DEVICE_ID_38C0800_REV1 || - pdev->device == PCI_DEVICE_ID_38C1600_REV1)) { - boardp->flags |= ASC_IS_WIDE_BOARD; - } -#endif /* CONFIG_PCI */ + pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; if (ASC_NARROW_BOARD(boardp)) { ASC_DBG(1, "advansys_board_found: narrow board\n"); @@ -13956,6 +13832,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", boardp->id, pci_resource_start(pdev, 1), boardp->asc_n_io_port); + ret = -ENODEV; goto err_shost; } adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr @@ -13984,6 +13861,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (!boardp->prtbuf) { ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); + ret = -ENOMEM; goto err_unmap; } #endif /* CONFIG_PROC_FS */ @@ -14010,7 +13888,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #endif /* CONFIG_ISA */ #ifdef CONFIG_PCI case ASC_IS_PCI: - shost->irq = asc_dvc_varp->irq_no = pdev->irq; shost->unchecked_isa_dma = FALSE; share_irq = IRQF_SHARED; break; @@ -14031,23 +13908,22 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * referenced only use the bit-wise AND operator "&". */ ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n"); - err_code = AscInitGetConfig(boardp); + ret = AscInitGetConfig(boardp) ? -ENODEV : 0; } else { #ifdef CONFIG_PCI /* * For Wide boards set PCI information before calling * AdvInitGetConfig(). */ - shost->irq = adv_dvc_varp->irq_no = pdev->irq; shost->unchecked_isa_dma = FALSE; share_irq = IRQF_SHARED; ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); - err_code = AdvInitGetConfig(pdev, boardp); + ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0; #endif /* CONFIG_PCI */ } - if (err_code != 0) + if (ret) goto err_free_proc; /* @@ -14091,17 +13967,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type) * Modify board configuration. */ ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); - err_code = AscInitSetConfig(pdev, boardp); - if (err_code) + ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0; + if (ret) goto err_free_proc; - - /* - * Finish initializing the 'Scsi_Host' structure. - */ - /* AscInitSetConfig() will set the IRQ for non-PCI boards. */ - if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) { - shost->irq = asc_dvc_varp->irq_no; - } } else { ADVEEP_3550_CONFIG *ep_3550; ADVEEP_38C0800_CONFIG *ep_38C0800; @@ -14346,24 +14214,24 @@ advansys_board_found(int iop, struct device *dev, int bus_type) #endif /* CONFIG_ISA */ /* Register IRQ Number. */ - ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq); + ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq); - ret = request_irq(shost->irq, advansys_interrupt, share_irq, + ret = request_irq(boardp->irq, advansys_interrupt, share_irq, DRV_NAME, shost); if (ret) { if (ret == -EBUSY) { ASC_PRINT2 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", - boardp->id, shost->irq); + boardp->id, boardp->irq); } else if (ret == -EINVAL) { ASC_PRINT2 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n", - boardp->id, shost->irq); + boardp->id, boardp->irq); } else { ASC_PRINT3 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", - boardp->id, shost->irq, ret); + boardp->id, boardp->irq, ret); } goto err_free_dma; } @@ -14374,33 +14242,35 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (ASC_NARROW_BOARD(boardp)) { ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n"); warn_code = AscInitAsc1000Driver(asc_dvc_varp); - err_code = asc_dvc_varp->err_code; - if (warn_code || err_code) { - ASC_PRINT4 - ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n", - boardp->id, - asc_dvc_varp->init_state, warn_code, err_code); + if (warn_code || asc_dvc_varp->err_code) { + ASC_PRINT4("advansys_board_found: board %d error: " + "init_state 0x%x, warn 0x%x, error 0x%x\n", + boardp->id, asc_dvc_varp->init_state, + warn_code, asc_dvc_varp->err_code); + if (asc_dvc_varp->err_code) + ret = -ENODEV; } } else { - err_code = advansys_wide_init_chip(boardp, adv_dvc_varp); + if (advansys_wide_init_chip(boardp, adv_dvc_varp)) + ret = -ENODEV; } - if (err_code != 0) + if (ret) goto err_free_wide_mem; ASC_DBG_PRT_SCSI_HOST(2, shost); - ret = scsi_add_host(shost, dev); + ret = scsi_add_host(shost, boardp->dev); if (ret) goto err_free_wide_mem; scsi_scan_host(shost); - return shost; + return 0; err_free_wide_mem: advansys_wide_free_mem(boardp); - free_irq(shost->irq, shost); + free_irq(boardp->irq, shost); err_free_dma: if (shost->dma_channel != NO_ISA_DMA) free_dma(shost->dma_channel); @@ -14410,8 +14280,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) if (boardp->ioremap_addr) iounmap(boardp->ioremap_addr); err_shost: - scsi_host_put(shost); - return NULL; + return ret; } /* @@ -14426,7 +14295,7 @@ static int advansys_release(struct Scsi_Host *shost) ASC_DBG(1, "advansys_release: begin\n"); scsi_remove_host(shost); boardp = ASC_BOARDP(shost); - free_irq(shost->irq, shost); + free_irq(boardp->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { ASC_DBG(1, "advansys_release: free_dma()\n"); free_dma(shost->dma_channel); @@ -14448,10 +14317,28 @@ static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = { 0x0210, 0x0230, 0x0250, 0x0330 }; +/* + * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as: + * 00: 10 + * 01: 11 + * 10: 12 + * 11: 15 + */ +static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base) +{ + unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base); + unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10; + if (chip_irq == 13) + chip_irq = 15; + return chip_irq; +} + static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) { + int err = -ENODEV; PortAddr iop_base = _asc_def_iop_base[id]; struct Scsi_Host *shost; + struct asc_board *board; if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n", @@ -14460,20 +14347,31 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) } ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); if (!AscFindSignature(iop_base)) - goto nodev; + goto release_region; if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) - goto nodev; + goto release_region; - shost = advansys_board_found(iop_base, dev, ASC_IS_ISA); + err = -ENOMEM; + shost = scsi_host_alloc(&advansys_template, sizeof(*board)); if (!shost) - goto nodev; + goto release_region; + + board = ASC_BOARDP(shost); + board->irq = advansys_isa_irq_no(iop_base); + board->dev = dev; + + err = advansys_board_found(shost, iop_base, ASC_IS_ISA); + if (err) + goto free_host; dev_set_drvdata(dev, shost); return 0; - nodev: + free_host: + scsi_host_put(shost); + release_region: release_region(iop_base, ASC_IOADR_GAP); - return -ENODEV; + return err; } static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) @@ -14493,10 +14391,32 @@ static struct isa_driver advansys_isa_driver = { }, }; +/* + * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as: + * 000: invalid + * 001: 10 + * 010: 11 + * 011: 12 + * 100: invalid + * 101: 14 + * 110: 15 + * 111: invalid + */ +static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base) +{ + unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base); + unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9; + if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15)) + return 0; + return chip_irq; +} + static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) { + int err = -ENODEV; PortAddr iop_base = _asc_def_iop_base[id]; struct Scsi_Host *shost; + struct asc_board *board; if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n", @@ -14505,23 +14425,34 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) } ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); if (!AscFindSignature(iop_base)) - goto nodev; + goto release_region; /* * I don't think this condition can actually happen, but the old * driver did it, and the chances of finding a VLB setup in 2007 * to do testing with is slight to none. */ if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL) - goto nodev; + goto release_region; - shost = advansys_board_found(iop_base, dev, ASC_IS_VL); + err = -ENOMEM; + shost = scsi_host_alloc(&advansys_template, sizeof(*board)); if (!shost) - goto nodev; + goto release_region; + + board = ASC_BOARDP(shost); + board->irq = advansys_vlb_irq_no(iop_base); + board->dev = dev; + + err = advansys_board_found(shost, iop_base, ASC_IS_VL); + if (err) + goto free_host; dev_set_drvdata(dev, shost); return 0; - nodev: + free_host: + scsi_host_put(shost); + release_region: release_region(iop_base, ASC_IOADR_GAP); return -ENODEV; } @@ -14551,9 +14482,29 @@ struct eisa_scsi_data { struct Scsi_Host *host[2]; }; +/* + * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as: + * 000: 10 + * 001: 11 + * 010: 12 + * 011: invalid + * 100: 14 + * 101: 15 + * 110: invalid + * 111: invalid + */ +static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev) +{ + unsigned short cfg_lsw = inw(edev->base_addr + 0xc86); + unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10; + if ((chip_irq == 13) || (chip_irq > 15)) + return 0; + return chip_irq; +} + static int __devinit advansys_eisa_probe(struct device *dev) { - int i, ioport; + int i, ioport, irq = 0; int err; struct eisa_device *edev = to_eisa_device(dev); struct eisa_scsi_data *data; @@ -14566,6 +14517,8 @@ static int __devinit advansys_eisa_probe(struct device *dev) err = -ENODEV; for (i = 0; i < 2; i++, ioport += 0x20) { + struct asc_board *board; + struct Scsi_Host *shost; if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) { printk(KERN_WARNING "Region %x-%x busy\n", ioport, ioport + ASC_IOADR_GAP - 1); @@ -14584,20 +14537,40 @@ static int __devinit advansys_eisa_probe(struct device *dev) * test with. */ inw(ioport + 4); - data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA); - if (data->host[i]) { - err = 0; - } else { - release_region(ioport, ASC_IOADR_GAP); + + if (!irq) + irq = advansys_eisa_irq_no(edev); + + err = -ENOMEM; + shost = scsi_host_alloc(&advansys_template, sizeof(*board)); + if (!shost) + goto release_region; + + board = ASC_BOARDP(shost); + board->irq = irq; + board->dev = dev; + + err = advansys_board_found(shost, ioport, ASC_IS_EISA); + if (!err) { + data->host[i] = shost; + continue; } - } - if (err) { - kfree(data); - } else { - dev_set_drvdata(dev, data); + scsi_host_put(shost); + release_region: + release_region(ioport, ASC_IOADR_GAP); + break; } + if (err) + goto free_data; + dev_set_drvdata(dev, data); + return 0; + + free_data: + kfree(data->host[0]); + kfree(data->host[1]); + kfree(data); fail: return err; } @@ -14667,6 +14640,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err, ioport; struct Scsi_Host *shost; + struct asc_board *board; err = pci_enable_device(pdev); if (err) @@ -14677,20 +14651,37 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); advansys_set_latency(pdev); + err = -ENODEV; if (pci_resource_len(pdev, 0) == 0) - goto nodev; + goto release_region; ioport = pci_resource_start(pdev, 0); - shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI); + err = -ENOMEM; + shost = scsi_host_alloc(&advansys_template, sizeof(*board)); if (!shost) - goto nodev; + goto release_region; + + board = ASC_BOARDP(shost); + board->irq = pdev->irq; + board->dev = &pdev->dev; + + if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW || + pdev->device == PCI_DEVICE_ID_38C0800_REV1 || + pdev->device == PCI_DEVICE_ID_38C1600_REV1) { + board->flags |= ASC_IS_WIDE_BOARD; + } + + err = advansys_board_found(shost, ioport, ASC_IS_PCI); + if (err) + goto free_host; pci_set_drvdata(pdev, shost); return 0; - nodev: - err = -ENODEV; + free_host: + scsi_host_put(shost); + release_region: pci_release_regions(pdev); disable_device: pci_disable_device(pdev); -- cgit v1.1 From 720349a879d3e37f3d932bf3ca9b94ac638d59b6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:30 -0400 Subject: [SCSI] advansys: Merge ASC_IERR definitions There were two blocks of ASC_IERR definitions; one for narrow and one for wide boards. Some of the same names were used (with the same values), and some of the same values were used with different names. This could only lead to confusion, so I unified them in one block of definitions with no overlapping values. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e2bd4c9..0f309e8 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -459,14 +459,22 @@ typedef struct asc_risc_sg_list_q { #define ASC_WARN_CFG_MSW_RECOVER 0x0040 /* - * Error code values are set in ASC_DVC_VAR 'err_code'. - */ -#define ASC_IERR_MCODE_CHKSUM 0x0002 -#define ASC_IERR_SET_PC_ADDR 0x0004 -#define ASC_IERR_START_STOP_CHIP 0x0008 -#define ASC_IERR_SET_SCSI_ID 0x0080 -#define ASC_IERR_BAD_SIGNATURE 0x0200 -#define ASC_IERR_NO_BUS_TYPE 0x0400 + * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'. + */ +#define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */ +#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ +#define ASC_IERR_SET_PC_ADDR 0x0004 +#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ +#define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */ +#define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */ +#define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */ +#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ +#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */ +#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ +#define ASC_IERR_NO_BUS_TYPE 0x0400 +#define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */ +#define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */ +#define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */ #define ASC_DEF_MAX_TOTAL_QNG (0xF0) #define ASC_MIN_TAG_Q_PER_DVC (0x04) @@ -1698,22 +1706,6 @@ typedef struct adveep_38C1600_config { #define ADV_MAX_LUN 7 /* max. logical unit number */ /* - * Error code values are set in ADV_DVC_VAR 'err_code'. - */ -#define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ -#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ -#define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ -#define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ -#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ -#define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ -#define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */ -#define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */ -#define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */ -#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */ -#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */ -#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */ - -/* * Fixed locations of microcode operating variables. */ #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ -- cgit v1.1 From d24114955846c321a9e94fff4764bbef532524b2 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:31 -0400 Subject: [SCSI] advansys: Remove asc_board_t typedef and ASC_BOARDP macro asc_board_t was simply a typedef for struct asc_board. ASC_BOARDP() can be replaced by shost_priv() except in the ASC_STATS* macros which rely on the cast; add an explicit cast there. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 132 +++++++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 81 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 0f309e8..7570380 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2203,10 +2203,7 @@ do { \ (sizeof(ADV_SG_BLOCK) * \ ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) -/* Reference Scsi_Host hostdata */ -#define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) - -/* asc_board_t flags */ +/* struct asc_board flags */ #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) @@ -2244,15 +2241,12 @@ do { \ #define HOST_BYTE(byte) ((byte) << 16) #define DRIVER_BYTE(byte) ((byte) << 24) +#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1) #ifndef ADVANSYS_STATS -#define ASC_STATS(shost, counter) #define ASC_STATS_ADD(shost, counter, count) #else /* ADVANSYS_STATS */ -#define ASC_STATS(shost, counter) \ - (ASC_BOARDP(shost)->asc_stats.counter++) - #define ASC_STATS_ADD(shost, counter, count) \ - (ASC_BOARDP(shost)->asc_stats.counter += (count)) + (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count)) #endif /* ADVANSYS_STATS */ #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit)) @@ -2475,7 +2469,7 @@ typedef struct adv_req { * of the 'Scsi_Host' structure starting at the 'hostdata' * field. It is guaranteed to be allocated from DMA-able memory. */ -typedef struct asc_board { +struct asc_board { struct device *dev; int id; /* Board Id */ uint flags; /* Board flags */ @@ -2523,7 +2517,7 @@ typedef struct asc_board { ushort bios_version; /* BIOS Version. */ ushort bios_codeseg; /* BIOS Code Segment. */ ushort bios_codelen; /* BIOS Code Segment Length. */ -} asc_board_t; +}; #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ dvc_var.adv_dvc_var) @@ -2543,9 +2537,7 @@ static int asc_dbglvl = 3; */ static void asc_prt_scsi_host(struct Scsi_Host *s) { - asc_board_t *boardp; - - boardp = ASC_BOARDP(s); + struct asc_board *boardp = shost_priv(s); printk("Scsi_Host at addr 0x%lx\n", (ulong)s); printk(" host_busy %u, host_no %d, last_reset %d,\n", @@ -2561,11 +2553,11 @@ static void asc_prt_scsi_host(struct Scsi_Host *s) s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); if (ASC_NARROW_BOARD(boardp)) { - asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); - asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); + asc_prt_asc_dvc_var(boardp->dvc_var.asc_dvc_var); + asc_prt_asc_dvc_cfg(boardp->dvc_cfg.asc_dvc_cfg); } else { - asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); - asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); + asc_prt_adv_dvc_var(boardp->dvc_var.adv_dvc_var); + asc_prt_adv_dvc_cfg(boardp->dvc_cfg.adv_dvc_cfg); } } @@ -2914,13 +2906,12 @@ static void asc_prt_hex(char *f, uchar *s, int l) static const char *advansys_info(struct Scsi_Host *shost) { static char info[ASC_INFO_SIZE]; - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); ASC_DVC_VAR *asc_dvc_varp; ADV_DVC_VAR *adv_dvc_varp; char *busname; char *widename = NULL; - boardp = ASC_BOARDP(shost); if (ASC_NARROW_BOARD(boardp)) { asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; ASC_DBG(1, "advansys_info: begin\n"); @@ -3032,14 +3023,13 @@ static int asc_prt_line(char *buf, int buflen, char *fmt, ...) */ static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); int leftlen; int totlen; int len; int chip_scsi_id; int i; - boardp = ASC_BOARDP(shost); leftlen = cplen; totlen = len = 0; @@ -3073,13 +3063,12 @@ static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) */ static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); int leftlen; int totlen; int len; ushort major, minor, letter; - boardp = ASC_BOARDP(shost); leftlen = cplen; totlen = len = 0; @@ -3239,7 +3228,7 @@ static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) */ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); ASC_DVC_VAR *asc_dvc_varp; int leftlen; int totlen; @@ -3251,7 +3240,6 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen #endif /* CONFIG_ISA */ uchar serialstr[13]; - boardp = ASC_BOARDP(shost); asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; ep = &boardp->eep_config.asc_eep; @@ -3373,7 +3361,7 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen */ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); ADV_DVC_VAR *adv_dvc_varp; int leftlen; int totlen; @@ -3388,7 +3376,6 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen ushort *wordp; ushort sdtr_speed = 0; - boardp = ASC_BOARDP(shost); adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { ep_3550 = &boardp->eep_config.adv_3550_eep; @@ -3660,14 +3647,12 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen */ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); int leftlen; int totlen; int len; int chip_scsi_id; - boardp = ASC_BOARDP(shost); - leftlen = cplen; totlen = len = 0; @@ -3724,7 +3709,7 @@ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) */ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); int chip_scsi_id; int leftlen; int totlen; @@ -3734,7 +3719,6 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) int i; int renegotiate = 0; - boardp = ASC_BOARDP(shost); v = &boardp->dvc_var.asc_dvc_var; c = &boardp->dvc_cfg.asc_dvc_cfg; chip_scsi_id = c->chip_scsi_id; @@ -3912,7 +3896,7 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) */ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); int leftlen; int totlen; int len; @@ -3929,7 +3913,6 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) ushort period = 0; int renegotiate = 0; - boardp = ASC_BOARDP(shost); v = &boardp->dvc_var.adv_dvc_var; c = &boardp->dvc_cfg.adv_dvc_cfg; iop_base = v->iop_base; @@ -4192,17 +4175,11 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, */ static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) { - int leftlen; - int totlen; - int len; - struct asc_stats *s; - asc_board_t *boardp; - - leftlen = cplen; - totlen = len = 0; + struct asc_board *boardp = shost_priv(shost); + struct asc_stats *s = &boardp->asc_stats; - boardp = ASC_BOARDP(shost); - s = &boardp->asc_stats; + int leftlen = cplen; + int len, totlen = 0; len = asc_prt_line(cp, leftlen, "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", @@ -4309,7 +4286,7 @@ static int advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); char *cp; int cplen; int cnt; @@ -4323,16 +4300,13 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, /* * User write not supported. */ - if (inout == TRUE) { - return (-ENOSYS); - } + if (inout == TRUE) + return -ENOSYS; /* * User read of /proc/scsi/advansys/[0...] file. */ - boardp = ASC_BOARDP(shost); - /* Copy read data starting at the beginning of the buffer. */ *start = buffer; curbuf = buffer; @@ -4477,7 +4451,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, static void asc_scsi_done(struct scsi_cmnd *scp) { - struct asc_board *boardp = ASC_BOARDP(scp->device->host); + struct asc_board *boardp = shost_priv(scp->device->host); if (scp->use_sg) dma_unmap_sg(boardp->dev, @@ -8376,7 +8350,7 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) */ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) { - asc_board_t *boardp; + struct asc_board *boardp; adv_req_t *reqp; adv_sgblk_t *sgblkp; struct scsi_cmnd *scp; @@ -8420,7 +8394,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) ASC_STATS(shost, callback); ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); - boardp = ASC_BOARDP(shost); + boardp = shost_priv(shost); BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); /* @@ -8825,7 +8799,7 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) uchar cur_dvc_qng; uchar asyn_sdtr; uchar scsi_status; - asc_board_t *boardp; + struct asc_board *boardp; BUG_ON(!asc_dvc->drv_ptr); boardp = asc_dvc->drv_ptr; @@ -9346,7 +9320,7 @@ _AscCopyLramScsiDoneQ(PortAddr iop_base, */ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) { - asc_board_t *boardp; + struct asc_board *boardp; struct scsi_cmnd *scp; struct Scsi_Host *shost; @@ -9371,7 +9345,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) ASC_STATS(shost, callback); ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); - boardp = ASC_BOARDP(shost); + boardp = shost_priv(shost); BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); /* @@ -9727,7 +9701,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) static int advansys_reset(struct scsi_cmnd *scp) { struct Scsi_Host *shost = scp->device->host; - struct asc_board *boardp = ASC_BOARDP(shost); + struct asc_board *boardp = shost_priv(shost); unsigned long flags; int status; int ret = SUCCESS; @@ -9810,11 +9784,10 @@ static int advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int ip[]) { - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(sdev->host); ASC_DBG(1, "advansys_biosparam: begin\n"); ASC_STATS(sdev->host, biosparam); - boardp = ASC_BOARDP(sdev->host); if (ASC_NARROW_BOARD(boardp)) { if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { @@ -9848,7 +9821,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) { unsigned long flags; struct Scsi_Host *shost = dev_id; - asc_board_t *boardp = ASC_BOARDP(shost); + struct asc_board *boardp = shost_priv(shost); irqreturn_t result = IRQ_NONE; ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); @@ -10110,7 +10083,7 @@ advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) */ static int advansys_slave_configure(struct scsi_device *sdev) { - asc_board_t *boardp = ASC_BOARDP(sdev->host); + struct asc_board *boardp = shost_priv(sdev->host); if (ASC_NARROW_BOARD(boardp)) advansys_narrow_slave_configure(sdev, @@ -10122,7 +10095,7 @@ static int advansys_slave_configure(struct scsi_device *sdev) return 0; } -static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, +static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, struct asc_scsi_q *asc_scsi_q) { memset(asc_scsi_q, 0, sizeof(*asc_scsi_q)); @@ -10257,7 +10230,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, * ADV_ERROR(-1) - SG List creation failed */ static int -adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, +adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg) { adv_sgblk_t *sgblkp; @@ -10367,7 +10340,7 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, * to little-endian order. */ static int -adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, +adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, ADV_SCSI_REQ_Q **adv_scsiqpp) { adv_req_t *reqp; @@ -11255,7 +11228,7 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) { int ret, err_code; - asc_board_t *boardp = ASC_BOARDP(scp->device->host); + struct asc_board *boardp = shost_priv(scp->device->host); ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp); @@ -11346,7 +11319,7 @@ static int advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { struct Scsi_Host *shost = scp->device->host; - asc_board_t *boardp = ASC_BOARDP(shost); + struct asc_board *boardp = shost_priv(shost); unsigned long flags; int asc_res, result = 0; @@ -12094,7 +12067,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static int __devinit AscInitGetConfig(asc_board_t *boardp) +static int __devinit AscInitGetConfig(struct asc_board *boardp) { ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; unsigned short warn_code = 0; @@ -12151,7 +12124,7 @@ static int __devinit AscInitGetConfig(asc_board_t *boardp) return asc_dvc->err_code; } -static int __devinit AscInitSetConfig(struct pci_dev *pdev, asc_board_t *boardp) +static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *boardp) { ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; PortAddr iop_base = asc_dvc->iop_base; @@ -13548,7 +13521,7 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) * then 0 is returned. */ static int __devinit -AdvInitGetConfig(struct pci_dev *pdev, asc_board_t *boardp) +AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) { ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; unsigned short warn_code = 0; @@ -13660,7 +13633,7 @@ static struct scsi_host_template advansys_template = { }; static int __devinit -advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) +advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) { int req_cnt = 0; adv_req_t *reqp = NULL; @@ -13764,7 +13737,7 @@ advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) return err_code; } -static void advansys_wide_free_mem(asc_board_t *boardp) +static void advansys_wide_free_mem(struct asc_board *boardp) { kfree(boardp->carrp); boardp->carrp = NULL; @@ -13781,12 +13754,11 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, unsigned int iop, int bus_type) { struct pci_dev *pdev; - asc_board_t *boardp; + struct asc_board *boardp = shost_priv(shost); ASC_DVC_VAR *asc_dvc_varp = NULL; ADV_DVC_VAR *adv_dvc_varp = NULL; int share_irq, warn_code, ret; - boardp = ASC_BOARDP(shost); boardp->id = asc_board_count++; spin_lock_init(&boardp->lock); pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; @@ -14282,11 +14254,9 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ static int advansys_release(struct Scsi_Host *shost) { - asc_board_t *boardp; - + struct asc_board *boardp = shost_priv(shost); ASC_DBG(1, "advansys_release: begin\n"); scsi_remove_host(shost); - boardp = ASC_BOARDP(shost); free_irq(boardp->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { ASC_DBG(1, "advansys_release: free_dma()\n"); @@ -14348,7 +14318,7 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) if (!shost) goto release_region; - board = ASC_BOARDP(shost); + board = shost_priv(shost); board->irq = advansys_isa_irq_no(iop_base); board->dev = dev; @@ -14431,7 +14401,7 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) if (!shost) goto release_region; - board = ASC_BOARDP(shost); + board = shost_priv(shost); board->irq = advansys_vlb_irq_no(iop_base); board->dev = dev; @@ -14538,7 +14508,7 @@ static int __devinit advansys_eisa_probe(struct device *dev) if (!shost) goto release_region; - board = ASC_BOARDP(shost); + board = shost_priv(shost); board->irq = irq; board->dev = dev; @@ -14654,7 +14624,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!shost) goto release_region; - board = ASC_BOARDP(shost); + board = shost_priv(shost); board->irq = pdev->irq; board->dev = &pdev->dev; -- cgit v1.1 From b08fc565500a6f691edae7c5ce2e0480365f848c Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:32 -0400 Subject: [SCSI] advansys: Remove library version & serial numbers With the ASC and ADV libraries merged into the driver, there really is no point in reporting their version numbers, or even trying to maintain them. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 60 +++++++++++++------------------------------------ 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 7570380..72ed972 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -77,10 +77,6 @@ /* Enable driver tracing. */ /* #define ADVANSYS_DEBUG */ -#define ASC_LIB_VERSION_MAJOR 1 -#define ASC_LIB_VERSION_MINOR 24 -#define ASC_LIB_SERIAL_NUMBER 123 - /* * Portable Data Types * @@ -554,8 +550,6 @@ typedef struct asc_dvc_cfg { uchar isa_dma_speed; uchar isa_dma_channel; uchar chip_version; - ushort lib_serial_no; - ushort lib_version; ushort mcode_date; ushort mcode_version; uchar max_tag_qng[ASC_MAX_TID + 1]; @@ -958,13 +952,6 @@ typedef struct asc_mc_saved { #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) -#define ADV_LIB_VERSION_MAJOR 5 -#define ADV_LIB_VERSION_MINOR 14 - -/* - * Define Adv Library required special types. - */ - /* * Portable Data Types * @@ -1856,7 +1843,6 @@ typedef struct adv_dvc_cfg { ushort disc_enable; /* enable disconnection */ uchar chip_version; /* chip version */ uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */ - ushort lib_version; /* Adv Library version number */ ushort control_flag; /* Microcode Control Flag */ ushort mcode_date; /* Microcode date */ ushort mcode_version; /* Microcode version */ @@ -2637,18 +2623,13 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n", h->disc_enable, h->sdtr_enable); - printk - (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", - h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, - h->chip_version); - - printk - (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", - to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, - h->mcode_date); + printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, " + "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, + h->isa_dma_channel, h->chip_version); - printk(" mcode_version %d, overrun_buf 0x%lx\n", - h->mcode_version, (ulong)h->overrun_buf); + printk(" pci_device_id %d, mcode_date 0x%x, mcode_version %d, " + "overrun_buf 0x%p\n", to_pci_dev(h->dev)->device, + h->mcode_date, h->mcode_version, h->overrun_buf); } /* @@ -2752,8 +2733,8 @@ static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) printk(" chip_version 0x%x, mcode_date 0x%x\n", h->chip_version, h->mcode_date); - printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", - h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); + printk(" mcode_version 0x%x, pci_device_id 0x%x\n", + h->mcode_version, to_pci_dev(h->dev)->device); printk(" control_flag 0x%x\n", h->control_flag); } @@ -3731,15 +3712,10 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) shost->host_no); ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n", - c->chip_version, c->lib_version, c->lib_serial_no, - c->mcode_date); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, - " mcode_version 0x%x, err_code %u\n", - c->mcode_version, v->err_code); + len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " + "mcode_version 0x%x, err_code %u\n", + c->chip_version, c->mcode_date, c->mcode_version, + v->err_code); ASC_PRT_NEXT(); /* Current number of commands waiting for the host. */ @@ -3934,10 +3910,9 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) v->err_code); ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, - " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n", - c->chip_version, c->lib_version, c->mcode_date, - c->mcode_version); + len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " + "mcode_version 0x%x\n", c->chip_version, + c->mcode_date, c->mcode_version); ASC_PRT_NEXT(); AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); @@ -11566,9 +11541,6 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; - asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; - asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | - ASC_LIB_VERSION_MINOR; chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); asc_dvc->cfg->chip_version = chip_version; asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; @@ -13542,8 +13514,6 @@ AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) if ((cmd & PCI_COMMAND_PARITY) == 0) asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; - asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | - ADV_LIB_VERSION_MINOR; asc_dvc->cfg->chip_version = AdvGetChipVersion(iop_base, asc_dvc->bus_type); -- cgit v1.1 From b352f9237622c64afbac367cadd10d23cb4c5484 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:33 -0400 Subject: [SCSI] advansys: Sort out debug macros Replace ASC_DBG{,1,2,3,4,5} with a single variadic macro ASC_DBG. As suggested by Jeff Garzik, include DRV_NAME and __FUNCTION__ in the output. Change all callers to no longer include the function name in the string. Enabling ADVANSYS_DEBUG to test this feature shows a lot of other problems that need to be fixed: - Reorder asc_prt_* functions now that their prototypes have been removed. - There is no longer a struct device in ASC_DVC_CFG/ADV_DVC_CFG, and it wasn't necessarily a PCI device to begin with. Print the bus_id from asc_board->dev instead. - isr_callback no longer exists. - ASC_DBG_PRT_SCSI_CMND isn't being used, so delete asc_prt_scsi_cmnd too. - A missing semicolon Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 628 ++++++++++++++++++++---------------------------- 1 file changed, 262 insertions(+), 366 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 72ed972..6bd8e83 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -75,7 +75,7 @@ #define ADVANSYS_STATS /* Enable driver tracing. */ -/* #define ADVANSYS_DEBUG */ +#undef ADVANSYS_DEBUG /* * Portable Data Types @@ -2277,13 +2277,8 @@ do { \ #ifndef ADVANSYS_DEBUG -#define ASC_DBG(lvl, s) -#define ASC_DBG1(lvl, s, a1) -#define ASC_DBG2(lvl, s, a1, a2) -#define ASC_DBG3(lvl, s, a1, a2, a3) -#define ASC_DBG4(lvl, s, a1, a2, a3, a4) +#define ASC_DBG(lvl, s...) #define ASC_DBG_PRT_SCSI_HOST(lvl, s) -#define ASC_DBG_PRT_SCSI_CMND(lvl, s) #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) @@ -2302,40 +2297,11 @@ do { \ * 2-N: Verbose Tracing */ -#define ASC_DBG(lvl, s) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - printk(s); \ - } \ - } - -#define ASC_DBG1(lvl, s, a1) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - printk((s), (a1)); \ - } \ - } - -#define ASC_DBG2(lvl, s, a1, a2) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - printk((s), (a1), (a2)); \ - } \ - } - -#define ASC_DBG3(lvl, s, a1, a2, a3) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - printk((s), (a1), (a2), (a3)); \ - } \ - } - -#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - printk((s), (a1), (a2), (a3), (a4)); \ - } \ - } +#define ASC_DBG(lvl, format, arg...) { \ + if (asc_dbglvl >= (lvl)) \ + printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \ + __FUNCTION__ , ## arg); \ +} #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ { \ @@ -2344,13 +2310,6 @@ do { \ } \ } -#define ASC_DBG_PRT_SCSI_CMND(lvl, s) \ - { \ - if (asc_dbglvl >= (lvl)) { \ - asc_prt_scsi_cmnd(s); \ - } \ - } - #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \ { \ if (asc_dbglvl >= (lvl)) { \ @@ -2519,64 +2478,6 @@ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; static int asc_dbglvl = 3; /* - * asc_prt_scsi_host() - */ -static void asc_prt_scsi_host(struct Scsi_Host *s) -{ - struct asc_board *boardp = shost_priv(s); - - printk("Scsi_Host at addr 0x%lx\n", (ulong)s); - printk(" host_busy %u, host_no %d, last_reset %d,\n", - s->host_busy, s->host_no, (unsigned)s->last_reset); - - printk(" base 0x%lx, io_port 0x%lx, irq 0x%x,\n", - (ulong)s->base, (ulong)s->io_port, boardp->irq); - - printk(" dma_channel %d, this_id %d, can_queue %d,\n", - s->dma_channel, s->this_id, s->can_queue); - - printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", - s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); - - if (ASC_NARROW_BOARD(boardp)) { - asc_prt_asc_dvc_var(boardp->dvc_var.asc_dvc_var); - asc_prt_asc_dvc_cfg(boardp->dvc_cfg.asc_dvc_cfg); - } else { - asc_prt_adv_dvc_var(boardp->dvc_var.adv_dvc_var); - asc_prt_adv_dvc_cfg(boardp->dvc_cfg.adv_dvc_cfg); - } -} - -/* - * asc_prt_scsi_cmnd() - */ -static void asc_prt_scsi_cmnd(struct scsi_cmnd *s) -{ - printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s); - - printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", - (ulong)s->device->host, (ulong)s->device, s->device->id, - s->device->lun, s->device->channel); - - asc_prt_hex(" CDB", s->cmnd, s->cmd_len); - - printk("sc_data_direction %u, resid %d\n", - s->sc_data_direction, s->resid); - - printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len); - - printk(" serial_number 0x%x, retries %d, allowed %d\n", - (unsigned)s->serial_number, s->retries, s->allowed); - - printk(" timeout_per_command %d\n", s->timeout_per_command); - - printk(" scsi_done 0x%p, done 0x%p, host_scribble 0x%p, result 0x%x\n", - s->scsi_done, s->done, s->host_scribble, s->result); - - printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid); -} - -/* * asc_prt_asc_dvc_var() */ static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) @@ -2627,65 +2528,11 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, h->chip_version); - printk(" pci_device_id %d, mcode_date 0x%x, mcode_version %d, " - "overrun_buf 0x%p\n", to_pci_dev(h->dev)->device, + printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n", h->mcode_date, h->mcode_version, h->overrun_buf); } /* - * asc_prt_asc_scsi_q() - */ -static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) -{ - ASC_SG_HEAD *sgp; - int i; - - printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); - - printk - (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", - q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, - q->q2.tag_code); - - printk - (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", - (ulong)le32_to_cpu(q->q1.data_addr), - (ulong)le32_to_cpu(q->q1.data_cnt), - (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); - - printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", - (ulong)q->cdbptr, q->q2.cdb_len, - (ulong)q->sg_head, q->q1.sg_queue_cnt); - - if (q->sg_head) { - sgp = q->sg_head; - printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); - printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, - sgp->queue_cnt); - for (i = 0; i < sgp->entry_cnt; i++) { - printk(" [%u]: addr 0x%lx, bytes %lu\n", - i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), - (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); - } - - } -} - -/* - * asc_prt_asc_qdone_info() - */ -static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) -{ - printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); - printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", - (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, - q->d2.tag_code); - printk - (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", - q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); -} - -/* * asc_prt_adv_dvc_var() * * Display an ADV_DVC_VAR structure. @@ -2697,9 +2544,8 @@ static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able); - printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n", - (ulong)h->isr_callback, (unsigned)h->sdtr_able, - (unsigned)h->wdtr_able); + printk(" sdtr_able 0x%x, wdtr_able 0x%x\n", + (unsigned)h->sdtr_able, (unsigned)h->wdtr_able); printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n", (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); @@ -2733,87 +2579,36 @@ static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) printk(" chip_version 0x%x, mcode_date 0x%x\n", h->chip_version, h->mcode_date); - printk(" mcode_version 0x%x, pci_device_id 0x%x\n", - h->mcode_version, to_pci_dev(h->dev)->device); - - printk(" control_flag 0x%x\n", h->control_flag); + printk(" mcode_version 0x%x, control_flag 0x%x\n", + h->mcode_version, h->control_flag); } /* - * asc_prt_adv_scsi_req_q() - * - * Display an ADV_SCSI_REQ_Q structure. + * asc_prt_scsi_host() */ -static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) +static void asc_prt_scsi_host(struct Scsi_Host *s) { - int sg_blk_cnt; - struct asc_sg_block *sg_ptr; - - printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); - - printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", - q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); - - printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", - q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); - - printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", - (ulong)le32_to_cpu(q->data_cnt), - (ulong)le32_to_cpu(q->sense_addr), q->sense_len); - - printk - (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", - q->cdb_len, q->done_status, q->host_status, q->scsi_status); + struct asc_board *boardp = shost_priv(s); - printk(" sg_working_ix 0x%x, target_cmd %u\n", - q->sg_working_ix, q->target_cmd); + printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id); + printk(" host_busy %u, host_no %d, last_reset %d,\n", + s->host_busy, s->host_no, (unsigned)s->last_reset); - printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", - (ulong)le32_to_cpu(q->scsiq_rptr), - (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); + printk(" base 0x%lx, io_port 0x%lx, irq %d,\n", + (ulong)s->base, (ulong)s->io_port, boardp->irq); - /* Display the request's ADV_SG_BLOCK structures. */ - if (q->sg_list_ptr != NULL) { - sg_blk_cnt = 0; - while (1) { - /* - * 'sg_ptr' is a physical address. Convert it to a virtual - * address by indexing 'sg_blk_cnt' into the virtual address - * array 'sg_list_ptr'. - * - * XXX - Assumes all SG physical blocks are virtually contiguous. - */ - sg_ptr = - &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); - asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); - if (sg_ptr->sg_ptr == 0) { - break; - } - sg_blk_cnt++; - } - } -} + printk(" dma_channel %d, this_id %d, can_queue %d,\n", + s->dma_channel, s->this_id, s->can_queue); -/* - * asc_prt_adv_sgblock() - * - * Display an ADV_SG_BLOCK structure. - */ -static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) -{ - int i; + printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", + s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); - printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", - (ulong)b, sgblockno); - printk(" sg_cnt %u, sg_ptr 0x%lx\n", - b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); - BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); - if (b->sg_ptr != 0) - BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); - for (i = 0; i < b->sg_cnt; i++) { - printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", - i, (ulong)b->sg_list[i].sg_addr, - (ulong)b->sg_list[i].sg_count); + if (ASC_NARROW_BOARD(boardp)) { + asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var); + asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg); + } else { + asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var); + asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg); } } @@ -2873,6 +2668,137 @@ static void asc_prt_hex(char *f, uchar *s, int l) printk("\n"); } } + +/* + * asc_prt_asc_scsi_q() + */ +static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) +{ + ASC_SG_HEAD *sgp; + int i; + + printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); + + printk + (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", + q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, + q->q2.tag_code); + + printk + (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", + (ulong)le32_to_cpu(q->q1.data_addr), + (ulong)le32_to_cpu(q->q1.data_cnt), + (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); + + printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", + (ulong)q->cdbptr, q->q2.cdb_len, + (ulong)q->sg_head, q->q1.sg_queue_cnt); + + if (q->sg_head) { + sgp = q->sg_head; + printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); + printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, + sgp->queue_cnt); + for (i = 0; i < sgp->entry_cnt; i++) { + printk(" [%u]: addr 0x%lx, bytes %lu\n", + i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), + (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); + } + + } +} + +/* + * asc_prt_asc_qdone_info() + */ +static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) +{ + printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); + printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", + (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, + q->d2.tag_code); + printk + (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", + q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); +} + +/* + * asc_prt_adv_sgblock() + * + * Display an ADV_SG_BLOCK structure. + */ +static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) +{ + int i; + + printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", + (ulong)b, sgblockno); + printk(" sg_cnt %u, sg_ptr 0x%lx\n", + b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); + BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); + if (b->sg_ptr != 0) + BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); + for (i = 0; i < b->sg_cnt; i++) { + printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", + i, (ulong)b->sg_list[i].sg_addr, + (ulong)b->sg_list[i].sg_count); + } +} + +/* + * asc_prt_adv_scsi_req_q() + * + * Display an ADV_SCSI_REQ_Q structure. + */ +static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) +{ + int sg_blk_cnt; + struct asc_sg_block *sg_ptr; + + printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); + + printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", + q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); + + printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", + q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); + + printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", + (ulong)le32_to_cpu(q->data_cnt), + (ulong)le32_to_cpu(q->sense_addr), q->sense_len); + + printk + (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", + q->cdb_len, q->done_status, q->host_status, q->scsi_status); + + printk(" sg_working_ix 0x%x, target_cmd %u\n", + q->sg_working_ix, q->target_cmd); + + printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", + (ulong)le32_to_cpu(q->scsiq_rptr), + (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); + + /* Display the request's ADV_SG_BLOCK structures. */ + if (q->sg_list_ptr != NULL) { + sg_blk_cnt = 0; + while (1) { + /* + * 'sg_ptr' is a physical address. Convert it to a virtual + * address by indexing 'sg_blk_cnt' into the virtual address + * array 'sg_list_ptr'. + * + * XXX - Assumes all SG physical blocks are virtually contiguous. + */ + sg_ptr = + &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); + asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); + if (sg_ptr->sg_ptr == 0) { + break; + } + sg_blk_cnt++; + } + } +} #endif /* ADVANSYS_DEBUG */ /* @@ -2895,7 +2821,7 @@ static const char *advansys_info(struct Scsi_Host *shost) if (ASC_NARROW_BOARD(boardp)) { asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; - ASC_DBG(1, "advansys_info: begin\n"); + ASC_DBG(1, "begin\n"); if (asc_dvc_varp->bus_type & ASC_IS_ISA) { if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) { @@ -2955,7 +2881,7 @@ static const char *advansys_info(struct Scsi_Host *shost) (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq); } BUG_ON(strlen(info) >= ASC_INFO_SIZE); - ASC_DBG(1, "advansys_info: end\n"); + ASC_DBG(1, "end\n"); return info; } @@ -4118,12 +4044,12 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, { int cnt = 0; - ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", + ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n", (unsigned)offset, (unsigned)advoffset, cplen); if (offset <= advoffset) { /* Read offset below current offset, copy everything. */ cnt = min(cplen, leftlen); - ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", + ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", (ulong)curbuf, (ulong)cp, cnt); memcpy(curbuf, cp, cnt); } else if (offset < advoffset + cplen) { @@ -4131,7 +4057,7 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, cnt = (advoffset + cplen) - offset; cp = (cp + cplen) - cnt; cnt = min(cnt, leftlen); - ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", + ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", (ulong)curbuf, (ulong)cp, cnt); memcpy(curbuf, cp, cnt); } @@ -4270,7 +4196,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, char *curbuf; off_t advoffset; - ASC_DBG(1, "advansys_proc_info: begin\n"); + ASC_DBG(1, "begin\n"); /* * User write not supported. @@ -4302,7 +4228,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4320,7 +4246,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4337,7 +4263,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4357,7 +4283,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4373,7 +4299,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4390,7 +4316,7 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; @@ -4412,13 +4338,13 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, totcnt += cnt; leftlen -= cnt; if (leftlen == 0) { - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } advoffset += cplen; curbuf += cnt; - ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); + ASC_DBG(1, "totcnt %d\n", totcnt); return totcnt; } @@ -4530,11 +4456,10 @@ static int AscFindSignature(PortAddr iop_base) { ushort sig_word; - ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n", + ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n", iop_base, AscGetChipSignatureByte(iop_base)); if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) { - ASC_DBG2(1, - "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n", + ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n", iop_base, AscGetChipSignatureWord(iop_base)); sig_word = AscGetChipSignatureWord(iop_base); if ((sig_word == (ushort)ASC_1000_ID0W) || @@ -4785,18 +4710,17 @@ AscLoadMicroCode(PortAddr iop_base, AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); - ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum); + ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum); mcode_chksum = (ushort)AscMemSumLramWord(iop_base, (ushort)ASC_CODE_SEC_BEG, (ushort)((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2)); - ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n", - (ulong)mcode_chksum); + ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum); AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); - return (chksum); + return chksum; } /* Microcode buffer is kept after initialization for error recovery. */ @@ -6511,8 +6435,7 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) warn_code |= AscInitLram(asc_dvc); if (asc_dvc->err_code != 0) return UW_ERR; - ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n", - (ulong)_asc_mcode_chksum); + ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum); if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, _asc_mcode_size) != _asc_mcode_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; @@ -6613,7 +6536,7 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, { ADV_PADDR paddr = virt_to_bus(vaddr); - ASC_DBG4(4, "DvcGetPhyAddr: vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n", + ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n", vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr); return paddr; @@ -8291,8 +8214,7 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) /* * The firmware detected a SCSI Bus reset. */ - ASC_DBG(0, - "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n"); + ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n"); break; case ADV_ASYNC_RDMA_FAILURE: @@ -8301,7 +8223,7 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) * possibly the chip if it is unresponsive. Log the error * with a unique code. */ - ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n"); + ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n"); AdvResetChipAndSB(adv_dvc_varp); break; @@ -8309,11 +8231,11 @@ static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) /* * Host generated SCSI bus reset occurred. */ - ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n"); + ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n"); break; default: - ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code); + ASC_DBG(0, "unknown code 0x%x\n", code); break; } } @@ -8332,7 +8254,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) struct Scsi_Host *shost; ADV_DCNT resid_cnt; - ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", + ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", (ulong)adv_dvc_varp, (ulong)scsiqp); ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); @@ -8342,7 +8264,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) * completed ADV_SCSI_REQ_Q structure. */ reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr); - ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp); + ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp); if (reqp == NULL) { ASC_PRINT("adv_isr_callback: reqp is NULL\n"); return; @@ -8357,7 +8279,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) * determined. */ scp = reqp->cmndp; - ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp); + ASC_DBG(1, "scp 0x%p\n", scp); if (scp == NULL) { ASC_PRINT ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); @@ -8367,7 +8289,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) shost = scp->device->host; ASC_STATS(shost, callback); - ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); + ASC_DBG(1, "shost 0x%p\n", shost); boardp = shost_priv(shost); BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); @@ -8377,7 +8299,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) */ switch (scsiqp->done_status) { case QD_NO_ERROR: - ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); + ASC_DBG(2, "QD_NO_ERROR\n"); scp->result = 0; /* @@ -8389,20 +8311,18 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) resid_cnt = le32_to_cpu(scsiqp->data_cnt); if (scp->request_bufflen != 0 && resid_cnt != 0 && resid_cnt <= scp->request_bufflen) { - ASC_DBG1(1, - "adv_isr_callback: underrun condition %lu bytes\n", + ASC_DBG(1, "underrun condition %lu bytes\n", (ulong)resid_cnt); scp->resid = resid_cnt; } break; case QD_WITH_ERROR: - ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); + ASC_DBG(2, "QD_WITH_ERROR\n"); switch (scsiqp->host_status) { case QHSTA_NO_ERROR: if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { - ASC_DBG(2, - "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); + ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* @@ -8426,22 +8346,20 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) default: /* Some other QHSTA error occurred. */ - ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n", - scsiqp->host_status); + ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status); scp->result = HOST_BYTE(DID_BAD_TARGET); break; } break; case QD_ABORTED_BY_HOST: - ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); + ASC_DBG(1, "QD_ABORTED_BY_HOST\n"); scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); break; default: - ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", - scsiqp->done_status); + ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status); scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); break; @@ -8479,7 +8397,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) reqp->next_reqp = boardp->adv_reqp; boardp->adv_reqp = reqp; - ASC_DBG(1, "adv_isr_callback: done\n"); + ASC_DBG(1, "done\n"); return; } @@ -9299,8 +9217,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) struct scsi_cmnd *scp; struct Scsi_Host *shost; - ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", - (ulong)asc_dvc_varp, (ulong)qdonep); + ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep); ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); /* @@ -9308,7 +9225,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) * command that has been completed. */ scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); - ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp); + ASC_DBG(1, "scp 0x%p\n", scp); if (scp == NULL) { ASC_PRINT("asc_isr_callback: scp is NULL\n"); @@ -9318,7 +9235,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) shost = scp->device->host; ASC_STATS(shost, callback); - ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); + ASC_DBG(1, "shost 0x%p\n", shost); boardp = shost_priv(shost); BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); @@ -9328,7 +9245,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) */ switch (qdonep->d3.done_stat) { case QD_NO_ERROR: - ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); + ASC_DBG(2, "QD_NO_ERROR\n"); scp->result = 0; /* @@ -9339,20 +9256,18 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) */ if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && qdonep->remain_bytes <= scp->request_bufflen) { - ASC_DBG1(1, - "asc_isr_callback: underrun condition %u bytes\n", + ASC_DBG(1, "underrun condition %u bytes\n", (unsigned)qdonep->remain_bytes); scp->resid = qdonep->remain_bytes; } break; case QD_WITH_ERROR: - ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); + ASC_DBG(2, "QD_WITH_ERROR\n"); switch (qdonep->d3.host_stat) { case QHSTA_NO_ERROR: if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { - ASC_DBG(2, - "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); + ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); ASC_DBG_PRT_SENSE(2, scp->sense_buffer, sizeof(scp->sense_buffer)); /* @@ -9376,15 +9291,14 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) default: /* QHSTA error occurred */ - ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n", - qdonep->d3.host_stat); + ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat); scp->result = HOST_BYTE(DID_BAD_TARGET); break; } break; case QD_ABORTED_BY_HOST: - ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); + ASC_DBG(1, "QD_ABORTED_BY_HOST\n"); scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3. scsi_msg) | @@ -9392,8 +9306,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) break; default: - ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", - qdonep->d3.done_stat); + ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat); scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3. scsi_msg) | @@ -9681,7 +9594,7 @@ static int advansys_reset(struct scsi_cmnd *scp) int status; int ret = SUCCESS; - ASC_DBG1(1, "advansys_reset: 0x%p\n", scp); + ASC_DBG(1, "0x%p\n", scp); ASC_STATS(shost, reset); @@ -9691,7 +9604,7 @@ static int advansys_reset(struct scsi_cmnd *scp) ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; /* Reset the chip and SCSI bus. */ - ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); + ASC_DBG(1, "before AscInitAsc1000Driver()\n"); status = AscInitAsc1000Driver(asc_dvc); /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ @@ -9707,7 +9620,7 @@ static int advansys_reset(struct scsi_cmnd *scp) "successful\n"); } - ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); + ASC_DBG(1, "after AscInitAsc1000Driver()\n"); spin_lock_irqsave(&boardp->lock, flags); } else { /* @@ -9719,7 +9632,7 @@ static int advansys_reset(struct scsi_cmnd *scp) /* * Reset the target's SCSI bus. */ - ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); + ASC_DBG(1, "before AdvResetChipAndSB()\n"); switch (AdvResetChipAndSB(adv_dvc)) { case ASC_TRUE: scmd_printk(KERN_INFO, scp, "SCSI bus reset " @@ -9739,7 +9652,7 @@ static int advansys_reset(struct scsi_cmnd *scp) boardp->last_reset = jiffies; spin_unlock_irqrestore(&boardp->lock, flags); - ASC_DBG1(1, "advansys_reset: ret %d\n", ret); + ASC_DBG(1, "ret %d\n", ret); return ret; } @@ -9761,7 +9674,7 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, { struct asc_board *boardp = shost_priv(sdev->host); - ASC_DBG(1, "advansys_biosparam: begin\n"); + ASC_DBG(1, "begin\n"); ASC_STATS(sdev->host, biosparam); if (ASC_NARROW_BOARD(boardp)) { if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & @@ -9783,7 +9696,7 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, } } ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); - ASC_DBG(1, "advansys_biosparam: end\n"); + ASC_DBG(1, "end\n"); return 0; } @@ -9799,17 +9712,17 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) struct asc_board *boardp = shost_priv(shost); irqreturn_t result = IRQ_NONE; - ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp); + ASC_DBG(2, "boardp 0x%p\n", boardp); spin_lock_irqsave(&boardp->lock, flags); if (ASC_NARROW_BOARD(boardp)) { if (AscIsIntPending(shost->io_port)) { result = IRQ_HANDLED; ASC_STATS(shost, interrupt); - ASC_DBG(1, "advansys_interrupt: before AscISR()\n"); + ASC_DBG(1, "before AscISR()\n"); AscISR(&boardp->dvc_var.asc_dvc_var); } } else { - ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); + ASC_DBG(1, "before AdvISR()\n"); if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { result = IRQ_HANDLED; ASC_STATS(shost, interrupt); @@ -9817,7 +9730,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) } spin_unlock_irqrestore(&boardp->lock, flags); - ASC_DBG(1, "advansys_interrupt: end\n"); + ASC_DBG(1, "end\n"); return result; } @@ -10186,7 +10099,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, } } - ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); + ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q); ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); return ASC_NOERROR; @@ -10229,7 +10142,7 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, * (15) scatter-gather elements. */ if ((sgblkp = boardp->adv_sgblkp) == NULL) { - ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); + ASC_DBG(1, "no free adv_sgblk_t\n"); ASC_STATS(scp->device->host, adv_build_nosg); /* @@ -10328,7 +10241,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, * the command. */ if (boardp->adv_reqp == NULL) { - ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); + ASC_DBG(1, "no free adv_req_t\n"); ASC_STATS(scp->device->host, adv_build_noreq); return ASC_BUSY; } else { @@ -11205,7 +11118,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) int ret, err_code; struct asc_board *boardp = shost_priv(scp->device->host); - ASC_DBG1(1, "asc_execute_scsi_cmnd: scp 0x%p\n", scp); + ASC_DBG(1, "scp 0x%p\n", scp); if (ASC_NARROW_BOARD(boardp)) { ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; @@ -11227,12 +11140,10 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) switch (adv_build_req(boardp, scp, &adv_scsiqp)) { case ASC_NOERROR: - ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_NOERROR\n"); + ASC_DBG(3, "adv_build_req ASC_NOERROR\n"); break; case ASC_BUSY: - ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_BUSY\n"); + ASC_DBG(1, "adv_build_req ASC_BUSY\n"); /* * The asc_stats fields 'adv_build_noreq' and * 'adv_build_nosg' count wide board busy conditions. @@ -11242,8 +11153,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) return ASC_BUSY; case ASC_ERROR: default: - ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " - "ASC_ERROR\n"); + ASC_DBG(1, "adv_build_req ASC_ERROR\n"); ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } @@ -11260,8 +11170,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * successful request counter. Wrapping doesn't matter. */ boardp->reqcnt[scp->device->id]++; - ASC_DBG(1, "asc_execute_scsi_cmnd: ExeScsiQueue(), " - "ASC_NOERROR\n"); + ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n"); break; case ASC_BUSY: ASC_STATS(scp->device->host, exe_busy); @@ -11280,7 +11189,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) break; } - ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); + ASC_DBG(1, "end\n"); return ret; } @@ -11911,7 +11820,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) AscSetChipCfgMsw(iop_base, cfg_msw); } chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); - ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum); + ASC_DBG(1, "chksum 0x%x\n", chksum); if (chksum == 0) { chksum = 0xaa55; } @@ -11932,13 +11841,11 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) } eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; - ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n", - eep_config->chksum); + ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum); if (chksum != eep_config->chksum) { if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == ASC_CHIP_VER_PCI_ULTRA_3050) { - ASC_DBG(1, - "AscInitFromEEP: chksum error ignored; EEPROM-less board\n"); + ASC_DBG(1, "chksum error ignored; EEPROM-less board\n"); eep_config->init_sdtr = 0xFF; eep_config->disc_enable = 0xFF; eep_config->start_motor = 0xFF; @@ -13517,11 +13424,11 @@ AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) asc_dvc->cfg->chip_version = AdvGetChipVersion(iop_base, asc_dvc->bus_type); - ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n", + ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n", (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), (ushort)ADV_CHIP_ID_BYTE); - ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n", + ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n", (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), (ushort)ADV_CHIP_ID_WORD); @@ -13616,7 +13523,7 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) * is about 4 KB, so allocate all at once. */ boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); - ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp); + ASC_DBG(1, "carrp 0x%p\n", boardp->carrp); if (!boardp->carrp) goto kmalloc_failed; @@ -13629,8 +13536,7 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) { reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); - ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, " - "bytes %lu\n", reqp, req_cnt, + ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt, (ulong)sizeof(adv_req_t) * req_cnt); if (reqp) @@ -13658,8 +13564,7 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) } - ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n", - sg_cnt, sizeof(adv_sgblk_t), + ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t), (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); if (!boardp->adv_sgblkp) @@ -13679,15 +13584,13 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) boardp->adv_reqp = &reqp[0]; if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { - ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n"); + ASC_DBG(2, "AdvInitAsc3550Driver()\n"); warn_code = AdvInitAsc3550Driver(adv_dvc_varp); } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { - ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()" - "\n"); + ASC_DBG(2, "AdvInitAsc38C0800Driver()\n"); warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); } else { - ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()" - "\n"); + ASC_DBG(2, "AdvInitAsc38C1600Driver()\n"); warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); } err_code = adv_dvc_varp->err_code; @@ -13734,7 +13637,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; if (ASC_NARROW_BOARD(boardp)) { - ASC_DBG(1, "advansys_board_found: narrow board\n"); + ASC_DBG(1, "narrow board\n"); asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; asc_dvc_varp->bus_type = bus_type; asc_dvc_varp->drv_ptr = boardp; @@ -13743,18 +13646,17 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, asc_dvc_varp->iop_base = iop; } else { #ifdef CONFIG_PCI - ASC_DBG(1, "advansys_board_found: wide board\n"); adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; adv_dvc_varp->drv_ptr = boardp; adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) { - ASC_DBG(1, "advansys_board_found: ASC-3550\n"); + ASC_DBG(1, "wide board ASC-3550\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) { - ASC_DBG(1, "advansys_board_found: ASC-38C0800\n"); + ASC_DBG(1, "wide board ASC-38C0800\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800; } else { - ASC_DBG(1, "advansys_board_found: ASC-38C1600\n"); + ASC_DBG(1, "wide board ASC-38C1600\n"); adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600; } @@ -13769,9 +13671,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, ret = -ENODEV; goto err_shost; } - adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr - ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n", - adv_dvc_varp->iop_base); + adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr; + ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base); /* * Even though it isn't used to access wide boards, other @@ -13780,9 +13681,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ boardp->ioport = iop; - ASC_DBG2(1, "advansys_board_found: iopb_chip_id_1 0x%x, " - "iopw_chip_id_0 0x%x\n", (ushort)inp(iop + 1), - (ushort)inpw(iop)); + ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n", + (ushort)inp(iop + 1), (ushort)inpw(iop)); #endif /* CONFIG_PCI */ } @@ -13841,7 +13741,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * longer be used. If the bus_type field must be * referenced only use the bit-wise AND operator "&". */ - ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n"); + ASC_DBG(2, "AscInitGetConfig()\n"); ret = AscInitGetConfig(boardp) ? -ENODEV : 0; } else { #ifdef CONFIG_PCI @@ -13851,7 +13751,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ shost->unchecked_isa_dma = FALSE; share_irq = IRQF_SHARED; - ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); + ASC_DBG(2, "AdvInitGetConfig()\n"); ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0; #endif /* CONFIG_PCI */ @@ -13900,7 +13800,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, /* * Modify board configuration. */ - ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); + ASC_DBG(2, "AscInitSetConfig()\n"); ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0; if (ret) goto err_free_proc; @@ -14081,7 +13981,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, shost->sg_tablesize = SG_ALL; } - ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize); + ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize); /* BIOS start address. */ if (ASC_NARROW_BOARD(boardp)) { @@ -14101,12 +14001,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN, boardp->bios_codelen); - ASC_DBG2(1, - "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n", + ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n", boardp->bios_signature, boardp->bios_version); - ASC_DBG2(1, - "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n", + ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n", boardp->bios_codeseg, boardp->bios_codelen); /* @@ -14148,7 +14046,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, #endif /* CONFIG_ISA */ /* Register IRQ Number. */ - ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", boardp->irq); + ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost); ret = request_irq(boardp->irq, advansys_interrupt, share_irq, DRV_NAME, shost); @@ -14174,7 +14072,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * Initialize board RISC chip and enable interrupts. */ if (ASC_NARROW_BOARD(boardp)) { - ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n"); + ASC_DBG(2, "AscInitAsc1000Driver()\n"); warn_code = AscInitAsc1000Driver(asc_dvc_varp); if (warn_code || asc_dvc_varp->err_code) { @@ -14225,11 +14123,11 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, static int advansys_release(struct Scsi_Host *shost) { struct asc_board *boardp = shost_priv(shost); - ASC_DBG(1, "advansys_release: begin\n"); + ASC_DBG(1, "begin\n"); scsi_remove_host(shost); free_irq(boardp->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { - ASC_DBG(1, "advansys_release: free_dma()\n"); + ASC_DBG(1, "free_dma()\n"); free_dma(shost->dma_channel); } if (!ASC_NARROW_BOARD(boardp)) { @@ -14238,7 +14136,7 @@ static int advansys_release(struct Scsi_Host *shost) } kfree(boardp->prtbuf); scsi_host_put(shost); - ASC_DBG(1, "advansys_release: end\n"); + ASC_DBG(1, "end\n"); return 0; } @@ -14273,11 +14171,10 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) struct asc_board *board; if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { - ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n", - iop_base); + ASC_DBG(1, "I/O port 0x%x busy\n", iop_base); return -ENODEV; } - ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); + ASC_DBG(1, "probing I/O port 0x%x\n", iop_base); if (!AscFindSignature(iop_base)) goto release_region; if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) @@ -14351,11 +14248,10 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) struct asc_board *board; if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { - ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n", - iop_base); + ASC_DBG(1, "I/O port 0x%x busy\n", iop_base); return -ENODEV; } - ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); + ASC_DBG(1, "probing I/O port 0x%x\n", iop_base); if (!AscFindSignature(iop_base)) goto release_region; /* -- cgit v1.1 From f092d2290f905b6e9928df6905f2fc9d18b6ae19 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:34 -0400 Subject: [SCSI] advansys: Remove private lock The board lock was essentially identical with the host lock. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 6bd8e83..a4091ab 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2439,7 +2439,6 @@ struct asc_board { ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */ } eep_config; ulong last_reset; /* Saved last reset time */ - spinlock_t lock; /* Board spinlock */ /* /proc/scsi/advansys/[0...] */ char *prtbuf; /* /proc print buffer */ #ifdef ADVANSYS_STATS @@ -9621,7 +9620,7 @@ static int advansys_reset(struct scsi_cmnd *scp) } ASC_DBG(1, "after AscInitAsc1000Driver()\n"); - spin_lock_irqsave(&boardp->lock, flags); + spin_lock_irqsave(shost->host_lock, flags); } else { /* * If the suggest reset bus flags are set, then reset the bus. @@ -9644,13 +9643,13 @@ static int advansys_reset(struct scsi_cmnd *scp) ret = FAILED; break; } - spin_lock_irqsave(&boardp->lock, flags); + spin_lock_irqsave(shost->host_lock, flags); AdvISR(adv_dvc); } /* Save the time of the most recently completed reset. */ boardp->last_reset = jiffies; - spin_unlock_irqrestore(&boardp->lock, flags); + spin_unlock_irqrestore(shost->host_lock, flags); ASC_DBG(1, "ret %d\n", ret); @@ -9707,13 +9706,12 @@ advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, */ static irqreturn_t advansys_interrupt(int irq, void *dev_id) { - unsigned long flags; struct Scsi_Host *shost = dev_id; struct asc_board *boardp = shost_priv(shost); irqreturn_t result = IRQ_NONE; ASC_DBG(2, "boardp 0x%p\n", boardp); - spin_lock_irqsave(&boardp->lock, flags); + spin_lock(shost->host_lock); if (ASC_NARROW_BOARD(boardp)) { if (AscIsIntPending(shost->io_port)) { result = IRQ_HANDLED; @@ -9728,7 +9726,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) ASC_STATS(shost, interrupt); } } - spin_unlock_irqrestore(&boardp->lock, flags); + spin_unlock(shost->host_lock); ASC_DBG(1, "end\n"); return result; @@ -11203,20 +11201,12 @@ static int advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { struct Scsi_Host *shost = scp->device->host; - struct asc_board *boardp = shost_priv(shost); - unsigned long flags; int asc_res, result = 0; ASC_STATS(shost, queuecommand); scp->scsi_done = done; - /* - * host_lock taken by mid-level prior to call, but need - * to protect against own ISR - */ - spin_lock_irqsave(&boardp->lock, flags); asc_res = asc_execute_scsi_cmnd(scp); - spin_unlock_irqrestore(&boardp->lock, flags); switch (asc_res) { case ASC_NOERROR: @@ -13633,7 +13623,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, int share_irq, warn_code, ret; boardp->id = asc_board_count++; - spin_lock_init(&boardp->lock); pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; if (ASC_NARROW_BOARD(boardp)) { -- cgit v1.1 From 9d0e96eba19e9973a1c21ddd1fdbc049b231bf3b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:35 -0400 Subject: [SCSI] advansys: Get rid of board index number It's always a mistake to have your own index of boards; just use the scsi host number. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 236 ++++++++++++++++++++---------------------------- 1 file changed, 100 insertions(+), 136 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index a4091ab..93bf3ec 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -66,8 +66,7 @@ * 5. check DMA mapping functions for failure * 6. Use scsi_transport_spi * 7. advansys_info is not safe against multiple simultaneous callers - * 8. Kill boardp->id - * 9. Add module_param to override ISA/VLB ioport array + * 8. Add module_param to override ISA/VLB ioport array */ #warning this driver is still not properly converted to the DMA API @@ -2416,7 +2415,6 @@ typedef struct adv_req { */ struct asc_board { struct device *dev; - int id; /* Board Id */ uint flags; /* Board flags */ unsigned int irq; union { @@ -2467,9 +2465,6 @@ struct asc_board { dvc_var.adv_dvc_var) #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) -/* Number of boards detected in system. */ -static int asc_board_count; - /* Overrun buffer used by all narrow boards. */ static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; @@ -2848,9 +2843,8 @@ static const char *advansys_info(struct Scsi_Host *shost) } } else { busname = "?"; - ASC_PRINT2("advansys_info: board %d: unknown " - "bus type %d\n", boardp->id, - asc_dvc_varp->bus_type); + shost_printk(KERN_ERR, shost, "unknown bus " + "type %d\n", asc_dvc_varp->bus_type); } sprintf(info, "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", @@ -4382,7 +4376,6 @@ static void AscSetBank(PortAddr iop_base, uchar bank) val &= ~CC_BANK_ONE; } AscSetChipControl(iop_base, val); - return; } static void AscSetChipIH(PortAddr iop_base, ushort ins_code) @@ -4390,7 +4383,6 @@ static void AscSetChipIH(PortAddr iop_base, ushort ins_code) AscSetBank(iop_base, 1); AscWriteChipIH(iop_base, ins_code); AscSetBank(iop_base, 0); - return; } static int AscStartChip(PortAddr iop_base) @@ -4475,7 +4467,6 @@ static void AscEnableInterrupt(PortAddr iop_base) cfg = AscGetChipCfgLsw(iop_base); AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); - return; } static void AscDisableInterrupt(PortAddr iop_base) @@ -4484,7 +4475,6 @@ static void AscDisableInterrupt(PortAddr iop_base) cfg = AscGetChipCfgLsw(iop_base); AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); - return; } static uchar AscReadLramByte(PortAddr iop_base, ushort addr) @@ -4542,7 +4532,6 @@ static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) { AscSetChipLramAddr(iop_base, addr); AscSetChipLramData(iop_base, word_val); - return; } static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) @@ -4560,7 +4549,6 @@ static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) word_data |= ((ushort)byte_val & 0x00FF); } AscWriteLramWord(iop_base, addr, word_data); - return; } /* @@ -4588,7 +4576,6 @@ AscMemWordCopyPtrToLram(PortAddr iop_base, outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); } - return; } /* @@ -4608,7 +4595,6 @@ AscMemDWordCopyPtrToLram(PortAddr iop_base, outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ } - return; } /* @@ -4630,7 +4616,6 @@ AscMemWordCopyPtrFromLram(PortAddr iop_base, d_buffer[i] = word & 0xff; d_buffer[i + 1] = (word >> 8) & 0xff; } - return; } static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) @@ -8397,8 +8382,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) boardp->adv_reqp = reqp; ASC_DBG(1, "done\n"); - - return; } /* @@ -8569,7 +8552,6 @@ static void AscAckInterrupt(PortAddr iop_base) } } AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); - return; } static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) @@ -9325,8 +9307,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) } asc_scsi_done(scp); - - return; } static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) @@ -10055,9 +10035,9 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, scp->sc_data_direction); if (use_sg > scp->device->host->sg_tablesize) { - ASC_PRINT3("asc_build_req: board %d: use_sg %d > " - "sg_tablesize %d\n", boardp->id, use_sg, - scp->device->host->sg_tablesize); + scmd_printk(KERN_ERR, scp, "use_sg %d > " + "sg_tablesize %d\n", use_sg, + scp->device->host->sg_tablesize); dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); scp->result = HOST_BYTE(DID_ERROR); @@ -10332,8 +10312,8 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, scp->sc_data_direction); if (use_sg > ADV_MAX_SG_LIST) { - ASC_PRINT3("adv_build_req: board %d: use_sg %d > " - "ADV_MAX_SG_LIST %d\n", boardp->id, use_sg, + scmd_printk(KERN_ERR, scp, "use_sg %d > " + "ADV_MAX_SG_LIST %d\n", use_sg, scp->device->host->sg_tablesize); dma_unmap_sg(boardp->dev, slp, scp->use_sg, scp->sc_data_direction); @@ -11174,14 +11154,14 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " - "ASC_ERROR, err_code 0x%x\n", boardp->id, err_code); + scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, " + "err_code 0x%x\n", err_code); ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); break; default: - ASC_PRINT2("asc_execute_scsi_cmnd: board %d: ExeScsiQueue() " - "unknown, err_code 0x%x\n", boardp->id, err_code); + scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, " + "err_code 0x%x\n", err_code); ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); break; @@ -11314,7 +11294,6 @@ static void __devinit AscEnableIsaDma(uchar dma_channel) outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); outp(0x00D4, (ushort)(dma_channel - 4)); } - return; } #endif /* CONFIG_ISA */ @@ -11613,7 +11592,6 @@ static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) static void __devinit AscWaitEEPWrite(void) { mdelay(20); - return; } static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) @@ -11936,9 +11914,10 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) return (warn_code); } -static int __devinit AscInitGetConfig(struct asc_board *boardp) +static int __devinit AscInitGetConfig(struct Scsi_Host *shost) { - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + struct asc_board *board = shost_priv(shost); + ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; unsigned short warn_code = 0; asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; @@ -11959,43 +11938,40 @@ static int __devinit AscInitGetConfig(struct asc_board *boardp) case 0: /* No error */ break; case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port address " - "modified\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port address " + "modified\n"); break; case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitGetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port increment switch " + "enabled\n"); break; case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitGetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); + shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); break; case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitGetConfig: board %d: IRQ modified\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "IRQ modified\n"); break; case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitGetConfig: board %d: tag queuing enabled " - "w/o disconnects\n", boardp->id); + shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o " + "disconnects\n"); break; default: - ASC_PRINT2("AscInitGetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); + shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", + warn_code); break; } - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitGetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } + if (asc_dvc->err_code != 0) + shost_printk(KERN_ERR, shost, "error 0x%x at init_state " + "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); return asc_dvc->err_code; } -static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *boardp) +static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) { - ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; + struct asc_board *board = shost_priv(shost); + ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; PortAddr iop_base = asc_dvc->iop_base; unsigned short cfg_msw; unsigned short warn_code = 0; @@ -12060,37 +12036,32 @@ static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct asc_board *bo case 0: /* No error. */ break; case ASC_WARN_IO_PORT_ROTATE: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port address " - "modified\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port address " + "modified\n"); break; case ASC_WARN_AUTO_CONFIG: - ASC_PRINT1("AscInitSetConfig: board %d: I/O port increment " - "switch enabled\n", boardp->id); + shost_printk(KERN_WARNING, shost, "I/O port increment switch " + "enabled\n"); break; case ASC_WARN_EEPROM_CHKSUM: - ASC_PRINT1("AscInitSetConfig: board %d: EEPROM checksum " - "error\n", boardp->id); + shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); break; case ASC_WARN_IRQ_MODIFIED: - ASC_PRINT1("AscInitSetConfig: board %d: IRQ modified\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "IRQ modified\n"); break; case ASC_WARN_CMD_QNG_CONFLICT: - ASC_PRINT1("AscInitSetConfig: board %d: tag queuing w/o " - "disconnects\n", - boardp->id); + shost_printk(KERN_WARNING, shost, "tag queuing w/o " + "disconnects\n"); break; default: - ASC_PRINT2("AscInitSetConfig: board %d: unknown warning: " - "0x%x\n", boardp->id, warn_code); + shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", + warn_code); break; } - if (asc_dvc->err_code != 0) { - ASC_PRINT3("AscInitSetConfig: board %d error: init_state 0x%x, " - "err_code 0x%x\n", boardp->id, asc_dvc->init_state, - asc_dvc->err_code); - } + if (asc_dvc->err_code != 0) + shost_printk(KERN_ERR, shost, "error 0x%x at init_state " + "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); return asc_dvc->err_code; } @@ -13390,9 +13361,10 @@ static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) * then 0 is returned. */ static int __devinit -AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) +AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) { - ADV_DVC_VAR *asc_dvc = &boardp->dvc_var.adv_dvc_var; + struct asc_board *board = shost_priv(shost); + ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var; unsigned short warn_code = 0; AdvPortAddr iop_base = asc_dvc->iop_base; u16 cmd; @@ -13458,15 +13430,12 @@ AdvInitGetConfig(struct pci_dev *pdev, struct asc_board *boardp) warn_code |= status; } - if (warn_code != 0) { - ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n", - boardp->id, warn_code); - } + if (warn_code != 0) + shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code); - if (asc_dvc->err_code) { - ASC_PRINT2("AdvInitGetConfig: board %d error: err_code 0x%x\n", - boardp->id, asc_dvc->err_code); - } + if (asc_dvc->err_code) + shost_printk(KERN_ERR, shost, "error code 0x%x\n", + asc_dvc->err_code); return asc_dvc->err_code; } @@ -13499,9 +13468,10 @@ static struct scsi_host_template advansys_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int __devinit -advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) +static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) { + struct asc_board *board = shost_priv(shost); + struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var; int req_cnt = 0; adv_req_t *reqp = NULL; int sg_cnt = 0; @@ -13512,10 +13482,10 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) * Allocate buffer carrier structures. The total size * is about 4 KB, so allocate all at once. */ - boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); - ASC_DBG(1, "carrp 0x%p\n", boardp->carrp); + board->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); + ASC_DBG(1, "carrp 0x%p\n", board->carrp); - if (!boardp->carrp) + if (!board->carrp) goto kmalloc_failed; /* @@ -13523,7 +13493,7 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) * board. The total size is about 16 KB, so allocate all at once. * If the allocation fails decrement and try again. */ - for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) { + for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) { reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt, @@ -13536,31 +13506,31 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) if (!reqp) goto kmalloc_failed; - boardp->orig_reqp = reqp; + board->orig_reqp = reqp; /* * Allocate up to ADV_TOT_SG_BLOCK request structures for * the Wide board. Each structure is about 136 bytes. */ - boardp->adv_sgblkp = NULL; + board->adv_sgblkp = NULL; for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL); if (!sgp) break; - sgp->next_sgblkp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgp; + sgp->next_sgblkp = board->adv_sgblkp; + board->adv_sgblkp = sgp; } ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t), (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); - if (!boardp->adv_sgblkp) + if (!board->adv_sgblkp) goto kmalloc_failed; - adv_dvc_varp->carrier_buf = boardp->carrp; + adv_dvc->carrier_buf = board->carrp; /* * Point 'adv_reqp' to the request structures and @@ -13571,30 +13541,29 @@ advansys_wide_init_chip(struct asc_board *boardp, ADV_DVC_VAR *adv_dvc_varp) for (; req_cnt > 0; req_cnt--) { reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; } - boardp->adv_reqp = &reqp[0]; + board->adv_reqp = &reqp[0]; - if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { + if (adv_dvc->chip_type == ADV_CHIP_ASC3550) { ASC_DBG(2, "AdvInitAsc3550Driver()\n"); - warn_code = AdvInitAsc3550Driver(adv_dvc_varp); - } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { + warn_code = AdvInitAsc3550Driver(adv_dvc); + } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) { ASC_DBG(2, "AdvInitAsc38C0800Driver()\n"); - warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); + warn_code = AdvInitAsc38C0800Driver(adv_dvc); } else { ASC_DBG(2, "AdvInitAsc38C1600Driver()\n"); - warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); + warn_code = AdvInitAsc38C1600Driver(adv_dvc); } - err_code = adv_dvc_varp->err_code; + err_code = adv_dvc->err_code; if (warn_code || err_code) { - ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x," - " error 0x%x\n", boardp->id, warn_code, err_code); + shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error " + "0x%x\n", warn_code, err_code); } goto exit; kmalloc_failed: - ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() " - "failed\n", boardp->id); + shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n"); err_code = ADV_ERROR; exit: return err_code; @@ -13622,7 +13591,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, ADV_DVC_VAR *adv_dvc_varp = NULL; int share_irq, warn_code, ret; - boardp->id = asc_board_count++; pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; if (ASC_NARROW_BOARD(boardp)) { @@ -13653,10 +13621,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1), boardp->asc_n_io_port); if (!boardp->ioremap_addr) { - ASC_PRINT3 - ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", - boardp->id, pci_resource_start(pdev, 1), - boardp->asc_n_io_port); + shost_printk(KERN_ERR, shost, "ioremap(%x, %d) " + "returned NULL\n", + pci_resource_start(pdev, 1), + boardp->asc_n_io_port); ret = -ENODEV; goto err_shost; } @@ -13682,8 +13650,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); if (!boardp->prtbuf) { - ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " - "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); + shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n", + ASC_PRTBUF_SIZE); ret = -ENOMEM; goto err_unmap; } @@ -13716,9 +13684,8 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, break; #endif /* CONFIG_PCI */ default: - ASC_PRINT2 - ("advansys_board_found: board %d: unknown adapter type: %d\n", - boardp->id, asc_dvc_varp->bus_type); + shost_printk(KERN_ERR, shost, "unknown adapter type: " + "%d\n", asc_dvc_varp->bus_type); shost->unchecked_isa_dma = TRUE; share_irq = 0; break; @@ -13731,7 +13698,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * referenced only use the bit-wise AND operator "&". */ ASC_DBG(2, "AscInitGetConfig()\n"); - ret = AscInitGetConfig(boardp) ? -ENODEV : 0; + ret = AscInitGetConfig(shost) ? -ENODEV : 0; } else { #ifdef CONFIG_PCI /* @@ -13742,7 +13709,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, share_irq = IRQF_SHARED; ASC_DBG(2, "AdvInitGetConfig()\n"); - ret = AdvInitGetConfig(pdev, boardp) ? -ENODEV : 0; + ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0; #endif /* CONFIG_PCI */ } @@ -13790,7 +13757,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, * Modify board configuration. */ ASC_DBG(2, "AscInitSetConfig()\n"); - ret = AscInitSetConfig(pdev, boardp) ? -ENODEV : 0; + ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0; if (ret) goto err_free_proc; } else { @@ -14024,9 +13991,9 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; ret = request_dma(shost->dma_channel, DRV_NAME); if (ret) { - ASC_PRINT3 - ("advansys_board_found: board %d: request_dma() %d failed %d\n", - boardp->id, shost->dma_channel, ret); + shost_printk(KERN_ERR, shost, "request_dma() " + "%d failed %d\n", + shost->dma_channel, ret); goto err_free_proc; } AscEnableIsaDma(shost->dma_channel); @@ -14042,17 +14009,14 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, if (ret) { if (ret == -EBUSY) { - ASC_PRINT2 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", - boardp->id, boardp->irq); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "already in use\n", boardp->irq); } else if (ret == -EINVAL) { - ASC_PRINT2 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n", - boardp->id, boardp->irq); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "not valid\n", boardp->irq); } else { - ASC_PRINT3 - ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", - boardp->id, boardp->irq, ret); + shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " + "failed with %d\n", boardp->irq, ret); } goto err_free_dma; } @@ -14065,15 +14029,15 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, warn_code = AscInitAsc1000Driver(asc_dvc_varp); if (warn_code || asc_dvc_varp->err_code) { - ASC_PRINT4("advansys_board_found: board %d error: " - "init_state 0x%x, warn 0x%x, error 0x%x\n", - boardp->id, asc_dvc_varp->init_state, - warn_code, asc_dvc_varp->err_code); + shost_printk(KERN_ERR, shost, "error: init_state 0x%x, " + "warn 0x%x, error 0x%x\n", + asc_dvc_varp->init_state, warn_code, + asc_dvc_varp->err_code); if (asc_dvc_varp->err_code) ret = -ENODEV; } } else { - if (advansys_wide_init_chip(boardp, adv_dvc_varp)) + if (advansys_wide_init_chip(shost)) ret = -ENODEV; } -- cgit v1.1 From afbb68c35f4bdf0964d88e9e005e6f62ba57d134 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:36 -0400 Subject: [SCSI] advansys: Make sdtr_period_tbl a pointer It's somewhat neater to make this a pointer to one of two tables than initialising an array in the driver. Also delete the unused AscSynIndexToPeriod and rename host_init_sdtr_index to min_sdtr_index Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 90 ++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 65 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 93bf3ec..93b1a47 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -481,34 +481,22 @@ typedef struct asc_risc_sg_list_q { #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 #define ASC_MAX_INRAM_TAG_QNG 16 #define ASC_IOADR_GAP 0x10 -#define ASC_MAX_SYN_XFER_NO 16 #define ASC_SYN_MAX_OFFSET 0x0F #define ASC_DEF_SDTR_OFFSET 0x0F #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 -#define SYN_XFER_NS_0 25 -#define SYN_XFER_NS_1 30 -#define SYN_XFER_NS_2 35 -#define SYN_XFER_NS_3 40 -#define SYN_XFER_NS_4 50 -#define SYN_XFER_NS_5 60 -#define SYN_XFER_NS_6 70 -#define SYN_XFER_NS_7 85 -#define SYN_ULTRA_XFER_NS_0 12 -#define SYN_ULTRA_XFER_NS_1 19 -#define SYN_ULTRA_XFER_NS_2 25 -#define SYN_ULTRA_XFER_NS_3 32 -#define SYN_ULTRA_XFER_NS_4 38 -#define SYN_ULTRA_XFER_NS_5 44 -#define SYN_ULTRA_XFER_NS_6 50 -#define SYN_ULTRA_XFER_NS_7 57 -#define SYN_ULTRA_XFER_NS_8 63 -#define SYN_ULTRA_XFER_NS_9 69 -#define SYN_ULTRA_XFER_NS_10 75 -#define SYN_ULTRA_XFER_NS_11 82 -#define SYN_ULTRA_XFER_NS_12 88 -#define SYN_ULTRA_XFER_NS_13 94 -#define SYN_ULTRA_XFER_NS_14 100 -#define SYN_ULTRA_XFER_NS_15 107 +#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 + +/* The narrow chip only supports a limited selection of transfer rates. + * These are encoded in the range 0..7 or 0..15 depending whether the chip + * is Ultra-capable or not. These tables let us convert from one to the other. + */ +static const unsigned char asc_syn_xfer_period[8] = { + 25, 30, 35, 40, 50, 60, 70, 85 +}; + +static const unsigned char asc_syn_ultra_xfer_period[16] = { + 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107 +}; typedef struct ext_msg { uchar msg_type; @@ -572,7 +560,6 @@ typedef struct asc_dvc_cfg { #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 -#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 #define ASC_MIN_TAGGED_CMD 7 #define ASC_MAX_SCSI_RESET_WAIT 30 @@ -602,7 +589,7 @@ typedef struct asc_dvc_var { uchar max_dvc_qng[ASC_MAX_TID + 1]; ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; - uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO]; + const uchar *sdtr_period_tbl; ASC_DVC_CFG *cfg; ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; char redo_scam; @@ -611,8 +598,8 @@ typedef struct asc_dvc_var { ASC_DCNT max_dma_count; ASC_SCSI_BIT_ID_TYPE no_scam; ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; + uchar min_sdtr_index; uchar max_sdtr_index; - uchar host_init_sdtr_index; struct asc_board *drv_ptr; ASC_DCNT uc_break; } ASC_DVC_VAR; @@ -896,7 +883,6 @@ typedef struct asc_mc_saved { #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) -#define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) @@ -8556,14 +8542,14 @@ static void AscAckInterrupt(PortAddr iop_base) static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) { - uchar *period_table; + const uchar *period_table; int max_index; int min_index; int i; period_table = asc_dvc->sdtr_period_tbl; max_index = (int)asc_dvc->max_sdtr_index; - min_index = (int)asc_dvc->host_init_sdtr_index; + min_index = (int)asc_dvc->min_sdtr_index; if ((syn_time <= period_table[max_index])) { for (i = min_index; i < (max_index - 1); i++) { if (syn_time <= period_table[i]) { @@ -8612,9 +8598,8 @@ AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) uchar sdtr_period_ix; sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); - if (sdtr_period_ix > asc_dvc->max_sdtr_index) { + if (sdtr_period_ix > asc_dvc->max_sdtr_index) return 0xFF; - } byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); return byte; } @@ -8725,15 +8710,14 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; } if ((ext_msg.xfer_period < - asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]) + asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index]) || (ext_msg.xfer_period > asc_dvc->sdtr_period_tbl[asc_dvc-> max_sdtr_index])) { sdtr_accept = FALSE; ext_msg.xfer_period = asc_dvc->sdtr_period_tbl[asc_dvc-> - host_init_sdtr_index]; + min_sdtr_index]; } if (sdtr_accept) { sdtr_data = @@ -8757,7 +8741,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); } else { if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { - q_cntl &= ~QC_MSG_OUT; asc_dvc->sdtr_done |= target_id; asc_dvc->init_sdtr |= target_id; @@ -8772,7 +8755,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) tid_no); boardp->sdtr_data[tid_no] = sdtr_data; } else { - q_cntl |= QC_MSG_OUT; AscMsgOutSDTR(asc_dvc, ext_msg.xfer_period, @@ -11407,7 +11389,7 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->queue_full_or_busy = 0; asc_dvc->redo_scam = 0; asc_dvc->res2 = 0; - asc_dvc->host_init_sdtr_index = 0; + asc_dvc->min_sdtr_index = 0; asc_dvc->cfg->can_tagged_qng = 0; asc_dvc->cfg->cmd_qng_enabled = 0; asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; @@ -11421,34 +11403,12 @@ static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); asc_dvc->cfg->chip_version = chip_version; - asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; + asc_dvc->sdtr_period_tbl = asc_syn_xfer_period; asc_dvc->max_sdtr_index = 7; if ((asc_dvc->bus_type & ASC_IS_PCI) && (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { asc_dvc->bus_type = ASC_IS_PCI_ULTRA; - asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; - asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; - asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; - asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; - asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; - asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; - asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; - asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; - asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; - asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; - asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; - asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; - asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; - asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; - asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; - asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; + asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period; asc_dvc->max_sdtr_index = 15; if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { AscSetExtraControl(iop_base, @@ -11889,7 +11849,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { - asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; + asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; } for (i = 0; i <= ASC_MAX_TID; i++) { @@ -11897,7 +11857,7 @@ static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; asc_dvc->cfg->sdtr_period_offset[i] = (uchar)(ASC_DEF_SDTR_OFFSET | - (asc_dvc->host_init_sdtr_index << 4)); + (asc_dvc->min_sdtr_index << 4)); } eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); if (write_eep) { -- cgit v1.1 From 98d41c29a4b38c5b5e8ce5e13c4f3ac852615e0b Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:37 -0400 Subject: [SCSI] advansys: Move a couple of fields from struct board to struct adv_dvc board->carrp is a duplicate of asc_dvc->carrier_buf, so cut out the middle-man and assign directly to carrier_buf. Move orig_reqp to adv_dvc too, since it's wide-board specific. Also eliminate an unnecessary BUG_ON (we'll never get there with a NULL carrier_buf, and will crash if we do). The bulk of this patch is rearranging structures so everything's declared in the right order. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 193 +++++++++++++++++++++++------------------------- 1 file changed, 92 insertions(+), 101 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 93b1a47..0459c85 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -983,15 +983,14 @@ typedef struct asc_mc_saved { * elements. Allow each command to have at least one ADV_SG_BLOCK structure. * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK * structures or 255 scatter-gather elements. - * */ #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG /* - * Define Adv Library required maximum number of scatter-gather - * elements per request. + * Define maximum number of scatter-gather elements per request. */ #define ADV_MAX_SG_LIST 255 +#define NO_OF_SG_PER_BLOCK 15 /* Number of SG blocks needed. */ #define ADV_NUM_SG_BLOCK \ @@ -1839,55 +1838,6 @@ typedef struct adv_dvc_cfg { struct adv_dvc_var; struct adv_scsi_req_q; -/* - * Adapter operation variable structure. - * - * One structure is required per host adapter. - * - * Field naming convention: - * - * *_able indicates both whether a feature should be enabled or disabled - * and whether a device isi capable of the feature. At initialization - * this field may be set, but later if a device is found to be incapable - * of the feature, the field is cleared. - */ -typedef struct adv_dvc_var { - AdvPortAddr iop_base; /* I/O port address */ - ushort err_code; /* fatal error code */ - ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ - ushort wdtr_able; /* try WDTR for a device */ - ushort sdtr_able; /* try SDTR for a device */ - ushort ultra_able; /* try SDTR Ultra speed for a device */ - ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ - ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ - ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ - ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ - ushort tagqng_able; /* try tagged queuing with a device */ - ushort ppr_able; /* PPR message capable per TID bitmask. */ - uchar max_dvc_qng; /* maximum number of tagged commands per device */ - ushort start_motor; /* start motor command allowed */ - uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ - uchar chip_no; /* should be assigned by caller */ - uchar max_host_qng; /* maximum number of Q'ed command allowed */ - ushort no_scam; /* scam_tolerant of EEPROM */ - struct asc_board *drv_ptr; /* driver pointer to private structure */ - uchar chip_scsi_id; /* chip SCSI target ID */ - uchar chip_type; - uchar bist_err_code; - ADV_CARR_T *carrier_buf; - ADV_CARR_T *carr_freelist; /* Carrier free list. */ - ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */ - ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */ - ushort carr_pending_cnt; /* Count of pending carriers. */ - /* - * Note: The following fields will not be used after initialization. The - * driver may discard the buffer after initialization is done. - */ - ADV_DVC_CFG *cfg; /* temporary configuration structure */ -} ADV_DVC_VAR; - -#define NO_OF_SG_PER_BLOCK 15 - typedef struct asc_sg_block { uchar reserved1; uchar reserved2; @@ -1946,6 +1896,83 @@ typedef struct adv_scsi_req_q { } ADV_SCSI_REQ_Q; /* + * The following two structures are used to process Wide Board requests. + * + * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library + * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the + * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the + * Mid-Level SCSI request structure. + * + * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each + * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux + * up to 255 scatter-gather elements may be used per request or + * ADV_SCSI_REQ_Q. + * + * Both structures must be 32 byte aligned. + */ +typedef struct adv_sgblk { + ADV_SG_BLOCK sg_block; /* Sgblock structure. */ + uchar align[32]; /* Sgblock structure padding. */ + struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ +} adv_sgblk_t; + +typedef struct adv_req { + ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ + uchar align[32]; /* Request structure padding. */ + struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */ + adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ + struct adv_req *next_reqp; /* Next Request Structure. */ +} adv_req_t; + +/* + * Adapter operation variable structure. + * + * One structure is required per host adapter. + * + * Field naming convention: + * + * *_able indicates both whether a feature should be enabled or disabled + * and whether a device isi capable of the feature. At initialization + * this field may be set, but later if a device is found to be incapable + * of the feature, the field is cleared. + */ +typedef struct adv_dvc_var { + AdvPortAddr iop_base; /* I/O port address */ + ushort err_code; /* fatal error code */ + ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ + ushort wdtr_able; /* try WDTR for a device */ + ushort sdtr_able; /* try SDTR for a device */ + ushort ultra_able; /* try SDTR Ultra speed for a device */ + ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ + ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ + ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ + ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ + ushort tagqng_able; /* try tagged queuing with a device */ + ushort ppr_able; /* PPR message capable per TID bitmask. */ + uchar max_dvc_qng; /* maximum number of tagged commands per device */ + ushort start_motor; /* start motor command allowed */ + uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ + uchar chip_no; /* should be assigned by caller */ + uchar max_host_qng; /* maximum number of Q'ed command allowed */ + ushort no_scam; /* scam_tolerant of EEPROM */ + struct asc_board *drv_ptr; /* driver pointer to private structure */ + uchar chip_scsi_id; /* chip SCSI target ID */ + uchar chip_type; + uchar bist_err_code; + ADV_CARR_T *carrier_buf; + ADV_CARR_T *carr_freelist; /* Carrier free list. */ + ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */ + ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */ + ushort carr_pending_cnt; /* Count of pending carriers. */ + struct adv_req *orig_reqp; /* adv_req_t memory block. */ + /* + * Note: The following fields will not be used after initialization. The + * driver may discard the buffer after initialization is done. + */ + ADV_DVC_CFG *cfg; /* temporary configuration structure */ +} ADV_DVC_VAR; + +/* * Microcode idle loop commands */ #define IDLE_CMD_COMPLETED 0 @@ -2362,37 +2389,6 @@ struct asc_stats { #endif /* ADVANSYS_STATS */ /* - * Adv Library Request Structures - * - * The following two structures are used to process Wide Board requests. - * - * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library - * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the - * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the - * Mid-Level SCSI request structure. - * - * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each - * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux - * up to 255 scatter-gather elements may be used per request or - * ADV_SCSI_REQ_Q. - * - * Both structures must be 32 byte aligned. - */ -typedef struct adv_sgblk { - ADV_SG_BLOCK sg_block; /* Sgblock structure. */ - uchar align[32]; /* Sgblock structure padding. */ - struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ -} adv_sgblk_t; - -typedef struct adv_req { - ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ - uchar align[32]; /* Request structure padding. */ - struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */ - adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ - struct adv_req *next_reqp; /* Next Request Structure. */ -} adv_req_t; - -/* * Structure allocated for each board. * * This structure is allocated by scsi_host_alloc() at the end @@ -2437,8 +2433,6 @@ struct asc_board { */ void __iomem *ioremap_addr; /* I/O Memory remap address. */ ushort ioport; /* I/O Port address. */ - ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */ - adv_req_t *orig_reqp; /* adv_req_t memory block. */ adv_req_t *adv_reqp; /* Request structures. */ adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ ushort bios_signature; /* BIOS Signature. */ @@ -6518,8 +6512,6 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) ADV_SDCNT buf_size; ADV_PADDR carr_paddr; - BUG_ON(!asc_dvc->carrier_buf); - carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); asc_dvc->carr_freelist = NULL; if (carrp == asc_dvc->carrier_buf) { @@ -13442,10 +13434,10 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) * Allocate buffer carrier structures. The total size * is about 4 KB, so allocate all at once. */ - board->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); - ASC_DBG(1, "carrp 0x%p\n", board->carrp); + adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); + ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf); - if (!board->carrp) + if (!adv_dvc->carrier_buf) goto kmalloc_failed; /* @@ -13466,7 +13458,7 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) if (!reqp) goto kmalloc_failed; - board->orig_reqp = reqp; + adv_dvc->orig_reqp = reqp; /* * Allocate up to ADV_TOT_SG_BLOCK request structures for @@ -13490,8 +13482,6 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) if (!board->adv_sgblkp) goto kmalloc_failed; - adv_dvc->carrier_buf = board->carrp; - /* * Point 'adv_reqp' to the request structures and * link them together. @@ -13529,15 +13519,16 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) return err_code; } -static void advansys_wide_free_mem(struct asc_board *boardp) +static void advansys_wide_free_mem(struct asc_board *board) { - kfree(boardp->carrp); - boardp->carrp = NULL; - kfree(boardp->orig_reqp); - boardp->orig_reqp = boardp->adv_reqp = NULL; - while (boardp->adv_sgblkp) { - adv_sgblk_t *sgp = boardp->adv_sgblkp; - boardp->adv_sgblkp = sgp->next_sgblkp; + struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var; + kfree(adv_dvc->carrier_buf); + adv_dvc->carrier_buf = NULL; + kfree(adv_dvc->orig_reqp); + adv_dvc->orig_reqp = board->adv_reqp = NULL; + while (board->adv_sgblkp) { + adv_sgblk_t *sgp = board->adv_sgblkp; + board->adv_sgblkp = sgp->next_sgblkp; kfree(sgp); } } -- cgit v1.1 From fd625f4705977de1ad00ac3cb519ec3ee8fd8598 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:38 -0400 Subject: [SCSI] advansys: Remove DvcGetPhyAddr This rather complex function boiled down to calling virt_to_bus(). Also get rid of some obsolete defines and variables that could never vary. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 73 ++----------------------------------------------- 1 file changed, 3 insertions(+), 70 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 0459c85..ab91082 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -992,19 +992,6 @@ typedef struct asc_mc_saved { #define ADV_MAX_SG_LIST 255 #define NO_OF_SG_PER_BLOCK 15 -/* Number of SG blocks needed. */ -#define ADV_NUM_SG_BLOCK \ - ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK) - -/* Total contiguous memory needed for SG blocks. */ -#define ADV_SG_TOTAL_MEM_SIZE \ - (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK) - -#define ADV_PAGE_SIZE PAGE_SIZE - -#define ADV_NUM_PAGE_CROSSING \ - ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) - #define ADV_EEP_DVC_CFG_BEGIN (0x00) #define ADV_EEP_DVC_CFG_END (0x15) #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */ @@ -1792,8 +1779,7 @@ typedef struct adv_carr_t { #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK) #define ADV_CARRIER_NUM_PAGE_CROSSING \ - (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \ - (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) + (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + (PAGE_SIZE - 1))/PAGE_SIZE) #define ADV_CARRIER_BUFSIZE \ ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T)) @@ -2174,16 +2160,6 @@ do { \ #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */ #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ -/* - * DvcGetPhyAddr() flag arguments - */ -#define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */ -#define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */ -#define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */ -#define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */ -#define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */ -#define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */ - /* Return the address that is aligned at the next doubleword >= to 'addr'. */ #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7) #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF) @@ -6483,29 +6459,6 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, return 0; } -/* - * DvcGetPhyAddr() - * - * Return the physical address of 'vaddr' and set '*lenp' to the - * number of physically contiguous bytes that follow 'vaddr'. - * 'flag' indicates the type of structure whose physical address - * is being translated. - * - * Note: Because Linux currently doesn't page the kernel and all - * kernel buffers are physically contiguous, leave '*lenp' unchanged. - */ -ADV_PADDR -DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, - uchar *vaddr, ADV_SDCNT *lenp, int flag) -{ - ADV_PADDR paddr = virt_to_bus(vaddr); - - ASC_DBG(4, "vaddr 0x%p, lenp 0x%p *lenp %lu, paddr 0x%lx\n", - vaddr, lenp, (ulong)*((ulong *)lenp), (ulong)paddr); - - return paddr; -} - static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) { ADV_CARR_T *carrp; @@ -6522,24 +6475,10 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) do { /* Get physical address of the carrier 'carrp'. */ - ADV_DCNT contig_len = sizeof(ADV_CARR_T); - carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, - (uchar *)carrp, - (ADV_SDCNT *)&contig_len, - ADV_IS_CARRIER_FLAG)); + carr_paddr = cpu_to_le32(virt_to_bus(carrp)); buf_size -= sizeof(ADV_CARR_T); - /* - * If the current carrier is not physically contiguous, then - * maybe there was a page crossing. Try the next carrier - * aligned start address. - */ - if (contig_len < sizeof(ADV_CARR_T)) { - carrp++; - continue; - } - carrp->carr_pa = carr_paddr; carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); @@ -10915,7 +10854,6 @@ static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) { AdvPortAddr iop_base; - ADV_DCNT req_size; ADV_PADDR req_paddr; ADV_CARR_T *new_carrp; @@ -10953,13 +10891,8 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) */ scsiq->a_flag &= ~ADV_SCSIQ_DONE; - req_size = sizeof(ADV_SCSI_REQ_Q); - req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq, - (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG); - + req_paddr = virt_to_bus(scsiq); BUG_ON(req_paddr & 31); - BUG_ON(req_size < sizeof(ADV_SCSI_REQ_Q)); - /* Wait for assertion before making little-endian */ req_paddr = cpu_to_le32(req_paddr); -- cgit v1.1 From 52c334e9450a15230b84ab4ef8ef7b034b37c371 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:39 -0400 Subject: [SCSI] advansys: convert to use the data buffer accessors - remove the unnecessary map_single path. - convert to use the new accessors for the sg lists and the parameters. Signed-off-by: FUJITA Tomonori - convert the statistics to not distinguish between single and sg xfers - replace ASC_CEILING with DIV_ROUND_UP - remove an obsolete comment Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 236 +++++++++++------------------------------------- 1 file changed, 52 insertions(+), 184 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ab91082..d35897e 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2223,8 +2223,6 @@ do { \ (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count)) #endif /* ADVANSYS_STATS */ -#define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit)) - /* If the result wraps when calculating tenths, return 0. */ #define ASC_TENTHS(num, den) \ (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \ @@ -2356,11 +2354,9 @@ struct asc_stats { ADV_DCNT exe_error; /* # ASC_ERROR returns. */ ADV_DCNT exe_unknown; /* # unknown returns. */ /* Data Transfer Statistics */ - ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */ - ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */ - ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */ - ADV_DCNT sg_elem; /* # scatter-gather elements */ - ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */ + ADV_DCNT xfer_cnt; /* # I/O requests received */ + ADV_DCNT xfer_elem; /* # scatter-gather elements */ + ADV_DCNT xfer_sect; /* # 512-byte blocks */ }; #endif /* ADVANSYS_STATS */ @@ -4057,57 +4053,32 @@ static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) /* * Display data transfer statistics. */ - if (s->cont_cnt > 0) { - len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); - ASC_PRT_NEXT(); - - len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", - s->cont_xfer / 2, - ASC_TENTHS(s->cont_xfer, 2)); - ASC_PRT_NEXT(); - - /* Contiguous transfer average size */ - len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", - (s->cont_xfer / 2) / s->cont_cnt, - ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt)); - ASC_PRT_NEXT(); - } - - if (s->sg_cnt > 0) { - - len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", - s->sg_cnt, s->sg_elem); + if (s->xfer_cnt > 0) { + len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ", + s->xfer_cnt, s->xfer_elem); ASC_PRT_NEXT(); - len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", - s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2)); + len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n", + s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2)); ASC_PRT_NEXT(); /* Scatter gather transfer statistics */ len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", - s->sg_elem / s->sg_cnt, - ASC_TENTHS(s->sg_elem, s->sg_cnt)); + s->xfer_elem / s->xfer_cnt, + ASC_TENTHS(s->xfer_elem, s->xfer_cnt)); ASC_PRT_NEXT(); len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", - (s->sg_xfer / 2) / s->sg_elem, - ASC_TENTHS((s->sg_xfer / 2), s->sg_elem)); + (s->xfer_sect / 2) / s->xfer_elem, + ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem)); ASC_PRT_NEXT(); len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", - (s->sg_xfer / 2) / s->sg_cnt, - ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt)); + (s->xfer_sect / 2) / s->xfer_cnt, + ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt)); ASC_PRT_NEXT(); } - /* - * Display request queuing statistics. - */ - len = asc_prt_line(cp, leftlen, - " Active and Waiting Request Queues (Time Unit: %d HZ):\n", - HZ); - ASC_PRT_NEXT(); - return totlen; } #endif /* ADVANSYS_STATS */ @@ -4301,18 +4272,8 @@ advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, static void asc_scsi_done(struct scsi_cmnd *scp) { - struct asc_board *boardp = shost_priv(scp->device->host); - - if (scp->use_sg) - dma_unmap_sg(boardp->dev, - (struct scatterlist *)scp->request_buffer, - scp->use_sg, scp->sc_data_direction); - else if (scp->request_bufflen) - dma_unmap_single(boardp->dev, scp->SCp.dma_handle, - scp->request_bufflen, scp->sc_data_direction); - + scsi_dma_unmap(scp); ASC_STATS(scp->device->host, done); - scp->scsi_done(scp); } @@ -8210,11 +8171,11 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) * then return the number of underrun bytes. */ resid_cnt = le32_to_cpu(scsiqp->data_cnt); - if (scp->request_bufflen != 0 && resid_cnt != 0 && - resid_cnt <= scp->request_bufflen) { + if (scsi_bufflen(scp) != 0 && resid_cnt != 0 && + resid_cnt <= scsi_bufflen(scp)) { ASC_DBG(1, "underrun condition %lu bytes\n", (ulong)resid_cnt); - scp->resid = resid_cnt; + scsi_set_resid(scp, resid_cnt); } break; @@ -9148,11 +9109,11 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) * If there was no error and an underrun condition, then * return the number of underrun bytes. */ - if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && - qdonep->remain_bytes <= scp->request_bufflen) { + if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 && + qdonep->remain_bytes <= scsi_bufflen(scp)) { ASC_DBG(1, "underrun condition %u bytes\n", (unsigned)qdonep->remain_bytes); - scp->resid = qdonep->remain_bytes; + scsi_set_resid(scp, qdonep->remain_bytes); } break; @@ -9877,6 +9838,8 @@ static int advansys_slave_configure(struct scsi_device *sdev) static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, struct asc_scsi_q *asc_scsi_q) { + int use_sg; + memset(asc_scsi_q, 0, sizeof(*asc_scsi_q)); /* @@ -9915,55 +9878,26 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG; } - /* - * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather - * buffer command. - */ - if (scp->use_sg == 0) { - /* - * CDB request of single contiguous buffer. - */ - ASC_STATS(scp->device->host, cont_cnt); - scp->SCp.dma_handle = scp->request_bufflen ? - dma_map_single(boardp->dev, scp->request_buffer, - scp->request_bufflen, - scp->sc_data_direction) : 0; - asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); - asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen); - ASC_STATS_ADD(scp->device->host, cont_xfer, - ASC_CEILING(scp->request_bufflen, 512)); - asc_scsi_q->q1.sg_queue_cnt = 0; - asc_scsi_q->sg_head = NULL; - } else { - /* - * CDB scatter-gather request list. - */ + /* Build ASC_SCSI_Q */ + use_sg = scsi_dma_map(scp); + if (use_sg != 0) { int sgcnt; - int use_sg; struct scatterlist *slp; struct asc_sg_head *asc_sg_head; - slp = (struct scatterlist *)scp->request_buffer; - use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - if (use_sg > scp->device->host->sg_tablesize) { scmd_printk(KERN_ERR, scp, "use_sg %d > " "sg_tablesize %d\n", use_sg, scp->device->host->sg_tablesize); - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); + scsi_dma_unmap(scp); scp->result = HOST_BYTE(DID_ERROR); return ASC_ERROR; } - ASC_STATS(scp->device->host, sg_cnt); - asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) + use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC); if (!asc_sg_head) { - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); + scsi_dma_unmap(scp); scp->result = HOST_BYTE(DID_SOFT_ERROR); return ASC_ERROR; } @@ -9974,22 +9908,24 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, asc_scsi_q->q1.data_addr = 0; /* This is a byte value, otherwise it would need to be swapped. */ asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg; - ASC_STATS_ADD(scp->device->host, sg_elem, + ASC_STATS_ADD(scp->device->host, xfer_elem, asc_sg_head->entry_cnt); /* * Convert scatter-gather list into ASC_SG_HEAD list. */ - for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { + scsi_for_each_sg(scp, slp, use_sg, sgcnt) { asc_sg_head->sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp)); asc_sg_head->sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp)); - ASC_STATS_ADD(scp->device->host, sg_xfer, - ASC_CEILING(sg_dma_len(slp), 512)); + ASC_STATS_ADD(scp->device->host, xfer_sect, + DIV_ROUND_UP(sg_dma_len(slp), 512)); } } + ASC_STATS(scp->device->host, xfer_cnt); + ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q); ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); @@ -10021,7 +9957,7 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int i; scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); - slp = (struct scatterlist *)scp->request_buffer; + slp = scsi_sglist(scp); sg_elem_cnt = use_sg; prev_sg_block = NULL; reqp->sgblkp = NULL; @@ -10093,8 +10029,8 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, cpu_to_le32(sg_dma_address(slp)); sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp)); - ASC_STATS_ADD(scp->device->host, sg_xfer, - ASC_CEILING(sg_dma_len(slp), 512)); + ASC_STATS_ADD(scp->device->host, xfer_sect, + DIV_ROUND_UP(sg_dma_len(slp), 512)); if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ sg_block->sg_cnt = i + 1; @@ -10126,6 +10062,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, ADV_SCSI_REQ_Q *scsiqp; int i; int ret; + int use_sg; /* * Allocate an adv_req_t structure from the board to execute @@ -10182,54 +10119,24 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); scsiqp->sense_len = sizeof(scp->sense_buffer); - /* - * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather - * buffer command. - */ + /* Build ADV_SCSI_REQ_Q */ - scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); - scsiqp->vdata_addr = scp->request_buffer; - scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); - - if (scp->use_sg == 0) { - /* - * CDB request of single contiguous buffer. - */ + use_sg = scsi_dma_map(scp); + if (use_sg == 0) { + /* Zero-length transfer */ reqp->sgblkp = NULL; - scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); - if (scp->request_bufflen) { - scsiqp->vdata_addr = scp->request_buffer; - scp->SCp.dma_handle = - dma_map_single(boardp->dev, scp->request_buffer, - scp->request_bufflen, - scp->sc_data_direction); - } else { - scsiqp->vdata_addr = NULL; - scp->SCp.dma_handle = 0; - } - scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); + scsiqp->data_cnt = 0; + scsiqp->vdata_addr = NULL; + + scsiqp->data_addr = 0; scsiqp->sg_list_ptr = NULL; scsiqp->sg_real_addr = 0; - ASC_STATS(scp->device->host, cont_cnt); - ASC_STATS_ADD(scp->device->host, cont_xfer, - ASC_CEILING(scp->request_bufflen, 512)); } else { - /* - * CDB scatter-gather request list. - */ - struct scatterlist *slp; - int use_sg; - - slp = (struct scatterlist *)scp->request_buffer; - use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); - if (use_sg > ADV_MAX_SG_LIST) { scmd_printk(KERN_ERR, scp, "use_sg %d > " "ADV_MAX_SG_LIST %d\n", use_sg, scp->device->host->sg_tablesize); - dma_unmap_sg(boardp->dev, slp, scp->use_sg, - scp->sc_data_direction); + scsi_dma_unmap(scp); scp->result = HOST_BYTE(DID_ERROR); /* @@ -10242,6 +10149,8 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, return ASC_ERROR; } + scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp)); + ret = adv_get_sglist(boardp, reqp, scp, use_sg); if (ret != ADV_SUCCESS) { /* @@ -10254,10 +10163,11 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, return ret; } - ASC_STATS(scp->device->host, sg_cnt); - ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); + ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg); } + ASC_STATS(scp->device->host, xfer_cnt); + ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); @@ -10955,48 +10865,6 @@ static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) /* * Execute a single 'Scsi_Cmnd'. - * - * The function 'done' is called when the request has been completed. - * - * Scsi_Cmnd: - * - * host - board controlling device - * device - device to send command - * target - target of device - * lun - lun of device - * cmd_len - length of SCSI CDB - * cmnd - buffer for SCSI 8, 10, or 12 byte CDB - * use_sg - if non-zero indicates scatter-gather request with use_sg elements - * - * if (use_sg == 0) { - * request_buffer - buffer address for request - * request_bufflen - length of request buffer - * } else { - * request_buffer - pointer to scatterlist structure - * } - * - * sense_buffer - sense command buffer - * - * result (4 bytes of an int): - * Byte Meaning - * 0 SCSI Status Byte Code - * 1 SCSI One Byte Message Code - * 2 Host Error Code - * 3 Mid-Level Error Code - * - * host driver fields: - * SCp - Scsi_Pointer used for command processing status - * scsi_done - used to save caller's done function - * host_scribble - used for pointer to another struct scsi_cmnd - * - * If this function returns ASC_NOERROR the request will be completed - * from the interrupt handler. - * - * If this function returns ASC_ERROR the host error code has been set, - * and the called must call asc_scsi_done. - * - * If ASC_BUSY is returned the request will be returned to the midlayer - * and re-tried later. */ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) { -- cgit v1.1 From b249c7fda2ca8efcbe37ace1e20a3fffac08bccb Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:40 -0400 Subject: [SCSI] advansys: Remove a couple of uses of bus_to_virt Replace ASC_VADDR_TO_U32 and ASC_U32_TO_VADDR with an auto-expanding array that maps pointers to 32-bit IDs and back. One of the uses of ASC_VADDR_TO_U32 was in error; it should have been using ADV_VADDR_TO_U32. Also replace the use of virt_to_bus when setting the sense_address with a call to dma_map_single() followed by dma_cache_sync. This part cribbed from the 53c700 driver. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 105 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index d35897e..88e7fef 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -90,17 +90,6 @@ #define ASC_DCNT __u32 /* Unsigned Data count type. */ #define ASC_SDCNT __s32 /* Signed Data count type. */ -/* - * These macros are used to convert a virtual address to a - * 32-bit value. This currently can be used on Linux Alpha - * which uses 64-bit virtual address but a 32-bit bus address. - * This is likely to break in the future, but doing this now - * will give us time to change the HW and FW to handle 64-bit - * addresses. - */ -#define ASC_VADDR_TO_U32 virt_to_bus -#define ASC_U32_TO_VADDR bus_to_virt - typedef unsigned char uchar; #ifndef TRUE @@ -601,6 +590,8 @@ typedef struct asc_dvc_var { uchar min_sdtr_index; uchar max_sdtr_index; struct asc_board *drv_ptr; + int ptr_map_count; + void **ptr_map; ASC_DCNT uc_break; } ASC_DVC_VAR; @@ -2748,6 +2739,59 @@ static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) #endif /* ADVANSYS_DEBUG */ /* + * The advansys chip/microcode contains a 32-bit identifier for each command + * known as the 'srb'. I don't know what it stands for. The driver used + * to encode the scsi_cmnd pointer by calling virt_to_bus and retrieve it + * with bus_to_virt. Now the driver keeps a per-host map of integers to + * pointers. It auto-expands when full, unless it can't allocate memory. + * Note that an srb of 0 is treated specially by the chip/firmware, hence + * the return of i+1 in this routine, and the corresponding subtraction in + * the inverse routine. + */ +#define BAD_SRB 0 +static u32 advansys_ptr_to_srb(struct asc_dvc_var *asc_dvc, void *ptr) +{ + int i; + void **new_ptr; + + for (i = 0; i < asc_dvc->ptr_map_count; i++) { + if (!asc_dvc->ptr_map[i]) + goto out; + } + + if (asc_dvc->ptr_map_count == 0) + asc_dvc->ptr_map_count = 1; + else + asc_dvc->ptr_map_count *= 2; + + new_ptr = krealloc(asc_dvc->ptr_map, + asc_dvc->ptr_map_count * sizeof(void *), GFP_ATOMIC); + if (!new_ptr) + return BAD_SRB; + asc_dvc->ptr_map = new_ptr; + out: + ASC_DBG(3, "Putting ptr %p into array offset %d\n", ptr, i); + asc_dvc->ptr_map[i] = ptr; + return i + 1; +} + +static void * advansys_srb_to_ptr(struct asc_dvc_var *asc_dvc, u32 srb) +{ + void *ptr; + + srb--; + if (srb >= asc_dvc->ptr_map_count) { + printk("advansys: bad SRB %u, max %u\n", srb, + asc_dvc->ptr_map_count); + return NULL; + } + ptr = asc_dvc->ptr_map[srb]; + asc_dvc->ptr_map[srb] = NULL; + ASC_DBG(3, "Returning ptr %p from array offset %d\n", ptr, srb); + return ptr; +} + +/* * advansys_info() * * Return suitable for printing on the console with the argument @@ -9075,17 +9119,10 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep); ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); - /* - * Get the struct scsi_cmnd structure and Scsi_Host structure for the - * command that has been completed. - */ - scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); - ASC_DBG(1, "scp 0x%p\n", scp); - - if (scp == NULL) { - ASC_PRINT("asc_isr_callback: scp is NULL\n"); + scp = advansys_srb_to_ptr(asc_dvc_varp, qdonep->d2.srb_ptr); + if (!scp) return; - } + ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); shost = scp->device->host; @@ -9095,6 +9132,8 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) boardp = shost_priv(shost); BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); + dma_unmap_single(boardp->dev, scp->SCp.dma_handle, + sizeof(scp->sense_buffer), DMA_FROM_DEVICE); /* * 'qdonep' contains the command's ending status. */ @@ -9835,9 +9874,20 @@ static int advansys_slave_configure(struct scsi_device *sdev) return 0; } +static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp) +{ + struct asc_board *board = shost_priv(scp->device->host); + scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer, + sizeof(scp->sense_buffer), DMA_FROM_DEVICE); + dma_cache_sync(board->dev, scp->sense_buffer, + sizeof(scp->sense_buffer), DMA_FROM_DEVICE); + return cpu_to_le32(scp->SCp.dma_handle); +} + static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, struct asc_scsi_q *asc_scsi_q) { + struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var; int use_sg; memset(asc_scsi_q, 0, sizeof(*asc_scsi_q)); @@ -9845,7 +9895,11 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, /* * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. */ - asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp); + asc_scsi_q->q2.srb_ptr = advansys_ptr_to_srb(asc_dvc, scp); + if (asc_scsi_q->q2.srb_ptr == BAD_SRB) { + scp->result = HOST_BYTE(DID_SOFT_ERROR); + return ASC_ERROR; + } /* * Build the ASC_SCSI_Q request. @@ -9856,8 +9910,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, asc_scsi_q->q1.target_lun = scp->device->lun; asc_scsi_q->q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); - asc_scsi_q->q1.sense_addr = - cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); + asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp); asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer); /* @@ -9871,7 +9924,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, * started request. * */ - if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && + if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) && (boardp->reqcnt[scp->device->id] % 255) == 0) { asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG; } else { @@ -10091,7 +10144,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, /* * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. */ - scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp); + scsiqp->srb_ptr = ADV_VADDR_TO_U32(reqp); /* * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. -- cgit v1.1 From d10fb2c7b5ce1b475df50cde9262d2c3fe3d296e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:41 -0400 Subject: [SCSI] advansys: Use dma mapping for overrun buffer Convert the call to virt_to_bus() into a call to dma_map_single(). Some architectures may require different DMA addresses for different devices, so allocate one overrun buffer per host rather than one for all cards. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/advansys.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 88e7fef..07507a7 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -529,7 +529,6 @@ typedef struct asc_dvc_cfg { ushort mcode_date; ushort mcode_version; uchar max_tag_qng[ASC_MAX_TID + 1]; - uchar *overrun_buf; uchar sdtr_period_offset[ASC_MAX_TID + 1]; uchar adapter_info[6]; } ASC_DVC_CFG; @@ -551,6 +550,7 @@ typedef struct asc_dvc_cfg { #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 #define ASC_MIN_TAGGED_CMD 7 #define ASC_MAX_SCSI_RESET_WAIT 30 +#define ASC_OVERRUN_BSIZE 64 struct asc_dvc_var; /* Forward Declaration. */ @@ -566,6 +566,8 @@ typedef struct asc_dvc_var { ASC_SCSI_BIT_ID_TYPE unit_not_ready; ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; ASC_SCSI_BIT_ID_TYPE start_motor; + uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); + dma_addr_t overrun_dma; uchar scsi_reset_wait; uchar chip_no; char is_in_int; @@ -668,7 +670,6 @@ typedef struct asceep_config { #define ASC_EEP_CMD_WRITE 0x40 #define ASC_EEP_CMD_WRITE_ABLE 0x30 #define ASC_EEP_CMD_WRITE_DISABLE 0x00 -#define ASC_OVERRUN_BSIZE 0x00000048UL #define ASCV_MSGOUT_BEG 0x0000 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) @@ -2404,13 +2405,12 @@ struct asc_board { ushort bios_codelen; /* BIOS Code Segment Length. */ }; +#define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \ + dvc_var.asc_dvc_var) #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ dvc_var.adv_dvc_var) #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) -/* Overrun buffer used by all narrow boards. */ -static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; - #ifdef ADVANSYS_DEBUG static int asc_dbglvl = 3; @@ -2465,8 +2465,8 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, h->chip_version); - printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n", - h->mcode_date, h->mcode_version, h->overrun_buf); + printk(" mcode_date 0x%x, mcode_version %d\n", + h->mcode_date, h->mcode_version); } /* @@ -6316,6 +6316,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) PortAddr iop_base; ASC_PADDR phy_addr; ASC_DCNT phy_size; + struct asc_board *board = asc_dvc_to_board(asc_dvc); iop_base = asc_dvc->iop_base; warn_code = 0; @@ -6330,12 +6331,14 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); - /* Align overrun buffer on an 8 byte boundary. */ - phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); - phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); + /* Ensure overrun buffer is aligned on an 8 byte boundary. */ + BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); + asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, + ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); + phy_addr = cpu_to_le32(asc_dvc->overrun_dma); AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, (uchar *)&phy_addr, 1); - phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); + phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE); AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, (uchar *)&phy_size, 1); @@ -13404,7 +13407,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, asc_dvc_varp->bus_type = bus_type; asc_dvc_varp->drv_ptr = boardp; asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; - asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; asc_dvc_varp->iop_base = iop; } else { #ifdef CONFIG_PCI @@ -13880,19 +13882,23 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, */ static int advansys_release(struct Scsi_Host *shost) { - struct asc_board *boardp = shost_priv(shost); + struct asc_board *board = shost_priv(shost); ASC_DBG(1, "begin\n"); scsi_remove_host(shost); - free_irq(boardp->irq, shost); + free_irq(board->irq, shost); if (shost->dma_channel != NO_ISA_DMA) { ASC_DBG(1, "free_dma()\n"); free_dma(shost->dma_channel); } - if (!ASC_NARROW_BOARD(boardp)) { - iounmap(boardp->ioremap_addr); - advansys_wide_free_mem(boardp); + if (ASC_NARROW_BOARD(board)) { + dma_unmap_single(board->dev, + board->dvc_var.asc_dvc_var.overrun_dma, + ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); + } else { + iounmap(board->ioremap_addr); + advansys_wide_free_mem(board); } - kfree(boardp->prtbuf); + kfree(board->prtbuf); scsi_host_put(shost); ASC_DBG(1, "end\n"); return 0; -- cgit v1.1 From 9d511a4b29de6764931343d03e493f2e04df0271 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 21:55:42 -0400 Subject: [SCSI] advansys: Changes to work on parisc Change PortAddr to be an unsigned int instead of an unsigned short (IO Port address are 24 bit on parisc). Fix a couple of printk argument warnings. Remove the Kconfig marking as 'BROKEN'. I haven't removed the #warning yet because virt_to_bus/bus_to_virt are only eliminated for narrow boards. Wide boards need more work. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 1 - drivers/scsi/advansys.c | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 69b2fac..de6a641 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -521,7 +521,6 @@ config SCSI_ADVANSYS tristate "AdvanSys SCSI support" depends on SCSI depends on ISA || EISA || PCI - depends on BROKEN || X86_32 help This is a driver for all SCSI host adapters manufactured by AdvanSys. It is documented in the kernel source in diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 07507a7..9dd3952 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -120,7 +120,7 @@ typedef unsigned char uchar; #define CC_VERY_LONG_SG_LIST 0 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr) -#define PortAddr unsigned short /* port address size */ +#define PortAddr unsigned int /* port address size */ #define inp(port) inb(port) #define outp(port, byte) outb((byte), (port)) @@ -13333,8 +13333,8 @@ static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) } - ASC_DBG(1, "sg_cnt %d * %u = %u bytes\n", sg_cnt, sizeof(adv_sgblk_t), - (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); + ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t), + sizeof(adv_sgblk_t) * sg_cnt); if (!board->adv_sgblkp) goto kmalloc_failed; @@ -13428,9 +13428,9 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1), boardp->asc_n_io_port); if (!boardp->ioremap_addr) { - shost_printk(KERN_ERR, shost, "ioremap(%x, %d) " + shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) " "returned NULL\n", - pci_resource_start(pdev, 1), + (long)pci_resource_start(pdev, 1), boardp->asc_n_io_port); ret = -ENODEV; goto err_shost; -- cgit v1.1 From a02676d4bd0a580046b087b2d2fa221173dbb312 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 2 Oct 2007 14:38:02 -0700 Subject: [SCSI] ibmmca: Remove dead references to MODULE_PARM macro Remove the useless references to the obsolete MODULE_PARM macro. Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/ibmmca.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 82f116a..1a924e9 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -460,13 +460,6 @@ module_param(boot_options, charp, 0); module_param_array(io_port, int, NULL, 0); module_param_array(scsi_id, int, NULL, 0); -#if 0 /* FIXME: No longer exist? --RR */ -MODULE_PARM(display, "1i"); -MODULE_PARM(adisplay, "1i"); -MODULE_PARM(normal, "1i"); -MODULE_PARM(ansi, "1i"); -#endif - MODULE_LICENSE("GPL"); #endif /*counter of concurrent disk read/writes, to turn on/off disk led */ -- cgit v1.1 From 774251ef64a1ad1e8b895e00d3d075cfa38d2af1 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 2 Oct 2007 14:38:01 -0700 Subject: [SCSI] nsp_cs: remove kernel 2.4 code Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/pcmcia/nsp_cs.c | 159 ++----------------------------------------- drivers/scsi/pcmcia/nsp_cs.h | 8 --- 2 files changed, 5 insertions(+), 162 deletions(-) diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 445cfbb..a45d89b 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -25,8 +25,6 @@ ***********************************************************************/ -/* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */ - #include #include #include @@ -59,7 +57,7 @@ #include "nsp_cs.h" MODULE_AUTHOR("YOKOTA Hiroshi "); -MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $"); +MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); #ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); @@ -83,10 +81,6 @@ static struct scsi_host_template nsp_driver_template = { .proc_name = "nsp_cs", .proc_info = nsp_proc_info, .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - .detect = nsp_detect_old, - .release = nsp_release_old, -#endif .info = nsp_info, .queuecommand = nsp_queuecommand, /* .eh_abort_handler = nsp_eh_abort,*/ @@ -97,9 +91,6 @@ static struct scsi_host_template nsp_driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)) - .use_new_eh_code = 1, -#endif }; static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ @@ -1313,11 +1304,7 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht) nsp_hw_data *data_b = &nsp_data_base, *data; nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data)); -#else - host = scsi_register(sht, sizeof(nsp_hw_data)); -#endif if (host == NULL) { nsp_dbg(NSP_DEBUG_INIT, "host failed"); return NULL; @@ -1354,37 +1341,6 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht) return host; /* detect done. */ } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int nsp_detect_old(struct scsi_host_template *sht) -{ - if (nsp_detect(sht) == NULL) { - return 0; - } else { - //MOD_INC_USE_COUNT; - return 1; - } -} - - -static int nsp_release_old(struct Scsi_Host *shpnt) -{ - //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata; - - /* PCMCIA Card Service dose same things below. */ - /* So we do nothing. */ - //if (shpnt->irq) { - // free_irq(shpnt->irq, data->ScsiInfo); - //} - //if (shpnt->io_port) { - // release_region(shpnt->io_port, shpnt->n_io_port); - //} - - //MOD_DEC_USE_COUNT; - - return 0; -} -#endif - /*----------------------------------------------------------------*/ /* return info string */ /*----------------------------------------------------------------*/ @@ -1403,19 +1359,9 @@ static const char *nsp_info(struct Scsi_Host *shpnt) nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ } \ } while(0) -static int -nsp_proc_info( -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) - struct Scsi_Host *host, -#endif - char *buffer, - char **start, - off_t offset, - int length, -#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) - int hostno, -#endif - int inout) + +static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start, + off_t offset, int length, int inout) { int id; char *pos = buffer; @@ -1423,24 +1369,13 @@ nsp_proc_info( int speed; unsigned long flags; nsp_hw_data *data; -#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) - struct Scsi_Host *host; -#else int hostno; -#endif + if (inout) { return -EINVAL; } -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) hostno = host->host_no; -#else - /* search this HBA host */ - host = scsi_host_hn_get(hostno); - if (host == NULL) { - return -ESRCH; - } -#endif data = (nsp_hw_data *)host->hostdata; @@ -1675,10 +1610,6 @@ static int nsp_cs_config(struct pcmcia_device *link) cistpl_cftable_entry_t dflt = { 0 }; struct Scsi_Host *host; nsp_hw_data *data = &nsp_data_base; -#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) - struct scsi_device *dev; - dev_node_t **tail, *node; -#endif nsp_dbg(NSP_DEBUG_INIT, "in"); @@ -1811,17 +1742,7 @@ static int nsp_cs_config(struct pcmcia_device *link) goto cs_failed; } -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) host = nsp_detect(&nsp_driver_template); -#else - scsi_register_host(&nsp_driver_template); - for (host = scsi_host_get_next(NULL); host != NULL; - host = scsi_host_get_next(host)) { - if (host->hostt == &nsp_driver_template) { - break; - } - } -#endif if (host == NULL) { nsp_dbg(NSP_DEBUG_INIT, "detect failed"); @@ -1829,7 +1750,6 @@ static int nsp_cs_config(struct pcmcia_device *link) } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) ret = scsi_add_host (host, NULL); if (ret) goto cs_failed; @@ -1840,52 +1760,6 @@ static int nsp_cs_config(struct pcmcia_device *link) link->dev_node = &info->node; info->host = host; -#else - nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); - tail = &link->dev_node; - info->ndev = 0; - - nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); - - for (dev = host->host_queue; dev != NULL; dev = dev->next) { - unsigned long id; - id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) + - ((dev->channel & 0x0f) << 8) + - ((dev->host->host_no & 0x0f) << 12); - node = &info->node[info->ndev]; - node->minor = 0; - switch (dev->type) { - case TYPE_TAPE: - node->major = SCSI_TAPE_MAJOR; - snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id); - break; - case TYPE_DISK: - case TYPE_MOD: - node->major = SCSI_DISK0_MAJOR; - snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id); - break; - case TYPE_ROM: - case TYPE_WORM: - node->major = SCSI_CDROM_MAJOR; - snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id); - break; - default: - node->major = SCSI_GENERIC_MAJOR; - snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id); - break; - } - *tail = node; tail = &node->next; - info->ndev++; - info->host = dev->host; - } - - *tail = NULL; - if (info->ndev == 0) { - nsp_msg(KERN_INFO, "no SCSI devices found"); - } - nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); -#endif - /* Finally, report what we've done */ printk(KERN_INFO "nsp_cs: index 0x%02x: ", link->conf.ConfigIndex); @@ -1938,13 +1812,9 @@ static void nsp_cs_release(struct pcmcia_device *link) nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); /* Unlink the device chain */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) if (info->host != NULL) { scsi_remove_host(info->host); } -#else - scsi_unregister_host(&nsp_driver_template); -#endif link->dev_node = NULL; if (link->win) { @@ -1954,11 +1824,9 @@ static void nsp_cs_release(struct pcmcia_device *link) } pcmcia_disable_device(link); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) if (info->host != NULL) { scsi_host_put(info->host); } -#endif } /* nsp_cs_release */ static int nsp_cs_suspend(struct pcmcia_device *link) @@ -2005,7 +1873,6 @@ static int nsp_cs_resume(struct pcmcia_device *link) /*======================================================================* * module entry point *====================================================================*/ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) static struct pcmcia_device_id nsp_cs_ids[] = { PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a), PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a), @@ -2029,28 +1896,12 @@ static struct pcmcia_driver nsp_driver = { .suspend = nsp_cs_suspend, .resume = nsp_cs_resume, }; -#endif static int __init nsp_cs_init(void) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) nsp_msg(KERN_INFO, "loading..."); return pcmcia_register_driver(&nsp_driver); -#else - servinfo_t serv; - - nsp_msg(KERN_INFO, "loading..."); - pcmcia_get_card_services_info(&serv); - if (serv.Revision != CS_RELEASE_CODE) { - nsp_msg(KERN_DEBUG, "Card Services release does not match!"); - return -EINVAL; - } - register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach); - - nsp_dbg(NSP_DEBUG_INIT, "out"); - return 0; -#endif } static void __exit nsp_cs_exit(void) diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 9102cbd..b7f0fa2 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -10,8 +10,6 @@ =========================================================*/ -/* $Id: nsp_cs.h,v 1.19 2003/08/18 11:09:19 elca Exp $ */ - #ifndef __nsp_cs__ #define __nsp_cs__ @@ -227,13 +225,7 @@ typedef struct scsi_info_t { struct pcmcia_device *p_dev; struct Scsi_Host *host; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) dev_node_t node; -#else - int ndev; - dev_node_t node[8]; - struct bus_operations *bus; -#endif int stop; } scsi_info_t; -- cgit v1.1 From 5975f643efc39ebb762dfaf18ca6f2c95983dac0 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 2 Oct 2007 14:37:59 -0700 Subject: [SCSI] arcmsr: build fix drivers/scsi/arcmsr/arcmsr_hba.c:129: error: 'arcmsr_pci_error_detected' undeclared here (not in a function) drivers/scsi/arcmsr/arcmsr_hba.c:130: error: 'arcmsr_pci_slot_reset' undeclared here (not in a function) Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr_hba.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index f4d2d52..cfcf401 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -125,6 +125,10 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .shost_attrs = arcmsr_host_attrs, }; #ifdef CONFIG_SCSI_ARCMSR_AER +static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); +static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, + pci_channel_state_t state); + static struct pci_error_handlers arcmsr_pci_error_handlers = { .error_detected = arcmsr_pci_error_detected, .slot_reset = arcmsr_pci_slot_reset, -- cgit v1.1 From f01f9d59433dd9d244664c19771e078a194e7984 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 2 Oct 2007 14:38:09 -0700 Subject: [SCSI] imm: fix check-after-use The Coverity checker spotted that we have already oops'ed if "cmd" was NULL. Since "cmd" being NULL doesn't seem to be possible at this point this patch removes the NULL check. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/imm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 005d2b0..74cdc1f 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -740,10 +740,6 @@ static void imm_interrupt(struct work_struct *work) struct Scsi_Host *host = cmd->device->host; unsigned long flags; - if (!cmd) { - printk("IMM: bug in imm_interrupt\n"); - return; - } if (imm_engine(dev, cmd)) { schedule_delayed_work(&dev->imm_tq, 1); return; -- cgit v1.1 From d773c082da27c445c832324cfb4a357498613a38 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 2 Oct 2007 14:38:05 -0700 Subject: [SCSI] scsi_transport_iscsi: add list, mutex includes scsi/scsi_transport_iscsi.h uses struct mutex and struct list_head, so while linux/mutex.h and linux/list.h seem to be pulled in indirectly by one of the headers it includes, the right thing is to include linux/mutex.h and linus/list.h directly. Signed-off-by: Michael S. Tsirkin Acked-by: Mike Christie Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- include/scsi/scsi_transport_iscsi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 706c0cd..7ff6199 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -24,6 +24,8 @@ #define SCSI_TRANSPORT_ISCSI_H #include +#include +#include #include struct scsi_transport_template; -- cgit v1.1 From 89932697ce742c094916d8270c282042b24776b3 Mon Sep 17 00:00:00 2001 From: Joe Korty Date: Tue, 2 Oct 2007 14:38:08 -0700 Subject: [SCSI] dpt_i2o: Fix section mismatch Fix section mismatch in the Adaptec DPT SCSI Raid driver. WARNING: vmlinux.o(.init.text+0x1fcd2): Section mismatch: reference to .exit.text:adpt_exit (between 'adpt_init' and 'ahc_linux_init') This warning is due to adaptec device detection calling the exit routine on failure to properly register the adaptec device. The exit routine + call was added on July 30 by Commit: 55d9fcf57ba5ec427544fca7abc335cf3da78160 Author: Matthew Wilcox Subject: [SCSI] dpt_i2o: convert to SCSI hotplug model. Mathew: isn't a module exit routine a little too strong to be calling on the failure of a single device? Module exit implies that other, non-failing adaptec raid devices will also get shut down. Signed-off-by: Joe Korty Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/dpt_i2o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 9d7bdf7..bea9d65 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -3346,7 +3346,7 @@ static int __init adpt_init(void) return count > 0 ? 0 : -ENODEV; } -static void __exit adpt_exit(void) +static void adpt_exit(void) { while (hba_chain) adpt_release(hba_chain); -- cgit v1.1 From 2ca482302f2080e6861eaf753051ac35b6b411ad Mon Sep 17 00:00:00 2001 From: Gabriel C Date: Tue, 2 Oct 2007 14:38:02 -0700 Subject: [SCSI] fdomain: fix CONFIG_PCI=n warnings I get this warnings on current git when CONFIG_PCI is not set : drivers/scsi/fdomain.c:390: warning: 'PCI_dev' defined but not used drivers/scsi/fdomain.c:1768: warning: 'fdomain_pci_tbl' defined but not used Signed-off-by: Gabriel Craciunescu Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- drivers/scsi/fdomain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 36169d5..5d282e6 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -387,7 +387,9 @@ static void __iomem * bios_mem; static int bios_major; static int bios_minor; static int PCI_bus; +#ifdef CONFIG_PCI static struct pci_dev *PCI_dev; +#endif static int Quantum; /* Quantum board variant */ static int interrupt_level; static volatile int in_command; @@ -1764,6 +1766,7 @@ struct scsi_host_template fdomain_driver_template = { }; #ifndef PCMCIA +#ifdef CONFIG_PCI static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, @@ -1771,7 +1774,7 @@ static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { { } }; MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); - +#endif #define driver_template fdomain_driver_template #include "scsi_module.c" -- cgit v1.1 From 55db6c1b8ed52bfc876e87971de8c67c42f36909 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 8 Oct 2007 16:35:19 +0200 Subject: [SCSI] scsi_error: code cleanup before refactoring of scsi_send_eh_cmnd() - regrouped variables for easier reviewing of next patch - Support of cmnd==NULL in call to scsi_send_eh_cmnd() - In the @sense_bytes case set transfer size to the minimum size of sense_buffer and passed @sense_bytes. cmnd[4] is set accordingly. - REQUEST_SENSE is set into cmnd[0] so if @sense_bytes is not Zero passed @cmnd should be NULL. - Also save/restore resid of failed command. - Adjust caller Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 71 ++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index f49feb9..4d53501 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -592,36 +592,39 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) /** * scsi_send_eh_cmnd - submit a scsi command as part of error recory * @scmd: SCSI command structure to hijack - * @cmnd: CDB to send + * @cmnd: CDB to send. Can be NULL if no new cmnd is needed * @cmnd_size: size in bytes of @cmnd * @timeout: timeout for this request - * @copy_sense: request sense data if set to 1 + * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) * * This function is used to send a scsi command down to a target device - * as part of the error recovery process. If @copy_sense is 0 the command - * sent must be one that does not transfer any data. If @copy_sense is 1 - * the command must be REQUEST_SENSE and this functions copies out the - * sense buffer it got into @scmd->sense_buffer. + * as part of the error recovery process. If @sense_bytes is 0 the command + * sent must be one that does not transfer any data. If @sense_bytes != 0 + * @cmnd is ignored and this functions sets up a REQUEST_SENSE command + * and cmnd buffers to read @sense_bytes into @scmd->sense_buffer. * * Return value: * SUCCESS or FAILED or NEEDS_RETRY **/ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, - int cmnd_size, int timeout, int copy_sense) + int cmnd_size, int timeout, unsigned sense_bytes) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; - int old_result = scmd->result; DECLARE_COMPLETION_ONSTACK(done); unsigned long timeleft; unsigned long flags; - struct scatterlist sgl; + + unsigned char old_cmd_len; unsigned char old_cmnd[MAX_COMMAND_SIZE]; enum dma_data_direction old_data_direction; - unsigned short old_use_sg; - unsigned char old_cmd_len; unsigned old_bufflen; void *old_buffer; + unsigned short old_use_sg; + int old_resid; + int old_result; + + struct scatterlist sgl; int rtn; /* @@ -631,35 +634,41 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, * we will need to restore these values prior to running the actual * command. */ - old_buffer = scmd->request_buffer; - old_bufflen = scmd->request_bufflen; + old_cmd_len = scmd->cmd_len; memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); old_data_direction = scmd->sc_data_direction; - old_cmd_len = scmd->cmd_len; + old_bufflen = scmd->request_bufflen; + old_buffer = scmd->request_buffer; old_use_sg = scmd->use_sg; + old_resid = scmd->resid; + old_result = scmd->result; - memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); - memcpy(scmd->cmnd, cmnd, cmnd_size); - - if (copy_sense) { - sg_init_one(&sgl, scmd->sense_buffer, - sizeof(scmd->sense_buffer)); - - scmd->sc_data_direction = DMA_FROM_DEVICE; - scmd->request_bufflen = sgl.length; + if (sense_bytes) { + scmd->request_bufflen = min_t(unsigned, + sizeof(scmd->sense_buffer), sense_bytes); + sg_init_one(&sgl, scmd->sense_buffer, scmd->request_bufflen); scmd->request_buffer = &sgl; + scmd->sc_data_direction = DMA_FROM_DEVICE; scmd->use_sg = 1; + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); + scmd->cmnd[0] = REQUEST_SENSE; + scmd->cmnd[4] = scmd->request_bufflen; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); } else { scmd->request_buffer = NULL; scmd->request_bufflen = 0; scmd->sc_data_direction = DMA_NONE; scmd->use_sg = 0; + if (cmnd) { + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); + memcpy(scmd->cmnd, cmnd, cmnd_size); + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + } } scmd->underflow = 0; - scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); - if (sdev->scsi_level <= SCSI_2) + if (sdev->scsi_level <= SCSI_2 && sdev->scsi_level != SCSI_UNKNOWN) scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | (sdev->lun << 5 & 0xe0); @@ -716,12 +725,13 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, /* * Restore original data */ - scmd->request_buffer = old_buffer; - scmd->request_bufflen = old_bufflen; + scmd->cmd_len = old_cmd_len; memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); scmd->sc_data_direction = old_data_direction; - scmd->cmd_len = old_cmd_len; + scmd->request_bufflen = old_bufflen; + scmd->request_buffer = old_buffer; scmd->use_sg = old_use_sg; + scmd->resid = old_resid; scmd->result = old_result; return rtn; } @@ -737,10 +747,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, **/ static int scsi_request_sense(struct scsi_cmnd *scmd) { - static unsigned char generic_sense[6] = - {REQUEST_SENSE, 0, 0, 0, 252, 0}; - - return scsi_send_eh_cmnd(scmd, generic_sense, 6, SENSE_TIMEOUT, 1); + return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0); } /** -- cgit v1.1 From e1c234685c50807e10a3e7873e6e006976a4d8e8 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 8 Oct 2007 16:36:45 +0200 Subject: [SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE - Drivers/transports that want to send a synchronous REQUEST_SENSE command as part of their .queuecommand sequence, have 2 new API's that facilitate in doing so and abstract them from scsi-ml internals. void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *sesci, unsigned char *cmnd, int cmnd_size, int sense_bytes) Will hijack a command and prepare it for request sense if needed. And will save any later needed info into a scsi_eh_save structure. void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *sesci); Will undo any changes done to a command by above function. Making it ready for completion. - Re-factor scsi_send_eh_cmnd() to use above APIs Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 114 +++++++++++++++++++++++++++------------------- include/scsi/scsi_eh.h | 23 +++++++++- 2 files changed, 90 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4d53501..d29f846 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -590,42 +590,23 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) } /** - * scsi_send_eh_cmnd - submit a scsi command as part of error recory + * scsi_eh_prep_cmnd - Save a scsi command info as part of error recory * @scmd: SCSI command structure to hijack + * @ses: structure to save restore information * @cmnd: CDB to send. Can be NULL if no new cmnd is needed * @cmnd_size: size in bytes of @cmnd - * @timeout: timeout for this request * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) * - * This function is used to send a scsi command down to a target device + * This function is used to save a scsi command information before re-execution * as part of the error recovery process. If @sense_bytes is 0 the command * sent must be one that does not transfer any data. If @sense_bytes != 0 * @cmnd is ignored and this functions sets up a REQUEST_SENSE command * and cmnd buffers to read @sense_bytes into @scmd->sense_buffer. - * - * Return value: - * SUCCESS or FAILED or NEEDS_RETRY **/ -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, - int cmnd_size, int timeout, unsigned sense_bytes) +void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, + unsigned char *cmnd, int cmnd_size, unsigned sense_bytes) { struct scsi_device *sdev = scmd->device; - struct Scsi_Host *shost = sdev->host; - DECLARE_COMPLETION_ONSTACK(done); - unsigned long timeleft; - unsigned long flags; - - unsigned char old_cmd_len; - unsigned char old_cmnd[MAX_COMMAND_SIZE]; - enum dma_data_direction old_data_direction; - unsigned old_bufflen; - void *old_buffer; - unsigned short old_use_sg; - int old_resid; - int old_result; - - struct scatterlist sgl; - int rtn; /* * We need saved copies of a number of fields - this is because @@ -634,20 +615,21 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, * we will need to restore these values prior to running the actual * command. */ - old_cmd_len = scmd->cmd_len; - memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); - old_data_direction = scmd->sc_data_direction; - old_bufflen = scmd->request_bufflen; - old_buffer = scmd->request_buffer; - old_use_sg = scmd->use_sg; - old_resid = scmd->resid; - old_result = scmd->result; + ses->cmd_len = scmd->cmd_len; + memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); + ses->data_direction = scmd->sc_data_direction; + ses->bufflen = scmd->request_bufflen; + ses->buffer = scmd->request_buffer; + ses->use_sg = scmd->use_sg; + ses->resid = scmd->resid; + ses->result = scmd->result; if (sense_bytes) { scmd->request_bufflen = min_t(unsigned, sizeof(scmd->sense_buffer), sense_bytes); - sg_init_one(&sgl, scmd->sense_buffer, scmd->request_bufflen); - scmd->request_buffer = &sgl; + sg_init_one(&ses->sense_sgl, scmd->sense_buffer, + scmd->request_bufflen); + scmd->request_buffer = &ses->sense_sgl; scmd->sc_data_direction = DMA_FROM_DEVICE; scmd->use_sg = 1; memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); @@ -677,7 +659,58 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, * untransferred sense data should be interpreted as being zero. */ memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); +} +EXPORT_SYMBOL(scsi_eh_prep_cmnd); + +/** + * scsi_eh_restore_cmnd - Restore a scsi command info as part of error recory + * @scmd: SCSI command structure to restore + * @ses: saved information from a coresponding call to scsi_prep_eh_cmnd + * + * Undo any damage done by above scsi_prep_eh_cmnd(). + **/ +void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) +{ + /* + * Restore original data + */ + scmd->cmd_len = ses->cmd_len; + memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); + scmd->sc_data_direction = ses->data_direction; + scmd->request_bufflen = ses->bufflen; + scmd->request_buffer = ses->buffer; + scmd->use_sg = ses->use_sg; + scmd->resid = ses->resid; + scmd->result = ses->result; +} +EXPORT_SYMBOL(scsi_eh_restore_cmnd); +/** + * scsi_send_eh_cmnd - submit a scsi command as part of error recory + * @scmd: SCSI command structure to hijack + * @cmnd: CDB to send + * @cmnd_size: size in bytes of @cmnd + * @timeout: timeout for this request + * @sense_bytes: size of sense data to copy or 0 + * + * This function is used to send a scsi command down to a target device + * as part of the error recovery process. See also scsi_eh_prep_cmnd() above. + * + * Return value: + * SUCCESS or FAILED or NEEDS_RETRY + **/ +static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, + int cmnd_size, int timeout, unsigned sense_bytes) +{ + struct scsi_device *sdev = scmd->device; + struct Scsi_Host *shost = sdev->host; + DECLARE_COMPLETION_ONSTACK(done); + unsigned long timeleft; + unsigned long flags; + struct scsi_eh_save ses; + int rtn; + + scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes); shost->eh_action = &done; spin_lock_irqsave(shost->host_lock, flags); @@ -721,18 +754,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, rtn = FAILED; } - - /* - * Restore original data - */ - scmd->cmd_len = old_cmd_len; - memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); - scmd->sc_data_direction = old_data_direction; - scmd->request_bufflen = old_bufflen; - scmd->request_buffer = old_buffer; - scmd->use_sg = old_use_sg; - scmd->resid = old_resid; - scmd->result = old_result; + scsi_eh_restore_cmnd(scmd, &ses); return rtn; } diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index c5c0f67..44224ba 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -1,7 +1,7 @@ #ifndef _SCSI_SCSI_EH_H #define _SCSI_SCSI_EH_H -struct scsi_cmnd; +#include struct scsi_device; struct Scsi_Host; @@ -65,4 +65,25 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, extern int scsi_reset_provider(struct scsi_device *, int); +struct scsi_eh_save { + int result; + enum dma_data_direction data_direction; + unsigned char cmd_len; + unsigned char cmnd[MAX_COMMAND_SIZE]; + + void *buffer; + unsigned bufflen; + unsigned short use_sg; + int resid; + + struct scatterlist sense_sgl; +}; + +extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, + struct scsi_eh_save *ses, unsigned char *cmnd, + int cmnd_size, unsigned sense_bytes); + +extern void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, + struct scsi_eh_save *ses); + #endif /* _SCSI_SCSI_EH_H */ -- cgit v1.1 From dff6de73f9d29868729cb1d21d86ba0dbd28871f Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 10 Sep 2007 22:36:31 +0300 Subject: [SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution - Use new scsi_eh_prep/restor_cmnd() for synchronous REQUEST_SENSE invocation. Signed-off-by: Boaz Harrosh Acked-by: Alan Stern Signed-off-by: James Bottomley --- drivers/usb/storage/transport.c | 46 ++++------------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 323293a..c646750 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include "usb.h" @@ -580,25 +580,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* Now, if we need to do the auto-sense, let's do it */ if (need_auto_sense) { int temp_result; - void* old_request_buffer; - unsigned short old_sg; - unsigned old_request_bufflen; - unsigned char old_sc_data_direction; - unsigned char old_cmd_len; - unsigned char old_cmnd[MAX_COMMAND_SIZE]; - int old_resid; + struct scsi_eh_save ses; US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); - /* save the old command */ - memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE); - old_cmd_len = srb->cmd_len; - - /* set the command and the LUN */ - memset(srb->cmnd, 0, MAX_COMMAND_SIZE); - srb->cmnd[0] = REQUEST_SENSE; - srb->cmnd[1] = old_cmnd[1] & 0xE0; - srb->cmnd[4] = 18; + scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE); /* FIXME: we must do the protocol translation here */ if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI) @@ -606,36 +592,12 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) else srb->cmd_len = 12; - /* set the transfer direction */ - old_sc_data_direction = srb->sc_data_direction; - srb->sc_data_direction = DMA_FROM_DEVICE; - - /* use the new buffer we have */ - old_request_buffer = srb->request_buffer; - srb->request_buffer = us->sensebuf; - - /* set the buffer length for transfer */ - old_request_bufflen = srb->request_bufflen; - srb->request_bufflen = US_SENSE_SIZE; - - /* set up for no scatter-gather use */ - old_sg = srb->use_sg; - srb->use_sg = 0; - /* issue the auto-sense command */ - old_resid = srb->resid; srb->resid = 0; temp_result = us->transport(us->srb, us); /* let's clean up right away */ - memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE); - srb->resid = old_resid; - srb->request_buffer = old_request_buffer; - srb->request_bufflen = old_request_bufflen; - srb->use_sg = old_sg; - srb->sc_data_direction = old_sc_data_direction; - srb->cmd_len = old_cmd_len; - memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); + scsi_eh_restore_cmnd(srb, &ses); if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { US_DEBUGP("-- auto-sense aborted\n"); -- cgit v1.1 From 28424d3a503d43482a5537e556f7b7652d8e56d8 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 10 Sep 2007 22:37:45 +0300 Subject: [SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation - Use new scsi_eh_prep/restor_cmnd() for synchronous REQUEST_SENSE invocation. Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/NCR5380.c | 23 +++++++++-------------- drivers/scsi/NCR5380.h | 7 +++++++ drivers/scsi/atari_NCR5380.c | 23 ++++++++--------------- drivers/scsi/sun3_NCR5380.c | 18 +++++++----------- 4 files changed, 31 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 5b27966..988f0bc 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -1542,9 +1542,7 @@ part2: hostdata->connected = cmd; hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); - if (cmd->SCp.ptr != (char *)cmd->sense_buffer) { - initialize_SCp(cmd); - } + initialize_SCp(cmd); return 0; @@ -2280,19 +2278,16 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); #ifdef AUTOSENSE + if ((cmd->cmnd[0] == REQUEST_SENSE) && + hostdata->ses.cmd_len) { + scsi_eh_restore_cmnd(cmd, &hostdata->ses); + hostdata->ses.cmd_len = 0 ; + } + if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { + scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); + dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no)); - cmd->cmnd[0] = REQUEST_SENSE; - cmd->cmnd[1] &= 0xe0; - cmd->cmnd[2] = 0; - cmd->cmnd[3] = 0; - cmd->cmnd[4] = sizeof(cmd->sense_buffer); - cmd->cmnd[5] = 0; - - cmd->SCp.buffer = NULL; - cmd->SCp.buffers_residual = 0; - cmd->SCp.ptr = (char *) cmd->sense_buffer; - cmd->SCp.this_residual = sizeof(cmd->sense_buffer); LIST(cmd, hostdata->issue_queue); cmd->host_scribble = (unsigned char *) diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index bccf13f..bdc468c 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -30,6 +30,10 @@ #include +#ifdef AUTOSENSE +#include +#endif + #define NCR5380_PUBLIC_RELEASE 7 #define NCR53C400_PUBLIC_RELEASE 2 @@ -281,6 +285,9 @@ struct NCR5380_hostdata { unsigned pendingr; unsigned pendingw; #endif +#ifdef AUTOSENSE + struct scsi_eh_save ses; +#endif }; #ifdef __KERNEL__ diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 743df4c..52d0b87 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -2235,24 +2235,17 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); #ifdef AUTOSENSE + if ((cmd->cmnd[0] == REQUEST_SENSE) && + hostdata->ses.cmd_len) { + scsi_eh_restore_cmnd(cmd, &hostdata->ses); + hostdata->ses.cmd_len = 0 ; + } + if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { + scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); + ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); - cmd->cmnd[0] = REQUEST_SENSE; - cmd->cmnd[1] &= 0xe0; - cmd->cmnd[2] = 0; - cmd->cmnd[3] = 0; - cmd->cmnd[4] = sizeof(cmd->sense_buffer); - cmd->cmnd[5] = 0; - cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); - - cmd->use_sg = 0; - /* this is initialized from initialize_SCp - cmd->SCp.buffer = NULL; - cmd->SCp.buffers_residual = 0; - */ - cmd->request_buffer = (char *) cmd->sense_buffer; - cmd->request_bufflen = sizeof(cmd->sense_buffer); local_irq_save(flags); LIST(cmd,hostdata->issue_queue); diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 3769537..dc15a22 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -2254,25 +2254,21 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); #ifdef AUTOSENSE + if ((cmd->cmnd[0] == REQUEST_SENSE) && + hostdata->ses.cmd_len) { + scsi_eh_restore_cmnd(cmd, &hostdata->ses); + hostdata->ses.cmd_len = 0 ; + } + if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { + scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); - cmd->cmnd[0] = REQUEST_SENSE; - cmd->cmnd[1] &= 0xe0; - cmd->cmnd[2] = 0; - cmd->cmnd[3] = 0; - cmd->cmnd[4] = sizeof(cmd->sense_buffer); - cmd->cmnd[5] = 0; - cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); - - cmd->use_sg = 0; /* this is initialized from initialize_SCp cmd->SCp.buffer = NULL; cmd->SCp.buffers_residual = 0; */ - cmd->request_buffer = (char *) cmd->sense_buffer; - cmd->request_bufflen = sizeof(cmd->sense_buffer); local_irq_save(flags); LIST(cmd,hostdata->issue_queue); -- cgit v1.1 From b8bff2aeafb1959de27bd889d1c103577b36712f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 2 Oct 2007 22:40:22 +0200 Subject: gdth: Make one abuse of scsi_cmnd less obvious Rather than having internal commands abuse scsi_done to call gdth_scsi_done, have all the places that use to call scsi_done directly call gdth_scsi_done, which now checks whether the command was internal, and calls scsi_done if not. Signed-off-by: Matthew Wilcox Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 317a282..fe5db2d 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -716,10 +716,12 @@ static void gdth_delay(int milliseconds) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static void gdth_scsi_done(struct scsi_cmnd *scp) { - TRACE2(("gdth_scsi_done()\n")); + TRACE2(("gdth_scsi_done()\n")); - if (IS_GDTH_INTERNAL_CMD(scp)) - complete((struct completion *)scp->request); + if (IS_GDTH_INTERNAL_CMD(scp)) + complete((struct completion *)scp->request); + else + scp->scsi_done(scp); } int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, @@ -742,7 +744,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, memcpy(scp->cmnd, cmnd, 12); scp->SCp.this_residual = IOCTL_PRI; /* priority */ scp->underflow = GDTH_MAGIC; - gdth_queuecommand(scp, gdth_scsi_done); + gdth_queuecommand(scp, NULL); wait_for_completion(&wait); rval = scp->SCp.Status; @@ -2508,7 +2510,7 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); + gdth_scsi_done(nscp); } } else if (IS_GDTH_INTERNAL_CMD(nscp)) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) @@ -2527,7 +2529,7 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); + gdth_scsi_done(nscp); } else { switch (nscp->cmnd[0]) { case TEST_UNIT_READY: @@ -2553,9 +2555,9 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); - } else if (gdth_internal_cache_cmd(hanum,nscp)) - nscp->scsi_done(nscp); + gdth_scsi_done(nscp); + } else if (gdth_internal_cache_cmd(hanum, nscp)) + gdth_scsi_done(nscp); break; case ALLOW_MEDIUM_REMOVAL: @@ -2569,7 +2571,7 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); + gdth_scsi_done(nscp); } else { nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; TRACE(("Prevent/allow r. %d rem. drive %d\n", @@ -2605,8 +2607,8 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); - } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) + gdth_scsi_done(nscp); + } else if (!(cmd_index=gdth_fill_cache_cmd(hanum, nscp, t))) this_cmd = FALSE; break; @@ -2620,7 +2622,7 @@ static void gdth_next(int hanum) if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; else - nscp->scsi_done(nscp); + gdth_scsi_done(nscp); break; } } @@ -3633,7 +3635,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (rval == 2) { gdth_putq(hanum,scp,scp->SCp.this_residual); } else if (rval == 1) { - scp->scsi_done(scp); + gdth_scsi_done(scp); } #ifdef INT_COAL @@ -4928,14 +4930,15 @@ static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) } -static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) +static int gdth_queuecommand(struct scsi_cmnd *scp, + void (*done)(struct scsi_cmnd *)) { int hanum; int priority; TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); - scp->scsi_done = (void *)done; + scp->scsi_done = done; scp->SCp.have_data_in = 1; scp->SCp.phase = -1; scp->SCp.sent_command = -1; -- cgit v1.1 From aed91cb520747d08dd5cb0220d0dd3492bead220 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 2 Oct 2007 22:48:16 +0200 Subject: [SCSI] gdth: split out isa probing (note: this is ontop of Jeff's pci cleanup patch) Split out isa probing into a helper of it's own. Error handling is cleaned up, but errors are not propagated yet. Also enclose the isa probe under the proper CONFIG_ISA symbol instead of the !IA64 hack. Signed-off-by: Christoph Hellwig Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 296 ++++++++++++++++++++++++++++------------------------ 1 file changed, 162 insertions(+), 134 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index fe5db2d..add2ebb 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -445,13 +445,11 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); static int gdth_search_eisa(ushort eisa_adr); -static int gdth_search_isa(ulong32 bios_adr); static int gdth_search_pci(gdth_pci_str *pcistr); static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, ushort vendor, ushort dev); static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha); -static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha); static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); static void gdth_enable_int(int hanum); @@ -476,6 +474,9 @@ static void gdth_flush(int hanum); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); static void gdth_scsi_done(struct scsi_cmnd *scp); +#ifdef CONFIG_ISA +static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); +#endif #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -584,7 +585,10 @@ static struct timer_list gdth_timer; #define gdth_writew(b,addr) writew((b),(addr)) #define gdth_writel(b,addr) writel((b),(addr)) +#ifdef CONFIG_ISA static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ +#endif + static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ static unchar gdth_polling; /* polling if TRUE */ static unchar gdth_from_wait = FALSE; /* gdth_wait() */ @@ -838,7 +842,7 @@ static int __init gdth_search_eisa(ushort eisa_adr) return 0; } - +#ifdef CONFIG_ISA static int __init gdth_search_isa(ulong32 bios_adr) { void __iomem *addr; @@ -853,7 +857,7 @@ static int __init gdth_search_isa(ulong32 bios_adr) } return 0; } - +#endif /* CONFIG_ISA */ static int __init gdth_search_pci(gdth_pci_str *pcistr) { @@ -1064,7 +1068,7 @@ static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) return 1; } - +#ifdef CONFIG_ISA static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) { register gdt2_dpram_str __iomem *dp2_ptr; @@ -1163,7 +1167,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) ha->dma64_support = 0; return 1; } - +#endif /* CONFIG_ISA */ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) { @@ -4282,6 +4286,7 @@ int __init option_setup(char *str) return 1; } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int __init gdth_detect(struct scsi_host_template *shtp) #else @@ -4291,7 +4296,6 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; gdth_ha_str *ha; - ulong32 isa_bios; ushort eisa_slot; int i,hanum,cnt,ctr,err; unchar b; @@ -4328,135 +4332,16 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) /* As default we do not probe for EISA or ISA controllers */ if (probe_eisa_isa) { /* scanning for controllers, at first: ISA controller */ - for (isa_bios=0xc8000UL; isa_bios<=0xd8000UL; isa_bios+=0x8000UL) { - dma_addr_t scratch_dma_handle; - scratch_dma_handle = 0; - - if (gdth_ctr_count >= MAXHA) +#ifdef CONFIG_ISA + ulong32 isa_bios; + for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; + isa_bios += 0x8000UL) { + if (gdth_ctr_count >= MAXHA) break; - if (gdth_search_isa(isa_bios)) { /* controller found */ - shp = scsi_register(shtp,sizeof(gdth_ext_str)); - if (shp == NULL) - continue; - - ha = HADATA(shp); - if (!gdth_init_isa(isa_bios,ha)) { - scsi_unregister(shp); - continue; - } -#ifdef __ia64__ - break; -#else - /* controller found and initialized */ - printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", - isa_bios,ha->irq,ha->drq); - - if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { - printk("GDT-ISA: Unable to allocate IRQ\n"); - scsi_unregister(shp); - continue; - } - if (request_dma(ha->drq,"gdth")) { - printk("GDT-ISA: Unable to allocate DMA channel\n"); - free_irq(ha->irq,ha); - scsi_unregister(shp); - continue; - } - set_dma_mode(ha->drq,DMA_MODE_CASCADE); - enable_dma(ha->drq); - shp->unchecked_isa_dma = 1; - shp->irq = ha->irq; - shp->dma_channel = ha->drq; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; - - ha->pccb = CMDDATA(shp); - ha->ccb_phys = 0L; - ha->pdev = NULL; - ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, - &scratch_dma_handle); - ha->scratch_phys = scratch_dma_handle; - ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), - &scratch_dma_handle); - ha->msg_phys = scratch_dma_handle; -#ifdef INT_COAL - ha->coal_stat = (gdth_coal_status *) - pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, &scratch_dma_handle); - ha->coal_stat_phys = scratch_dma_handle; -#endif - - ha->scratch_busy = FALSE; - ha->req_first = NULL; - ha->tid_cnt = MAX_HDRIVES; - if (max_ids > 0 && max_ids < ha->tid_cnt) - ha->tid_cnt = max_ids; - for (i=0; icmd_tab[i].cmnd = UNUSED_CMND; - ha->scan_mode = rescan ? 0x10 : 0; - - if (ha->pscratch == NULL || ha->pmsg == NULL || - !gdth_search_drives(hanum)) { - printk("GDT-ISA: Error during device scan\n"); - --gdth_ctr_count; - --gdth_ctr_vcount; - -#ifdef INT_COAL - if (ha->coal_stat) - pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, ha->coal_stat, - ha->coal_stat_phys); -#endif - if (ha->pscratch) - pci_free_consistent(ha->pdev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - if (ha->pmsg) - pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - - free_irq(ha->irq,ha); - scsi_unregister(shp); - continue; - } - if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) - hdr_channel = ha->bus_cnt; - ha->virt_bus = hdr_channel; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ - LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - shp->highmem_io = 0; -#endif - if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) - shp->max_cmd_len = 16; - - shp->max_id = ha->tid_cnt; - shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 1; - shp->irq = ha->irq; - shp->dma_channel = ha->drq; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } - - spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); -#endif /* !__ia64__ */ - } + gdth_isa_probe_one(shtp, isa_bios); } +#endif - /* scanning for EISA controllers */ for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) { dma_addr_t scratch_dma_handle; scratch_dma_handle = 0; @@ -4754,7 +4639,7 @@ static int gdth_release(struct Scsi_Host *shp) if (shp->irq) { free_irq(shp->irq,ha); } -#ifndef __ia64__ +#ifdef CONFIG_ISA if (shp->dma_channel != 0xff) { free_dma(shp->dma_channel); } @@ -5674,6 +5559,149 @@ static Scsi_Host_Template driver_template = { #endif }; +#ifdef CONFIG_ISA +static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) +{ + struct Scsi_Host *shp; + gdth_ha_str *ha; + dma_addr_t scratch_dma_handle = 0; + int error, hanum, i; + u8 b; + + if (!gdth_search_isa(isa_bios)) + return -ENXIO; + + shp = scsi_register(shtp, sizeof(gdth_ext_str)); + if (!shp) + return -ENOMEM; + ha = HADATA(shp); + + error = -ENODEV; + if (!gdth_init_isa(isa_bios,ha)) + goto out_host_put; + + /* controller found and initialized */ + printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", + isa_bios, ha->irq, ha->drq); + + error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); + if (error) { + printk("GDT-ISA: Unable to allocate IRQ\n"); + goto out_host_put; + } + + error = request_dma(ha->drq, "gdth"); + if (error) { + printk("GDT-ISA: Unable to allocate DMA channel\n"); + goto out_free_irq; + } + + set_dma_mode(ha->drq,DMA_MODE_CASCADE); + enable_dma(ha->drq); + shp->unchecked_isa_dma = 1; + shp->irq = ha->irq; + shp->dma_channel = ha->drq; + hanum = gdth_ctr_count; + gdth_ctr_tab[gdth_ctr_count++] = shp; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum= 0; + + ha->pccb = CMDDATA(shp); + ha->ccb_phys = 0L; + ha->pdev = NULL; + + error = -ENOMEM; + + ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, + &scratch_dma_handle); + if (!ha->pscratch) + goto out_dec_counters; + ha->scratch_phys = scratch_dma_handle; + + ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), + &scratch_dma_handle); + if (!ha->pmsg) + goto out_free_pscratch; + ha->msg_phys = scratch_dma_handle; + +#ifdef INT_COAL + ha->coal_stat = pci_alloc_consistent(ha->pdev, + sizeof(gdth_coal_status) * MAXOFFSETS, + &scratch_dma_handle); + if (!ha->coal_stat) + goto out_free_pmsg; + ha->coal_stat_phys = scratch_dma_handle; +#endif + + ha->scratch_busy = FALSE; + ha->req_first = NULL; + ha->tid_cnt = MAX_HDRIVES; + if (max_ids > 0 && max_ids < ha->tid_cnt) + ha->tid_cnt = max_ids; + for (i = 0; i < GDTH_MAXCMDS; ++i) + ha->cmd_tab[i].cmnd = UNUSED_CMND; + ha->scan_mode = rescan ? 0x10 : 0; + + error = -ENODEV; + if (!gdth_search_drives(hanum)) { + printk("GDT-ISA: Error during device scan\n"); + goto out_free_coal_stat; + } + + if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) + hdr_channel = ha->bus_cnt; + ha->virt_bus = hdr_channel; + + if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) + shp->max_cmd_len = 16; + + shp->max_id = ha->tid_cnt; + shp->max_lun = MAXLUN; + shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; + if (virt_ctr) { + virt_ctr = 1; + /* register addit. SCSI channels as virtual controllers */ + for (b = 1; b < ha->bus_cnt + 1; ++b) { + shp = scsi_register(shtp,sizeof(gdth_num_str)); + shp->unchecked_isa_dma = 1; + shp->irq = ha->irq; + shp->dma_channel = ha->drq; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum = b; + } + } + + spin_lock_init(&ha->smp_lock); + gdth_enable_int(hanum); + + return 0; + + out_free_coal_stat: +#ifdef INT_COAL + pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, + ha->coal_stat, ha->coal_stat_phys); + out_free_pmsg: +#endif + pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), + ha->pmsg, ha->msg_phys); + out_free_pscratch: + pci_free_consistent(ha->pdev, GDTH_SCRATCH, + ha->pscratch, ha->scratch_phys); + out_dec_counters: + gdth_ctr_count--; + gdth_ctr_vcount--; + out_free_irq: + free_irq(ha->irq, ha); + out_host_put: + scsi_unregister(shp); + return error; +} +#endif /* CONFIG_ISA */ + + #include "scsi_module.c" #ifndef MODULE __setup("gdth=", option_setup); -- cgit v1.1 From 706a5d456762e77e199903e55377a9c00814c007 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 2 Oct 2007 22:49:35 +0200 Subject: [SCSI] gdth: split out eisa probing Split eisa probing into it's own helper, and do proper error unwinding. Protect EISA probind by the proper CONFIG_EISA symbol. Signed-off-by: Christoph Hellwig Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 285 +++++++++++++++++++++++++++++----------------------- 1 file changed, 159 insertions(+), 126 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index add2ebb..05108ea 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -444,12 +444,10 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); -static int gdth_search_eisa(ushort eisa_adr); static int gdth_search_pci(gdth_pci_str *pcistr); static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, ushort vendor, ushort dev); static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); -static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha); static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); static void gdth_enable_int(int hanum); @@ -477,6 +475,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp); #ifdef CONFIG_ISA static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); #endif +#ifdef CONFIG_EISA +static int gdth_eisa_probe_one(struct scsi_host_template *, ushort); +#endif #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -588,8 +589,9 @@ static struct timer_list gdth_timer; #ifdef CONFIG_ISA static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ #endif - +#ifdef CONFIG_EISA static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ +#endif static unchar gdth_polling; /* polling if TRUE */ static unchar gdth_from_wait = FALSE; /* gdth_wait() */ static int wait_index,wait_hanum; /* gdth_wait() */ @@ -824,7 +826,7 @@ static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs } /* controller search and initialization functions */ - +#ifdef CONFIG_EISA static int __init gdth_search_eisa(ushort eisa_adr) { ulong32 id; @@ -841,6 +843,7 @@ static int __init gdth_search_eisa(ushort eisa_adr) return 0; } +#endif /* CONFIG_EISA */ #ifdef CONFIG_ISA static int __init gdth_search_isa(ulong32 bios_adr) @@ -975,7 +978,7 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) } while (changed); } - +#ifdef CONFIG_EISA static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) { ulong32 retries,id; @@ -1067,6 +1070,7 @@ static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) ha->dma64_support = 0; return 1; } +#endif /* CONFIG_EISA */ #ifdef CONFIG_ISA static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) @@ -4296,7 +4300,6 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; gdth_ha_str *ha; - ushort eisa_slot; int i,hanum,cnt,ctr,err; unchar b; @@ -4341,128 +4344,16 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) gdth_isa_probe_one(shtp, isa_bios); } #endif - - for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) { - dma_addr_t scratch_dma_handle; - scratch_dma_handle = 0; - - if (gdth_ctr_count >= MAXHA) +#ifdef CONFIG_EISA + { + ushort eisa_slot; + for (eisa_slot = 0x1000; eisa_slot <= 0x8000; eisa_slot += 0x1000) { + if (gdth_ctr_count >= MAXHA) break; - if (gdth_search_eisa(eisa_slot)) { /* controller found */ - shp = scsi_register(shtp,sizeof(gdth_ext_str)); - if (shp == NULL) - continue; - - ha = HADATA(shp); - if (!gdth_init_eisa(eisa_slot,ha)) { - scsi_unregister(shp); - continue; - } - /* controller found and initialized */ - printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", - eisa_slot>>12,ha->irq); - - if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { - printk("GDT-EISA: Unable to allocate IRQ\n"); - scsi_unregister(shp); - continue; - } - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; - TRACE2(("EISA detect Bus 0: hanum %d\n", - NUMDATA(shp)->hanum)); - - ha->pccb = CMDDATA(shp); - ha->ccb_phys = 0L; - - ha->pdev = NULL; - ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, - &scratch_dma_handle); - ha->scratch_phys = scratch_dma_handle; - ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), - &scratch_dma_handle); - ha->msg_phys = scratch_dma_handle; -#ifdef INT_COAL - ha->coal_stat = (gdth_coal_status *) - pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, &scratch_dma_handle); - ha->coal_stat_phys = scratch_dma_handle; -#endif - ha->ccb_phys = - pci_map_single(ha->pdev,ha->pccb, - sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); - ha->scratch_busy = FALSE; - ha->req_first = NULL; - ha->tid_cnt = MAX_HDRIVES; - if (max_ids > 0 && max_ids < ha->tid_cnt) - ha->tid_cnt = max_ids; - for (i=0; icmd_tab[i].cmnd = UNUSED_CMND; - ha->scan_mode = rescan ? 0x10 : 0; - - if (ha->pscratch == NULL || ha->pmsg == NULL || - !gdth_search_drives(hanum)) { - printk("GDT-EISA: Error during device scan\n"); - --gdth_ctr_count; - --gdth_ctr_vcount; -#ifdef INT_COAL - if (ha->coal_stat) - pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, ha->coal_stat, - ha->coal_stat_phys); -#endif - if (ha->pscratch) - pci_free_consistent(ha->pdev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - if (ha->pmsg) - pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - if (ha->ccb_phys) - pci_unmap_single(ha->pdev,ha->ccb_phys, - sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); - free_irq(ha->irq,ha); - scsi_unregister(shp); - continue; - } - if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) - hdr_channel = ha->bus_cnt; - ha->virt_bus = hdr_channel; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ - LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - shp->highmem_io = 0; -#endif - if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) - shp->max_cmd_len = 16; - - shp->max_id = ha->tid_cnt; - shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } - - spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); - } + gdth_eisa_probe_one(shtp, eisa_slot); } + } +#endif } /* scanning for PCI controllers */ @@ -5701,6 +5592,148 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) } #endif /* CONFIG_ISA */ +#ifdef CONFIG_EISA +static int gdth_eisa_probe_one(struct scsi_host_template *shtp, + ushort eisa_slot) +{ + struct Scsi_Host *shp; + gdth_ha_str *ha; + dma_addr_t scratch_dma_handle = 0; + int error, hanum, i; + u8 b; + + if (!gdth_search_eisa(eisa_slot)) + return -ENXIO; + + shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if (!shp) + return -ENOMEM; + ha = HADATA(shp); + + error = -ENODEV; + if (!gdth_init_eisa(eisa_slot,ha)) + goto out_host_put; + + /* controller found and initialized */ + printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", + eisa_slot >> 12, ha->irq); + + error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); + if (error) { + printk("GDT-EISA: Unable to allocate IRQ\n"); + goto out_host_put; + } + + shp->unchecked_isa_dma = 0; + shp->irq = ha->irq; + shp->dma_channel = 0xff; + hanum = gdth_ctr_count; + gdth_ctr_tab[gdth_ctr_count++] = shp; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum= 0; + TRACE2(("EISA detect Bus 0: hanum %d\n", + NUMDATA(shp)->hanum)); + + ha->pccb = CMDDATA(shp); + ha->ccb_phys = 0L; + + error = -ENOMEM; + + ha->pdev = NULL; + ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, + &scratch_dma_handle); + if (!ha->pscratch) + goto out_free_irq; + ha->scratch_phys = scratch_dma_handle; + + ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), + &scratch_dma_handle); + if (!ha->pmsg) + goto out_free_pscratch; + ha->msg_phys = scratch_dma_handle; + +#ifdef INT_COAL + ha->coal_stat = pci_alloc_consistent(ha->pdev, + sizeof(gdth_coal_status) * MAXOFFSETS, + &scratch_dma_handle); + if (!ha->coal_stat) + goto out_free_pmsg; + ha->coal_stat_phys = scratch_dma_handle; +#endif + + ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb, + sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL); + if (!ha->ccb_phys) + goto out_free_coal_stat; + + ha->scratch_busy = FALSE; + ha->req_first = NULL; + ha->tid_cnt = MAX_HDRIVES; + if (max_ids > 0 && max_ids < ha->tid_cnt) + ha->tid_cnt = max_ids; + for (i = 0; i < GDTH_MAXCMDS; ++i) + ha->cmd_tab[i].cmnd = UNUSED_CMND; + ha->scan_mode = rescan ? 0x10 : 0; + + if (!gdth_search_drives(hanum)) { + printk("GDT-EISA: Error during device scan\n"); + error = -ENODEV; + goto out_free_ccb_phys; + } + + if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) + hdr_channel = ha->bus_cnt; + ha->virt_bus = hdr_channel; + + if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) + shp->max_cmd_len = 16; + + shp->max_id = ha->tid_cnt; + shp->max_lun = MAXLUN; + shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; + if (virt_ctr) { + virt_ctr = 1; + /* register addit. SCSI channels as virtual controllers */ + for (b = 1; b < ha->bus_cnt + 1; ++b) { + shp = scsi_register(shtp,sizeof(gdth_num_str)); + shp->unchecked_isa_dma = 0; + shp->irq = ha->irq; + shp->dma_channel = 0xff; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum = b; + } + } + + spin_lock_init(&ha->smp_lock); + gdth_enable_int(hanum); + return 0; + + out_free_ccb_phys: + pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str), + PCI_DMA_BIDIRECTIONAL); + out_free_coal_stat: +#ifdef INT_COAL + pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, + ha->coal_stat, ha->coal_stat_phys); + out_free_pmsg: +#endif + pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), + ha->pmsg, ha->msg_phys); + out_free_pscratch: + pci_free_consistent(ha->pdev, GDTH_SCRATCH, + ha->pscratch, ha->scratch_phys); + out_free_irq: + free_irq(ha->irq, ha); + gdth_ctr_count--; + gdth_ctr_vcount--; + out_host_put: + scsi_unregister(shp); + return error; +} +#endif /* CONFIG_EISA */ #include "scsi_module.c" #ifndef MODULE -- cgit v1.1 From 8514ef27ee462747454f26a77982f670d9c3c391 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 2 Oct 2007 22:51:06 +0200 Subject: [SCSI] gdth: split out pci probing Split out per-device pci probing and put it under proper CONFIG_PCI. Signed-off-by: Christoph Hellwig Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 312 ++++++++++++++++++++++++++++------------------------ 1 file changed, 167 insertions(+), 145 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 05108ea..9e4dd48 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -444,12 +444,6 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); -static int gdth_search_pci(gdth_pci_str *pcistr); -static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, - ushort vendor, ushort dev); -static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); -static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); - static void gdth_enable_int(int hanum); static int gdth_get_status(unchar *pIStatus,int irq); static int gdth_test_busy(int hanum); @@ -478,6 +472,9 @@ static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); #ifdef CONFIG_EISA static int gdth_eisa_probe_one(struct scsi_host_template *, ushort); #endif +#ifdef CONFIG_PCI +static int gdth_pci_probe_one(struct scsi_host_template *, gdth_pci_str *, int); +#endif #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -862,6 +859,10 @@ static int __init gdth_search_isa(ulong32 bios_adr) } #endif /* CONFIG_ISA */ +#ifdef CONFIG_PCI +static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, + ushort vendor, ushort dev); + static int __init gdth_search_pci(gdth_pci_str *pcistr) { ushort device, cnt; @@ -940,7 +941,6 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, } } - static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) { gdth_pci_str temp; @@ -977,6 +977,7 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) } } while (changed); } +#endif /* CONFIG_PCI */ #ifdef CONFIG_EISA static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) @@ -1173,6 +1174,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) } #endif /* CONFIG_ISA */ +#ifdef CONFIG_PCI static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) { register gdt6_dpram_str __iomem *dp6_ptr; @@ -1555,7 +1557,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) return 1; } - +#endif /* CONFIG_PCI */ /* controller protocol functions */ @@ -4297,13 +4299,6 @@ static int __init gdth_detect(struct scsi_host_template *shtp) static int __init gdth_detect(Scsi_Host_Template *shtp) #endif { - struct Scsi_Host *shp; - gdth_pci_str pcistr[MAXHA]; - gdth_ha_str *ha; - int i,hanum,cnt,ctr,err; - unchar b; - - #ifdef DEBUG_GDTH printk("GDT: This driver contains debugging information !! Trace level = %d\n", DebugState); @@ -4329,7 +4324,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); /* initializations */ - gdth_polling = TRUE; b = 0; + gdth_polling = TRUE; gdth_clear_events(); /* As default we do not probe for EISA or ISA controllers */ @@ -4356,143 +4351,22 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) #endif } +#ifdef CONFIG_PCI /* scanning for PCI controllers */ + { + gdth_pci_str pcistr[MAXHA]; + int cnt,ctr; + cnt = gdth_search_pci(pcistr); printk("GDT-HA: Found %d PCI Storage RAID Controllers\n",cnt); gdth_sort_pci(pcistr,cnt); for (ctr = 0; ctr < cnt; ++ctr) { - dma_addr_t scratch_dma_handle; - scratch_dma_handle = 0; - if (gdth_ctr_count >= MAXHA) break; - shp = scsi_register(shtp,sizeof(gdth_ext_str)); - if (shp == NULL) - continue; - - ha = HADATA(shp); - if (!gdth_init_pci(&pcistr[ctr],ha)) { - scsi_unregister(shp); - continue; - } - /* controller found and initialized */ - printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", - pcistr[ctr].pdev->bus->number, - PCI_SLOT(pcistr[ctr].pdev->devfn), ha->irq); - - if (request_irq(ha->irq, gdth_interrupt, - IRQF_DISABLED|IRQF_SHARED, "gdth", ha)) - { - printk("GDT-PCI: Unable to allocate IRQ\n"); - scsi_unregister(shp); - continue; - } - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; - - ha->pccb = CMDDATA(shp); - ha->ccb_phys = 0L; - - ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, - &scratch_dma_handle); - ha->scratch_phys = scratch_dma_handle; - ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), - &scratch_dma_handle); - ha->msg_phys = scratch_dma_handle; -#ifdef INT_COAL - ha->coal_stat = (gdth_coal_status *) - pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, &scratch_dma_handle); - ha->coal_stat_phys = scratch_dma_handle; -#endif - ha->scratch_busy = FALSE; - ha->req_first = NULL; - ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; - if (max_ids > 0 && max_ids < ha->tid_cnt) - ha->tid_cnt = max_ids; - for (i=0; icmd_tab[i].cmnd = UNUSED_CMND; - ha->scan_mode = rescan ? 0x10 : 0; - - err = FALSE; - if (ha->pscratch == NULL || ha->pmsg == NULL || - !gdth_search_drives(hanum)) { - err = TRUE; - } else { - if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) - hdr_channel = ha->bus_cnt; - ha->virt_bus = hdr_channel; - - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - scsi_set_pci_device(shp, pcistr[ctr].pdev); -#endif - if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)|| - /* 64-bit DMA only supported from FW >= x.43 */ - (!ha->dma64_support)) { - if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING "GDT-PCI %d: Unable to set 32-bit DMA\n", hanum); - err = TRUE; - } - } else { - shp->max_cmd_len = 16; - if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { - printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); - } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING "GDT-PCI %d: Unable to set 64/32-bit DMA\n", hanum); - err = TRUE; - } - } - } - - if (err) { - printk("GDT-PCI %d: Error during device scan\n", hanum); - --gdth_ctr_count; - --gdth_ctr_vcount; -#ifdef INT_COAL - if (ha->coal_stat) - pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, ha->coal_stat, - ha->coal_stat_phys); -#endif - if (ha->pscratch) - pci_free_consistent(ha->pdev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - if (ha->pmsg) - pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - free_irq(ha->irq,ha); - scsi_unregister(shp); - continue; - } - - shp->max_id = ha->tid_cnt; - shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } - - spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); + gdth_pci_probe_one(shtp, pcistr, ctr); } + } +#endif /* CONFIG_PCI */ TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count)); if (gdth_ctr_count > 0) { @@ -5735,6 +5609,154 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, } #endif /* CONFIG_EISA */ +#ifdef CONFIG_PCI +static int gdth_pci_probe_one(struct scsi_host_template *shtp, + gdth_pci_str *pcistr, int ctr) +{ + struct Scsi_Host *shp; + gdth_ha_str *ha; + dma_addr_t scratch_dma_handle = 0; + int error, hanum, i; + u8 b; + + shp = scsi_register(shtp,sizeof(gdth_ext_str)); + if (!shp) + return -ENOMEM; + ha = HADATA(shp); + + error = -ENODEV; + if (!gdth_init_pci(&pcistr[ctr],ha)) + goto out_host_put; + + /* controller found and initialized */ + printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", + pcistr[ctr].pdev->bus->number, + PCI_SLOT(pcistr[ctr].pdev->devfn), + ha->irq); + + error = request_irq(ha->irq, gdth_interrupt, + IRQF_DISABLED|IRQF_SHARED, "gdth", ha); + if (error) { + printk("GDT-PCI: Unable to allocate IRQ\n"); + goto out_host_put; + } + + shp->unchecked_isa_dma = 0; + shp->irq = ha->irq; + shp->dma_channel = 0xff; + hanum = gdth_ctr_count; + gdth_ctr_tab[gdth_ctr_count++] = shp; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum= 0; + + ha->pccb = CMDDATA(shp); + ha->ccb_phys = 0L; + + error = -ENOMEM; + + ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, + &scratch_dma_handle); + if (!ha->pscratch) + goto out_free_irq; + ha->scratch_phys = scratch_dma_handle; + + ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), + &scratch_dma_handle); + if (!ha->pmsg) + goto out_free_pscratch; + ha->msg_phys = scratch_dma_handle; + +#ifdef INT_COAL + ha->coal_stat = pci_alloc_consistent(ha->pdev, + sizeof(gdth_coal_status) * MAXOFFSETS, + &scratch_dma_handle); + if (!ha->coal_stat) + goto out_free_pmsg; + ha->coal_stat_phys = scratch_dma_handle; +#endif + + ha->scratch_busy = FALSE; + ha->req_first = NULL; + ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; + if (max_ids > 0 && max_ids < ha->tid_cnt) + ha->tid_cnt = max_ids; + for (i = 0; i < GDTH_MAXCMDS; ++i) + ha->cmd_tab[i].cmnd = UNUSED_CMND; + ha->scan_mode = rescan ? 0x10 : 0; + + error = -ENODEV; + if (!gdth_search_drives(hanum)) { + printk("GDT-PCI %d: Error during device scan\n", hanum); + goto out_free_coal_stat; + } + + if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) + hdr_channel = ha->bus_cnt; + ha->virt_bus = hdr_channel; + + /* 64-bit DMA only supported from FW >= x.43 */ + if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || + !ha->dma64_support) { + if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + printk(KERN_WARNING "GDT-PCI %d: " + "Unable to set 32-bit DMA\n", hanum); + goto out_free_coal_stat; + } + } else { + shp->max_cmd_len = 16; + if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { + printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); + } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + printk(KERN_WARNING "GDT-PCI %d: " + "Unable to set 64/32-bit DMA\n", hanum); + goto out_free_coal_stat; + } + } + + shp->max_id = ha->tid_cnt; + shp->max_lun = MAXLUN; + shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; + if (virt_ctr) { + virt_ctr = 1; + /* register addit. SCSI channels as virtual controllers */ + for (b = 1; b < ha->bus_cnt + 1; ++b) { + shp = scsi_register(shtp,sizeof(gdth_num_str)); + shp->unchecked_isa_dma = 0; + shp->irq = ha->irq; + shp->dma_channel = 0xff; + gdth_ctr_vtab[gdth_ctr_vcount++] = shp; + NUMDATA(shp)->hanum = (ushort)hanum; + NUMDATA(shp)->busnum = b; + } + } + + spin_lock_init(&ha->smp_lock); + gdth_enable_int(hanum); + return 0; + + out_free_coal_stat: +#ifdef INT_COAL + pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, + ha->coal_stat, ha->coal_stat_phys); + out_free_pmsg: +#endif + pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), + ha->pmsg, ha->msg_phys); + out_free_pscratch: + pci_free_consistent(ha->pdev, GDTH_SCRATCH, + ha->pscratch, ha->scratch_phys); + out_free_irq: + free_irq(ha->irq, ha); + gdth_ctr_count--; + gdth_ctr_vcount--; + out_host_put: + scsi_unregister(shp); + return error; +} +#endif /* CONFIG_PCI */ + #include "scsi_module.c" #ifndef MODULE __setup("gdth=", option_setup); -- cgit v1.1 From 8d7a5da4fc95cb6210cd66e7c886161e10a1307f Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 2 Oct 2007 22:54:28 +0200 Subject: [SCSI] gdth: Remove 2.4.x support, in-kernel changelog * Remove in-source changelog. It's archived permanently in git and various kernel archives, and changelogs should exist purely in git. * Remove 2.4.x kernel support. It is an active obstacle to modernizing this driver, at this point. This includes killing gdth_kcompat.h which is 100% redundant in modern kernels. Signed-off-by: Jeff Garzik Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 396 +------------------------------------------- drivers/scsi/gdth.h | 1 - drivers/scsi/gdth_kcompat.h | 31 ---- drivers/scsi/gdth_proc.c | 27 --- 4 files changed, 2 insertions(+), 453 deletions(-) delete mode 100644 drivers/scsi/gdth_kcompat.h diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 9e4dd48..a3b0190 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -27,280 +27,8 @@ * along with this kernel; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * - * Linux kernel 2.4.x, 2.6.x supported * + * Linux kernel 2.6.x supported * * * - * $Log: gdth.c,v $ - * Revision 1.74 2006/04/10 13:44:47 achim - * Community changes for 2.6.x - * Kernel 2.2.x no longer supported - * scsi_request interface removed, thanks to Christoph Hellwig - * - * Revision 1.73 2004/03/31 13:33:03 achim - * Special command 0xfd implemented to detect 64-bit DMA support - * - * Revision 1.72 2004/03/17 08:56:04 achim - * 64-bit DMA only enabled if FW >= x.43 - * - * Revision 1.71 2004/03/05 15:51:29 achim - * Screen service: separate message buffer, bugfixes - * - * Revision 1.70 2004/02/27 12:19:07 achim - * Bugfix: Reset bit in config (0xfe) call removed - * - * Revision 1.69 2004/02/20 09:50:24 achim - * Compatibility changes for kernels < 2.4.20 - * Bugfix screen service command size - * pci_set_dma_mask() error handling added - * - * Revision 1.68 2004/02/19 15:46:54 achim - * 64-bit DMA bugfixes - * Drive size bugfix for drives > 1TB - * - * Revision 1.67 2004/01/14 13:11:57 achim - * Tool access over /proc no longer supported - * Bugfixes IOCTLs - * - * Revision 1.66 2003/12/19 15:04:06 achim - * Bugfixes support for drives > 2TB - * - * Revision 1.65 2003/12/15 11:21:56 achim - * 64-bit DMA support added - * Support for drives > 2 TB implemented - * Kernels 2.2.x, 2.4.x, 2.6.x supported - * - * Revision 1.64 2003/09/17 08:30:26 achim - * EISA/ISA controller scan disabled - * Command line switch probe_eisa_isa added - * - * Revision 1.63 2003/07/12 14:01:00 Daniele Bellucci - * Minor cleanups in gdth_ioctl. - * - * Revision 1.62 2003/02/27 15:01:59 achim - * Dynamic DMA mapping implemented - * New (character device) IOCTL interface added - * Other controller related changes made - * - * Revision 1.61 2002/11/08 13:09:52 boji - * Added support for XSCALE based RAID Controllers - * Fixed SCREENSERVICE initialization in SMP cases - * Added checks for gdth_polling before GDTH_HA_LOCK - * - * Revision 1.60 2002/02/05 09:35:22 achim - * MODULE_LICENSE only if kernel >= 2.4.11 - * - * Revision 1.59 2002/01/30 09:46:33 achim - * Small changes - * - * Revision 1.58 2002/01/29 15:30:02 achim - * Set default value of shared_access to Y - * New status S_CACHE_RESERV for clustering added - * - * Revision 1.57 2001/08/21 11:16:35 achim - * Bugfix free_irq() - * - * Revision 1.56 2001/08/09 11:19:39 achim - * Scsi_Host_Template changes - * - * Revision 1.55 2001/08/09 10:11:28 achim - * Command HOST_UNFREEZE_IO before cache service init. - * - * Revision 1.54 2001/07/20 13:48:12 achim - * Expand: gdth_analyse_hdrive() removed - * - * Revision 1.53 2001/07/17 09:52:49 achim - * Small OEM related change - * - * Revision 1.52 2001/06/19 15:06:20 achim - * New host command GDT_UNFREEZE_IO added - * - * Revision 1.51 2001/05/22 06:42:37 achim - * PCI: Subdevice ID added - * - * Revision 1.50 2001/05/17 13:42:16 achim - * Support for Intel Storage RAID Controllers added - * - * Revision 1.50 2001/05/17 12:12:34 achim - * Support for Intel Storage RAID Controllers added - * - * Revision 1.49 2001/03/15 15:07:17 achim - * New __setup interface for boot command line options added - * - * Revision 1.48 2001/02/06 12:36:28 achim - * Bugfix Cluster protocol - * - * Revision 1.47 2001/01/10 14:42:06 achim - * New switch shared_access added - * - * Revision 1.46 2001/01/09 08:11:35 achim - * gdth_command() removed - * meaning of Scsi_Pointer members changed - * - * Revision 1.45 2000/11/16 12:02:24 achim - * Changes for kernel 2.4 - * - * Revision 1.44 2000/10/11 08:44:10 achim - * Clustering changes: New flag media_changed added - * - * Revision 1.43 2000/09/20 12:59:01 achim - * DPMEM remap functions for all PCI controller types implemented - * Small changes for ia64 platform - * - * Revision 1.42 2000/07/20 09:04:50 achim - * Small changes for kernel 2.4 - * - * Revision 1.41 2000/07/04 14:11:11 achim - * gdth_analyse_hdrive() added to rescan drives after online expansion - * - * Revision 1.40 2000/06/27 11:24:16 achim - * Changes Clustering, Screenservice - * - * Revision 1.39 2000/06/15 13:09:04 achim - * Changes for gdth_do_cmd() - * - * Revision 1.38 2000/06/15 12:08:43 achim - * Bugfix gdth_sync_event(), service SCREENSERVICE - * Data direction for command 0xc2 changed to DOU - * - * Revision 1.37 2000/05/25 13:50:10 achim - * New driver parameter virt_ctr added - * - * Revision 1.36 2000/05/04 08:50:46 achim - * Event buffer now in gdth_ha_str - * - * Revision 1.35 2000/03/03 10:44:08 achim - * New event_string only valid for the RP controller family - * - * Revision 1.34 2000/03/02 14:55:29 achim - * New mechanism for async. event handling implemented - * - * Revision 1.33 2000/02/21 15:37:37 achim - * Bugfix Alpha platform + DPMEM above 4GB - * - * Revision 1.32 2000/02/14 16:17:37 achim - * Bugfix sense_buffer[] + raw devices - * - * Revision 1.31 2000/02/10 10:29:00 achim - * Delete sense_buffer[0], if command OK - * - * Revision 1.30 1999/11/02 13:42:39 achim - * ARRAY_DRV_LIST2 implemented - * Now 255 log. and 100 host drives supported - * - * Revision 1.29 1999/10/05 13:28:47 achim - * GDT_CLUST_RESET added - * - * Revision 1.28 1999/08/12 13:44:54 achim - * MOUNTALL removed - * Cluster drives -> removeable drives - * - * Revision 1.27 1999/06/22 07:22:38 achim - * Small changes - * - * Revision 1.26 1999/06/10 16:09:12 achim - * Cluster Host Drive support: Bugfixes - * - * Revision 1.25 1999/06/01 16:03:56 achim - * gdth_init_pci(): Manipulate config. space to start RP controller - * - * Revision 1.24 1999/05/26 11:53:06 achim - * Cluster Host Drive support added - * - * Revision 1.23 1999/03/26 09:12:31 achim - * Default value for hdr_channel set to 0 - * - * Revision 1.22 1999/03/22 16:27:16 achim - * Bugfix: gdth_store_event() must not be locked with GDTH_LOCK_HA() - * - * Revision 1.21 1999/03/16 13:40:34 achim - * Problems with reserved drives solved - * gdth_eh_bus_reset() implemented - * - * Revision 1.20 1999/03/10 09:08:13 achim - * Bugfix: Corrections in gdth_direction_tab[] made - * Bugfix: Increase command timeout (gdth_update_timeout()) NOT in gdth_putq() - * - * Revision 1.19 1999/03/05 14:38:16 achim - * Bugfix: Heads/Sectors mapping for reserved devices possibly wrong - * -> gdth_eval_mapping() implemented, changes in gdth_bios_param() - * INIT_RETRIES set to 100s to avoid DEINIT-Timeout for controllers - * with BIOS disabled and memory test set to Intensive - * Enhanced /proc support - * - * Revision 1.18 1999/02/24 09:54:33 achim - * Command line parameter hdr_channel implemented - * Bugfix for EISA controllers + Linux 2.2.x - * - * Revision 1.17 1998/12/17 15:58:11 achim - * Command line parameters implemented - * Changes for Alpha platforms - * PCI controller scan changed - * SMP support improved (spin_lock_irqsave(),...) - * New async. events, new scan/reserve commands included - * - * Revision 1.16 1998/09/28 16:08:46 achim - * GDT_PCIMPR: DPMEM remapping, if required - * mdelay() added - * - * Revision 1.15 1998/06/03 14:54:06 achim - * gdth_delay(), gdth_flush() implemented - * Bugfix: gdth_release() changed - * - * Revision 1.14 1998/05/22 10:01:17 achim - * mj: pcibios_strerror() removed - * Improved SMP support (if version >= 2.1.95) - * gdth_halt(): halt_called flag added (if version < 2.1) - * - * Revision 1.13 1998/04/16 09:14:57 achim - * Reserve drives (for raw service) implemented - * New error handling code enabled - * Get controller name from board_info() IOCTL - * Final round of PCI device driver patches by Martin Mares - * - * Revision 1.12 1998/03/03 09:32:37 achim - * Fibre channel controller support added - * - * Revision 1.11 1998/01/27 16:19:14 achim - * SA_SHIRQ added - * add_timer()/del_timer() instead of GDTH_TIMER - * scsi_add_timer()/scsi_del_timer() instead of SCSI_TIMER - * New error handling included - * - * Revision 1.10 1997/10/31 12:29:57 achim - * Read heads/sectors from host drive - * - * Revision 1.9 1997/09/04 10:07:25 achim - * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ... - * register_reboot_notifier() to get a notify on shutown used - * - * Revision 1.8 1997/04/02 12:14:30 achim - * Version 1.00 (see gdth.h), tested with kernel 2.0.29 - * - * Revision 1.7 1997/03/12 13:33:37 achim - * gdth_reset() changed, new async. events - * - * Revision 1.6 1997/03/04 14:01:11 achim - * Shutdown routine gdth_halt() implemented - * - * Revision 1.5 1997/02/21 09:08:36 achim - * New controller included (RP, RP1, RP2 series) - * IOCTL interface implemented - * - * Revision 1.4 1996/07/05 12:48:55 achim - * Function gdth_bios_param() implemented - * New constant GDTH_MAXC_P_L inserted - * GDT_WRITE_THR, GDT_EXT_INFO implemented - * Function gdth_reset() changed - * - * Revision 1.3 1996/05/10 09:04:41 achim - * Small changes for Linux 1.2.13 - * - * Revision 1.2 1996/05/09 12:45:27 achim - * Loadable module support implemented - * /proc support corrections made - * - * Revision 1.1 1996/04/11 07:35:57 achim - * Initial revision - * ************************************************************************/ /* All GDT Disk Array Controllers are fully supported by this driver. @@ -392,12 +120,7 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) #include -#else -#define DMA_32BIT_MASK 0x00000000ffffffffULL -#define DMA_64BIT_MASK 0xffffffffffffffffULL -#endif #ifdef GDTH_RTC #include @@ -409,16 +132,10 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include -#else -#include -#include "sd.h" -#endif #include "scsi.h" #include -#include "gdth_kcompat.h" #include "gdth.h" static void gdth_delay(int milliseconds); @@ -658,7 +375,6 @@ static int probe_eisa_isa = 0; static int force_dma32 = 0; /* parameters for modprobe/insmod */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) module_param_array(irq, int, NULL, 0); module_param(disable, int, 0); module_param(reserve_mode, int, 0); @@ -671,20 +387,6 @@ module_param(virt_ctr, int, 0); module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); -#else -MODULE_PARM(irq, "i"); -MODULE_PARM(disable, "i"); -MODULE_PARM(reserve_mode, "i"); -MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); -MODULE_PARM(reverse_scan, "i"); -MODULE_PARM(hdr_channel, "i"); -MODULE_PARM(max_ids, "i"); -MODULE_PARM(rescan, "i"); -MODULE_PARM(virt_ctr, "i"); -MODULE_PARM(shared_access, "i"); -MODULE_PARM(probe_eisa_isa, "i"); -MODULE_PARM(force_dma32, "i"); -#endif MODULE_AUTHOR("Achim Leubner"); MODULE_LICENSE("GPL"); @@ -716,7 +418,6 @@ static void gdth_delay(int milliseconds) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static void gdth_scsi_done(struct scsi_cmnd *scp) { TRACE2(("gdth_scsi_done()\n")); @@ -756,42 +457,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, kfree(scp); return rval; } -#else -static void gdth_scsi_done(Scsi_Cmnd *scp) -{ - TRACE2(("gdth_scsi_done()\n")); - - scp->request.rq_status = RQ_SCSI_DONE; - if (scp->request.waiting) - complete(scp->request.waiting); -} - -int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); - unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; - DECLARE_COMPLETION_ONSTACK(wait); - int rval; - - if (!scp) - return -ENOMEM; - scp->cmd_len = 12; - scp->use_sg = 0; - scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->request.rq_status = RQ_SCSI_BUSY; - scp->request.waiting = &wait; - scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); - wait_for_completion(&wait); - - rval = scp->SCp.Status; - if (info) - *info = scp->SCp.Message; - - scsi_release_command(scp); - return rval; -} -#endif int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info) @@ -2258,29 +1923,17 @@ static int __init gdth_search_drives(int hanum) printk("GDT-HA %d: Vendor: %s Name: %s\n", hanum,oemstr->text.oem_company_name,ha->binfo.type_string); /* Save the Host Drive inquiry data */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, sizeof(ha->oem_name)); -#else - strncpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,7); - ha->oem_name[7] = '\0'; -#endif } else { /* Old method, based on PCI ID */ TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); printk("GDT-HA %d: Name: %s\n", hanum,ha->binfo.type_string); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) if (ha->oem_id == OEM_ID_INTEL) strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); else strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); -#else - if (ha->oem_id == OEM_ID_INTEL) - strcpy(ha->oem_name,"Intel "); - else - strcpy(ha->oem_name,"ICP "); -#endif } /* scanning for host drives */ @@ -2689,17 +2342,10 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, return; } local_irq_save(flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; memcpy(address,buffer,cpnow); flush_dcache_page(sl->page); kunmap_atomic(address, KM_BIO_SRC_IRQ); -#else - address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; - memcpy(address,buffer,cpnow); - flush_dcache_page(sl->page); - kunmap_atomic(address, KM_BH_IRQ); -#endif local_irq_restore(flags); if (cpsum == cpcount) break; @@ -4293,11 +3939,7 @@ int __init option_setup(char *str) } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int __init gdth_detect(struct scsi_host_template *shtp) -#else -static int __init gdth_detect(Scsi_Host_Template *shtp) -#endif { #ifdef DEBUG_GDTH printk("GDT: This driver contains debugging information !! Trace level = %d\n", @@ -4539,11 +4181,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) return SUCCESS; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) -#else -static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) -#endif { unchar b, t; int hanum; @@ -4551,13 +4189,8 @@ static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) struct scsi_device *sd; unsigned capacity; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) sd = sdev; capacity = cap; -#else - sd = disk->device; - capacity = disk->capacity; -#endif hanum = NUMDATA(sd->host)->hanum; b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel; t = sd->id; @@ -5173,7 +4806,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, hanum = res.ionode; ha = HADATA(gdth_ctr_tab[hanum]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) return -ENOMEM; @@ -5184,17 +4816,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); kfree(scp); -#else - scp = scsi_allocate_device(ha->sdev, 1, FALSE); - if (!scp) - return -ENOMEM; - scp->cmd_len = 12; - scp->use_sg = 0; - scp->channel = virt_ctr ? 0 : res.number; - rval = gdth_eh_bus_reset(scp); - res.status = (rval == SUCCESS ? S_OK : S_GENERR); - scsi_release_command(scp); -#endif + if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) return -EFAULT; break; @@ -5282,7 +4904,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) return NOTIFY_OK; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* configure lun */ static int gdth_slave_configure(struct scsi_device *sdev) { @@ -5291,13 +4912,8 @@ static int gdth_slave_configure(struct scsi_device *sdev) sdev->skip_ms_page_8 = 1; return 0; } -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct scsi_host_template driver_template = { -#else -static Scsi_Host_Template driver_template = { -#endif .proc_name = "gdth", .proc_info = gdth_proc_info, .name = "GDT SCSI Disk Array Controller", @@ -5308,20 +4924,12 @@ static Scsi_Host_Template driver_template = { .eh_bus_reset_handler = gdth_eh_bus_reset, .bios_param = gdth_bios_param, .can_queue = GDTH_MAXCMDS, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .slave_configure = gdth_slave_configure, -#endif .this_id = -1, .sg_tablesize = GDTH_MAXSG, .cmd_per_lun = GDTH_MAXC_P_L, .unchecked_isa_dma = 1, .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - .use_new_eh_code = 1, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) - .highmem_io = 1, -#endif -#endif }; #ifdef CONFIG_ISA diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 3742330..6884587 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -13,7 +13,6 @@ * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ */ -#include #include #ifndef TRUE diff --git a/drivers/scsi/gdth_kcompat.h b/drivers/scsi/gdth_kcompat.h deleted file mode 100644 index 2a302ee..0000000 --- a/drivers/scsi/gdth_kcompat.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef IRQ_HANDLED -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#endif - -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(x) -#endif - -#ifndef __iomem -#define __iomem -#endif - -#ifndef __attribute_used__ -#define __attribute_used__ __devinitdata -#endif - -#ifndef __user -#define __user -#endif - -#ifndef SERVICE_ACTION_IN -#define SERVICE_ACTION_IN 0x9e -#endif -#ifndef READ_16 -#define READ_16 0x88 -#endif -#ifndef WRITE_16 -#define WRITE_16 0x8a -#endif diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 1f8d9a5..cece6f2 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -4,7 +4,6 @@ #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, int inout) { @@ -21,32 +20,6 @@ int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offse else return(gdth_get_info(buffer,start,offset,length,host,hanum,busnum)); } -#else -int gdth_proc_info(char *buffer,char **start,off_t offset,int length,int hostno, - int inout) -{ - int hanum,busnum,i; - - TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", - length,(int)offset,inout)); - - for (i = 0; i < gdth_ctr_vcount; ++i) { - if (gdth_ctr_vtab[i]->host_no == hostno) - break; - } - if (i == gdth_ctr_vcount) - return(-EINVAL); - - hanum = NUMDATA(gdth_ctr_vtab[i])->hanum; - busnum= NUMDATA(gdth_ctr_vtab[i])->busnum; - - if (inout) - return(gdth_set_info(buffer,length,gdth_ctr_vtab[i],hanum,busnum)); - else - return(gdth_get_info(buffer,start,offset,length, - gdth_ctr_vtab[i],hanum,busnum)); -} -#endif static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, int hanum,int busnum) -- cgit v1.1 From a52667f3cd84fa395e98b505967070b984fac4df Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 2 Oct 2007 22:55:53 +0200 Subject: [SCSI] gdth: kill gdth_{read,write}[bwl] wrappers They are direct equivalents to {read,write}[bwl]. Signed-off-by: Jeff Garzik Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 313 +++++++++++++++++++++++++--------------------------- 1 file changed, 153 insertions(+), 160 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index a3b0190..afda12f 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -293,13 +293,6 @@ static struct timer_list gdth_timer; #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) -#define gdth_readb(addr) readb(addr) -#define gdth_readw(addr) readw(addr) -#define gdth_readl(addr) readl(addr) -#define gdth_writeb(b,addr) writeb((b),(addr)) -#define gdth_writew(b,addr) writew((b),(addr)) -#define gdth_writel(b,addr) writel((b),(addr)) - #ifdef CONFIG_ISA static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ #endif @@ -515,7 +508,7 @@ static int __init gdth_search_isa(ulong32 bios_adr) TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { - id = gdth_readl(addr); + id = readl(addr); iounmap(addr); if (id == GDT2_ID) /* GDT2000 */ return 1; @@ -754,22 +747,22 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) return 0; } dp2_ptr = ha->brd; - gdth_writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ + writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ /* reset interface area */ memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); - if (gdth_readl(&dp2_ptr->u) != 0) { + if (readl(&dp2_ptr->u) != 0) { printk("GDT-ISA: Initialization error (DPMEM write error)\n"); iounmap(ha->brd); return 0; } /* disable board interrupts, read DRQ and IRQ */ - gdth_writeb(0xff, &dp2_ptr->io.irqdel); - gdth_writeb(0x00, &dp2_ptr->io.irqen); - gdth_writeb(0x00, &dp2_ptr->u.ic.S_Status); - gdth_writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); + writeb(0xff, &dp2_ptr->io.irqdel); + writeb(0x00, &dp2_ptr->io.irqen); + writeb(0x00, &dp2_ptr->u.ic.S_Status); + writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); - irq_drq = gdth_readb(&dp2_ptr->io.rq); + irq_drq = readb(&dp2_ptr->io.rq); for (i=0; i<3; ++i) { if ((irq_drq & 1)==0) break; @@ -777,7 +770,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) } ha->drq = gdth_drq_tab[i]; - irq_drq = gdth_readb(&dp2_ptr->io.rq) >> 3; + irq_drq = readb(&dp2_ptr->io.rq) >> 3; for (i=1; i<5; ++i) { if ((irq_drq & 1)==0) break; @@ -786,12 +779,12 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) ha->irq = gdth_irq_tab[i]; /* deinitialize services */ - gdth_writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); - gdth_writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(0, &dp2_ptr->io.event); + writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); + writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); + writeb(0, &dp2_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xff) { + while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("GDT-ISA: Initialization error (DEINIT failed)\n"); iounmap(ha->brd); @@ -799,9 +792,9 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) } gdth_delay(1); } - prot_ver = (unchar)gdth_readl(&dp2_ptr->u.ic.S_Info[0]); - gdth_writeb(0, &dp2_ptr->u.ic.Status); - gdth_writeb(0xff, &dp2_ptr->io.irqdel); + prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]); + writeb(0, &dp2_ptr->u.ic.Status); + writeb(0xff, &dp2_ptr->io.irqdel); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-ISA: Illegal protocol version\n"); iounmap(ha->brd); @@ -815,15 +808,15 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) ha->brd_phys = bios_adr >> 4; /* special request to controller BIOS */ - gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[0]); - gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[1]); - gdth_writel(0x01, &dp2_ptr->u.ic.S_Info[2]); - gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[3]); - gdth_writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(0, &dp2_ptr->io.event); + writel(0x00, &dp2_ptr->u.ic.S_Info[0]); + writel(0x00, &dp2_ptr->u.ic.S_Info[1]); + writel(0x01, &dp2_ptr->u.ic.S_Info[2]); + writel(0x00, &dp2_ptr->u.ic.S_Info[3]); + writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); + writeb(0, &dp2_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { + while (readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-ISA: Initialization error\n"); iounmap(ha->brd); @@ -831,8 +824,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) } gdth_delay(1); } - gdth_writeb(0, &dp2_ptr->u.ic.Status); - gdth_writeb(0xff, &dp2_ptr->io.irqdel); + writeb(0, &dp2_ptr->u.ic.Status); + writeb(0xff, &dp2_ptr->io.irqdel); ha->dma64_support = 0; return 1; @@ -870,8 +863,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } /* check and reset interface area */ dp6_ptr = ha->brd; - gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); - if (gdth_readl(&dp6_ptr->u) != DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6_ptr->u); + if (readl(&dp6_ptr->u) != DPMEM_MAGIC) { printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", pcistr->dpmem); found = FALSE; @@ -882,7 +875,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } - if (gdth_readw(ha->brd) != 0xffff) { + if (readw(ha->brd) != 0xffff) { TRACE2(("init_pci_old() address 0x%x busy\n", i)); continue; } @@ -895,8 +888,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) return 0; } dp6_ptr = ha->brd; - gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); - if (gdth_readl(&dp6_ptr->u) == DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6_ptr->u); + if (readl(&dp6_ptr->u) == DPMEM_MAGIC) { printk("GDT-PCI: Use free address at 0x%x\n", i); found = TRUE; break; @@ -909,24 +902,24 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } } memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); - if (gdth_readl(&dp6_ptr->u) != 0) { + if (readl(&dp6_ptr->u) != 0) { printk("GDT-PCI: Initialization error (DPMEM write error)\n"); iounmap(ha->brd); return 0; } /* disable board interrupts, deinit services */ - gdth_writeb(0xff, &dp6_ptr->io.irqdel); - gdth_writeb(0x00, &dp6_ptr->io.irqen); - gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status); - gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); - - gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); - gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(0, &dp6_ptr->io.event); + writeb(0xff, &dp6_ptr->io.irqdel); + writeb(0x00, &dp6_ptr->io.irqen); + writeb(0x00, &dp6_ptr->u.ic.S_Status); + writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); + + writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); + writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); + writeb(0, &dp6_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) { + while (readb(&dp6_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("GDT-PCI: Initialization error (DEINIT failed)\n"); iounmap(ha->brd); @@ -934,9 +927,9 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]); - gdth_writeb(0, &dp6_ptr->u.ic.S_Status); - gdth_writeb(0xff, &dp6_ptr->io.irqdel); + prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]); + writeb(0, &dp6_ptr->u.ic.S_Status); + writeb(0xff, &dp6_ptr->io.irqdel); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-PCI: Illegal protocol version\n"); iounmap(ha->brd); @@ -947,15 +940,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) ha->ic_all_size = sizeof(dp6_ptr->u); /* special command to controller BIOS */ - gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]); - gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]); - gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[2]); - gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]); - gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(0, &dp6_ptr->io.event); + writel(0x00, &dp6_ptr->u.ic.S_Info[0]); + writel(0x00, &dp6_ptr->u.ic.S_Info[1]); + writel(0x00, &dp6_ptr->u.ic.S_Info[2]); + writel(0x00, &dp6_ptr->u.ic.S_Info[3]); + writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); + writeb(0, &dp6_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { + while (readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-PCI: Initialization error\n"); iounmap(ha->brd); @@ -963,8 +956,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - gdth_writeb(0, &dp6_ptr->u.ic.S_Status); - gdth_writeb(0xff, &dp6_ptr->io.irqdel); + writeb(0, &dp6_ptr->u.ic.S_Status); + writeb(0xff, &dp6_ptr->io.irqdel); ha->dma64_support = 0; @@ -980,8 +973,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } /* check and reset interface area */ dp6c_ptr = ha->brd; - gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); - if (gdth_readl(&dp6c_ptr->u) != DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6c_ptr->u); + if (readl(&dp6c_ptr->u) != DPMEM_MAGIC) { printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", pcistr->dpmem); found = FALSE; @@ -992,7 +985,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } - if (gdth_readw(ha->brd) != 0xffff) { + if (readw(ha->brd) != 0xffff) { TRACE2(("init_pci_plx() address 0x%x busy\n", i)); continue; } @@ -1005,8 +998,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) return 0; } dp6c_ptr = ha->brd; - gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); - if (gdth_readl(&dp6c_ptr->u) == DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6c_ptr->u); + if (readl(&dp6c_ptr->u) == DPMEM_MAGIC) { printk("GDT-PCI: Use free address at 0x%x\n", i); found = TRUE; break; @@ -1019,7 +1012,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } } memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); - if (gdth_readl(&dp6c_ptr->u) != 0) { + if (readl(&dp6c_ptr->u) != 0) { printk("GDT-PCI: Initialization error (DPMEM write error)\n"); iounmap(ha->brd); return 0; @@ -1029,17 +1022,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) outb(0x00,PTR2USHORT(&ha->plx->control1)); outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); - gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status); - gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); + writeb(0x00, &dp6c_ptr->u.ic.S_Status); + writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); - gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); - gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); + writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); + writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { + while (readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("GDT-PCI: Initialization error (DEINIT failed)\n"); iounmap(ha->brd); @@ -1047,8 +1040,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]); - gdth_writeb(0, &dp6c_ptr->u.ic.Status); + prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]); + writeb(0, &dp6c_ptr->u.ic.Status); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-PCI: Illegal protocol version\n"); iounmap(ha->brd); @@ -1059,17 +1052,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) ha->ic_all_size = sizeof(dp6c_ptr->u); /* special command to controller BIOS */ - gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); - gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); - gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); - gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); - gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); + writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); + writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); + writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); + writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); + writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { + while (readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-PCI: Initialization error\n"); iounmap(ha->brd); @@ -1077,7 +1070,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - gdth_writeb(0, &dp6c_ptr->u.ic.S_Status); + writeb(0, &dp6c_ptr->u.ic.S_Status); ha->dma64_support = 0; @@ -1105,12 +1098,12 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) /* Ensure that it is safe to access the non HW portions of DPMEM. * Aditional check needed for Xscale based RAID controllers */ - while( ((int)gdth_readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) + while( ((int)readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) gdth_delay(1); /* check and reset interface area */ - gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); - if (gdth_readl(&dp6m_ptr->u) != DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6m_ptr->u); + if (readl(&dp6m_ptr->u) != DPMEM_MAGIC) { printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", pcistr->dpmem); found = FALSE; @@ -1121,7 +1114,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } - if (gdth_readw(ha->brd) != 0xffff) { + if (readw(ha->brd) != 0xffff) { TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); continue; } @@ -1134,8 +1127,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) return 0; } dp6m_ptr = ha->brd; - gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); - if (gdth_readl(&dp6m_ptr->u) == DPMEM_MAGIC) { + writel(DPMEM_MAGIC, &dp6m_ptr->u); + if (readl(&dp6m_ptr->u) == DPMEM_MAGIC) { printk("GDT-PCI: Use free address at 0x%x\n", i); found = TRUE; break; @@ -1150,18 +1143,18 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); /* disable board interrupts, deinit services */ - gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, + writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, &dp6m_ptr->i960r.edoor_en_reg); - gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - gdth_writeb(0x00, &dp6m_ptr->u.ic.S_Status); - gdth_writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); + writeb(0xff, &dp6m_ptr->i960r.edoor_reg); + writeb(0x00, &dp6m_ptr->u.ic.S_Status); + writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); - gdth_writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); - gdth_writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); + writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); + writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); + writeb(1, &dp6m_ptr->i960r.ldoor_reg); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { + while (readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("GDT-PCI: Initialization error (DEINIT failed)\n"); iounmap(ha->brd); @@ -1169,8 +1162,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - prot_ver = (unchar)gdth_readl(&dp6m_ptr->u.ic.S_Info[0]); - gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); + prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]); + writeb(0, &dp6m_ptr->u.ic.S_Status); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-PCI: Illegal protocol version\n"); iounmap(ha->brd); @@ -1181,15 +1174,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) ha->ic_all_size = sizeof(dp6m_ptr->u); /* special command to controller BIOS */ - gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); - gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); - gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); - gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); - gdth_writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); + writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); + writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); + writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); + writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); + writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); + writeb(1, &dp6m_ptr->i960r.ldoor_reg); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { + while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-PCI: Initialization error\n"); iounmap(ha->brd); @@ -1197,14 +1190,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); + writeb(0, &dp6m_ptr->u.ic.S_Status); /* read FW version to detect 64-bit DMA support */ - gdth_writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); - gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); + writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); + writeb(1, &dp6m_ptr->i960r.ldoor_reg); retries = INIT_RETRIES; gdth_delay(20); - while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { + while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { if (--retries == 0) { printk("GDT-PCI: Initialization error (DEINIT failed)\n"); iounmap(ha->brd); @@ -1212,8 +1205,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) } gdth_delay(1); } - prot_ver = (unchar)(gdth_readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); - gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); + prot_ver = (unchar)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); + writeb(0, &dp6m_ptr->u.ic.S_Status); if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ ha->dma64_support = 0; else @@ -1244,21 +1237,21 @@ static void __init gdth_enable_int(int hanum) outb(0x01, ha->bmic + EINTENABREG); } else if (ha->type == GDT_ISA) { dp2_ptr = ha->brd; - gdth_writeb(1, &dp2_ptr->io.irqdel); - gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index); - gdth_writeb(1, &dp2_ptr->io.irqen); + writeb(1, &dp2_ptr->io.irqdel); + writeb(0, &dp2_ptr->u.ic.Cmd_Index); + writeb(1, &dp2_ptr->io.irqen); } else if (ha->type == GDT_PCI) { dp6_ptr = ha->brd; - gdth_writeb(1, &dp6_ptr->io.irqdel); - gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index); - gdth_writeb(1, &dp6_ptr->io.irqen); + writeb(1, &dp6_ptr->io.irqdel); + writeb(0, &dp6_ptr->u.ic.Cmd_Index); + writeb(1, &dp6_ptr->io.irqen); } else if (ha->type == GDT_PCINEW) { outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); outb(0x03, PTR2USHORT(&ha->plx->control1)); } else if (ha->type == GDT_PCIMPR) { dp6m_ptr = ha->brd; - gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, + writeb(0xff, &dp6m_ptr->i960r.edoor_reg); + writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, &dp6m_ptr->i960r.edoor_en_reg); } spin_unlock_irqrestore(&ha->smp_lock, flags); @@ -1282,15 +1275,15 @@ static int gdth_get_status(unchar *pIStatus,int irq) *pIStatus = inb((ushort)ha->bmic + EDOORREG); else if (ha->type == GDT_ISA) *pIStatus = - gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); + readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCI) *pIStatus = - gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); + readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCINEW) *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); else if (ha->type == GDT_PCIMPR) *pIStatus = - gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); + readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); if (*pIStatus) return i; /* board found */ @@ -1310,14 +1303,14 @@ static int gdth_test_busy(int hanum) if (ha->type == GDT_EISA) gdtsema0 = (int)inb(ha->bmic + SEMA0REG); else if (ha->type == GDT_ISA) - gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); + gdtsema0 = (int)readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); else if (ha->type == GDT_PCI) - gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); + gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); else if (ha->type == GDT_PCINEW) gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); else if (ha->type == GDT_PCIMPR) gdtsema0 = - (int)gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); + (int)readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); return (gdtsema0 & 1); } @@ -1353,13 +1346,13 @@ static void gdth_set_sema0(int hanum) if (ha->type == GDT_EISA) { outb(1, ha->bmic + SEMA0REG); } else if (ha->type == GDT_ISA) { - gdth_writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); + writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); } else if (ha->type == GDT_PCI) { - gdth_writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); + writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); } else if (ha->type == GDT_PCINEW) { outb(1, PTR2USHORT(&ha->plx->sema0_reg)); } else if (ha->type == GDT_PCIMPR) { - gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); + writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); } } @@ -1395,30 +1388,30 @@ static void gdth_copy_command(int hanum) /* set offset and service, copy command to DPMEM */ if (ha->type == GDT_ISA) { dp2_ptr = ha->brd; - gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, + writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp2_ptr->u.ic.comm_queue[cmd_no].offset); - gdth_writew((ushort)cmd_ptr->Service, + writew((ushort)cmd_ptr->Service, &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } else if (ha->type == GDT_PCI) { dp6_ptr = ha->brd; - gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, + writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp6_ptr->u.ic.comm_queue[cmd_no].offset); - gdth_writew((ushort)cmd_ptr->Service, + writew((ushort)cmd_ptr->Service, &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } else if (ha->type == GDT_PCINEW) { dp6c_ptr = ha->brd; - gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, + writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); - gdth_writew((ushort)cmd_ptr->Service, + writew((ushort)cmd_ptr->Service, &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } else if (ha->type == GDT_PCIMPR) { dp6m_ptr = ha->brd; - gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, + writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); - gdth_writew((ushort)cmd_ptr->Service, + writew((ushort)cmd_ptr->Service, &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } @@ -1454,13 +1447,13 @@ static void gdth_release_event(int hanum) outl(ha->ccb_phys, ha->bmic + MAILBOXREG); outb(ha->pccb->Service, ha->bmic + LDOORREG); } else if (ha->type == GDT_ISA) { - gdth_writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); + writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); } else if (ha->type == GDT_PCI) { - gdth_writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); + writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); } else if (ha->type == GDT_PCINEW) { outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); } else if (ha->type == GDT_PCIMPR) { - gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); + writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); } } @@ -3143,32 +3136,32 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) dp2_ptr = ha->brd; if (IStatus & 0x80) { /* error flag */ IStatus &= ~0x80; - ha->status = gdth_readw(&dp2_ptr->u.ic.Status); + ha->status = readw(&dp2_ptr->u.ic.Status); TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); } else /* no error */ ha->status = S_OK; - ha->info = gdth_readl(&dp2_ptr->u.ic.Info[0]); - ha->service = gdth_readw(&dp2_ptr->u.ic.Service); - ha->info2 = gdth_readl(&dp2_ptr->u.ic.Info[1]); + ha->info = readl(&dp2_ptr->u.ic.Info[0]); + ha->service = readw(&dp2_ptr->u.ic.Service); + ha->info2 = readl(&dp2_ptr->u.ic.Info[1]); - gdth_writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ - gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ - gdth_writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ + writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ + writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ + writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ } else if (ha->type == GDT_PCI) { dp6_ptr = ha->brd; if (IStatus & 0x80) { /* error flag */ IStatus &= ~0x80; - ha->status = gdth_readw(&dp6_ptr->u.ic.Status); + ha->status = readw(&dp6_ptr->u.ic.Status); TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); } else /* no error */ ha->status = S_OK; - ha->info = gdth_readl(&dp6_ptr->u.ic.Info[0]); - ha->service = gdth_readw(&dp6_ptr->u.ic.Service); - ha->info2 = gdth_readl(&dp6_ptr->u.ic.Info[1]); + ha->info = readl(&dp6_ptr->u.ic.Info[0]); + ha->service = readw(&dp6_ptr->u.ic.Service); + ha->info2 = readl(&dp6_ptr->u.ic.Info[1]); - gdth_writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ - gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ - gdth_writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ + writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ + writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ + writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ } else if (ha->type == GDT_PCINEW) { if (IStatus & 0x80) { /* error flag */ IStatus &= ~0x80; @@ -3191,7 +3184,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) ha->status = pcs->ext_status & 0xffff; else #endif - ha->status = gdth_readw(&dp6m_ptr->i960r.status); + ha->status = readw(&dp6m_ptr->i960r.status); TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); } else /* no error */ ha->status = S_OK; @@ -3204,18 +3197,18 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) } else #endif { - ha->info = gdth_readl(&dp6m_ptr->i960r.info[0]); - ha->service = gdth_readw(&dp6m_ptr->i960r.service); - ha->info2 = gdth_readl(&dp6m_ptr->i960r.info[1]); + ha->info = readl(&dp6m_ptr->i960r.info[0]); + ha->service = readw(&dp6m_ptr->i960r.service); + ha->info2 = readl(&dp6m_ptr->i960r.info[1]); } /* event string */ if (IStatus == ASYNCINDEX) { if (ha->service != SCREENSERVICE && (ha->fw_vers & 0xff) >= 0x1a) { - ha->dvr.severity = gdth_readb + ha->dvr.severity = readb (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); for (i = 0; i < 256; ++i) { - ha->dvr.event_string[i] = gdth_readb + ha->dvr.event_string[i] = readb (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); if (ha->dvr.event_string[i] == 0) break; @@ -3228,8 +3221,8 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (!coalesced) #endif { - gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); + writeb(0xff, &dp6m_ptr->i960r.edoor_reg); + writeb(0, &dp6m_ptr->i960r.sema1_reg); } } else { TRACE2(("gdth_interrupt() unknown controller type\n")); @@ -3314,8 +3307,8 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) /* coalescing only for new GDT_PCIMPR controllers available */ if (ha->type == GDT_PCIMPR && coalesced) { - gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); - gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); + writeb(0xff, &dp6m_ptr->i960r.edoor_reg); + writeb(0, &dp6m_ptr->i960r.sema1_reg); } #endif -- cgit v1.1 From 69916b7ceac0dfbbc868ae5451062cb789b1b58a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 2 Oct 2007 22:57:58 +0200 Subject: [SCSI] gdth: Reorder scsi_host_template intitializers shuffle scsi_host_template members such that they appear in the order in which they are defined in the header. this makes is easier to verify when initializers are missing members. Signed-off-by: Jeff Garzik Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index afda12f..dba27b3 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4907,17 +4907,17 @@ static int gdth_slave_configure(struct scsi_device *sdev) } static struct scsi_host_template driver_template = { - .proc_name = "gdth", - .proc_info = gdth_proc_info, .name = "GDT SCSI Disk Array Controller", .detect = gdth_detect, .release = gdth_release, .info = gdth_info, .queuecommand = gdth_queuecommand, .eh_bus_reset_handler = gdth_eh_bus_reset, + .slave_configure = gdth_slave_configure, .bios_param = gdth_bios_param, + .proc_info = gdth_proc_info, + .proc_name = "gdth", .can_queue = GDTH_MAXCMDS, - .slave_configure = gdth_slave_configure, .this_id = -1, .sg_tablesize = GDTH_MAXSG, .cmd_per_lun = GDTH_MAXC_P_L, -- cgit v1.1 From 52759e6abc88fe007a080772ee01ef1154f96f30 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 2 Oct 2007 22:59:53 +0200 Subject: [SCSI] gdth: Remove virt hosts The virt_ctr option allows to register a new scsi_host for each bus on the raid controller. This non-default option makes no sense with the current scsi code and prevents cleaning up the host registration, so remove it. Signed-off-by: Christoph Hellwig Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 88 +++++++----------------------------------------- drivers/scsi/gdth_proc.c | 28 ++++++--------- drivers/scsi/gdth_proc.h | 4 +-- 3 files changed, 25 insertions(+), 95 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index dba27b3..c4db926 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -56,8 +56,6 @@ * max_ids:x x - target ID count per channel (1..MAXID) * rescan:Y rescan all channels/IDs * rescan:N use all devices found until now - * virt_ctr:Y map every channel to a virtual controller - * virt_ctr:N use multi channel support * hdr_channel:x x - number of virtual bus for host drives * shared_access:Y disable driver reserve/release protocol to * access a shared resource from several nodes, @@ -69,7 +67,7 @@ * force_dma32:N use 64 bit DMA mode, if supported * * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, - * max_ids:127,rescan:N,virt_ctr:N,hdr_channel:0, + * max_ids:127,rescan:N,hdr_channel:0, * shared_access:Y,probe_eisa_isa:N,force_dma32:N". * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". * @@ -80,7 +78,7 @@ * '1' in place of 'Y' and '0' in place of 'N'. * * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 - * max_ids=127 rescan=0 virt_ctr=0 hdr_channel=0 shared_access=0 + * max_ids=127 rescan=0 hdr_channel=0 shared_access=0 * probe_eisa_isa=0 force_dma32=0" * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". */ @@ -303,10 +301,8 @@ static unchar gdth_polling; /* polling if TRUE */ static unchar gdth_from_wait = FALSE; /* gdth_wait() */ static int wait_index,wait_hanum; /* gdth_wait() */ static int gdth_ctr_count = 0; /* controller count */ -static int gdth_ctr_vcount = 0; /* virt. ctr. count */ static int gdth_ctr_released = 0; /* gdth_release() */ static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ -static struct Scsi_Host *gdth_ctr_vtab[MAXHA*MAXBUS]; /* virt. ctr. table */ static unchar gdth_write_through = FALSE; /* write through */ static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ static int elastidx; @@ -358,8 +354,6 @@ static int hdr_channel = 0; static int max_ids = MAXID; /* rescan all IDs */ static int rescan = 0; -/* map channels to virtual controllers */ -static int virt_ctr = 0; /* shared access */ static int shared_access = 1; /* enable support for EISA and ISA controllers */ @@ -376,7 +370,6 @@ module_param(reverse_scan, int, 0); module_param(hdr_channel, int, 0); module_param(max_ids, int, 0); module_param(rescan, int, 0); -module_param(virt_ctr, int, 0); module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); @@ -2018,7 +2011,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) if (!IS_GDTH_INTERNAL_CMD(scp)) { scp->SCp.this_residual = (int)priority; - b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; + b = scp->device->channel; t = scp->device->id; if (priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || @@ -2080,8 +2073,7 @@ static void gdth_next(int hanum) if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; if (!IS_GDTH_INTERNAL_CMD(nscp)) { - b = virt_ctr ? - NUMDATA(nscp->device->host)->busnum : nscp->device->channel; + b = nscp->device->channel; t = nscp->device->id; l = nscp->device->lun; if (nscp->SCp.this_residual >= DEFAULT_PRI) { @@ -3397,7 +3389,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) printk("\n"); } else { - b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + b = scp->device->channel; t = scp->device->id; if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; @@ -3883,8 +3875,6 @@ static void __init internal_setup(char *str,int *ints) max_ids = val; else if (!strncmp(argv, "rescan:", 7)) rescan = val; - else if (!strncmp(argv, "virt_ctr:", 9)) - virt_ctr = val; else if (!strncmp(argv, "shared_access:", 14)) shared_access = val; else if (!strncmp(argv, "probe_eisa_isa:", 15)) @@ -3931,7 +3921,6 @@ int __init option_setup(char *str) return 1; } - static int __init gdth_detect(struct scsi_host_template *shtp) { #ifdef DEBUG_GDTH @@ -4018,7 +4007,7 @@ static int __init gdth_detect(struct scsi_host_template *shtp) register_reboot_notifier(&gdth_notifier); } gdth_polling = FALSE; - return gdth_ctr_vcount; + return gdth_ctr_count; } static int gdth_release(struct Scsi_Host *shp) @@ -4027,7 +4016,6 @@ static int gdth_release(struct Scsi_Host *shp) gdth_ha_str *ha; TRACE2(("gdth_release()\n")); - if (NUMDATA(shp)->busnum == 0) { hanum = NUMDATA(shp)->hanum; ha = HADATA(gdth_ctr_tab[hanum]); if (ha->sdev) { @@ -4069,7 +4057,6 @@ static int gdth_release(struct Scsi_Host *shp) unregister_chrdev(major,"gdth"); unregister_reboot_notifier(&gdth_notifier); } - } scsi_unregister(shp); return 0; @@ -4131,7 +4118,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) TRACE2(("gdth_eh_bus_reset()\n")); hanum = NUMDATA(scp->device->host)->hanum; - b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + b = scp->device->channel; ha = HADATA(gdth_ctr_tab[hanum]); /* clear command tab */ @@ -4185,7 +4172,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se sd = sdev; capacity = cap; hanum = NUMDATA(sd->host)->hanum; - b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel; + b = sd->channel; t = sd->id; TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); ha = HADATA(gdth_ctr_tab[hanum]); @@ -4805,7 +4792,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, scp->device = ha->sdev; scp->cmd_len = 12; scp->use_sg = 0; - scp->device->channel = virt_ctr ? 0 : res.number; + scp->device->channel = res.number; rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); kfree(scp); @@ -4932,7 +4919,6 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; int error, hanum, i; - u8 b; if (!gdth_search_isa(isa_bios)) return -ENXIO; @@ -4969,10 +4955,8 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) shp->dma_channel = ha->drq; hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; ha->pccb = CMDDATA(shp); ha->ccb_phys = 0L; @@ -5025,20 +5009,7 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 1; - shp->irq = ha->irq; - shp->dma_channel = ha->drq; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } + shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); @@ -5058,7 +5029,6 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) ha->pscratch, ha->scratch_phys); out_dec_counters: gdth_ctr_count--; - gdth_ctr_vcount--; out_free_irq: free_irq(ha->irq, ha); out_host_put: @@ -5075,7 +5045,6 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; int error, hanum, i; - u8 b; if (!gdth_search_eisa(eisa_slot)) return -ENXIO; @@ -5104,10 +5073,8 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, shp->dma_channel = 0xff; hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; TRACE2(("EISA detect Bus 0: hanum %d\n", NUMDATA(shp)->hanum)); @@ -5167,20 +5134,7 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } + shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); @@ -5203,7 +5157,6 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, out_free_irq: free_irq(ha->irq, ha); gdth_ctr_count--; - gdth_ctr_vcount--; out_host_put: scsi_unregister(shp); return error; @@ -5218,7 +5171,6 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; int error, hanum, i; - u8 b; shp = scsi_register(shtp,sizeof(gdth_ext_str)); if (!shp) @@ -5247,10 +5199,8 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, shp->dma_channel = 0xff; hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum= 0; ha->pccb = CMDDATA(shp); ha->ccb_phys = 0L; @@ -5318,20 +5268,7 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; - shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; - if (virt_ctr) { - virt_ctr = 1; - /* register addit. SCSI channels as virtual controllers */ - for (b = 1; b < ha->bus_cnt + 1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } - } + shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); @@ -5351,7 +5288,6 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, out_free_irq: free_irq(ha->irq, ha); gdth_ctr_count--; - gdth_ctr_vcount--; out_host_put: scsi_unregister(shp); return error; diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index cece6f2..b060bd6 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -7,26 +7,25 @@ int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, int inout) { - int hanum,busnum; + int hanum; TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", length,(int)offset,inout)); hanum = NUMDATA(host)->hanum; - busnum= NUMDATA(host)->busnum; if (inout) - return(gdth_set_info(buffer,length,host,hanum,busnum)); + return(gdth_set_info(buffer,length,host,hanum)); else - return(gdth_get_info(buffer,start,offset,length,host,hanum,busnum)); + return(gdth_get_info(buffer,start,offset,length,host,hanum)); } static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - int hanum,int busnum) + int hanum) { int ret_val = -EINVAL; - TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); + TRACE2(("gdth_set_info() ha %d\n",hanum,)); if (length >= 4) { if (strncmp(buffer,"gdth",4) == 0) { @@ -154,7 +153,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, } static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host,int hanum,int busnum) + struct Scsi_Host *host,int hanum) { int size = 0,len = 0; off_t begin = 0,pos = 0; @@ -187,7 +186,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, memset(cmnd, 0xff, 12); memset(gdtcmd, 0, sizeof(gdth_cmd_str)); - TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); + TRACE2(("gdth_get_info() ha %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); @@ -218,10 +217,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* controller information */ size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); len += size; pos = begin + len; - if (virt_ctr) - sprintf(hrec, "%s (Bus %d)", ha->binfo.type_string, busnum); - else - strcpy(hrec, ha->binfo.type_string); + strcpy(hrec, ha->binfo.type_string); size = sprintf(buffer+len, " Number: \t%d \tName: \t%s\n", hanum, hrec); @@ -753,7 +749,7 @@ static void gdth_wait_completion(int hanum, int busnum, int id) for (i = 0; i < GDTH_MAXCMDS; ++i) { scp = ha->cmd_tab[i].cmnd; - b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + b = scp->device->channel; t = scp->device->id; if (!SPECIAL_SCP(scp) && t == (unchar)id && b == (unchar)busnum) { @@ -779,8 +775,7 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { if (!IS_GDTH_INTERNAL_CMD(scp)) { - b = virt_ctr ? - NUMDATA(scp->device->host)->busnum : scp->device->channel; + b = scp->device->channel; t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); @@ -803,8 +798,7 @@ static void gdth_start_timeout(int hanum, int busnum, int id) for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { if (!IS_GDTH_INTERNAL_CMD(scp)) { - b = virt_ctr ? - NUMDATA(scp->device->host)->busnum : scp->device->channel; + b = scp->device->channel; t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_start_timeout(): update_timeout()\n")); diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h index a679eeb..dd71777 100644 --- a/drivers/scsi/gdth_proc.h +++ b/drivers/scsi/gdth_proc.h @@ -9,9 +9,9 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info); static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - int hanum,int busnum); + int hanum); static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host,int hanum,int busnum); + struct Scsi_Host *host,int hanum); static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, int length, int hanum); -- cgit v1.1 From 45f1a41b2b2e02e91d29bde66a8da4d050959f65 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:05:53 +0200 Subject: [SCSI] gdth: clean up host private data - Based on same patch from Christoph Hellwig - Get rid of all the indirection in the Scsi_Host private data and always put the gdth_ha_str directly into it. - Change all internal functions prototype to recieve an "gdth_ha_str *ha" pointer directlly and kill all that redundent access to the "gdth_ctr_tab[]" controller-table. Signed-off-by: Boaz Harrosh Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 558 +++++++++++++++++++++-------------------------- drivers/scsi/gdth.h | 17 +- drivers/scsi/gdth_proc.c | 80 +++---- drivers/scsi/gdth_proc.h | 20 +- 4 files changed, 291 insertions(+), 384 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index c4db926..c90e407 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -139,14 +139,15 @@ static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); static irqreturn_t gdth_interrupt(int irq, void *dev_id); -static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); -static int gdth_async_event(int hanum); +static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, + Scsi_Cmnd *scp); +static int gdth_async_event(gdth_ha_str *ha); static void gdth_log_event(gdth_evt_data *dvr, char *buffer); -static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority); -static void gdth_next(int hanum); -static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b); -static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp); +static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority); +static void gdth_next(gdth_ha_str *ha); +static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b); +static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, ushort idx, gdth_evt_data *evt); static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); @@ -154,30 +155,30 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, gdth_evt_str *estr); static void gdth_clear_events(void); -static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, +static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, char *buffer,ushort count); -static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); -static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); +static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); +static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); -static void gdth_enable_int(int hanum); +static void gdth_enable_int(gdth_ha_str *ha); static int gdth_get_status(unchar *pIStatus,int irq); -static int gdth_test_busy(int hanum); -static int gdth_get_cmd_index(int hanum); -static void gdth_release_event(int hanum); -static int gdth_wait(int hanum,int index,ulong32 time); -static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, - ulong64 p2,ulong64 p3); -static int gdth_search_drives(int hanum); -static int gdth_analyse_hdrive(int hanum, ushort hdrive); +static int gdth_test_busy(gdth_ha_str *ha); +static int gdth_get_cmd_index(gdth_ha_str *ha); +static void gdth_release_event(gdth_ha_str *ha); +static int gdth_wait(gdth_ha_str *ha, int index,ulong32 time); +static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, + ulong32 p1, ulong64 p2,ulong64 p3); +static int gdth_search_drives(gdth_ha_str *ha); +static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive); -static const char *gdth_ctr_name(int hanum); +static const char *gdth_ctr_name(gdth_ha_str *ha); static int gdth_open(struct inode *inode, struct file *filep); static int gdth_close(struct inode *inode, struct file *filep); static int gdth_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); -static void gdth_flush(int hanum); +static void gdth_flush(gdth_ha_str *ha); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); static void gdth_scsi_done(struct scsi_cmnd *scp); @@ -285,10 +286,6 @@ static struct timer_list gdth_timer; #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) #define INDEX_OK(i,t) ((i)hostdata)) -#define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) -#define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext) - #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) #ifdef CONFIG_ISA @@ -1212,16 +1209,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) /* controller protocol functions */ -static void __init gdth_enable_int(int hanum) +static void __init gdth_enable_int(gdth_ha_str *ha) { - gdth_ha_str *ha; ulong flags; gdt2_dpram_str __iomem *dp2_ptr; gdt6_dpram_str __iomem *dp6_ptr; gdt6m_dpram_str __iomem *dp6m_ptr; - TRACE(("gdth_enable_int() hanum %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE(("gdth_enable_int() hanum %d\n",ha->hanum)); spin_lock_irqsave(&ha->smp_lock, flags); if (ha->type == GDT_EISA) { @@ -1261,7 +1256,7 @@ static int gdth_get_status(unchar *pIStatus,int irq) *pIStatus = 0; for (i=0; iirq != (unchar)irq) /* check IRQ */ continue; if (ha->type == GDT_EISA) @@ -1285,14 +1280,12 @@ static int gdth_get_status(unchar *pIStatus,int irq) } -static int gdth_test_busy(int hanum) +static int gdth_test_busy(gdth_ha_str *ha) { - register gdth_ha_str *ha; register int gdtsema0 = 0; - TRACE(("gdth_test_busy() hanum %d\n",hanum)); - - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE(("gdth_test_busy() hanum %d\n", ha->hanum)); + if (ha->type == GDT_EISA) gdtsema0 = (int)inb(ha->bmic + SEMA0REG); else if (ha->type == GDT_ISA) @@ -1309,14 +1302,12 @@ static int gdth_test_busy(int hanum) } -static int gdth_get_cmd_index(int hanum) +static int gdth_get_cmd_index(gdth_ha_str *ha) { - register gdth_ha_str *ha; int i; - TRACE(("gdth_get_cmd_index() hanum %d\n",hanum)); + TRACE(("gdth_get_cmd_index() hanum %d\n", ha->hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); for (i=0; icmd_tab[i].cmnd == UNUSED_CMND) { ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; @@ -1329,13 +1320,10 @@ static int gdth_get_cmd_index(int hanum) } -static void gdth_set_sema0(int hanum) +static void gdth_set_sema0(gdth_ha_str *ha) { - register gdth_ha_str *ha; - - TRACE(("gdth_set_sema0() hanum %d\n",hanum)); + TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); if (ha->type == GDT_EISA) { outb(1, ha->bmic + SEMA0REG); } else if (ha->type == GDT_ISA) { @@ -1350,9 +1338,8 @@ static void gdth_set_sema0(int hanum) } -static void gdth_copy_command(int hanum) +static void gdth_copy_command(gdth_ha_str *ha) { - register gdth_ha_str *ha; register gdth_cmd_str *cmd_ptr; register gdt6m_dpram_str __iomem *dp6m_ptr; register gdt6c_dpram_str __iomem *dp6c_ptr; @@ -1360,9 +1347,8 @@ static void gdth_copy_command(int hanum) gdt2_dpram_str __iomem *dp2_ptr; ushort cp_count,dp_offset,cmd_no; - TRACE(("gdth_copy_command() hanum %d\n",hanum)); + TRACE(("gdth_copy_command() hanum %d\n", ha->hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); cp_count = ha->cmd_len; dp_offset= ha->cmd_offs_dpmem; cmd_no = ha->cmd_cnt; @@ -1411,12 +1397,9 @@ static void gdth_copy_command(int hanum) } -static void gdth_release_event(int hanum) +static void gdth_release_event(gdth_ha_str *ha) { - register gdth_ha_str *ha; - - TRACE(("gdth_release_event() hanum %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE(("gdth_release_event() hanum %d\n", ha->hanum)); #ifdef GDTH_STATISTICS { @@ -1450,46 +1433,41 @@ static void gdth_release_event(int hanum) } } - -static int gdth_wait(int hanum,int index,ulong32 time) +static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time) { - gdth_ha_str *ha; int answer_found = FALSE; - TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum,index,time)); + TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); - ha = HADATA(gdth_ctr_tab[hanum]); if (index == 0) return 1; /* no wait required */ gdth_from_wait = TRUE; do { gdth_interrupt((int)ha->irq,ha); - if (wait_hanum==hanum && wait_index==index) { + if (wait_hanum==ha->hanum && wait_index==index) { answer_found = TRUE; break; } gdth_delay(1); } while (--time); gdth_from_wait = FALSE; - - while (gdth_test_busy(hanum)) + + while (gdth_test_busy(ha)) gdth_delay(0); return (answer_found); } -static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, - ulong64 p2,ulong64 p3) +static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, + ulong32 p1, ulong64 p2, ulong64 p3) { - register gdth_ha_str *ha; register gdth_cmd_str *cmd_ptr; int retries,index; TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); - ha = HADATA(gdth_ctr_tab[hanum]); cmd_ptr = ha->pccb; memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); @@ -1497,11 +1475,11 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, for (retries = INIT_RETRIES;;) { cmd_ptr->Service = service; cmd_ptr->RequestBuffer = INTERNAL_CMND; - if (!(index=gdth_get_cmd_index(hanum))) { + if (!(index=gdth_get_cmd_index(ha))) { TRACE(("GDT: No free command index found\n")); return 0; } - gdth_set_sema0(hanum); + gdth_set_sema0(ha); cmd_ptr->OpCode = opcode; cmd_ptr->BoardNode = LOCALBOARD; if (service == CACHESERVICE) { @@ -1541,10 +1519,10 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, ha->cmd_len = sizeof(gdth_cmd_str); ha->cmd_offs_dpmem = 0; ha->cmd_cnt = 0; - gdth_copy_command(hanum); - gdth_release_event(hanum); + gdth_copy_command(ha); + gdth_release_event(ha); gdth_delay(20); - if (!gdth_wait(hanum,index,INIT_TIMEOUT)) { + if (!gdth_wait(ha, index, INIT_TIMEOUT)) { printk("GDT: Initialization error (timeout service %d)\n",service); return 0; } @@ -1559,9 +1537,8 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, /* search for devices */ -static int __init gdth_search_drives(int hanum) +static int __init gdth_search_drives(gdth_ha_str *ha) { - register gdth_ha_str *ha; ushort cdev_cnt, i; int ok; ulong32 bus_no, drv_cnt, drv_no, j; @@ -1581,22 +1558,21 @@ static int __init gdth_search_drives(int hanum) ulong flags; #endif - TRACE(("gdth_search_drives() hanum %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE(("gdth_search_drives() hanum %d\n", ha->hanum)); ok = 0; /* initialize controller services, at first: screen service */ ha->screen_feat = 0; if (!force_dma32) { - ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_X_INIT_SCR,0,0,0); + ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_X_INIT_SCR, 0, 0, 0); if (ok) ha->screen_feat = GDT_64BIT; } if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) - ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_INIT,0,0,0); + ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0); if (!ok) { printk("GDT-HA %d: Initialization error screen service (code %d)\n", - hanum, ha->status); + ha->hanum, ha->status); return 0; } TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); @@ -1620,25 +1596,26 @@ static int __init gdth_search_drives(int hanum) TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); /* 3. send to controller firmware */ - gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0], + gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(ulong32 *)&rtc[0], *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); #endif /* unfreeze all IOs */ - gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0); + gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0); /* initialize cache service */ ha->cache_feat = 0; if (!force_dma32) { - ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INIT_HOST,LINUX_OS,0,0); + ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INIT_HOST, LINUX_OS, + 0, 0); if (ok) ha->cache_feat = GDT_64BIT; } if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) - ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0); + ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0); if (!ok) { printk("GDT-HA %d: Initialization error cache service (code %d)\n", - hanum, ha->status); + ha->hanum, ha->status); return 0; } TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); @@ -1667,9 +1644,9 @@ static int __init gdth_search_drives(int hanum) pmod->cmd_buff_size = 0; pmod->reserved1 = 0; pmod->reserved2 = 0; - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,SET_PERF_MODES, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SET_PERF_MODES, INVALID_CHANNEL,sizeof(gdth_perf_modes))) { - printk("GDT-HA %d: Interrupt coalescing activated\n", hanum); + printk("GDT-HA %d: Interrupt coalescing activated\n", ha->hanum); } } #endif @@ -1681,7 +1658,7 @@ static int __init gdth_search_drives(int hanum) iocr->hdr.first_chan = 0; iocr->hdr.last_chan = MAXBUS-1; iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_RAW_DESC, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_RAW_DESC, INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { TRACE2(("IOCHAN_RAW_DESC supported!\n")); ha->bus_cnt = iocr->hdr.chan_count; @@ -1696,13 +1673,13 @@ static int __init gdth_search_drives(int hanum) chn = (gdth_getch_str *)ha->pscratch; for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { chn->channel_no = bus_no; - if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SCSI_CHAN_CNT | L_CTRL_PATTERN, IO_CHANNEL | INVALID_CHANNEL, sizeof(gdth_getch_str))) { if (bus_no == 0) { printk("GDT-HA %d: Error detecting channel count (0x%x)\n", - hanum, ha->status); + ha->hanum, ha->status); return 0; } break; @@ -1717,10 +1694,10 @@ static int __init gdth_search_drives(int hanum) TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); /* read cache configuration */ - if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO, + if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_INFO, INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { printk("GDT-HA %d: Initialization error cache service (code %d)\n", - hanum, ha->status); + ha->hanum, ha->status); return 0; } ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; @@ -1730,11 +1707,11 @@ static int __init gdth_search_drives(int hanum) /* read board info and features */ ha->more_proc = FALSE; - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_INFO, INVALID_CHANNEL,sizeof(gdth_binfo_str))) { memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, sizeof(gdth_binfo_str)); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_FEATURES, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_FEATURES, INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; @@ -1742,7 +1719,7 @@ static int __init gdth_search_drives(int hanum) } } else { TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); - strcpy(ha->binfo.type_string, gdth_ctr_name(hanum)); + strcpy(ha->binfo.type_string, gdth_ctr_name(ha)); } TRACE2(("Controller name: %s\n",ha->binfo.type_string)); @@ -1755,7 +1732,7 @@ static int __init gdth_search_drives(int hanum) ioc->hdr.first_chan = 0; ioc->hdr.last_chan = MAXBUS-1; ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_DESC, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_DESC, INVALID_CHANNEL,sizeof(gdth_iochan_str))) { for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { ha->raw[bus_no].address = ioc->list[bus_no].address; @@ -1770,7 +1747,7 @@ static int __init gdth_search_drives(int hanum) for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { chn = (gdth_getch_str *)ha->pscratch; chn->channel_no = ha->raw[bus_no].local_no; - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SCSI_CHAN_CNT | L_CTRL_PATTERN, ha->raw[bus_no].address | INVALID_CHANNEL, sizeof(gdth_getch_str))) { @@ -1782,7 +1759,7 @@ static int __init gdth_search_drives(int hanum) drl = (gdth_drlist_str *)ha->pscratch; drl->sc_no = ha->raw[bus_no].local_no; drl->sc_cnt = ha->raw[bus_no].pdev_cnt; - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SCSI_DR_LIST | L_CTRL_PATTERN, ha->raw[bus_no].address | INVALID_CHANNEL, sizeof(gdth_drlist_str))) { @@ -1795,10 +1772,10 @@ static int __init gdth_search_drives(int hanum) } /* logical drives */ - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_CNT, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT, INVALID_CHANNEL,sizeof(ulong32))) { drv_cnt = *(ulong32 *)ha->pscratch; - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_LIST, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST, INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { for (j = 0; j < drv_cnt; ++j) { drv_no = ((ulong32 *)ha->pscratch)[j]; @@ -1812,7 +1789,7 @@ static int __init gdth_search_drives(int hanum) alst->entries_avail = MAX_LDRIVES; alst->first_entry = 0; alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, INVALID_CHANNEL, sizeof(gdth_arcdl_str) + (alst->entries_avail-1) * sizeof(gdth_alist_str))) { @@ -1823,7 +1800,7 @@ static int __init gdth_search_drives(int hanum) ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; ha->hdr[j].master_no = alst->list[j].cd_handle; } - } else if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + } else if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, ARRAY_DRV_LIST | LA_CTRL_PATTERN, 0, 35 * sizeof(gdth_alist_str))) { for (j = 0; j < 35; ++j) { @@ -1841,24 +1818,24 @@ static int __init gdth_search_drives(int hanum) /* initialize raw service */ ha->raw_feat = 0; if (!force_dma32) { - ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_X_INIT_RAW,0,0,0); + ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_X_INIT_RAW, 0, 0, 0); if (ok) ha->raw_feat = GDT_64BIT; } if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) - ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0); + ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0); if (!ok) { printk("GDT-HA %d: Initialization error raw service (code %d)\n", - hanum, ha->status); + ha->hanum, ha->status); return 0; } TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); /* set/get features raw service (scatter/gather) */ - if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER, - 0,0)) { + if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_SET_FEAT, SCATTER_GATHER, + 0, 0)) { TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); - if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) { + if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) { TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", ha->info)); ha->raw_feat |= (ushort)ha->info; @@ -1866,10 +1843,10 @@ static int __init gdth_search_drives(int hanum) } /* set/get features cache service (equal to raw service) */ - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_SET_FEAT, 0, SCATTER_GATHER,0)) { TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) { + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) { TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", ha->info)); ha->cache_feat |= (ushort)ha->info; @@ -1878,22 +1855,22 @@ static int __init gdth_search_drives(int hanum) /* reserve drives for raw service */ if (reserve_mode != 0) { - gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE_ALL, + gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE_ALL, reserve_mode == 1 ? 1 : 3, 0, 0); TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", ha->status)); } for (i = 0; i < MAX_RES_ARGS; i += 4) { - if (reserve_list[i] == hanum && reserve_list[i+1] < ha->bus_cnt && + if (reserve_list[i] == ha->hanum && reserve_list[i+1] < ha->bus_cnt && reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", reserve_list[i], reserve_list[i+1], reserve_list[i+2], reserve_list[i+3])); - if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0, + if (!gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE, 0, reserve_list[i+1], reserve_list[i+2] | (reserve_list[i+3] << 8))) { printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", - hanum, ha->status); + ha->hanum, ha->status); } } } @@ -1902,12 +1879,12 @@ static int __init gdth_search_drives(int hanum) oemstr = (gdth_oem_str_ioctl *)ha->pscratch; oemstr->params.ctl_version = 0x01; oemstr->params.buffer_size = sizeof(oemstr->text); - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, sizeof(gdth_oem_str_ioctl))) { TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); printk("GDT-HA %d: Vendor: %s Name: %s\n", - hanum,oemstr->text.oem_company_name,ha->binfo.type_string); + ha->hanum, oemstr->text.oem_company_name, ha->binfo.type_string); /* Save the Host Drive inquiry data */ strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, sizeof(ha->oem_name)); @@ -1915,7 +1892,7 @@ static int __init gdth_search_drives(int hanum) /* Old method, based on PCI ID */ TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); printk("GDT-HA %d: Name: %s\n", - hanum,ha->binfo.type_string); + ha->hanum, ha->binfo.type_string); if (ha->oem_id == OEM_ID_INTEL) strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); else @@ -1924,24 +1901,22 @@ static int __init gdth_search_drives(int hanum) /* scanning for host drives */ for (i = 0; i < cdev_cnt; ++i) - gdth_analyse_hdrive(hanum,i); + gdth_analyse_hdrive(ha, i); TRACE(("gdth_search_drives() OK\n")); return 1; } -static int gdth_analyse_hdrive(int hanum,ushort hdrive) +static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) { - register gdth_ha_str *ha; ulong32 drv_cyls; int drv_hds, drv_secs; - TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n",hanum,hdrive)); + TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive)); if (hdrive >= MAX_HDRIVES) return 0; - ha = HADATA(gdth_ctr_tab[hanum]); - if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,hdrive,0,0)) + if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_INFO, hdrive, 0, 0)) return 0; ha->hdr[hdrive].present = TRUE; ha->hdr[hdrive].size = ha->info; @@ -1961,7 +1936,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; if (ha->cache_feat & GDT_64BIT) { - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INFO,hdrive,0,0) + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0) && ha->info2 != 0) { ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; } @@ -1970,14 +1945,14 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); /* get informations about device */ - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_DEVTYPE,hdrive,0,0)) { + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) { TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", hdrive,ha->info)); ha->hdr[hdrive].devtype = (ushort)ha->info; } /* cluster info */ - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_CLUST_INFO,hdrive,0,0)) { + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_INFO, hdrive, 0, 0)) { TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", hdrive,ha->info)); if (!shared_access) @@ -1985,7 +1960,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) } /* R/W attributes */ - if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_RW_ATTRIBS,hdrive,0,0)) { + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) { TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", hdrive,ha->info)); ha->hdr[hdrive].rw_attribs = (unchar)ha->info; @@ -1997,16 +1972,14 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) /* command queueing/sending functions */ -static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) +static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) { - register gdth_ha_str *ha; register Scsi_Cmnd *pscp; register Scsi_Cmnd *nscp; ulong flags; unchar b, t; TRACE(("gdth_putq() priority %d\n",priority)); - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); if (!IS_GDTH_INTERNAL_CMD(scp)) { @@ -2017,7 +1990,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b==ha->virt_bus && thdr[t].lock)) { TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); + scp->SCp.buffers_residual = gdth_update_timeout(scp, 0); } } } @@ -2049,9 +2022,8 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) #endif } -static void gdth_next(int hanum) +static void gdth_next(gdth_ha_str *ha) { - register gdth_ha_str *ha; register Scsi_Cmnd *pscp; register Scsi_Cmnd *nscp; unchar b, t, l, firsttime; @@ -2059,8 +2031,7 @@ static void gdth_next(int hanum) ulong flags = 0; int cmd_index; - TRACE(("gdth_next() hanum %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE(("gdth_next() hanum %d\n", ha->hanum)); if (!gdth_polling) spin_lock_irqsave(&ha->smp_lock, flags); @@ -2085,13 +2056,13 @@ static void gdth_next(int hanum) b = t = l = 0; if (firsttime) { - if (gdth_test_busy(hanum)) { /* controller busy ? */ - TRACE(("gdth_next() controller %d busy !\n",hanum)); + if (gdth_test_busy(ha)) { /* controller busy ? */ + TRACE(("gdth_next() controller %d busy !\n", ha->hanum)); if (!gdth_polling) { spin_unlock_irqrestore(&ha->smp_lock, flags); return; } - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(1); } firsttime = FALSE; @@ -2143,11 +2114,11 @@ static void gdth_next(int hanum) if (nscp->SCp.sent_command != -1) { if ((nscp->SCp.phase & 0xff) == CACHESERVICE) { - if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) + if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) this_cmd = FALSE; next_cmd = FALSE; } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) { - if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) + if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) this_cmd = FALSE; next_cmd = FALSE; } else { @@ -2161,12 +2132,12 @@ static void gdth_next(int hanum) gdth_scsi_done(nscp); } } else if (IS_GDTH_INTERNAL_CMD(nscp)) { - if (!(cmd_index=gdth_special_cmd(hanum,nscp))) + if (!(cmd_index=gdth_special_cmd(ha, nscp))) this_cmd = FALSE; next_cmd = FALSE; } else if (b != ha->virt_bus) { if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || - !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) + !(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) this_cmd = FALSE; else ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; @@ -2204,7 +2175,7 @@ static void gdth_next(int hanum) nscp->SCp.have_data_in++; else gdth_scsi_done(nscp); - } else if (gdth_internal_cache_cmd(hanum, nscp)) + } else if (gdth_internal_cache_cmd(ha, nscp)) gdth_scsi_done(nscp); break; @@ -2224,7 +2195,7 @@ static void gdth_next(int hanum) nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; TRACE(("Prevent/allow r. %d rem. drive %d\n", nscp->cmnd[4],nscp->cmnd[3])); - if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) + if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) this_cmd = FALSE; } break; @@ -2233,7 +2204,7 @@ static void gdth_next(int hanum) case RELEASE: TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? "RESERVE" : "RELEASE")); - if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) + if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) this_cmd = FALSE; break; @@ -2256,7 +2227,7 @@ static void gdth_next(int hanum) nscp->SCp.have_data_in++; else gdth_scsi_done(nscp); - } else if (!(cmd_index=gdth_fill_cache_cmd(hanum, nscp, t))) + } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) this_cmd = FALSE; break; @@ -2265,7 +2236,7 @@ static void gdth_next(int hanum) nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], nscp->cmnd[4],nscp->cmnd[5])); printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", - hanum, nscp->cmnd[0]); + ha->hanum, nscp->cmnd[0]); nscp->result = DID_ABORT << 16; if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; @@ -2286,30 +2257,28 @@ static void gdth_next(int hanum) } if (ha->cmd_cnt > 0) { - gdth_release_event(hanum); + gdth_release_event(ha); } if (!gdth_polling) spin_unlock_irqrestore(&ha->smp_lock, flags); if (gdth_polling && ha->cmd_cnt > 0) { - if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT)) + if (!gdth_wait(ha, cmd_index, POLL_TIMEOUT)) printk("GDT-HA %d: Command %d timed out !\n", - hanum,cmd_index); + ha->hanum, cmd_index); } } -static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, +static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, char *buffer,ushort count) { ushort cpcount,i; ushort cpsum,cpnow; struct scatterlist *sl; - gdth_ha_str *ha; char *address; cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; - ha = HADATA(gdth_ctr_tab[hanum]); if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; @@ -2323,7 +2292,7 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, cpsum += cpnow; if (!sl->page) { printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", - hanum); + ha->hanum); return; } local_irq_save(flags); @@ -2342,16 +2311,14 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, } } -static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) +static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) { - register gdth_ha_str *ha; unchar t; gdth_inq_data inq; gdth_rdcap_data rdc; gdth_sense_data sd; gdth_modep_data mpd; - ha = HADATA(gdth_ctr_tab[hanum]); t = scp->device->id; TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", scp->cmnd[0],t)); @@ -2382,7 +2349,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) strcpy(inq.vendor,ha->oem_name); sprintf(inq.product,"Host Drive #%02d",t); strcpy(inq.revision," "); - gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data)); + gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data)); break; case REQUEST_SENSE: @@ -2392,7 +2359,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) sd.key = NO_SENSE; sd.info = 0; sd.add_length= 0; - gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data)); + gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data)); break; case MODE_SENSE: @@ -2404,7 +2371,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); - gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data)); + gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data)); break; case READ_CAPACITY: @@ -2414,7 +2381,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) else rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); rdc.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data)); + gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data)); break; case SERVICE_ACTION_IN: @@ -2425,7 +2392,8 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) TRACE2(("Read capacity (16) hdrive %d\n",t)); rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); rdc16.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(hanum,scp,(char*)&rdc16,sizeof(gdth_rdcap16_data)); + gdth_copy_internal_data(ha, scp, (char*)&rdc16, + sizeof(gdth_rdcap16_data)); } else { scp->result = DID_ABORT << 16; } @@ -2443,10 +2411,9 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) return 0; } - -static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) + +static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) { - register gdth_ha_str *ha; register gdth_cmd_str *cmdp; struct scatterlist *sl; ulong32 cnt, blockcnt; @@ -2456,7 +2423,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) struct page *page; ulong offset; - ha = HADATA(gdth_ctr_tab[hanum]); cmdp = ha->pccb; TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", scp->cmnd[0],scp->cmd_len,hdrive)); @@ -2472,13 +2438,13 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) cmdp->Service = CACHESERVICE; cmdp->RequestBuffer = scp; /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(hanum))) { + if (!(cmd_index=gdth_get_cmd_index(ha))) { TRACE(("GDT: No free command index found\n")); return 0; } /* if it's the first command, set command semaphore */ if (ha->cmd_cnt == 0) - gdth_set_sema0(hanum); + gdth_set_sema0(ha); /* fill command */ read_write = 0; @@ -2650,13 +2616,12 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) } /* copy command */ - gdth_copy_command(hanum); + gdth_copy_command(ha); return cmd_index; } -static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) +static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) { - register gdth_ha_str *ha; register gdth_cmd_str *cmdp; struct scatterlist *sl; ushort i; @@ -2666,7 +2631,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) struct page *page; ulong offset; - ha = HADATA(gdth_ctr_tab[hanum]); t = scp->device->id; l = scp->device->lun; cmdp = ha->pccb; @@ -2681,13 +2645,13 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) cmdp->Service = SCSIRAWSERVICE; cmdp->RequestBuffer = scp; /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(hanum))) { + if (!(cmd_index=gdth_get_cmd_index(ha))) { TRACE(("GDT: No free command index found\n")); return 0; } /* if it's the first command, set command semaphore */ if (ha->cmd_cnt == 0) - gdth_set_sema0(hanum); + gdth_set_sema0(ha); /* fill command */ if (scp->SCp.sent_command != -1) { @@ -2855,17 +2819,15 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) } /* copy command */ - gdth_copy_command(hanum); + gdth_copy_command(ha); return cmd_index; } -static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) +static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) { - register gdth_ha_str *ha; register gdth_cmd_str *cmdp; int cmd_index; - ha = HADATA(gdth_ctr_tab[hanum]); cmdp= ha->pccb; TRACE2(("gdth_special_cmd(): ")); @@ -2876,14 +2838,14 @@ static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) cmdp->RequestBuffer = scp; /* search free command index */ - if (!(cmd_index=gdth_get_cmd_index(hanum))) { + if (!(cmd_index=gdth_get_cmd_index(ha))) { TRACE(("GDT: No free command index found\n")); return 0; } /* if it's the first command, set command semaphore */ if (ha->cmd_cnt == 0) - gdth_set_sema0(hanum); + gdth_set_sema0(ha); /* evaluate command size, check space */ if (cmdp->OpCode == GDT_IOCTL) { @@ -2921,7 +2883,7 @@ static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) } /* copy command */ - gdth_copy_command(hanum); + gdth_copy_command(ha); return cmd_index; } @@ -3087,7 +3049,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; } - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[hanum]); #ifdef GDTH_STATISTICS ++act_ints; @@ -3233,10 +3195,10 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (IStatus == ASYNCINDEX) { TRACE2(("gdth_interrupt() async. event\n")); - gdth_async_event(hanum); + gdth_async_event(ha); if (!gdth_polling) spin_unlock_irqrestore(&ha2->smp_lock, flags); - gdth_next(hanum); + gdth_next(ha); return IRQ_HANDLED; } @@ -3270,11 +3232,11 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) } TRACE(("gdth_interrupt() sync. status\n")); - rval = gdth_sync_event(hanum,Service,IStatus,scp); + rval = gdth_sync_event(ha,Service,IStatus,scp); if (!gdth_polling) spin_unlock_irqrestore(&ha2->smp_lock, flags); if (rval == 2) { - gdth_putq(hanum,scp,scp->SCp.this_residual); + gdth_putq(ha, scp,scp->SCp.this_residual); } else if (rval == 1) { gdth_scsi_done(scp); } @@ -3304,18 +3266,17 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) } #endif - gdth_next(hanum); + gdth_next(ha); return IRQ_HANDLED; } -static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) +static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, + Scsi_Cmnd *scp) { - register gdth_ha_str *ha; gdth_msg_str *msg; gdth_cmd_str *cmdp; unchar b, t; - ha = HADATA(gdth_ctr_tab[hanum]); cmdp = ha->pccb; TRACE(("gdth_sync_event() serv %d status %d\n", service,ha->status)); @@ -3333,12 +3294,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) } if (msg->msg_ext && !msg->msg_answer) { - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(0); cmdp->Service = SCREENSERVICE; cmdp->RequestBuffer = SCREEN_CMND; - gdth_get_cmd_index(hanum); - gdth_set_sema0(hanum); + gdth_get_cmd_index(ha); + gdth_set_sema0(ha); cmdp->OpCode = GDT_READ; cmdp->BoardNode = LOCALBOARD; cmdp->u.screen.reserved = 0; @@ -3348,8 +3309,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) + sizeof(ulong64); ha->cmd_cnt = 0; - gdth_copy_command(hanum); - gdth_release_event(hanum); + gdth_copy_command(ha); + gdth_release_event(ha); return 0; } @@ -3367,12 +3328,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) } msg->msg_ext = 0; msg->msg_answer = 0; - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(0); cmdp->Service = SCREENSERVICE; cmdp->RequestBuffer = SCREEN_CMND; - gdth_get_cmd_index(hanum); - gdth_set_sema0(hanum); + gdth_get_cmd_index(ha); + gdth_set_sema0(ha); cmdp->OpCode = GDT_WRITE; cmdp->BoardNode = LOCALBOARD; cmdp->u.screen.reserved = 0; @@ -3382,8 +3343,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) + sizeof(ulong64); ha->cmd_cnt = 0; - gdth_copy_command(hanum); - gdth_release_event(hanum); + gdth_copy_command(ha); + gdth_release_event(ha); return 0; } printk("\n"); @@ -3496,7 +3457,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) } if (!IS_GDTH_INTERNAL_CMD(scp)) { ha->dvr.size = sizeof(ha->dvr.eu.sync); - ha->dvr.eu.sync.ionode = hanum; + ha->dvr.eu.sync.ionode = ha->hanum; ha->dvr.eu.sync.service = service; ha->dvr.eu.sync.status = ha->status; ha->dvr.eu.sync.info = ha->info; @@ -3680,25 +3641,23 @@ static char *async_cache_tab[] = { }; -static int gdth_async_event(int hanum) +static int gdth_async_event(gdth_ha_str *ha) { - gdth_ha_str *ha; gdth_cmd_str *cmdp; int cmd_index; - ha = HADATA(gdth_ctr_tab[hanum]); cmdp= ha->pccb; TRACE2(("gdth_async_event() ha %d serv %d\n", - hanum,ha->service)); + ha->hanum, ha->service)); if (ha->service == SCREENSERVICE) { if (ha->status == MSG_REQUEST) { - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(0); cmdp->Service = SCREENSERVICE; cmdp->RequestBuffer = SCREEN_CMND; - cmd_index = gdth_get_cmd_index(hanum); - gdth_set_sema0(hanum); + cmd_index = gdth_get_cmd_index(ha); + gdth_set_sema0(ha); cmdp->OpCode = GDT_READ; cmdp->BoardNode = LOCALBOARD; cmdp->u.screen.reserved = 0; @@ -3708,7 +3667,7 @@ static int gdth_async_event(int hanum) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) + sizeof(ulong64); ha->cmd_cnt = 0; - gdth_copy_command(hanum); + gdth_copy_command(ha); if (ha->type == GDT_EISA) printk("[EISA slot %d] ",(ushort)ha->brd_phys); else if (ha->type == GDT_ISA) @@ -3716,19 +3675,19 @@ static int gdth_async_event(int hanum) else printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), (ushort)((ha->brd_phys>>3)&0x1f)); - gdth_release_event(hanum); + gdth_release_event(ha); } } else { if (ha->type == GDT_PCIMPR && (ha->fw_vers & 0xff) >= 0x1a) { ha->dvr.size = 0; - ha->dvr.eu.async.ionode = hanum; + ha->dvr.eu.async.ionode = ha->hanum; ha->dvr.eu.async.status = ha->status; /* severity and event_string already set! */ } else { ha->dvr.size = sizeof(ha->dvr.eu.async); - ha->dvr.eu.async.ionode = hanum; + ha->dvr.eu.async.ionode = ha->hanum; ha->dvr.eu.async.service = ha->service; ha->dvr.eu.async.status = ha->status; ha->dvr.eu.async.info = ha->info; @@ -3810,9 +3769,8 @@ static void gdth_timeout(ulong data) Scsi_Cmnd *nscp; gdth_ha_str *ha; ulong flags; - int hanum = 0; - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[0]); spin_lock_irqsave(&ha->smp_lock, flags); for (act_stats=0,i=0; ihanum; - ha = HADATA(gdth_ctr_tab[hanum]); if (ha->sdev) { scsi_free_host_dev(ha->sdev); ha->sdev = NULL; } - gdth_flush(hanum); + gdth_flush(ha); if (shp->irq) { free_irq(shp->irq,ha); @@ -4063,14 +4018,10 @@ static int gdth_release(struct Scsi_Host *shp) } -static const char *gdth_ctr_name(int hanum) +static const char *gdth_ctr_name(gdth_ha_str *ha) { - gdth_ha_str *ha; - TRACE2(("gdth_ctr_name()\n")); - ha = HADATA(gdth_ctr_tab[hanum]); - if (ha->type == GDT_EISA) { switch (ha->stype) { case GDT3_ID: @@ -4097,29 +4048,23 @@ static const char *gdth_ctr_name(int hanum) static const char *gdth_info(struct Scsi_Host *shp) { - int hanum; - gdth_ha_str *ha; + gdth_ha_str *ha = shost_priv(shp); TRACE2(("gdth_info()\n")); - hanum = NUMDATA(shp)->hanum; - ha = HADATA(gdth_ctr_tab[hanum]); - return ((const char *)ha->binfo.type_string); } static int gdth_eh_bus_reset(Scsi_Cmnd *scp) { - int i, hanum; - gdth_ha_str *ha; + gdth_ha_str *ha = shost_priv(scp->device->host); + int i; ulong flags; Scsi_Cmnd *cmnd; unchar b; TRACE2(("gdth_eh_bus_reset()\n")); - hanum = NUMDATA(scp->device->host)->hanum; b = scp->device->channel; - ha = HADATA(gdth_ctr_tab[hanum]); /* clear command tab */ spin_lock_irqsave(&ha->smp_lock, flags); @@ -4136,9 +4081,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) if (ha->hdr[i].present) { spin_lock_irqsave(&ha->smp_lock, flags); gdth_polling = TRUE; - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(0); - if (gdth_internal_cmd(hanum, CACHESERVICE, + if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_RESET, i, 0, 0)) ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; gdth_polling = FALSE; @@ -4151,9 +4096,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) for (i = 0; i < MAXID; ++i) ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; gdth_polling = TRUE; - while (gdth_test_busy(hanum)) + while (gdth_test_busy(ha)) gdth_delay(0); - gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, + gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESET_BUS, BUS_L2P(ha,b), 0, 0); gdth_polling = FALSE; spin_unlock_irqrestore(&ha->smp_lock, flags); @@ -4164,18 +4109,15 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) { unchar b, t; - int hanum; - gdth_ha_str *ha; + gdth_ha_str *ha = shost_priv(sdev->host); struct scsi_device *sd; unsigned capacity; sd = sdev; capacity = cap; - hanum = NUMDATA(sd->host)->hanum; b = sd->channel; t = sd->id; - TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", ha->hanum, b, t)); if (b != ha->virt_bus || ha->hdr[t].heads == 0) { /* raw device or host drive without mapping information */ @@ -4196,7 +4138,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se static int gdth_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { - int hanum; + gdth_ha_str *ha = shost_priv(scp->device->host); int priority; TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); @@ -4208,7 +4150,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, scp->SCp.Status = GDTH_MAP_NONE; scp->SCp.buffer = (struct scatterlist *)NULL; - hanum = NUMDATA(scp->device->host)->hanum; #ifdef GDTH_STATISTICS ++act_ios; #endif @@ -4217,10 +4158,10 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, if (IS_GDTH_INTERNAL_CMD(scp)) priority = scp->SCp.this_residual; else - gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); + gdth_update_timeout(scp, scp->timeout_per_command * 6); - gdth_putq( hanum, scp, priority ); - gdth_next( hanum ); + gdth_putq(ha, scp, priority); + gdth_next(ha); return 0; } @@ -4231,7 +4172,7 @@ static int gdth_open(struct inode *inode, struct file *filep) int i; for (i = 0; i < gdth_ctr_count; i++) { - ha = HADATA(gdth_ctr_tab[i]); + ha = shost_priv(gdth_ctr_tab[i]); if (!ha->sdev) ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); } @@ -4255,7 +4196,7 @@ static int ioc_event(void __user *arg) if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) || evt.ionode >= gdth_ctr_count) return -EFAULT; - ha = HADATA(gdth_ctr_tab[evt.ionode]); + ha = shost_priv(gdth_ctr_tab[evt.ionode]); if (evt.erase == 0xff) { if (evt.event.event_source == ES_TEST) @@ -4292,7 +4233,7 @@ static int ioc_lockdrv(void __user *arg) if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) || ldrv.ionode >= gdth_ctr_count) return -EFAULT; - ha = HADATA(gdth_ctr_tab[ldrv.ionode]); + ha = shost_priv(gdth_ctr_tab[ldrv.ionode]); for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { j = ldrv.drives[i]; @@ -4302,14 +4243,14 @@ static int ioc_lockdrv(void __user *arg) spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[j].lock = 1; spin_unlock_irqrestore(&ha->smp_lock, flags); - gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); - gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); + gdth_wait_completion(ha, ha->bus_cnt, j); + gdth_stop_timeout(ha, ha->bus_cnt, j); } else { spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[j].lock = 0; spin_unlock_irqrestore(&ha->smp_lock, flags); - gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); - gdth_next(ldrv.ionode); + gdth_start_timeout(ha, ha->bus_cnt, j); + gdth_next(ha); } } return 0; @@ -4319,16 +4260,14 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) { gdth_ioctl_reset res; gdth_cmd_str cmd; - int hanum; gdth_ha_str *ha; int rval; if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) return -EFAULT; - hanum = res.ionode; - ha = HADATA(gdth_ctr_tab[hanum]); - + ha = shost_priv(gdth_ctr_tab[res.ionode]); + if (!ha->hdr[res.number].present) return 0; memset(&cmd, 0, sizeof(gdth_cmd_str)); @@ -4354,22 +4293,20 @@ static int ioc_general(void __user *arg, char *cmnd) gdth_ioctl_general gen; char *buf = NULL; ulong64 paddr; - int hanum; gdth_ha_str *ha; int rval; if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || gen.ionode >= gdth_ctr_count) return -EFAULT; - hanum = gen.ionode; - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[gen.ionode]); if (gen.data_len + gen.sense_len != 0) { - if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, + if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, &paddr))) return -EFAULT; if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), gen.data_len + gen.sense_len)) { - gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); + gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); return -EFAULT; } @@ -4443,7 +4380,7 @@ static int ioc_general(void __user *arg, char *cmnd) gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; } } else { - gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); + gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); return -EFAULT; } } @@ -4455,15 +4392,15 @@ static int ioc_general(void __user *arg, char *cmnd) if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, gen.data_len + gen.sense_len)) { - gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); + gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); return -EFAULT; } if (copy_to_user(arg, &gen, sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { - gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); + gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); return -EFAULT; } - gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); + gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); return 0; } @@ -4473,7 +4410,7 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) gdth_cmd_str *cmd; gdth_ha_str *ha; unchar i; - int hanum, rc = -ENOMEM; + int rc = -ENOMEM; u32 cluster_type = 0; rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); @@ -4486,8 +4423,7 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) rc = -EFAULT; goto free_fail; } - hanum = rsc->ionode; - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[rsc->ionode]); memset(cmd, 0, sizeof(gdth_cmd_str)); for (i = 0; i < MAX_HDRIVES; ++i) { @@ -4528,7 +4464,7 @@ static int ioc_rescan(void __user *arg, char *cmnd) gdth_cmd_str *cmd; ushort i, status, hdr_cnt; ulong32 info; - int hanum, cyls, hds, secs; + int cyls, hds, secs; int rc = -ENOMEM; ulong flags; gdth_ha_str *ha; @@ -4543,8 +4479,7 @@ static int ioc_rescan(void __user *arg, char *cmnd) rc = -EFAULT; goto free_fail; } - hanum = rsc->ionode; - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[rsc->ionode]); memset(cmd, 0, sizeof(gdth_cmd_str)); if (rsc->flag == 0) { @@ -4703,7 +4638,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || ctrt.ionode >= gdth_ctr_count) return -EFAULT; - ha = HADATA(gdth_ctr_tab[ctrt.ionode]); + ha = shost_priv(gdth_ctr_tab[ctrt.ionode]); if (ha->type == GDT_ISA || ha->type == GDT_EISA) { ctrt.type = (unchar)((ha->stype>>20) - 0x10); } else { @@ -4744,7 +4679,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || lchn.ionode >= gdth_ctr_count) return -EFAULT; - ha = HADATA(gdth_ctr_tab[lchn.ionode]); + ha = shost_priv(gdth_ctr_tab[lchn.ionode]); i = lchn.channel; if (i < ha->bus_cnt) { @@ -4753,16 +4688,16 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, ha->raw[i].lock = 1; spin_unlock_irqrestore(&ha->smp_lock, flags); for (j = 0; j < ha->tid_cnt; ++j) { - gdth_wait_completion(lchn.ionode, i, j); - gdth_stop_timeout(lchn.ionode, i, j); + gdth_wait_completion(ha, i, j); + gdth_stop_timeout(ha, i, j); } } else { spin_lock_irqsave(&ha->smp_lock, flags); ha->raw[i].lock = 0; spin_unlock_irqrestore(&ha->smp_lock, flags); for (j = 0; j < ha->tid_cnt; ++j) { - gdth_start_timeout(lchn.ionode, i, j); - gdth_next(lchn.ionode); + gdth_start_timeout(ha, i, j); + gdth_next(ha); } } } @@ -4778,13 +4713,12 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, case GDTIOCTL_RESET_BUS: { gdth_ioctl_reset res; - int hanum, rval; + int rval; if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || res.ionode >= gdth_ctr_count) return -EFAULT; - hanum = res.ionode; - ha = HADATA(gdth_ctr_tab[hanum]); + ha = shost_priv(gdth_ctr_tab[res.ionode]); scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) @@ -4813,16 +4747,14 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, /* flush routine */ -static void gdth_flush(int hanum) +static void gdth_flush(gdth_ha_str *ha) { int i; - gdth_ha_str *ha; gdth_cmd_str gdtcmd; char cmnd[MAX_COMMAND_SIZE]; memset(cmnd, 0xff, MAX_COMMAND_SIZE); - TRACE2(("gdth_flush() hanum %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE2(("gdth_flush() hanum %d\n", ha->hanum)); for (i = 0; i < MAX_HDRIVES; ++i) { if (ha->hdr[i].present) { @@ -4838,9 +4770,9 @@ static void gdth_flush(int hanum) gdtcmd.u.cache.BlockNo = 1; gdtcmd.u.cache.sg_canz = 0; } - TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); + TRACE2(("gdth_flush(): flush ha %d drive %d\n", ha->hanum, i)); - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); + gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL); } } } @@ -4864,7 +4796,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) notifier_disabled = 1; printk("GDT-HA: Flushing all host drives .. "); for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { - gdth_flush(hanum); + gdth_ha_str *ha = shost_priv(gdth_ctr_tab[hanum]); + gdth_flush(ha); #ifndef __alpha__ /* controller reset */ @@ -4872,8 +4805,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdtcmd.BoardNode = LOCALBOARD; gdtcmd.Service = CACHESERVICE; gdtcmd.OpCode = GDT_RESET; - TRACE2(("gdth_halt(): reset controller %d\n", hanum)); - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); + TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); + gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); #endif } printk("Done.\n"); @@ -4923,10 +4856,10 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) if (!gdth_search_isa(isa_bios)) return -ENXIO; - shp = scsi_register(shtp, sizeof(gdth_ext_str)); + shp = scsi_register(shtp, sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; - ha = HADATA(shp); + ha = shost_priv(shp); error = -ENODEV; if (!gdth_init_isa(isa_bios,ha)) @@ -4956,9 +4889,10 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; + ha->hanum = (ushort)hanum; + ha->shost = shp; - ha->pccb = CMDDATA(shp); + ha->pccb = &ha->cmdext; ha->ccb_phys = 0L; ha->pdev = NULL; @@ -4995,7 +4929,7 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) ha->scan_mode = rescan ? 0x10 : 0; error = -ENODEV; - if (!gdth_search_drives(hanum)) { + if (!gdth_search_drives(ha)) { printk("GDT-ISA: Error during device scan\n"); goto out_free_coal_stat; } @@ -5012,7 +4946,7 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); + gdth_enable_int(ha); return 0; @@ -5049,10 +4983,10 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, if (!gdth_search_eisa(eisa_slot)) return -ENXIO; - shp = scsi_register(shtp,sizeof(gdth_ext_str)); + shp = scsi_register(shtp,sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; - ha = HADATA(shp); + ha = shost_priv(shp); error = -ENODEV; if (!gdth_init_eisa(eisa_slot,ha)) @@ -5074,11 +5008,12 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - TRACE2(("EISA detect Bus 0: hanum %d\n", - NUMDATA(shp)->hanum)); + ha->hanum = (ushort)hanum; + ha->shost = shp; + + TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); - ha->pccb = CMDDATA(shp); + ha->pccb = &ha->cmdext; ha->ccb_phys = 0L; error = -ENOMEM; @@ -5119,7 +5054,7 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, ha->cmd_tab[i].cmnd = UNUSED_CMND; ha->scan_mode = rescan ? 0x10 : 0; - if (!gdth_search_drives(hanum)) { + if (!gdth_search_drives(ha)) { printk("GDT-EISA: Error during device scan\n"); error = -ENODEV; goto out_free_ccb_phys; @@ -5137,7 +5072,7 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); + gdth_enable_int(ha); return 0; out_free_ccb_phys: @@ -5172,10 +5107,10 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, dma_addr_t scratch_dma_handle = 0; int error, hanum, i; - shp = scsi_register(shtp,sizeof(gdth_ext_str)); + shp = scsi_register(shtp,sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; - ha = HADATA(shp); + ha = shost_priv(shp); error = -ENODEV; if (!gdth_init_pci(&pcistr[ctr],ha)) @@ -5200,9 +5135,10 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, hanum = gdth_ctr_count; gdth_ctr_tab[gdth_ctr_count++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; + ha->hanum = (ushort)hanum; + ha->shost = shp; - ha->pccb = CMDDATA(shp); + ha->pccb = &ha->cmdext; ha->ccb_phys = 0L; error = -ENOMEM; @@ -5238,8 +5174,8 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, ha->scan_mode = rescan ? 0x10 : 0; error = -ENODEV; - if (!gdth_search_drives(hanum)) { - printk("GDT-PCI %d: Error during device scan\n", hanum); + if (!gdth_search_drives(ha)) { + printk("GDT-PCI %d: Error during device scan\n", ha->hanum); goto out_free_coal_stat; } @@ -5252,16 +5188,16 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, !ha->dma64_support) { if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "GDT-PCI %d: " - "Unable to set 32-bit DMA\n", hanum); + "Unable to set 32-bit DMA\n", ha->hanum); goto out_free_coal_stat; } } else { shp->max_cmd_len = 16; if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { - printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); + printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "GDT-PCI %d: " - "Unable to set 64/32-bit DMA\n", hanum); + "Unable to set 64/32-bit DMA\n", ha->hanum); goto out_free_coal_stat; } } @@ -5271,7 +5207,7 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, shp->max_channel = ha->bus_cnt; spin_lock_init(&ha->smp_lock); - gdth_enable_int(hanum); + gdth_enable_int(ha); return 0; out_free_coal_stat: diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 6884587..e8b9eb7 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -853,6 +853,8 @@ typedef struct { /* controller information structure */ typedef struct { + struct Scsi_Host *shost; + ushort hanum; ushort oem_id; /* OEM */ ushort type; /* controller class */ ulong32 stype; /* subtype (PCI: device ID) */ @@ -864,6 +866,7 @@ typedef struct { void __iomem *brd; /* DPRAM address */ ulong32 brd_phys; /* slot number/BIOS address */ gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ + gdth_cmd_str cmdext; gdth_cmd_str *pccb; /* address command structure */ ulong32 ccb_phys; /* phys. address */ #ifdef INT_COAL @@ -937,20 +940,6 @@ typedef struct { struct scsi_device *sdev; } gdth_ha_str; -/* structure for scsi_register(), SCSI bus != 0 */ -typedef struct { - ushort hanum; - ushort busnum; -} gdth_num_str; - -/* structure for scsi_register() */ -typedef struct { - gdth_num_str numext; /* must be the first element */ - gdth_ha_str haext; - gdth_cmd_str cmdext; -} gdth_ext_str; - - /* INQUIRY data format */ typedef struct { unchar type_qual; diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index b060bd6..fe070ab 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -7,31 +7,29 @@ int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, int inout) { - int hanum; + gdth_ha_str *ha = shost_priv(host); TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", length,(int)offset,inout)); - hanum = NUMDATA(host)->hanum; - if (inout) - return(gdth_set_info(buffer,length,host,hanum)); + return(gdth_set_info(buffer,length,host,ha)); else - return(gdth_get_info(buffer,start,offset,length,host,hanum)); + return(gdth_get_info(buffer,start,offset,length,host,ha)); } static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - int hanum) + gdth_ha_str *ha) { int ret_val = -EINVAL; - TRACE2(("gdth_set_info() ha %d\n",hanum,)); + TRACE2(("gdth_set_info() ha %d\n",ha->hanum,)); if (length >= 4) { if (strncmp(buffer,"gdth",4) == 0) { buffer += 5; length -= 5; - ret_val = gdth_set_asc_info(host, buffer, length, hanum); + ret_val = gdth_set_asc_info(host, buffer, length, ha); } } @@ -39,11 +37,10 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, } static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length,int hanum) + int length, gdth_ha_str *ha) { int orig_length, drive, wb_mode; int i, found; - gdth_ha_str *ha; gdth_cmd_str gdtcmd; gdth_cpar_str *pcpar; ulong64 paddr; @@ -52,8 +49,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, memset(cmnd, 0xff, 12); memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); - TRACE2(("gdth_set_asc_info() ha %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum)); orig_length = length + 5; drive = -1; wb_mode = 0; @@ -129,7 +125,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, } if (wb_mode) { - if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE, &paddr)) + if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr)) return(-EBUSY); pcpar = (gdth_cpar_str *)ha->pscratch; memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); @@ -143,7 +139,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, gdth_execute(host, &gdtcmd, cmnd, 30, NULL); - gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr); + gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr); printk("Done.\n"); return(orig_length); } @@ -153,11 +149,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, } static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host,int hanum) + struct Scsi_Host *host, gdth_ha_str *ha) { int size = 0,len = 0; off_t begin = 0,pos = 0; - gdth_ha_str *ha; int id, i, j, k, sec, flag; int no_mdrv = 0, drv_no, is_mirr; ulong32 cnt; @@ -186,8 +181,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, memset(cmnd, 0xff, 12); memset(gdtcmd, 0, sizeof(gdth_cmd_str)); - TRACE2(("gdth_get_info() ha %d\n",hanum)); - ha = HADATA(gdth_ctr_tab[hanum]); + TRACE2(("gdth_get_info() ha %d\n",ha->hanum)); /* request is i.e. "cat /proc/scsi/gdth/0" */ @@ -220,7 +214,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, strcpy(hrec, ha->binfo.type_string); size = sprintf(buffer+len, " Number: \t%d \tName: \t%s\n", - hanum, hrec); + ha->hanum, hrec); len += size; pos = begin + len; if (ha->more_proc) @@ -270,7 +264,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, len += size; pos = begin + len; flag = FALSE; - buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); + buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); if (!buf) goto stop_output; for (i = 0; i < ha->bus_cnt; ++i) { @@ -373,7 +367,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, goto stop_output; } } - gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); + gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); if (!flag) { size = sprintf(buffer+len, "\n --\n"); @@ -385,7 +379,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, len += size; pos = begin + len; flag = FALSE; - buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); + buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); if (!buf) goto stop_output; for (i = 0; i < MAX_LDRIVES; ++i) { @@ -479,7 +473,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, if (pos > offset + length) goto stop_output; } - gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); + gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); if (!flag) { size = sprintf(buffer+len, "\n --\n"); @@ -491,7 +485,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, len += size; pos = begin + len; flag = FALSE; - buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); + buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); if (!buf) goto stop_output; for (i = 0; i < MAX_LDRIVES; ++i) { @@ -550,7 +544,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, goto stop_output; } } - gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); + gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); if (!flag) { size = sprintf(buffer+len, "\n --\n"); @@ -562,7 +556,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, len += size; pos = begin + len; flag = FALSE; - buf = gdth_ioctl_alloc(hanum, sizeof(gdth_hget_str), FALSE, &paddr); + buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr); if (!buf) goto stop_output; for (i = 0; i < MAX_LDRIVES; ++i) { @@ -595,7 +589,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, } } } - gdth_ioctl_free(hanum, sizeof(gdth_hget_str), buf, paddr); + gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr); for (i = 0; i < MAX_HDRIVES; ++i) { if (!(ha->hdr[i].present)) @@ -633,7 +627,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, id = gdth_read_event(ha, id, estr); if (estr->event_source == 0) break; - if (estr->event_data.eu.driver.ionode == hanum && + if (estr->event_data.eu.driver.ionode == ha->hanum && estr->event_source == ES_ASYNC) { gdth_log_event(&estr->event_data, hrec); do_gettimeofday(&tv); @@ -668,17 +662,15 @@ free_fail: return rc; } -static char *gdth_ioctl_alloc(int hanum, int size, int scratch, +static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, ulong64 *paddr) { - gdth_ha_str *ha; ulong flags; char *ret_val; if (size == 0) return NULL; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); if (!ha->scratch_busy && size <= GDTH_SCRATCH) { @@ -698,12 +690,10 @@ static char *gdth_ioctl_alloc(int hanum, int size, int scratch, return ret_val; } -static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) +static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr) { - gdth_ha_str *ha; ulong flags; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); if (buf == ha->pscratch) { @@ -716,13 +706,11 @@ static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) } #ifdef GDTH_IOCTL_PROC -static int gdth_ioctl_check_bin(int hanum, ushort size) +static int gdth_ioctl_check_bin(gdth_ha_str *ha, ushort size) { - gdth_ha_str *ha; ulong flags; int ret_val; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); ret_val = FALSE; @@ -735,15 +723,13 @@ static int gdth_ioctl_check_bin(int hanum, ushort size) } #endif -static void gdth_wait_completion(int hanum, int busnum, int id) +static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id) { - gdth_ha_str *ha; ulong flags; int i; Scsi_Cmnd *scp; unchar b, t; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); for (i = 0; i < GDTH_MAXCMDS; ++i) { @@ -763,14 +749,12 @@ static void gdth_wait_completion(int hanum, int busnum, int id) spin_unlock_irqrestore(&ha->smp_lock, flags); } -static void gdth_stop_timeout(int hanum, int busnum, int id) +static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id) { - gdth_ha_str *ha; ulong flags; Scsi_Cmnd *scp; unchar b, t; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { @@ -779,21 +763,19 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); + scp->SCp.buffers_residual = gdth_update_timeout(scp, 0); } } } spin_unlock_irqrestore(&ha->smp_lock, flags); } -static void gdth_start_timeout(int hanum, int busnum, int id) +static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id) { - gdth_ha_str *ha; ulong flags; Scsi_Cmnd *scp; unchar b, t; - ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { @@ -802,14 +784,14 @@ static void gdth_start_timeout(int hanum, int busnum, int id) t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_start_timeout(): update_timeout()\n")); - gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); + gdth_update_timeout(scp, scp->SCp.buffers_residual); } } } spin_unlock_irqrestore(&ha->smp_lock, flags); } -static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout) +static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout) { int oldto; diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h index dd71777..45e6fda 100644 --- a/drivers/scsi/gdth_proc.h +++ b/drivers/scsi/gdth_proc.h @@ -9,20 +9,20 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info); static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, - int hanum); + gdth_ha_str *ha); static int gdth_get_info(char *buffer,char **start,off_t offset,int length, - struct Scsi_Host *host,int hanum); + struct Scsi_Host *host, gdth_ha_str *ha); static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length, int hanum); + int length, gdth_ha_str *ha); -static char *gdth_ioctl_alloc(int hanum, int size, int scratch, - ulong64 *paddr); -static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr); -static void gdth_wait_completion(int hanum, int busnum, int id); -static void gdth_stop_timeout(int hanum, int busnum, int id); -static void gdth_start_timeout(int hanum, int busnum, int id); -static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout); +static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, + ulong64 *paddr); +static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr); +static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id); +static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id); +static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id); +static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout); #endif -- cgit v1.1 From 10e1b4bc9238687a4b1311bd5b6769d6b8c704e6 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:08:10 +0200 Subject: [SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes - gdth_get_status() returns a single device interrupt IStatus - gdth_interrupt split to __gdth_interrupt() that receives flags if is called from gdth_wait(). - Use dev_id passed from kernel and do not loop on all controllers. - gdth_wait(), get read of all global variables and call the new __gdth_interrupt with these variables on the stack Signed-off-by Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 93 +++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index c90e407..ef67e66 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -139,6 +139,8 @@ static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); static irqreturn_t gdth_interrupt(int irq, void *dev_id); +static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, + int gdth_from_wait, int* pIndex); static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, Scsi_Cmnd *scp); static int gdth_async_event(gdth_ha_str *ha); @@ -161,7 +163,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); static void gdth_enable_int(gdth_ha_str *ha); -static int gdth_get_status(unchar *pIStatus,int irq); +static unchar gdth_get_status(gdth_ha_str *ha, int irq); static int gdth_test_busy(gdth_ha_str *ha); static int gdth_get_cmd_index(gdth_ha_str *ha); static void gdth_release_event(gdth_ha_str *ha); @@ -295,8 +297,6 @@ static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ #endif static unchar gdth_polling; /* polling if TRUE */ -static unchar gdth_from_wait = FALSE; /* gdth_wait() */ -static int wait_index,wait_hanum; /* gdth_wait() */ static int gdth_ctr_count = 0; /* controller count */ static int gdth_ctr_released = 0; /* gdth_release() */ static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ @@ -1245,41 +1245,32 @@ static void __init gdth_enable_int(gdth_ha_str *ha) spin_unlock_irqrestore(&ha->smp_lock, flags); } - -static int gdth_get_status(unchar *pIStatus,int irq) +/* return IStatus if interrupt was from this card else 0 */ +static unchar gdth_get_status(gdth_ha_str *ha, int irq) { - register gdth_ha_str *ha; - int i; + unchar IStatus = 0; + + TRACE(("gdth_get_status() irq %d ctr_count %d\n", irq, gdth_ctr_count)); - TRACE(("gdth_get_status() irq %d ctr_count %d\n", - irq,gdth_ctr_count)); - - *pIStatus = 0; - for (i=0; iirq != (unchar)irq) /* check IRQ */ - continue; + return false; if (ha->type == GDT_EISA) - *pIStatus = inb((ushort)ha->bmic + EDOORREG); + IStatus = inb((ushort)ha->bmic + EDOORREG); else if (ha->type == GDT_ISA) - *pIStatus = + IStatus = readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCI) - *pIStatus = + IStatus = readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCINEW) - *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); + IStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); else if (ha->type == GDT_PCIMPR) - *pIStatus = + IStatus = readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); - - if (*pIStatus) - return i; /* board found */ - } - return -1; + + return IStatus; } - - + static int gdth_test_busy(gdth_ha_str *ha) { register int gdtsema0 = 0; @@ -1436,22 +1427,21 @@ static void gdth_release_event(gdth_ha_str *ha) static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time) { int answer_found = FALSE; + int wait_index = 0; TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); if (index == 0) return 1; /* no wait required */ - gdth_from_wait = TRUE; do { - gdth_interrupt((int)ha->irq,ha); - if (wait_hanum==ha->hanum && wait_index==index) { + __gdth_interrupt(ha, (int)ha->irq, true, &wait_index); + if (wait_index == index) { answer_found = TRUE; break; } gdth_delay(1); } while (--time); - gdth_from_wait = FALSE; while (gdth_test_busy(ha)) gdth_delay(0); @@ -3010,15 +3000,14 @@ static void gdth_clear_events(void) /* SCSI interface functions */ -static irqreturn_t gdth_interrupt(int irq,void *dev_id) +static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, + int gdth_from_wait, int* pIndex) { - gdth_ha_str *ha2 = (gdth_ha_str *)dev_id; - register gdth_ha_str *ha; gdt6m_dpram_str __iomem *dp6m_ptr = NULL; gdt6_dpram_str __iomem *dp6_ptr; gdt2_dpram_str __iomem *dp2_ptr; Scsi_Cmnd *scp; - int hanum, rval, i; + int rval, i; unchar IStatus; ushort Service; ulong flags = 0; @@ -3039,17 +3028,15 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) } if (!gdth_polling) - spin_lock_irqsave(&ha2->smp_lock, flags); - wait_index = 0; + spin_lock_irqsave(&ha->smp_lock, flags); /* search controller */ - if ((hanum = gdth_get_status(&IStatus,irq)) == -1) { + if (0 == (IStatus = gdth_get_status(ha, irq))) { /* spurious interrupt */ if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); - return IRQ_HANDLED; + spin_unlock_irqrestore(&ha->smp_lock, flags); + return IRQ_HANDLED; } - ha = shost_priv(gdth_ctr_tab[hanum]); #ifdef GDTH_STATISTICS ++act_ints; @@ -3181,7 +3168,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) } else { TRACE2(("gdth_interrupt() unknown controller type\n")); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return IRQ_HANDLED; } @@ -3189,15 +3176,14 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) IStatus,ha->status,ha->info)); if (gdth_from_wait) { - wait_hanum = hanum; - wait_index = (int)IStatus; + *pIndex = (int)IStatus; } if (IStatus == ASYNCINDEX) { TRACE2(("gdth_interrupt() async. event\n")); gdth_async_event(ha); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); gdth_next(ha); return IRQ_HANDLED; } @@ -3205,10 +3191,10 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (IStatus == SPEZINDEX) { TRACE2(("Service unknown or not initialized !\n")); ha->dvr.size = sizeof(ha->dvr.eu.driver); - ha->dvr.eu.driver.ionode = hanum; + ha->dvr.eu.driver.ionode = ha->hanum; gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return IRQ_HANDLED; } scp = ha->cmd_tab[IStatus-2].cmnd; @@ -3217,24 +3203,24 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) if (scp == UNUSED_CMND) { TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); ha->dvr.size = sizeof(ha->dvr.eu.driver); - ha->dvr.eu.driver.ionode = hanum; + ha->dvr.eu.driver.ionode = ha->hanum; ha->dvr.eu.driver.index = IStatus; gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return IRQ_HANDLED; } if (scp == INTERNAL_CMND) { TRACE(("gdth_interrupt() answer to internal command\n")); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return IRQ_HANDLED; } TRACE(("gdth_interrupt() sync. status\n")); rval = gdth_sync_event(ha,Service,IStatus,scp); if (!gdth_polling) - spin_unlock_irqrestore(&ha2->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); if (rval == 2) { gdth_putq(ha, scp,scp->SCp.this_residual); } else if (rval == 1) { @@ -3270,6 +3256,13 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) return IRQ_HANDLED; } +static irqreturn_t gdth_interrupt(int irq, void *dev_id) +{ + gdth_ha_str *ha = (gdth_ha_str *)dev_id; + + return __gdth_interrupt(ha, irq, false, NULL); +} + static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, Scsi_Cmnd *scp) { -- cgit v1.1 From 835cc24aff0fd4b9da9d0a45d9bd043adcb2cf89 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 2 Oct 2007 23:09:56 +0200 Subject: [SCSI] gdth: switch to modern scsi host registration - Use scsi_add_host and friends and track instances ourselves. And generally modernize the driver's structure. - TODO: Next we can remove the controller table - TODO: Fix use of deprecated pci_find_device() Signed-off-by: Christoph Hellwig Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 320 +++++++++++++++++++++++++--------------------------- drivers/scsi/gdth.h | 1 + 2 files changed, 157 insertions(+), 164 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index ef67e66..11796e6 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -119,6 +119,7 @@ #include #include #include +#include #ifdef GDTH_RTC #include @@ -184,15 +185,6 @@ static void gdth_flush(gdth_ha_str *ha); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); static void gdth_scsi_done(struct scsi_cmnd *scp); -#ifdef CONFIG_ISA -static int gdth_isa_probe_one(struct scsi_host_template *, ulong32); -#endif -#ifdef CONFIG_EISA -static int gdth_eisa_probe_one(struct scsi_host_template *, ushort); -#endif -#ifdef CONFIG_PCI -static int gdth_pci_probe_one(struct scsi_host_template *, gdth_pci_str *, int); -#endif #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -298,8 +290,8 @@ static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ #endif static unchar gdth_polling; /* polling if TRUE */ static int gdth_ctr_count = 0; /* controller count */ -static int gdth_ctr_released = 0; /* gdth_release() */ static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ +static LIST_HEAD(gdth_instances); static unchar gdth_write_through = FALSE; /* write through */ static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ static int elastidx; @@ -3872,145 +3864,6 @@ int __init option_setup(char *str) return 1; } -static int __init gdth_detect(struct scsi_host_template *shtp) -{ -#ifdef DEBUG_GDTH - printk("GDT: This driver contains debugging information !! Trace level = %d\n", - DebugState); - printk(" Destination of debugging information: "); -#ifdef __SERIAL__ -#ifdef __COM2__ - printk("Serial port COM2\n"); -#else - printk("Serial port COM1\n"); -#endif -#else - printk("Console\n"); -#endif - gdth_delay(3000); -#endif - - TRACE(("gdth_detect()\n")); - - if (disable) { - printk("GDT-HA: Controller driver disabled from command line !\n"); - return 0; - } - - printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); - /* initializations */ - gdth_polling = TRUE; - gdth_clear_events(); - - /* As default we do not probe for EISA or ISA controllers */ - if (probe_eisa_isa) { - /* scanning for controllers, at first: ISA controller */ -#ifdef CONFIG_ISA - ulong32 isa_bios; - for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; - isa_bios += 0x8000UL) { - if (gdth_ctr_count >= MAXHA) - break; - gdth_isa_probe_one(shtp, isa_bios); - } -#endif -#ifdef CONFIG_EISA - { - ushort eisa_slot; - for (eisa_slot = 0x1000; eisa_slot <= 0x8000; eisa_slot += 0x1000) { - if (gdth_ctr_count >= MAXHA) - break; - gdth_eisa_probe_one(shtp, eisa_slot); - } - } -#endif - } - -#ifdef CONFIG_PCI - /* scanning for PCI controllers */ - { - gdth_pci_str pcistr[MAXHA]; - int cnt,ctr; - - cnt = gdth_search_pci(pcistr); - printk("GDT-HA: Found %d PCI Storage RAID Controllers\n",cnt); - gdth_sort_pci(pcistr,cnt); - for (ctr = 0; ctr < cnt; ++ctr) { - if (gdth_ctr_count >= MAXHA) - break; - gdth_pci_probe_one(shtp, pcistr, ctr); - } - } -#endif /* CONFIG_PCI */ - - TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count)); - if (gdth_ctr_count > 0) { -#ifdef GDTH_STATISTICS - TRACE2(("gdth_detect(): Initializing timer !\n")); - init_timer(&gdth_timer); - gdth_timer.expires = jiffies + HZ; - gdth_timer.data = 0L; - gdth_timer.function = gdth_timeout; - add_timer(&gdth_timer); -#endif - major = register_chrdev(0,"gdth",&gdth_fops); - notifier_disabled = 0; - register_reboot_notifier(&gdth_notifier); - } - gdth_polling = FALSE; - return gdth_ctr_count; -} - -static int gdth_release(struct Scsi_Host *shp) -{ - gdth_ha_str *ha = shost_priv(shp); - - TRACE2(("gdth_release()\n")); - if (ha->sdev) { - scsi_free_host_dev(ha->sdev); - ha->sdev = NULL; - } - gdth_flush(ha); - - if (shp->irq) { - free_irq(shp->irq,ha); - } -#ifdef CONFIG_ISA - if (shp->dma_channel != 0xff) { - free_dma(shp->dma_channel); - } -#endif -#ifdef INT_COAL - if (ha->coal_stat) - pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * - MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); -#endif - if (ha->pscratch) - pci_free_consistent(ha->pdev, GDTH_SCRATCH, - ha->pscratch, ha->scratch_phys); - if (ha->pmsg) - pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), - ha->pmsg, ha->msg_phys); - if (ha->ccb_phys) - pci_unmap_single(ha->pdev,ha->ccb_phys, - sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); - gdth_ctr_released++; - TRACE2(("gdth_release(): HA %d of %d\n", - gdth_ctr_released, gdth_ctr_count)); - - if (gdth_ctr_released == gdth_ctr_count) { -#ifdef GDTH_STATISTICS - del_timer(&gdth_timer); -#endif - unregister_chrdev(major,"gdth"); - unregister_reboot_notifier(&gdth_notifier); - } - - scsi_unregister(shp); - return 0; -} - - static const char *gdth_ctr_name(gdth_ha_str *ha) { TRACE2(("gdth_ctr_name()\n")); @@ -4819,10 +4672,8 @@ static int gdth_slave_configure(struct scsi_device *sdev) return 0; } -static struct scsi_host_template driver_template = { +static struct scsi_host_template gdth_template = { .name = "GDT SCSI Disk Array Controller", - .detect = gdth_detect, - .release = gdth_release, .info = gdth_info, .queuecommand = gdth_queuecommand, .eh_bus_reset_handler = gdth_eh_bus_reset, @@ -4839,7 +4690,7 @@ static struct scsi_host_template driver_template = { }; #ifdef CONFIG_ISA -static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) +static int gdth_isa_probe_one(ulong32 isa_bios) { struct Scsi_Host *shp; gdth_ha_str *ha; @@ -4849,7 +4700,7 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) if (!gdth_search_isa(isa_bios)) return -ENXIO; - shp = scsi_register(shtp, sizeof(gdth_ha_str)); + shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; ha = shost_priv(shp); @@ -4941,6 +4792,10 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) spin_lock_init(&ha->smp_lock); gdth_enable_int(ha); + error = scsi_add_host(shp, NULL); + if (error) + goto out_free_coal_stat; + list_add_tail(&ha->list, &gdth_instances); return 0; out_free_coal_stat: @@ -4959,14 +4814,13 @@ static int gdth_isa_probe_one(struct scsi_host_template *shtp, ulong32 isa_bios) out_free_irq: free_irq(ha->irq, ha); out_host_put: - scsi_unregister(shp); + scsi_host_put(shp); return error; } #endif /* CONFIG_ISA */ #ifdef CONFIG_EISA -static int gdth_eisa_probe_one(struct scsi_host_template *shtp, - ushort eisa_slot) +static int gdth_eisa_probe_one(ushort eisa_slot) { struct Scsi_Host *shp; gdth_ha_str *ha; @@ -4976,7 +4830,7 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, if (!gdth_search_eisa(eisa_slot)) return -ENXIO; - shp = scsi_register(shtp,sizeof(gdth_ha_str)); + shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; ha = shost_priv(shp); @@ -5066,6 +4920,11 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, spin_lock_init(&ha->smp_lock); gdth_enable_int(ha); + + error = scsi_add_host(shp, NULL); + if (error) + goto out_free_coal_stat; + list_add_tail(&ha->list, &gdth_instances); return 0; out_free_ccb_phys: @@ -5086,21 +4945,20 @@ static int gdth_eisa_probe_one(struct scsi_host_template *shtp, free_irq(ha->irq, ha); gdth_ctr_count--; out_host_put: - scsi_unregister(shp); + scsi_host_put(shp); return error; } #endif /* CONFIG_EISA */ #ifdef CONFIG_PCI -static int gdth_pci_probe_one(struct scsi_host_template *shtp, - gdth_pci_str *pcistr, int ctr) +static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) { struct Scsi_Host *shp; gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; int error, hanum, i; - shp = scsi_register(shtp,sizeof(gdth_ha_str)); + shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); if (!shp) return -ENOMEM; ha = shost_priv(shp); @@ -5201,6 +5059,11 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, spin_lock_init(&ha->smp_lock); gdth_enable_int(ha); + + error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); + if (error) + goto out_free_coal_stat; + list_add_tail(&ha->list, &gdth_instances); return 0; out_free_coal_stat: @@ -5218,12 +5081,141 @@ static int gdth_pci_probe_one(struct scsi_host_template *shtp, free_irq(ha->irq, ha); gdth_ctr_count--; out_host_put: - scsi_unregister(shp); + scsi_host_put(shp); return error; } #endif /* CONFIG_PCI */ -#include "scsi_module.c" +static void gdth_remove_one(gdth_ha_str *ha) +{ + struct Scsi_Host *shp = ha->shost; + + TRACE2(("gdth_remove_one()\n")); + + scsi_remove_host(shp); + + if (ha->sdev) { + scsi_free_host_dev(ha->sdev); + ha->sdev = NULL; + } + + gdth_flush(ha); + + if (shp->irq) + free_irq(shp->irq,ha); + +#ifdef CONFIG_ISA + if (shp->dma_channel != 0xff) + free_dma(shp->dma_channel); +#endif +#ifdef INT_COAL + if (ha->coal_stat) + pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * + MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); +#endif + if (ha->pscratch) + pci_free_consistent(ha->pdev, GDTH_SCRATCH, + ha->pscratch, ha->scratch_phys); + if (ha->pmsg) + pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), + ha->pmsg, ha->msg_phys); + if (ha->ccb_phys) + pci_unmap_single(ha->pdev,ha->ccb_phys, + sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); + + scsi_host_put(shp); +} + +static int __init gdth_init(void) +{ + if (disable) { + printk("GDT-HA: Controller driver disabled from" + " command line !\n"); + return 0; + } + + printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n", + GDTH_VERSION_STR); + + /* initializations */ + gdth_polling = TRUE; + gdth_clear_events(); + + /* As default we do not probe for EISA or ISA controllers */ + if (probe_eisa_isa) { + /* scanning for controllers, at first: ISA controller */ +#ifdef CONFIG_ISA + ulong32 isa_bios; + for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; + isa_bios += 0x8000UL) { + if (gdth_ctr_count >= MAXHA) + break; + gdth_isa_probe_one(isa_bios); + } +#endif +#ifdef CONFIG_EISA + { + ushort eisa_slot; + for (eisa_slot = 0x1000; eisa_slot <= 0x8000; + eisa_slot += 0x1000) { + if (gdth_ctr_count >= MAXHA) + break; + gdth_eisa_probe_one(eisa_slot); + } + } +#endif + } + +#ifdef CONFIG_PCI + /* scanning for PCI controllers */ + { + gdth_pci_str pcistr[MAXHA]; + int cnt,ctr; + + cnt = gdth_search_pci(pcistr); + printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); + gdth_sort_pci(pcistr,cnt); + for (ctr = 0; ctr < cnt; ++ctr) { + if (gdth_ctr_count >= MAXHA) + break; + gdth_pci_probe_one(pcistr, ctr); + } + } +#endif /* CONFIG_PCI */ + + TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); +#ifdef GDTH_STATISTICS + TRACE2(("gdth_detect(): Initializing timer !\n")); + init_timer(&gdth_timer); + gdth_timer.expires = jiffies + HZ; + gdth_timer.data = 0L; + gdth_timer.function = gdth_timeout; + add_timer(&gdth_timer); +#endif + major = register_chrdev(0,"gdth", &gdth_fops); + notifier_disabled = 0; + register_reboot_notifier(&gdth_notifier); + gdth_polling = FALSE; + return 0; +} + +static void __exit gdth_exit(void) +{ + gdth_ha_str *ha; + + list_for_each_entry(ha, &gdth_instances, list) + gdth_remove_one(ha); + +#ifdef GDTH_STATISTICS + del_timer(&gdth_timer); +#endif + unregister_chrdev(major,"gdth"); + unregister_reboot_notifier(&gdth_notifier); +} + +module_init(gdth_init); +module_exit(gdth_exit); + #ifndef MODULE __setup("gdth=", option_setup); #endif diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index e8b9eb7..e6178c4 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -854,6 +854,7 @@ typedef struct { /* controller information structure */ typedef struct { struct Scsi_Host *shost; + struct list_head list; ushort hanum; ushort oem_id; /* OEM */ ushort type; /* controller class */ -- cgit v1.1 From 884f7fba09646714f94d945162e698f0822a6fdd Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:11:24 +0200 Subject: [SCSI] gdth: Remove gdth_ctr_tab[] - Places like Initialization and Reset that Just loop on all devices can use the link list with the list_for_each_entry macro. But the io_ctrl from user mode now suffers performance-wise because code has to do a sequential search for the requested host number. I have isolated this search in a gdth_find_ha(int hanum) member for future enhancement if needed. Signed-off-by Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 109 ++++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 58 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 11796e6..4248b04 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -290,8 +290,7 @@ static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ #endif static unchar gdth_polling; /* polling if TRUE */ static int gdth_ctr_count = 0; /* controller count */ -static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ -static LIST_HEAD(gdth_instances); +static LIST_HEAD(gdth_instances); /* controller list */ static unchar gdth_write_through = FALSE; /* write through */ static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ static int elastidx; @@ -384,6 +383,17 @@ static struct notifier_block gdth_notifier = { }; static int notifier_disabled = 0; +static gdth_ha_str *gdth_find_ha(int hanum) +{ + gdth_ha_str *ha; + + list_for_each_entry(ha, &gdth_instances, list) + if (hanum == ha->hanum) + return ha; + + return NULL; +} + static void gdth_delay(int milliseconds) { if (milliseconds == 0) { @@ -3755,7 +3765,7 @@ static void gdth_timeout(ulong data) gdth_ha_str *ha; ulong flags; - ha = shost_priv(gdth_ctr_tab[0]); + ha = list_first_entry(&gdth_instances, gdth_ha_str, list); spin_lock_irqsave(&ha->smp_lock, flags); for (act_stats=0,i=0; isdev) - ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); + ha->sdev = scsi_get_host_dev(ha->shost); } TRACE(("gdth_open()\n")); @@ -4039,10 +4047,11 @@ static int ioc_event(void __user *arg) gdth_ha_str *ha; ulong flags; - if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) || - evt.ionode >= gdth_ctr_count) + if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event))) + return -EFAULT; + ha = gdth_find_ha(evt.ionode); + if (!ha) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[evt.ionode]); if (evt.erase == 0xff) { if (evt.event.event_source == ES_TEST) @@ -4076,11 +4085,12 @@ static int ioc_lockdrv(void __user *arg) ulong flags; gdth_ha_str *ha; - if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) || - ldrv.ionode >= gdth_ctr_count) + if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv))) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[ldrv.ionode]); - + ha = gdth_find_ha(ldrv.ionode); + if (!ha) + return -EFAULT; + for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { j = ldrv.drives[i]; if (j >= MAX_HDRIVES || !ha->hdr[j].present) @@ -4110,9 +4120,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) int rval; if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || - res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) + res.number >= MAX_HDRIVES) + return -EFAULT; + ha = gdth_find_ha(res.ionode); + if (!ha) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[res.ionode]); if (!ha->hdr[res.number].present) return 0; @@ -4141,11 +4153,12 @@ static int ioc_general(void __user *arg, char *cmnd) ulong64 paddr; gdth_ha_str *ha; int rval; - - if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || - gen.ionode >= gdth_ctr_count) + + if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) + return -EFAULT; + ha = gdth_find_ha(gen.ionode); + if (!ha) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[gen.ionode]); if (gen.data_len + gen.sense_len != 0) { if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, &paddr))) @@ -4265,11 +4278,10 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || - rsc->ionode >= gdth_ctr_count) { + (NULL == (ha = gdth_find_ha(rsc->ionode)))) { rc = -EFAULT; goto free_fail; } - ha = shost_priv(gdth_ctr_tab[rsc->ionode]); memset(cmd, 0, sizeof(gdth_cmd_str)); for (i = 0; i < MAX_HDRIVES; ++i) { @@ -4321,11 +4333,10 @@ static int ioc_rescan(void __user *arg, char *cmnd) goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || - rsc->ionode >= gdth_ctr_count) { + (NULL == (ha = gdth_find_ha(rsc->ionode)))) { rc = -EFAULT; goto free_fail; } - ha = shost_priv(gdth_ctr_tab[rsc->ionode]); memset(cmd, 0, sizeof(gdth_cmd_str)); if (rsc->flag == 0) { @@ -4482,9 +4493,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, gdth_ioctl_ctrtype ctrt; if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || - ctrt.ionode >= gdth_ctr_count) + (NULL == (ha = gdth_find_ha(ctrt.ionode)))) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[ctrt.ionode]); + if (ha->type == GDT_ISA || ha->type == GDT_EISA) { ctrt.type = (unchar)((ha->stype>>20) - 0x10); } else { @@ -4523,10 +4534,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, unchar i, j; if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || - lchn.ionode >= gdth_ctr_count) + (NULL == (ha = gdth_find_ha(lchn.ionode)))) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[lchn.ionode]); - + i = lchn.channel; if (i < ha->bus_cnt) { if (lchn.lock) { @@ -4562,9 +4572,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, int rval; if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || - res.ionode >= gdth_ctr_count) + (NULL == (ha = gdth_find_ha(res.ionode)))) return -EFAULT; - ha = shost_priv(gdth_ctr_tab[res.ionode]); scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) @@ -4626,7 +4635,7 @@ static void gdth_flush(gdth_ha_str *ha) /* shutdown routine */ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) { - int hanum; + gdth_ha_str *ha; #ifndef __alpha__ gdth_cmd_str gdtcmd; char cmnd[MAX_COMMAND_SIZE]; @@ -4641,8 +4650,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) notifier_disabled = 1; printk("GDT-HA: Flushing all host drives .. "); - for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { - gdth_ha_str *ha = shost_priv(gdth_ctr_tab[hanum]); + list_for_each_entry(ha, &gdth_instances, list) { gdth_flush(ha); #ifndef __alpha__ @@ -4695,7 +4703,7 @@ static int gdth_isa_probe_one(ulong32 isa_bios) struct Scsi_Host *shp; gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; - int error, hanum, i; + int error, i; if (!gdth_search_isa(isa_bios)) return -ENXIO; @@ -4730,10 +4738,8 @@ static int gdth_isa_probe_one(ulong32 isa_bios) shp->unchecked_isa_dma = 1; shp->irq = ha->irq; shp->dma_channel = ha->drq; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - ha->hanum = (ushort)hanum; + ha->hanum = gdth_ctr_count++; ha->shost = shp; ha->pccb = &ha->cmdext; @@ -4825,7 +4831,7 @@ static int gdth_eisa_probe_one(ushort eisa_slot) struct Scsi_Host *shp; gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; - int error, hanum, i; + int error, i; if (!gdth_search_eisa(eisa_slot)) return -ENXIO; @@ -4852,10 +4858,8 @@ static int gdth_eisa_probe_one(ushort eisa_slot) shp->unchecked_isa_dma = 0; shp->irq = ha->irq; shp->dma_channel = 0xff; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - ha->hanum = (ushort)hanum; + ha->hanum = gdth_ctr_count++; ha->shost = shp; TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); @@ -4956,7 +4960,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) struct Scsi_Host *shp; gdth_ha_str *ha; dma_addr_t scratch_dma_handle = 0; - int error, hanum, i; + int error, i; shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); if (!shp) @@ -4983,10 +4987,8 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) shp->unchecked_isa_dma = 0; shp->irq = ha->irq; shp->dma_channel = 0xff; - hanum = gdth_ctr_count; - gdth_ctr_tab[gdth_ctr_count++] = shp; - ha->hanum = (ushort)hanum; + ha->hanum = gdth_ctr_count++; ha->shost = shp; ha->pccb = &ha->cmdext; @@ -5147,21 +5149,15 @@ static int __init gdth_init(void) #ifdef CONFIG_ISA ulong32 isa_bios; for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; - isa_bios += 0x8000UL) { - if (gdth_ctr_count >= MAXHA) - break; + isa_bios += 0x8000UL) gdth_isa_probe_one(isa_bios); - } #endif #ifdef CONFIG_EISA { ushort eisa_slot; for (eisa_slot = 0x1000; eisa_slot <= 0x8000; - eisa_slot += 0x1000) { - if (gdth_ctr_count >= MAXHA) - break; + eisa_slot += 0x1000) gdth_eisa_probe_one(eisa_slot); - } } #endif } @@ -5175,11 +5171,8 @@ static int __init gdth_init(void) cnt = gdth_search_pci(pcistr); printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); gdth_sort_pci(pcistr,cnt); - for (ctr = 0; ctr < cnt; ++ctr) { - if (gdth_ctr_count >= MAXHA) - break; + for (ctr = 0; ctr < cnt; ++ctr) gdth_pci_probe_one(pcistr, ctr); - } } #endif /* CONFIG_PCI */ -- cgit v1.1 From 3058d5de47ce09ac0e531290566937c7d94d0653 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:14:39 +0200 Subject: [SCSI] gdth: Setup proper per-command private data - scsi_cmnd and specifically ->SCp of, where heavily abused with internal meaning members and flags. So introduce a new struct gdth_cmndinfo, put it on ->host_scribble and define a gdth_cmnd_priv() accessor to retrieve it from a scsi_cmnd. - The structure now holds two members: internal_command - replaces the IS_GDTH_INTERNAL_CMD() croft. sense_paddr - which was a 64-bit spanning on 2 32-bit members of SCp. More overloaded members from SCp and scsi_cmnd will be moved in a later patch (For easy review). - Split up gdth_queuecommand to an additional internal_function. The later is the one called by gdth_execute(). This will be more evident later in the scsi accessors patch, but it also facilitates in the differentiation between internal_command and external. And the setup of gdth_cmndinfo of each command. Signed-off-by Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 111 ++++++++++++++++++++++++++++++++--------------- drivers/scsi/gdth.h | 10 +++++ drivers/scsi/gdth_proc.c | 6 ++- 3 files changed, 91 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 4248b04..e002c39 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -86,8 +86,8 @@ /* The meaning of the Scsi_Pointer members in this driver is as follows: * ptr: Chaining * this_residual: Command priority - * buffer: phys. DMA sense buffer - * dma_handle: phys. DMA buffer (kernel >= 2.4.0) + * buffer: unused + * dma_handle: will drop in !use_sg patch. * buffers_residual: Timeout value * Status: Command status (gdth_do_cmd()), DMA mem. mappings * Message: Additional info (gdth_do_cmd()), DMA direction @@ -184,6 +184,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, static void gdth_flush(gdth_ha_str *ha); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); +static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, + struct gdth_cmndinfo *cmndinfo); static void gdth_scsi_done(struct scsi_cmnd *scp); #ifdef DEBUG_GDTH @@ -371,9 +373,6 @@ static const struct file_operations gdth_fops = { .release = gdth_close, }; -#define GDTH_MAGIC 0xc2e7c389 /* I got it from /dev/urandom */ -#define IS_GDTH_INTERNAL_CMD(scp) (scp->underflow == GDTH_MAGIC) - #include "gdth_proc.h" #include "gdth_proc.c" @@ -394,6 +393,34 @@ static gdth_ha_str *gdth_find_ha(int hanum) return NULL; } +static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) +{ + struct gdth_cmndinfo *priv = NULL; + ulong flags; + int i; + + spin_lock_irqsave(&ha->smp_lock, flags); + + for (i=0; icmndinfo[i].index == 0) { + priv = &ha->cmndinfo[i]; + priv->index = i+1; + memset(priv, 0, sizeof(*priv)); + break; + } + } + + spin_unlock_irqrestore(&ha->smp_lock, flags); + + return priv; +} + +static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) +{ + BUG_ON(!priv); + priv->index = 0; +} + static void gdth_delay(int milliseconds) { if (milliseconds == 0) { @@ -405,9 +432,15 @@ static void gdth_delay(int milliseconds) static void gdth_scsi_done(struct scsi_cmnd *scp) { + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); + int internal_command = cmndinfo->internal_command; + TRACE2(("gdth_scsi_done()\n")); - if (IS_GDTH_INTERNAL_CMD(scp)) + gdth_put_cmndinfo(cmndinfo); + scp->host_scribble = NULL; + + if (internal_command) complete((struct completion *)scp->request); else scp->scsi_done(scp); @@ -416,7 +449,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp) int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info) { + gdth_ha_str *ha = shost_priv(sdev->host); Scsi_Cmnd *scp; + struct gdth_cmndinfo cmndinfo; DECLARE_COMPLETION_ONSTACK(wait); int rval; @@ -425,6 +460,8 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, return -ENOMEM; scp->device = sdev; + memset(&cmndinfo, 0, sizeof(cmndinfo)); + /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; @@ -432,8 +469,11 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->underflow = GDTH_MAGIC; - gdth_queuecommand(scp, NULL); + cmndinfo.internal_command = 1; + + TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); + __gdth_queuecommand(ha, scp, &cmndinfo); + wait_for_completion(&wait); rval = scp->SCp.Status; @@ -1966,6 +2006,7 @@ static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) { + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); register Scsi_Cmnd *pscp; register Scsi_Cmnd *nscp; ulong flags; @@ -1974,7 +2015,7 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) TRACE(("gdth_putq() priority %d\n",priority)); spin_lock_irqsave(&ha->smp_lock, flags); - if (!IS_GDTH_INTERNAL_CMD(scp)) { + if (!cmndinfo->internal_command) { scp->SCp.this_residual = (int)priority; b = scp->device->channel; t = scp->device->id; @@ -2035,7 +2076,7 @@ static void gdth_next(gdth_ha_str *ha) for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - if (!IS_GDTH_INTERNAL_CMD(nscp)) { + if (!gdth_cmnd_priv(nscp)->internal_command) { b = nscp->device->channel; t = nscp->device->id; l = nscp->device->lun; @@ -2060,7 +2101,7 @@ static void gdth_next(gdth_ha_str *ha) firsttime = FALSE; } - if (!IS_GDTH_INTERNAL_CMD(nscp)) { + if (!gdth_cmnd_priv(nscp)->internal_command) { if (nscp->SCp.phase == -1) { nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ if (nscp->cmnd[0] == TEST_UNIT_READY) { @@ -2123,7 +2164,7 @@ static void gdth_next(gdth_ha_str *ha) else gdth_scsi_done(nscp); } - } else if (IS_GDTH_INTERNAL_CMD(nscp)) { + } else if (gdth_cmnd_priv(nscp)->internal_command) { if (!(cmd_index=gdth_special_cmd(ha, nscp))) this_cmd = FALSE; next_cmd = FALSE; @@ -2622,6 +2663,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) unchar t,l; struct page *page; ulong offset; + struct gdth_cmndinfo *cmndinfo; t = scp->device->id; l = scp->device->lun; @@ -2645,6 +2687,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) if (ha->cmd_cnt == 0) gdth_set_sema0(ha); + cmndinfo = gdth_cmnd_priv(scp); /* fill command */ if (scp->SCp.sent_command != -1) { cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ @@ -2668,9 +2711,8 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) offset = (ulong)scp->sense_buffer & ~PAGE_MASK; sense_paddr = pci_map_page(ha->pdev,page,offset, 16,PCI_DMA_FROMDEVICE); - *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; - /* high part, if 64bit */ - *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); + + cmndinfo->sense_paddr = sense_paddr; cmdp->OpCode = GDT_WRITE; /* always */ cmdp->BoardNode = LOCALBOARD; if (mode64) { @@ -3271,6 +3313,7 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, gdth_msg_str *msg; gdth_cmd_str *cmdp; unchar b, t; + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); cmdp = ha->pccb; TRACE(("gdth_sync_event() serv %d status %d\n", @@ -3364,14 +3407,9 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, else if (scp->SCp.Status == GDTH_MAP_SINGLE) pci_unmap_page(ha->pdev,scp->SCp.dma_handle, scp->request_bufflen,scp->SCp.Message); - if (scp->SCp.buffer) { - dma_addr_t addr; - addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; - if (scp->host_scribble) - addr += (dma_addr_t) - ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); - pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); - } + if (cmndinfo->sense_paddr) + pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, + PCI_DMA_FROMDEVICE); if (ha->status == S_OK) { scp->SCp.Status = S_OK; @@ -3450,7 +3488,7 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, scp->sense_buffer[2] = NOT_READY; scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); } - if (!IS_GDTH_INTERNAL_CMD(scp)) { + if (!cmndinfo->internal_command) { ha->dvr.size = sizeof(ha->dvr.eu.sync); ha->dvr.eu.sync.ionode = ha->hanum; ha->dvr.eu.sync.service = service; @@ -3995,28 +4033,33 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { gdth_ha_str *ha = shost_priv(scp->device->host); - int priority; + struct gdth_cmndinfo *cmndinfo; TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); - + + cmndinfo = gdth_get_cmndinfo(ha); + BUG_ON(!cmndinfo); + scp->scsi_done = done; + gdth_update_timeout(scp, scp->timeout_per_command * 6); + scp->SCp.this_residual = DEFAULT_PRI; + return __gdth_queuecommand(ha, scp, cmndinfo); +} + +static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, + struct gdth_cmndinfo *cmndinfo) +{ + scp->host_scribble = (unsigned char *)cmndinfo; scp->SCp.have_data_in = 1; scp->SCp.phase = -1; scp->SCp.sent_command = -1; scp->SCp.Status = GDTH_MAP_NONE; - scp->SCp.buffer = (struct scatterlist *)NULL; #ifdef GDTH_STATISTICS ++act_ios; #endif - priority = DEFAULT_PRI; - if (IS_GDTH_INTERNAL_CMD(scp)) - priority = scp->SCp.this_residual; - else - gdth_update_timeout(scp, scp->timeout_per_command * 6); - - gdth_putq(ha, scp, priority); + gdth_putq(ha, scp, scp->SCp.this_residual); gdth_next(ha); return 0; } diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index e6178c4..be4ae5a 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -919,6 +919,11 @@ typedef struct { Scsi_Cmnd *cmnd; /* pending request */ ushort service; /* service */ } cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */ + struct gdth_cmndinfo { /* per-command private info */ + int index; + int internal_command; /* don't call scsi_done */ + dma_addr_t sense_paddr; /* sense dma-addr */ + } cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */ unchar bus_cnt; /* SCSI bus count */ unchar tid_cnt; /* Target ID count */ unchar bus_id[MAXBUS]; /* IOP IDs */ @@ -941,6 +946,11 @@ typedef struct { struct scsi_device *sdev; } gdth_ha_str; +static inline struct gdth_cmndinfo *gdth_cmnd_priv(struct scsi_cmnd* cmd) +{ + return (struct gdth_cmndinfo *)cmd->host_scribble; +} + /* INQUIRY data format */ typedef struct { unchar type_qual; diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index fe070ab..ad1b60d 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -758,7 +758,8 @@ static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (!IS_GDTH_INTERNAL_CMD(scp)) { + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); + if (!cmndinfo->internal_command) { b = scp->device->channel; t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { @@ -779,7 +780,8 @@ static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (!IS_GDTH_INTERNAL_CMD(scp)) { + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); + if (!cmndinfo->internal_command) { b = scp->device->channel; t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { -- cgit v1.1 From f842b64e0ffbcc9ce48a3bf799d0b005094107c1 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:16:01 +0200 Subject: [SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2 - Cleanup the rest of the scsi_cmnd->SCp members and move them to gdth_cmndinfo: SCp.this_residual => priority SCp.buffers_residual => timeout SCp.Status => status and dma_dir SCp.Message => info SCp.have_data_in => volatile wait_for_completion SCp.sent_command => OpCode SCp.phase => phase - Two more members will be naturally removed in the !use_sg cleanup TODO: What is the meaning of gdth_cmndinfo.phase? (rhetorically) Signed-off-by Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 177 ++++++++++++++++++++++++----------------------- drivers/scsi/gdth.h | 8 +++ drivers/scsi/gdth_proc.c | 10 +-- 3 files changed, 104 insertions(+), 91 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index e002c39..a68004b 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -85,15 +85,15 @@ /* The meaning of the Scsi_Pointer members in this driver is as follows: * ptr: Chaining - * this_residual: Command priority + * this_residual: unused * buffer: unused * dma_handle: will drop in !use_sg patch. - * buffers_residual: Timeout value - * Status: Command status (gdth_do_cmd()), DMA mem. mappings - * Message: Additional info (gdth_do_cmd()), DMA direction - * have_data_in: Flag for gdth_wait_completion() - * sent_command: Opcode special command - * phase: Service/parameter/return code special command + * buffers_residual: unused + * Status: DMA mem. mappings (FIXME: drop in !use_sg patch.) + * Message: unused + * have_data_in: unused + * sent_command: unused + * phase: unused */ @@ -468,7 +468,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->request_buffer = gdtcmd; scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); - scp->SCp.this_residual = IOCTL_PRI; /* priority */ + cmndinfo.priority = IOCTL_PRI; cmndinfo.internal_command = 1; TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); @@ -476,9 +476,9 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, wait_for_completion(&wait); - rval = scp->SCp.Status; + rval = cmndinfo.status; if (info) - *info = scp->SCp.Message; + *info = cmndinfo.info; kfree(scp); return rval; } @@ -2016,14 +2016,14 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) spin_lock_irqsave(&ha->smp_lock, flags); if (!cmndinfo->internal_command) { - scp->SCp.this_residual = (int)priority; + cmndinfo->priority = priority; b = scp->device->channel; t = scp->device->id; if (priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b==ha->virt_bus && thdr[t].lock)) { TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(scp, 0); + cmndinfo->timeout = gdth_update_timeout(scp, 0); } } } @@ -2035,7 +2035,7 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) pscp = ha->req_first; nscp = (Scsi_Cmnd *)pscp->SCp.ptr; /* priority: 0-highest,..,0xff-lowest */ - while (nscp && (unchar)nscp->SCp.this_residual <= priority) { + while (nscp && gdth_cmnd_priv(nscp)->priority <= priority) { pscp = nscp; nscp = (Scsi_Cmnd *)pscp->SCp.ptr; } @@ -2074,13 +2074,14 @@ static void gdth_next(gdth_ha_str *ha) cmd_index = 0; for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { + struct gdth_cmndinfo *nscp_cmndinfo = gdth_cmnd_priv(nscp); if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - if (!gdth_cmnd_priv(nscp)->internal_command) { + if (!nscp_cmndinfo->internal_command) { b = nscp->device->channel; t = nscp->device->id; l = nscp->device->lun; - if (nscp->SCp.this_residual >= DEFAULT_PRI) { + if (nscp_cmndinfo->priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) continue; @@ -2101,9 +2102,9 @@ static void gdth_next(gdth_ha_str *ha) firsttime = FALSE; } - if (!gdth_cmnd_priv(nscp)->internal_command) { - if (nscp->SCp.phase == -1) { - nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ + if (!nscp_cmndinfo->internal_command) { + if (nscp_cmndinfo->phase == -1) { + nscp_cmndinfo->phase = CACHESERVICE; /* default: cache svc. */ if (nscp->cmnd[0] == TEST_UNIT_READY) { TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", b, t, l)); @@ -2116,8 +2117,8 @@ static void gdth_next(gdth_ha_str *ha) } else if ((ha->scan_mode & 0x0f) == 1) { if (b == 0 && ((t == 0 && l == 1) || (t == 1 && l == 0))) { - nscp->SCp.sent_command = GDT_SCAN_START; - nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) + nscp_cmndinfo->OpCode = GDT_SCAN_START; + nscp_cmndinfo->phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) | SCSIRAWSERVICE; ha->scan_mode = 0x12; TRACE2(("Scan mode: 0x%x (SCAN_START)\n", @@ -2128,8 +2129,8 @@ static void gdth_next(gdth_ha_str *ha) } } else if (ha->scan_mode == 0x12) { if (b == ha->bus_cnt && t == ha->tid_cnt-1) { - nscp->SCp.phase = SCSIRAWSERVICE; - nscp->SCp.sent_command = GDT_SCAN_END; + nscp_cmndinfo->phase = SCSIRAWSERVICE; + nscp_cmndinfo->OpCode = GDT_SCAN_END; ha->scan_mode &= 0x10; TRACE2(("Scan mode: 0x%x (SCAN_END)\n", ha->scan_mode)); @@ -2140,17 +2141,17 @@ static void gdth_next(gdth_ha_str *ha) nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { /* always GDT_CLUST_INFO! */ - nscp->SCp.sent_command = GDT_CLUST_INFO; + nscp_cmndinfo->OpCode = GDT_CLUST_INFO; } } } - if (nscp->SCp.sent_command != -1) { - if ((nscp->SCp.phase & 0xff) == CACHESERVICE) { + if (nscp_cmndinfo->OpCode != -1) { + if ((nscp_cmndinfo->phase & 0xff) == CACHESERVICE) { if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) this_cmd = FALSE; next_cmd = FALSE; - } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) { + } else if ((nscp_cmndinfo->phase & 0xff) == SCSIRAWSERVICE) { if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) this_cmd = FALSE; next_cmd = FALSE; @@ -2159,8 +2160,8 @@ static void gdth_next(gdth_ha_str *ha) nscp->sense_buffer[0] = 0x70; nscp->sense_buffer[2] = NOT_READY; nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); } @@ -2178,8 +2179,8 @@ static void gdth_next(gdth_ha_str *ha) TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", nscp->cmnd[0], b, t, l)); nscp->result = DID_BAD_TARGET << 16; - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); } else { @@ -2204,8 +2205,8 @@ static void gdth_next(gdth_ha_str *ha) nscp->sense_buffer[0] = 0x70; nscp->sense_buffer[2] = UNIT_ATTENTION; nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); } else if (gdth_internal_cache_cmd(ha, nscp)) @@ -2220,8 +2221,8 @@ static void gdth_next(gdth_ha_str *ha) TRACE(("Prevent r. nonremov. drive->do nothing\n")); nscp->result = DID_OK << 16; nscp->sense_buffer[0] = 0; - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); } else { @@ -2256,8 +2257,8 @@ static void gdth_next(gdth_ha_str *ha) nscp->sense_buffer[0] = 0x70; nscp->sense_buffer[2] = UNIT_ATTENTION; nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) @@ -2271,8 +2272,8 @@ static void gdth_next(gdth_ha_str *ha) printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", ha->hanum, nscp->cmnd[0]); nscp->result = DID_ABORT << 16; - if (!nscp->SCp.have_data_in) - nscp->SCp.have_data_in++; + if (!nscp_cmndinfo->wait_for_completion) + nscp_cmndinfo->wait_for_completion++; else gdth_scsi_done(nscp); break; @@ -2351,6 +2352,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) gdth_rdcap_data rdc; gdth_sense_data sd; gdth_modep_data mpd; + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); t = scp->device->id; TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", @@ -2437,8 +2439,8 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) break; } - if (!scp->SCp.have_data_in) - scp->SCp.have_data_in++; + if (!cmndinfo->wait_for_completion) + cmndinfo->wait_for_completion++; else return 1; @@ -2448,6 +2450,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) { register gdth_cmd_str *cmdp; + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); struct scatterlist *sl; ulong32 cnt, blockcnt; ulong64 no, blockno; @@ -2481,8 +2484,8 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) /* fill command */ read_write = 0; - if (scp->SCp.sent_command != -1) - cmdp->OpCode = scp->SCp.sent_command; /* special cache cmd. */ + if (cmndinfo->OpCode != -1) + cmdp->OpCode = cmndinfo->OpCode; /* special cache cmd. */ else if (scp->cmnd[0] == RESERVE) cmdp->OpCode = GDT_RESERVE_DRV; else if (scp->cmnd[0] == RELEASE) @@ -2547,9 +2550,9 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) sl = (struct scatterlist *)scp->request_buffer; sgcnt = scp->use_sg; scp->SCp.Status = GDTH_MAP_SG; - scp->SCp.Message = (read_write == 1 ? + cmndinfo->dma_dir = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); + sgcnt = pci_map_sg(ha->pdev, sl, scp->use_sg, cmndinfo->dma_dir); if (mode64) { cmdp->u.cache64.DestAddr= (ulong64)-1; cmdp->u.cache64.sg_canz = sgcnt; @@ -2584,12 +2587,12 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) } else if (scp->request_bufflen) { scp->SCp.Status = GDTH_MAP_SINGLE; - scp->SCp.Message = (read_write == 1 ? + cmndinfo->dma_dir = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); page = virt_to_page(scp->request_buffer); offset = (ulong)scp->request_buffer & ~PAGE_MASK; phys_addr = pci_map_page(ha->pdev,page,offset, - scp->request_bufflen,scp->SCp.Message); + scp->request_bufflen, cmndinfo->dma_dir); scp->SCp.dma_handle = phys_addr; if (mode64) { if (ha->cache_feat & SCATTER_GATHER) { @@ -2689,17 +2692,17 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) cmndinfo = gdth_cmnd_priv(scp); /* fill command */ - if (scp->SCp.sent_command != -1) { - cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ + if (cmndinfo->OpCode != -1) { + cmdp->OpCode = cmndinfo->OpCode; /* special raw cmd. */ cmdp->BoardNode = LOCALBOARD; if (mode64) { - cmdp->u.raw64.direction = (scp->SCp.phase >> 8); + cmdp->u.raw64.direction = (cmndinfo->phase >> 8); TRACE2(("special raw cmd 0x%x param 0x%x\n", cmdp->OpCode, cmdp->u.raw64.direction)); /* evaluate command size */ ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); } else { - cmdp->u.raw.direction = (scp->SCp.phase >> 8); + cmdp->u.raw.direction = (cmndinfo->phase >> 8); TRACE2(("special raw cmd 0x%x param 0x%x\n", cmdp->OpCode, cmdp->u.raw.direction)); /* evaluate command size */ @@ -2754,8 +2757,8 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) sl = (struct scatterlist *)scp->request_buffer; sgcnt = scp->use_sg; scp->SCp.Status = GDTH_MAP_SG; - scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; - sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); + cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; + sgcnt = pci_map_sg(ha->pdev,sl, scp->use_sg, cmndinfo->dma_dir); if (mode64) { cmdp->u.raw64.sdata = (ulong64)-1; cmdp->u.raw64.sg_ranz = sgcnt; @@ -2790,11 +2793,11 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) } else if (scp->request_bufflen) { scp->SCp.Status = GDTH_MAP_SINGLE; - scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; + cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; page = virt_to_page(scp->request_buffer); offset = (ulong)scp->request_buffer & ~PAGE_MASK; phys_addr = pci_map_page(ha->pdev,page,offset, - scp->request_bufflen,scp->SCp.Message); + scp->request_bufflen, cmndinfo->dma_dir); scp->SCp.dma_handle = phys_addr; if (mode64) { @@ -3266,7 +3269,7 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, if (!gdth_polling) spin_unlock_irqrestore(&ha->smp_lock, flags); if (rval == 2) { - gdth_putq(ha, scp,scp->SCp.this_residual); + gdth_putq(ha, scp, gdth_cmnd_priv(scp)->priority); } else if (rval == 1) { gdth_scsi_done(scp); } @@ -3390,60 +3393,60 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, } else { b = scp->device->channel; t = scp->device->id; - if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { + if (cmndinfo->OpCode == -1 && b != ha->virt_bus) { ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; } /* cache or raw service */ if (ha->status == S_BSY) { TRACE2(("Controller busy -> retry !\n")); - if (scp->SCp.sent_command == GDT_MOUNT) - scp->SCp.sent_command = GDT_CLUST_INFO; + if (cmndinfo->OpCode == GDT_MOUNT) + cmndinfo->OpCode = GDT_CLUST_INFO; /* retry */ return 2; } if (scp->SCp.Status == GDTH_MAP_SG) pci_unmap_sg(ha->pdev,scp->request_buffer, - scp->use_sg,scp->SCp.Message); + scp->use_sg, cmndinfo->dma_dir); else if (scp->SCp.Status == GDTH_MAP_SINGLE) pci_unmap_page(ha->pdev,scp->SCp.dma_handle, - scp->request_bufflen,scp->SCp.Message); + scp->request_bufflen, cmndinfo->dma_dir); if (cmndinfo->sense_paddr) pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, PCI_DMA_FROMDEVICE); if (ha->status == S_OK) { - scp->SCp.Status = S_OK; - scp->SCp.Message = ha->info; - if (scp->SCp.sent_command != -1) { + cmndinfo->status = S_OK; + cmndinfo->info = ha->info; + if (cmndinfo->OpCode != -1) { TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", - scp->SCp.sent_command)); + cmndinfo->OpCode)); /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ - if (scp->SCp.sent_command == GDT_CLUST_INFO) { + if (cmndinfo->OpCode == GDT_CLUST_INFO) { ha->hdr[t].cluster_type = (unchar)ha->info; if (!(ha->hdr[t].cluster_type & CLUSTER_MOUNTED)) { /* NOT MOUNTED -> MOUNT */ - scp->SCp.sent_command = GDT_MOUNT; + cmndinfo->OpCode = GDT_MOUNT; if (ha->hdr[t].cluster_type & CLUSTER_RESERVED) { /* cluster drive RESERVED (on the other node) */ - scp->SCp.phase = -2; /* reservation conflict */ + cmndinfo->phase = -2; /* reservation conflict */ } } else { - scp->SCp.sent_command = -1; + cmndinfo->OpCode = -1; } } else { - if (scp->SCp.sent_command == GDT_MOUNT) { + if (cmndinfo->OpCode == GDT_MOUNT) { ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; ha->hdr[t].media_changed = TRUE; - } else if (scp->SCp.sent_command == GDT_UNMOUNT) { + } else if (cmndinfo->OpCode == GDT_UNMOUNT) { ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; ha->hdr[t].media_changed = TRUE; } - scp->SCp.sent_command = -1; + cmndinfo->OpCode = -1; } /* retry */ - scp->SCp.this_residual = HIGH_PRI; + cmndinfo->priority = HIGH_PRI; return 2; } else { /* RESERVE/RELEASE ? */ @@ -3456,17 +3459,17 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, scp->sense_buffer[0] = 0; } } else { - scp->SCp.Status = ha->status; - scp->SCp.Message = ha->info; + cmndinfo->status = ha->status; + cmndinfo->info = ha->info; - if (scp->SCp.sent_command != -1) { + if (cmndinfo->OpCode != -1) { TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", - scp->SCp.sent_command, ha->status)); - if (scp->SCp.sent_command == GDT_SCAN_START || - scp->SCp.sent_command == GDT_SCAN_END) { - scp->SCp.sent_command = -1; + cmndinfo->OpCode, ha->status)); + if (cmndinfo->OpCode == GDT_SCAN_START || + cmndinfo->OpCode == GDT_SCAN_END) { + cmndinfo->OpCode = -1; /* retry */ - scp->SCp.this_residual = HIGH_PRI; + cmndinfo->priority = HIGH_PRI; return 2; } memset((char*)scp->sense_buffer,0,16); @@ -3509,8 +3512,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, } } } - if (!scp->SCp.have_data_in) - scp->SCp.have_data_in++; + if (!cmndinfo->wait_for_completion) + cmndinfo->wait_for_completion++; else return 1; } @@ -4042,7 +4045,7 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, scp->scsi_done = done; gdth_update_timeout(scp, scp->timeout_per_command * 6); - scp->SCp.this_residual = DEFAULT_PRI; + cmndinfo->priority = DEFAULT_PRI; return __gdth_queuecommand(ha, scp, cmndinfo); } @@ -4050,16 +4053,16 @@ static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, struct gdth_cmndinfo *cmndinfo) { scp->host_scribble = (unsigned char *)cmndinfo; - scp->SCp.have_data_in = 1; - scp->SCp.phase = -1; - scp->SCp.sent_command = -1; + cmndinfo->wait_for_completion = 1; + cmndinfo->phase = -1; + cmndinfo->OpCode = -1; scp->SCp.Status = GDTH_MAP_NONE; #ifdef GDTH_STATISTICS ++act_ios; #endif - gdth_putq(ha, scp, scp->SCp.this_residual); + gdth_putq(ha, scp, cmndinfo->priority); gdth_next(ha); return 0; } diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index be4ae5a..25803a8 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -923,6 +923,14 @@ typedef struct { int index; int internal_command; /* don't call scsi_done */ dma_addr_t sense_paddr; /* sense dma-addr */ + unchar priority; + int timeout; + volatile int wait_for_completion; + ushort status; + ulong32 info; + enum dma_data_direction dma_dir; + int phase; /* ???? */ + int OpCode; } cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */ unchar bus_cnt; /* SCSI bus count */ unchar tid_cnt; /* Target ID count */ diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index ad1b60d..de57734 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -728,20 +728,22 @@ static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id) ulong flags; int i; Scsi_Cmnd *scp; + struct gdth_cmndinfo *cmndinfo; unchar b, t; spin_lock_irqsave(&ha->smp_lock, flags); for (i = 0; i < GDTH_MAXCMDS; ++i) { scp = ha->cmd_tab[i].cmnd; + cmndinfo = gdth_cmnd_priv(scp); b = scp->device->channel; t = scp->device->id; if (!SPECIAL_SCP(scp) && t == (unchar)id && b == (unchar)busnum) { - scp->SCp.have_data_in = 0; + cmndinfo->wait_for_completion = 0; spin_unlock_irqrestore(&ha->smp_lock, flags); - while (!scp->SCp.have_data_in) + while (!cmndinfo->wait_for_completion) barrier(); spin_lock_irqsave(&ha->smp_lock, flags); } @@ -764,7 +766,7 @@ static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id) t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(scp, 0); + cmndinfo->timeout = gdth_update_timeout(scp, 0); } } } @@ -786,7 +788,7 @@ static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id) t = scp->device->id; if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_start_timeout(): update_timeout()\n")); - gdth_update_timeout(scp, scp->SCp.buffers_residual); + gdth_update_timeout(scp, cmndinfo->timeout); } } } -- cgit v1.1 From 3892d88ae6fb186ff6205f764213b556d70800b0 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 2 Oct 2007 23:18:03 +0200 Subject: [SCSI] gdth: !use_sg cleanup and use of scsi accessors gdth_execute() will issue an internal, none scsi-standard commands onto __gdth_queuecommand(). Since it is not recommended to set struct scsi_cmnd IO members in llds, gdth now uses internal IO members for IO. In the case of gdth_execute() these members will be set properly. In case the command was issued from scsi-ml (by gdth_queuecommand) they will be set from scsi IO accessors. * define gdth IO accessors and use them throughout the driver. * use an sg-of-one in gdth_execute() and fix gdth_special_cmd() accordingly. * Clean the not use_sg code path and company Signed-off-by Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 228 +++++++++++++++++++++++++--------------------------- drivers/scsi/gdth.h | 7 -- 2 files changed, 109 insertions(+), 126 deletions(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index a68004b..0153d1d 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -85,11 +85,11 @@ /* The meaning of the Scsi_Pointer members in this driver is as follows: * ptr: Chaining - * this_residual: unused - * buffer: unused - * dma_handle: will drop in !use_sg patch. - * buffers_residual: unused - * Status: DMA mem. mappings (FIXME: drop in !use_sg patch.) + * this_residual: gdth_bufflen + * buffer: gdth_sglist + * dma_handle: unused + * buffers_residual: gdth_sg_count + * Status: unused * Message: unused * have_data_in: unused * sent_command: unused @@ -132,6 +132,7 @@ #include #include #include +#include #include "scsi.h" #include @@ -159,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, static void gdth_clear_events(void); static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer,ushort count); + char *buffer, ushort count, int to_buffer); static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); @@ -373,6 +374,47 @@ static const struct file_operations gdth_fops = { .release = gdth_close, }; +/* + * gdth scsi_command access wrappers. + * below 6 functions are used throughout the driver to access scsi_command's + * io parameters. The reason we do not use the regular accessors from + * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for + * llds to directly set scsi_cmnd's IO members. This driver will use SCp + * members for IO parameters, and will copy scsi_cmnd's members to Scp + * members in queuecommand. For internal commands through gdth_execute() + * SCp's members will be set directly. + */ +static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) +{ + return (unsigned)cmd->SCp.this_residual; +} + +static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) +{ + cmd->SCp.this_residual = bufflen; +} + +static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) +{ + return (unsigned)cmd->SCp.buffers_residual; +} + +static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) +{ + cmd->SCp.buffers_residual = sg_count; +} + +static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) +{ + return cmd->SCp.buffer; +} + +static inline void gdth_set_sglist(struct scsi_cmnd *cmd, + struct scatterlist *sglist) +{ + cmd->SCp.buffer = sglist; +} + #include "gdth_proc.h" #include "gdth_proc.c" @@ -452,6 +494,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, gdth_ha_str *ha = shost_priv(sdev->host); Scsi_Cmnd *scp; struct gdth_cmndinfo cmndinfo; + struct scatterlist one_sg; DECLARE_COMPLETION_ONSTACK(wait); int rval; @@ -465,7 +508,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; - scp->request_buffer = gdtcmd; + sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); + gdth_set_sglist(scp, &one_sg); + gdth_set_sg_count(scp, 1); + gdth_set_bufflen(scp, sizeof(*gdtcmd)); scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); cmndinfo.priority = IOCTL_PRI; @@ -2303,24 +2349,28 @@ static void gdth_next(gdth_ha_str *ha) ha->hanum, cmd_index); } } - + +/* + * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's + * buffers, kmap_atomic() as needed. + */ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer,ushort count) + char *buffer, ushort count, int to_buffer) { - ushort cpcount,i; + ushort cpcount,i, max_sg = gdth_sg_count(scp); ushort cpsum,cpnow; struct scatterlist *sl; char *address; - cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; + cpcount = min_t(ushort, count, gdth_bufflen(scp)); - if (scp->use_sg) { - sl = (struct scatterlist *)scp->request_buffer; - for (i=0,cpsum=0; iuse_sg; ++i,++sl) { + if (cpcount) { + cpsum=0; + scsi_for_each_sg(scp, sl, max_sg, i) { unsigned long flags; cpnow = (ushort)sl->length; TRACE(("copy_internal() now %d sum %d count %d %d\n", - cpnow,cpsum,cpcount,(ushort)scp->bufflen)); + cpnow, cpsum, cpcount, gdth_bufflen(scp))); if (cpsum+cpnow > cpcount) cpnow = cpcount - cpsum; cpsum += cpnow; @@ -2331,7 +2381,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, } local_irq_save(flags); address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; - memcpy(address,buffer,cpnow); + if (to_buffer) + memcpy(buffer, address, cpnow); + else + memcpy(address, buffer, cpnow); flush_dcache_page(sl->page); kunmap_atomic(address, KM_BIO_SRC_IRQ); local_irq_restore(flags); @@ -2339,9 +2392,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, break; buffer += cpnow; } - } else { - TRACE(("copy_internal() count %d\n",cpcount)); - memcpy((char*)scp->request_buffer,buffer,cpcount); + } else if (count) { + printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n", + ha->hanum); + WARN_ON(1); } } @@ -2384,7 +2438,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) strcpy(inq.vendor,ha->oem_name); sprintf(inq.product,"Host Drive #%02d",t); strcpy(inq.revision," "); - gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data)); + gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); break; case REQUEST_SENSE: @@ -2394,7 +2448,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) sd.key = NO_SENSE; sd.info = 0; sd.add_length= 0; - gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data)); + gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); break; case MODE_SENSE: @@ -2406,7 +2460,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); - gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data)); + gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); break; case READ_CAPACITY: @@ -2416,7 +2470,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) else rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); rdc.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data)); + gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); break; case SERVICE_ACTION_IN: @@ -2428,7 +2482,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); rdc16.block_length = cpu_to_be32(SECTOR_SIZE); gdth_copy_internal_data(ha, scp, (char*)&rdc16, - sizeof(gdth_rdcap16_data)); + sizeof(gdth_rdcap16_data), 0); } else { scp->result = DID_ABORT << 16; } @@ -2451,13 +2505,9 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) { register gdth_cmd_str *cmdp; struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); - struct scatterlist *sl; ulong32 cnt, blockcnt; ulong64 no, blockno; - dma_addr_t phys_addr; int i, cmd_index, read_write, sgcnt, mode64; - struct page *page; - ulong offset; cmdp = ha->pccb; TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", @@ -2546,17 +2596,17 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) cmdp->u.cache.BlockCnt = blockcnt; } - if (scp->use_sg) { - sl = (struct scatterlist *)scp->request_buffer; - sgcnt = scp->use_sg; - scp->SCp.Status = GDTH_MAP_SG; + if (gdth_bufflen(scp)) { cmndinfo->dma_dir = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - sgcnt = pci_map_sg(ha->pdev, sl, scp->use_sg, cmndinfo->dma_dir); + sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), + cmndinfo->dma_dir); if (mode64) { + struct scatterlist *sl; + cmdp->u.cache64.DestAddr= (ulong64)-1; cmdp->u.cache64.sg_canz = sgcnt; - for (i=0; iu.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); #ifdef GDTH_DMA_STATISTICS if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) @@ -2567,9 +2617,11 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); } } else { + struct scatterlist *sl; + cmdp->u.cache.DestAddr= 0xffffffff; cmdp->u.cache.sg_canz = sgcnt; - for (i=0; iu.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); #ifdef GDTH_DMA_STATISTICS ha->dma32_cnt++; @@ -2585,38 +2637,6 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) } #endif - } else if (scp->request_bufflen) { - scp->SCp.Status = GDTH_MAP_SINGLE; - cmndinfo->dma_dir = (read_write == 1 ? - PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - page = virt_to_page(scp->request_buffer); - offset = (ulong)scp->request_buffer & ~PAGE_MASK; - phys_addr = pci_map_page(ha->pdev,page,offset, - scp->request_bufflen, cmndinfo->dma_dir); - scp->SCp.dma_handle = phys_addr; - if (mode64) { - if (ha->cache_feat & SCATTER_GATHER) { - cmdp->u.cache64.DestAddr = (ulong64)-1; - cmdp->u.cache64.sg_canz = 1; - cmdp->u.cache64.sg_lst[0].sg_ptr = phys_addr; - cmdp->u.cache64.sg_lst[0].sg_len = scp->request_bufflen; - cmdp->u.cache64.sg_lst[1].sg_len = 0; - } else { - cmdp->u.cache64.DestAddr = phys_addr; - cmdp->u.cache64.sg_canz= 0; - } - } else { - if (ha->cache_feat & SCATTER_GATHER) { - cmdp->u.cache.DestAddr = 0xffffffff; - cmdp->u.cache.sg_canz = 1; - cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr; - cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen; - cmdp->u.cache.sg_lst[1].sg_len = 0; - } else { - cmdp->u.cache.DestAddr = phys_addr; - cmdp->u.cache.sg_canz= 0; - } - } } } /* evaluate command size, check space */ @@ -2659,9 +2679,8 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) { register gdth_cmd_str *cmdp; - struct scatterlist *sl; ushort i; - dma_addr_t phys_addr, sense_paddr; + dma_addr_t sense_paddr; int cmd_index, sgcnt, mode64; unchar t,l; struct page *page; @@ -2727,7 +2746,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) cmdp->u.raw64.lun = l; cmdp->u.raw64.bus = b; cmdp->u.raw64.priority = 0; - cmdp->u.raw64.sdlen = scp->request_bufflen; + cmdp->u.raw64.sdlen = gdth_bufflen(scp); cmdp->u.raw64.sense_len = 16; cmdp->u.raw64.sense_data = sense_paddr; cmdp->u.raw64.direction = @@ -2744,7 +2763,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) cmdp->u.raw.bus = b; cmdp->u.raw.priority = 0; cmdp->u.raw.link_p = 0; - cmdp->u.raw.sdlen = scp->request_bufflen; + cmdp->u.raw.sdlen = gdth_bufflen(scp); cmdp->u.raw.sense_len = 16; cmdp->u.raw.sense_data = sense_paddr; cmdp->u.raw.direction = @@ -2753,16 +2772,16 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) cmdp->u.raw.sg_ranz = 0; } - if (scp->use_sg) { - sl = (struct scatterlist *)scp->request_buffer; - sgcnt = scp->use_sg; - scp->SCp.Status = GDTH_MAP_SG; + if (gdth_bufflen(scp)) { cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; - sgcnt = pci_map_sg(ha->pdev,sl, scp->use_sg, cmndinfo->dma_dir); + sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), + cmndinfo->dma_dir); if (mode64) { + struct scatterlist *sl; + cmdp->u.raw64.sdata = (ulong64)-1; cmdp->u.raw64.sg_ranz = sgcnt; - for (i=0; iu.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); #ifdef GDTH_DMA_STATISTICS if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) @@ -2773,9 +2792,11 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); } } else { + struct scatterlist *sl; + cmdp->u.raw.sdata = 0xffffffff; cmdp->u.raw.sg_ranz = sgcnt; - for (i=0; iu.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); #ifdef GDTH_DMA_STATISTICS ha->dma32_cnt++; @@ -2791,38 +2812,6 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) } #endif - } else if (scp->request_bufflen) { - scp->SCp.Status = GDTH_MAP_SINGLE; - cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; - page = virt_to_page(scp->request_buffer); - offset = (ulong)scp->request_buffer & ~PAGE_MASK; - phys_addr = pci_map_page(ha->pdev,page,offset, - scp->request_bufflen, cmndinfo->dma_dir); - scp->SCp.dma_handle = phys_addr; - - if (mode64) { - if (ha->raw_feat & SCATTER_GATHER) { - cmdp->u.raw64.sdata = (ulong64)-1; - cmdp->u.raw64.sg_ranz= 1; - cmdp->u.raw64.sg_lst[0].sg_ptr = phys_addr; - cmdp->u.raw64.sg_lst[0].sg_len = scp->request_bufflen; - cmdp->u.raw64.sg_lst[1].sg_len = 0; - } else { - cmdp->u.raw64.sdata = phys_addr; - cmdp->u.raw64.sg_ranz= 0; - } - } else { - if (ha->raw_feat & SCATTER_GATHER) { - cmdp->u.raw.sdata = 0xffffffff; - cmdp->u.raw.sg_ranz= 1; - cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr; - cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen; - cmdp->u.raw.sg_lst[1].sg_len = 0; - } else { - cmdp->u.raw.sdata = phys_addr; - cmdp->u.raw.sg_ranz= 0; - } - } } if (mode64) { TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", @@ -2871,7 +2860,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) if (ha->type==GDT_EISA && ha->cmd_cnt>0) return 0; - memcpy( cmdp, scp->request_buffer, sizeof(gdth_cmd_str)); + gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); cmdp->RequestBuffer = scp; /* search free command index */ @@ -3404,12 +3393,10 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, /* retry */ return 2; } - if (scp->SCp.Status == GDTH_MAP_SG) - pci_unmap_sg(ha->pdev,scp->request_buffer, - scp->use_sg, cmndinfo->dma_dir); - else if (scp->SCp.Status == GDTH_MAP_SINGLE) - pci_unmap_page(ha->pdev,scp->SCp.dma_handle, - scp->request_bufflen, cmndinfo->dma_dir); + if (gdth_bufflen(scp)) + pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), + cmndinfo->dma_dir); + if (cmndinfo->sense_paddr) pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, PCI_DMA_FROMDEVICE); @@ -4046,6 +4033,11 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, scp->scsi_done = done; gdth_update_timeout(scp, scp->timeout_per_command * 6); cmndinfo->priority = DEFAULT_PRI; + + gdth_set_bufflen(scp, scsi_bufflen(scp)); + gdth_set_sg_count(scp, scsi_sg_count(scp)); + gdth_set_sglist(scp, scsi_sglist(scp)); + return __gdth_queuecommand(ha, scp, cmndinfo); } @@ -4056,7 +4048,6 @@ static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, cmndinfo->wait_for_completion = 1; cmndinfo->phase = -1; cmndinfo->OpCode = -1; - scp->SCp.Status = GDTH_MAP_NONE; #ifdef GDTH_STATISTICS ++act_ios; @@ -4626,7 +4617,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, return -ENOMEM; scp->device = ha->sdev; scp->cmd_len = 12; - scp->use_sg = 0; scp->device->channel = res.number; rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 25803a8..1434c6b 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -303,15 +303,8 @@ #define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */ #define EISAREG 0x0cc0 /* EISA configuration */ -/* DMA memory mappings */ -#define GDTH_MAP_NONE 0 -#define GDTH_MAP_SINGLE 1 -#define GDTH_MAP_SG 2 -#define GDTH_MAP_IOCTL 3 - /* other defines */ #define LINUX_OS 8 /* used for cache optim. */ -#define SCATTER_GATHER 1 /* s/g feature */ #define SECS32 0x1f /* round capacity */ #define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ #define LOCALBOARD 0 /* board node always 0 */ -- cgit v1.1 From 76246808248ac4c94ec3b57e37f35f8e05dfa0b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 11 Oct 2007 17:35:20 +0200 Subject: [SCSI] esp_scsi: remove __dev{init,exit} Since scsi_esp_{,un}register() are EXPORT_SYMBOL'ed, these functions (and the functions they use) can't be __dev{init,exit}. Based on a bug report by Rob Landley. Signed-off-by: Adrian Bunk Acked-by: David S. Miller Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 77b06a9..f346fd1 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2138,7 +2138,7 @@ irqreturn_t scsi_esp_intr(int irq, void *dev_id) } EXPORT_SYMBOL(scsi_esp_intr); -static void __devinit esp_get_revision(struct esp *esp) +static void esp_get_revision(struct esp *esp) { u8 val; @@ -2187,7 +2187,7 @@ static void __devinit esp_get_revision(struct esp *esp) } } -static void __devinit esp_init_swstate(struct esp *esp) +static void esp_init_swstate(struct esp *esp) { int i; @@ -2233,7 +2233,7 @@ static void esp_bootup_reset(struct esp *esp) esp_read8(ESP_INTRPT); } -static void __devinit esp_set_clock_params(struct esp *esp) +static void esp_set_clock_params(struct esp *esp) { int fmhz; u8 ccf; @@ -2306,7 +2306,7 @@ static const char *esp_chip_names[] = { static struct scsi_transport_template *esp_transport_template; -int __devinit scsi_esp_register(struct esp *esp, struct device *dev) +int scsi_esp_register(struct esp *esp, struct device *dev) { static int instance; int err; @@ -2345,7 +2345,7 @@ int __devinit scsi_esp_register(struct esp *esp, struct device *dev) } EXPORT_SYMBOL(scsi_esp_register); -void __devexit scsi_esp_unregister(struct esp *esp) +void scsi_esp_unregister(struct esp *esp) { scsi_remove_host(esp->host); } -- cgit v1.1 From c8e91b0a8fc8493e3bf3efcb3c8f866e9453cf1c Mon Sep 17 00:00:00 2001 From: Dhaval Giani Date: Fri, 12 Oct 2007 15:12:31 +0530 Subject: [SCSI] gdth: fix CONFIG_ISA build failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/scsi/gdth.c: In function ‘gdth_search_dev’: drivers/scsi/gdth.c:646: warning: ‘pci_find_device’ is deprecated (declared at include/linux/pci.h:482) drivers/scsi/gdth.c: In function ‘gdth_init_isa’: drivers/scsi/gdth.c:857: error: ‘gdth_irq_tab’ undeclared (first use in this function) drivers/scsi/gdth.c:857: error: (Each undeclared identifier is reported only once drivers/scsi/gdth.c:857: error: for each function it appears in.) drivers/scsi/gdth.c: In function ‘gdth_copy_internal_data’: drivers/scsi/gdth.c:2362: warning: unused variable ‘sg’ Looking into the code I notice that gdth_irq_tab is not declared with CONFIG_ISA=y and !CONFIG_EISA. The values seem to be same in 2.6.23 (I am not sure why it has been put with #ifdefs in -mm) so I have just modified the #ifdef to take care of CONFIG_ISA as well. Signed-off-by: Dhaval Giani Signed-off-by: James Bottomley --- drivers/scsi/gdth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 0153d1d..e8010a7 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -288,7 +288,7 @@ static struct timer_list gdth_timer; #ifdef CONFIG_ISA static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ #endif -#ifdef CONFIG_EISA +#if defined(CONFIG_EISA) || defined(CONFIG_ISA) static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ #endif static unchar gdth_polling; /* polling if TRUE */ -- cgit v1.1