From 53c165e0a6c8a4ff7df316557528fa7a52d20711 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 22 Aug 2005 10:06:19 -0500 Subject: [PATCH 01/32] [SCSI] correct attribute_container list usage One of the changes in the attribute_container code in the scsi-misc tree was to add a lock to protect the list of devices per container. This, unfortunately, leads to potential scheduling while atomic problems if there's a sleep in the function called by a trigger. The correct solution is to use the kernel klist infrastructure instead which allows lockless traversal of a list. Signed-off-by: James Bottomley --- drivers/base/attribute_container.c | 51 ++++++++++++++++------------- include/linux/attribute_container.h | 4 +-- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index ebcae5c3413..6c0f49340eb 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -22,7 +22,7 @@ /* This is a private structure used to tie the classdev and the * container .. it should never be visible outside this file */ struct internal_container { - struct list_head node; + struct klist_node node; struct attribute_container *cont; struct class_device classdev; }; @@ -57,8 +57,7 @@ int attribute_container_register(struct attribute_container *cont) { INIT_LIST_HEAD(&cont->node); - INIT_LIST_HEAD(&cont->containers); - spin_lock_init(&cont->containers_lock); + klist_init(&cont->containers); down(&attribute_container_mutex); list_add_tail(&cont->node, &attribute_container_list); @@ -78,13 +77,13 @@ attribute_container_unregister(struct attribute_container *cont) { int retval = -EBUSY; down(&attribute_container_mutex); - spin_lock(&cont->containers_lock); - if (!list_empty(&cont->containers)) + spin_lock(&cont->containers.k_lock); + if (!list_empty(&cont->containers.k_list)) goto out; retval = 0; list_del(&cont->node); out: - spin_unlock(&cont->containers_lock); + spin_unlock(&cont->containers.k_lock); up(&attribute_container_mutex); return retval; @@ -143,7 +142,6 @@ attribute_container_add_device(struct device *dev, continue; } memset(ic, 0, sizeof(struct internal_container)); - INIT_LIST_HEAD(&ic->node); ic->cont = cont; class_device_initialize(&ic->classdev); ic->classdev.dev = get_device(dev); @@ -154,13 +152,22 @@ attribute_container_add_device(struct device *dev, fn(cont, dev, &ic->classdev); else attribute_container_add_class_device(&ic->classdev); - spin_lock(&cont->containers_lock); - list_add_tail(&ic->node, &cont->containers); - spin_unlock(&cont->containers_lock); + klist_add_tail(&ic->node, &cont->containers); } up(&attribute_container_mutex); } +/* FIXME: can't break out of this unless klist_iter_exit is also + * called before doing the break + */ +#define klist_for_each_entry(pos, head, member, iter) \ + for (klist_iter_init(head, iter); (pos = ({ \ + struct klist_node *n = klist_next(iter); \ + n ? ({ klist_iter_exit(iter) ; NULL; }) : \ + container_of(n, typeof(*pos), member);\ + }) ) != NULL; ) + + /** * attribute_container_remove_device - make device eligible for removal. * @@ -187,18 +194,19 @@ attribute_container_remove_device(struct device *dev, down(&attribute_container_mutex); list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic, *tmp; + struct internal_container *ic; + struct klist_iter iter; if (attribute_container_no_classdevs(cont)) continue; if (!cont->match(cont, dev)) continue; - spin_lock(&cont->containers_lock); - list_for_each_entry_safe(ic, tmp, &cont->containers, node) { + + klist_for_each_entry(ic, &cont->containers, node, &iter) { if (dev != ic->classdev.dev) continue; - list_del(&ic->node); + klist_remove(&ic->node); if (fn) fn(cont, dev, &ic->classdev); else { @@ -206,7 +214,6 @@ attribute_container_remove_device(struct device *dev, class_device_unregister(&ic->classdev); } } - spin_unlock(&cont->containers_lock); } up(&attribute_container_mutex); } @@ -232,7 +239,8 @@ attribute_container_device_trigger(struct device *dev, down(&attribute_container_mutex); list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic, *tmp; + struct internal_container *ic; + struct klist_iter iter; if (!cont->match(cont, dev)) continue; @@ -242,12 +250,10 @@ attribute_container_device_trigger(struct device *dev, continue; } - spin_lock(&cont->containers_lock); - list_for_each_entry_safe(ic, tmp, &cont->containers, node) { + klist_for_each_entry(ic, &cont->containers, node, &iter) { if (dev == ic->classdev.dev) fn(cont, dev, &ic->classdev); } - spin_unlock(&cont->containers_lock); } up(&attribute_container_mutex); } @@ -397,15 +403,16 @@ attribute_container_find_class_device(struct attribute_container *cont, { struct class_device *cdev = NULL; struct internal_container *ic; + struct klist_iter iter; - spin_lock(&cont->containers_lock); - list_for_each_entry(ic, &cont->containers, node) { + klist_for_each_entry(ic, &cont->containers, node, &iter) { if (ic->classdev.dev == dev) { cdev = &ic->classdev; + /* FIXME: must exit iterator then break */ + klist_iter_exit(&iter); break; } } - spin_unlock(&cont->containers_lock); return cdev; } diff --git a/include/linux/attribute_container.h b/include/linux/attribute_container.h index ee83fe64a10..93bfb0beb62 100644 --- a/include/linux/attribute_container.h +++ b/include/linux/attribute_container.h @@ -11,12 +11,12 @@ #include #include +#include #include struct attribute_container { struct list_head node; - struct list_head containers; - spinlock_t containers_lock; + struct klist containers; struct class *class; struct class_device_attribute **attrs; int (*match)(struct attribute_container *, struct device *); From 2b7d6a8cb9718fc1d9e826201b64909c44a915f4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 28 Aug 2005 09:13:17 -0500 Subject: [PATCH 02/32] [SCSI] attribute container final klist fixes Since the attribute container deletes from a klist while it's walking it, it is vulnerable to the problem (and fix) here: http://marc.theaimsgroup.com/?l=linux-scsi&m=112485448830217 The attached fixes this (but won't compile without the above). It also fixes the logical reversal in the traversal loop which meant that we were never actually traversing the loop to hit this bug in the first place. Signed-off-by: James Bottomley --- drivers/base/attribute_container.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 6c0f49340eb..373e7b728fa 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -27,6 +27,21 @@ struct internal_container { struct class_device classdev; }; +static void internal_container_klist_get(struct klist_node *n) +{ + struct internal_container *ic = + container_of(n, struct internal_container, node); + class_device_get(&ic->classdev); +} + +static void internal_container_klist_put(struct klist_node *n) +{ + struct internal_container *ic = + container_of(n, struct internal_container, node); + class_device_put(&ic->classdev); +} + + /** * attribute_container_classdev_to_container - given a classdev, return the container * @@ -57,7 +72,8 @@ int attribute_container_register(struct attribute_container *cont) { INIT_LIST_HEAD(&cont->node); - klist_init(&cont->containers); + klist_init(&cont->containers,internal_container_klist_get, + internal_container_klist_put); down(&attribute_container_mutex); list_add_tail(&cont->node, &attribute_container_list); @@ -163,8 +179,8 @@ attribute_container_add_device(struct device *dev, #define klist_for_each_entry(pos, head, member, iter) \ for (klist_iter_init(head, iter); (pos = ({ \ struct klist_node *n = klist_next(iter); \ - n ? ({ klist_iter_exit(iter) ; NULL; }) : \ - container_of(n, typeof(*pos), member);\ + n ? container_of(n, typeof(*pos), member) : \ + ({ klist_iter_exit(iter) ; NULL; }); \ }) ) != NULL; ) @@ -206,7 +222,7 @@ attribute_container_remove_device(struct device *dev, klist_for_each_entry(ic, &cont->containers, node, &iter) { if (dev != ic->classdev.dev) continue; - klist_remove(&ic->node); + klist_del(&ic->node); if (fn) fn(cont, dev, &ic->classdev); else { From 61a7afa2c476a3be261cf88a95b0dea0c3bd29d4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 16 Aug 2005 18:27:34 -0500 Subject: [PATCH 03/32] [SCSI] embryonic RAID class The idea behind a RAID class is to provide a uniform interface to all RAID subsystems (both hardware and software) in the kernel. To do that, I've made this class a transport class that's entirely subsystem independent (although the matching routines have to match per subsystem, as you'll see looking at the code). I put it in the scsi subdirectory purely because I needed somewhere to play with it, but it's not a scsi specific module. I used a fusion raid card as the test bed for this; with that kind of card, this is the type of class output you get: jejb@titanic> ls -l /sys/class/raid_devices/20\:0\:0\:0/ total 0 lrwxrwxrwx 1 root root 0 Aug 16 17:21 component-0 -> ../../../devices/pci0000:80/0000:80:04.0/host20/target20:1:0/20:1:0:0/ lrwxrwxrwx 1 root root 0 Aug 16 17:21 component-1 -> ../../../devices/pci0000:80/0000:80:04.0/host20/target20:1:1/20:1:1:0/ lrwxrwxrwx 1 root root 0 Aug 16 17:21 device -> ../../../devices/pci0000:80/0000:80:04.0/host20/target20:0:0/20:0:0:0/ -r--r--r-- 1 root root 16384 Aug 16 17:21 level -r--r--r-- 1 root root 16384 Aug 16 17:21 resync -r--r--r-- 1 root root 16384 Aug 16 17:21 state So it's really simple: for a SCSI device representing a hardware raid, it shows the raid level, the array state, the resync % complete (if the state is resyncing) and the underlying components of the RAID (these are exposed in fusion on the virtual channel 1). As you can see, this type of information can be exported by almost anything, including software raid. The more difficult trick, of course, is going to be getting it to perform configuration type actions with writable attributes. Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 6 + drivers/scsi/Makefile | 2 + drivers/scsi/raid_class.c | 250 +++++++++++++++++++++++++++++++++++++ include/linux/raid_class.h | 59 +++++++++ 4 files changed, 317 insertions(+) create mode 100644 drivers/scsi/raid_class.c create mode 100644 include/linux/raid_class.h diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 96df148ed96..68adc3cc8ad 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,5 +1,11 @@ menu "SCSI device support" +config RAID_ATTRS + tristate "RAID Transport Class" + default n + ---help--- + Provides RAID + config SCSI tristate "SCSI device support" ---help--- diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 3746fb9fa2f..85f9e6bb34b 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -22,6 +22,8 @@ subdir-$(CONFIG_PCMCIA) += pcmcia obj-$(CONFIG_SCSI) += scsi_mod.o +obj-$(CONFIG_RAID_ATTRS) += raid_class.o + # --- NOTE ORDERING HERE --- # For kernel non-modular link, transport attributes need to # be initialised before drivers diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c new file mode 100644 index 00000000000..f1ea5027865 --- /dev/null +++ b/drivers/scsi/raid_class.c @@ -0,0 +1,250 @@ +/* + * RAID Attributes + */ +#include +#include +#include +#include +#include +#include + +#define RAID_NUM_ATTRS 3 + +struct raid_internal { + struct raid_template r; + struct raid_function_template *f; + /* The actual attributes */ + struct class_device_attribute private_attrs[RAID_NUM_ATTRS]; + /* The array of null terminated pointers to attributes + * needed by scsi_sysfs.c */ + struct class_device_attribute *attrs[RAID_NUM_ATTRS + 1]; +}; + +struct raid_component { + struct list_head node; + struct device *dev; + int num; +}; + +#define to_raid_internal(tmpl) container_of(tmpl, struct raid_internal, r) + +#define tc_to_raid_internal(tcont) ({ \ + struct raid_template *r = \ + container_of(tcont, struct raid_template, raid_attrs); \ + to_raid_internal(r); \ +}) + +#define ac_to_raid_internal(acont) ({ \ + struct transport_container *tc = \ + container_of(acont, struct transport_container, ac); \ + tc_to_raid_internal(tc); \ +}) + +#define class_device_to_raid_internal(cdev) ({ \ + struct attribute_container *ac = \ + attribute_container_classdev_to_container(cdev); \ + ac_to_raid_internal(ac); \ +}) + + +static int raid_match(struct attribute_container *cont, struct device *dev) +{ + /* We have to look for every subsystem that could house + * emulated RAID devices, so start with SCSI */ + struct raid_internal *i = ac_to_raid_internal(cont); + + if (scsi_is_sdev_device(dev)) { + struct scsi_device *sdev = to_scsi_device(dev); + + if (i->f->cookie != sdev->host->hostt) + return 0; + + return i->f->is_raid(dev); + } + /* FIXME: look at other subsystems too */ + return 0; +} + +static int raid_setup(struct transport_container *tc, struct device *dev, + struct class_device *cdev) +{ + struct raid_data *rd; + + BUG_ON(class_get_devdata(cdev)); + + rd = kmalloc(sizeof(*rd), GFP_KERNEL); + if (!rd) + return -ENOMEM; + + memset(rd, 0, sizeof(*rd)); + INIT_LIST_HEAD(&rd->component_list); + class_set_devdata(cdev, rd); + + return 0; +} + +static int raid_remove(struct transport_container *tc, struct device *dev, + struct class_device *cdev) +{ + struct raid_data *rd = class_get_devdata(cdev); + struct raid_component *rc, *next; + class_set_devdata(cdev, NULL); + list_for_each_entry_safe(rc, next, &rd->component_list, node) { + char buf[40]; + snprintf(buf, sizeof(buf), "component-%d", rc->num); + list_del(&rc->node); + sysfs_remove_link(&cdev->kobj, buf); + kfree(rc); + } + kfree(class_get_devdata(cdev)); + return 0; +} + +static DECLARE_TRANSPORT_CLASS(raid_class, + "raid_devices", + raid_setup, + raid_remove, + NULL); + +static struct { + enum raid_state value; + char *name; +} raid_states[] = { + { RAID_ACTIVE, "active" }, + { RAID_DEGRADED, "degraded" }, + { RAID_RESYNCING, "resyncing" }, + { RAID_OFFLINE, "offline" }, +}; + +static const char *raid_state_name(enum raid_state state) +{ + int i; + char *name = NULL; + + for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) { + if (raid_states[i].value == state) { + name = raid_states[i].name; + break; + } + } + return name; +} + + +#define raid_attr_show_internal(attr, fmt, var, code) \ +static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \ +{ \ + struct raid_data *rd = class_get_devdata(cdev); \ + code \ + return snprintf(buf, 20, #fmt "\n", var); \ +} + +#define raid_attr_ro_states(attr, states, code) \ +raid_attr_show_internal(attr, %s, name, \ + const char *name; \ + code \ + name = raid_##states##_name(rd->attr); \ +) \ +static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL) + + +#define raid_attr_ro_internal(attr, code) \ +raid_attr_show_internal(attr, %d, rd->attr, code) \ +static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL) + +#define ATTR_CODE(attr) \ + struct raid_internal *i = class_device_to_raid_internal(cdev); \ + if (i->f->get_##attr) \ + i->f->get_##attr(cdev->dev); + +#define raid_attr_ro(attr) raid_attr_ro_internal(attr, ) +#define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr)) +#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr)) + +raid_attr_ro(level); +raid_attr_ro_fn(resync); +raid_attr_ro_state(state); + +void raid_component_add(struct raid_template *r,struct device *raid_dev, + struct device *component_dev) +{ + struct class_device *cdev = + attribute_container_find_class_device(&r->raid_attrs.ac, + raid_dev); + struct raid_component *rc; + struct raid_data *rd = class_get_devdata(cdev); + char buf[40]; + + rc = kmalloc(sizeof(*rc), GFP_KERNEL); + if (!rc) + return; + + INIT_LIST_HEAD(&rc->node); + rc->dev = component_dev; + rc->num = rd->component_count++; + + snprintf(buf, sizeof(buf), "component-%d", rc->num); + list_add_tail(&rc->node, &rd->component_list); + sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf); +} +EXPORT_SYMBOL(raid_component_add); + +struct raid_template * +raid_class_attach(struct raid_function_template *ft) +{ + struct raid_internal *i = kmalloc(sizeof(struct raid_internal), + GFP_KERNEL); + int count = 0; + + if (unlikely(!i)) + return NULL; + + memset(i, 0, sizeof(*i)); + + i->f = ft; + + i->r.raid_attrs.ac.class = &raid_class.class; + i->r.raid_attrs.ac.match = raid_match; + i->r.raid_attrs.ac.attrs = &i->attrs[0]; + + attribute_container_register(&i->r.raid_attrs.ac); + + i->attrs[count++] = &class_device_attr_level; + i->attrs[count++] = &class_device_attr_resync; + i->attrs[count++] = &class_device_attr_state; + + i->attrs[count] = NULL; + BUG_ON(count > RAID_NUM_ATTRS); + + return &i->r; +} +EXPORT_SYMBOL(raid_class_attach); + +void +raid_class_release(struct raid_template *r) +{ + struct raid_internal *i = to_raid_internal(r); + + attribute_container_unregister(&i->r.raid_attrs.ac); + + kfree(i); +} +EXPORT_SYMBOL(raid_class_release); + +static __init int raid_init(void) +{ + return transport_class_register(&raid_class); +} + +static __exit void raid_exit(void) +{ + transport_class_unregister(&raid_class); +} + +MODULE_AUTHOR("James Bottomley"); +MODULE_DESCRIPTION("RAID device class"); +MODULE_LICENSE("GPL"); + +module_init(raid_init); +module_exit(raid_exit); + diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h new file mode 100644 index 00000000000..a71123c2827 --- /dev/null +++ b/include/linux/raid_class.h @@ -0,0 +1,59 @@ +/* + */ +#include + +struct raid_template { + struct transport_container raid_attrs; +}; + +struct raid_function_template { + void *cookie; + int (*is_raid)(struct device *); + void (*get_resync)(struct device *); + void (*get_state)(struct device *); +}; + +enum raid_state { + RAID_ACTIVE = 1, + RAID_DEGRADED, + RAID_RESYNCING, + RAID_OFFLINE, +}; + +struct raid_data { + struct list_head component_list; + int component_count; + int level; + enum raid_state state; + int resync; +}; + +#define DEFINE_RAID_ATTRIBUTE(type, attr) \ +static inline void \ +raid_set_##attr(struct raid_template *r, struct device *dev, type value) { \ + struct class_device *cdev = \ + attribute_container_find_class_device(&r->raid_attrs.ac, dev);\ + struct raid_data *rd; \ + BUG_ON(!cdev); \ + rd = class_get_devdata(cdev); \ + rd->attr = value; \ +} \ +static inline type \ +raid_get_##attr(struct raid_template *r, struct device *dev) { \ + struct class_device *cdev = \ + attribute_container_find_class_device(&r->raid_attrs.ac, dev);\ + struct raid_data *rd; \ + BUG_ON(!cdev); \ + rd = class_get_devdata(cdev); \ + return rd->attr; \ +} + +DEFINE_RAID_ATTRIBUTE(int, level) +DEFINE_RAID_ATTRIBUTE(int, resync) +DEFINE_RAID_ATTRIBUTE(enum raid_state, state) + +struct raid_template *raid_class_attach(struct raid_function_template *); +void raid_class_release(struct raid_template *); + +void raid_component_add(struct raid_template *, struct device *, + struct device *); From 07542b832309b93a2741cd162a391ab909f66438 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 31 Aug 2005 20:27:22 -0400 Subject: [PATCH 04/32] This patch fixes in st.c the bug in the signed/unsigned int comparison reported by Doug Gilbert and fixed by him in sg.c (see [PATCH] sg direct io/mmap oops). Doug fixed the comparison in sg.c. This fix for st.c does not touch the comparison but makes both arguments signed to remove the problem. The new code is adapted from linux/fs/bio.c. Signed-off-by: Kai Makisara Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/st.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 47a5698a712..5325cf0ab19 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static char *verstr = "20050802"; +static char *verstr = "20050830"; #include @@ -4444,12 +4444,12 @@ static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pag static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, unsigned long uaddr, size_t count, int rw) { + unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT; + unsigned long start = uaddr >> PAGE_SHIFT; + const int nr_pages = end - start; int res, i, j; - unsigned int nr_pages; struct page **pages; - nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; - /* User attempted Overflow! */ if ((uaddr + count) < uaddr) return -EINVAL; From deb92b7ee98e8e580cafaa63bd1edbe6646877bc Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Thu, 1 Sep 2005 21:50:02 +1000 Subject: [PATCH 05/32] [SCSI] sg direct io/mmap oops, st sync This patch adopts the same solution as proposed by Kai M. in a post titled: "[PATCH] SCSI tape signed/unsigned fix". The fix is in a function that the sg driver borrowed from the st driver so its maintenance is a little easier if the functions remain the same after the fix. - change nr_pages type from unsigned to signed so errors from get_user_pages() call are properly handled Signed-off-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/sg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 14fb179b384..616c3f3e62f 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -61,7 +61,7 @@ static int sg_version_num = 30533; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20050328"; +static char *sg_version_date = "20050901"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -1794,12 +1794,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, unsigned long uaddr, size_t count, int rw, unsigned long max_pfn) { + unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT; + unsigned long start = uaddr >> PAGE_SHIFT; + const int nr_pages = end - start; int res, i, j; - unsigned int nr_pages; struct page **pages; - nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; - /* User attempted Overflow! */ if ((uaddr + count) < uaddr) return -EINVAL; From 77d71d222e871670300f3e3092e2a06f20c842f0 Mon Sep 17 00:00:00 2001 From: Mark Haverkamp Date: Thu, 1 Sep 2005 08:19:23 -0700 Subject: [PATCH 06/32] [SCSI] aacraid: bad BUG_ON fix This was noticed by Doug Bazamic and the fix found by Mark Salyzyn at Adaptec. There was an error in the BUG_ON() statement that validated the calculated fib size which can cause the driver to panic. Signed-off-by: Mark Haverkamp Signed-off-by: James Bottomley --- drivers/scsi/aacraid/aachba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 83bfab73ff6..a8e3dfcd0dc 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -972,7 +972,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) fibsize = sizeof(struct aac_read64) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentry64)); - BUG_ON (fibsize > (sizeof(struct hw_fib) - + BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter From 1ff927306e08b356d764e605eff7c50079550bd2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 19 Aug 2005 18:57:13 +0200 Subject: [PATCH 07/32] [SCSI] aic7xxx: remove aiclib.c #include of C files and macro tricks to rename symbols are evil and just cause trouble. Let's doublicate the two functions as they're going to go away soon enough anyway. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic79xx_osm.c | 96 +++++++++++++++++++--- drivers/scsi/aic7xxx/aic79xx_proc.c | 45 ++++++++++- drivers/scsi/aic7xxx/aic7xxx_osm.c | 89 ++++++++++++++++++-- drivers/scsi/aic7xxx/aic7xxx_proc.c | 45 ++++++++++- drivers/scsi/aic7xxx/aiclib.c | 121 ---------------------------- drivers/scsi/aic7xxx/aiclib.h | 22 ----- 6 files changed, 253 insertions(+), 165 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 3feb739cd55..6b6d4e28779 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -48,12 +48,6 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL; -/* - * Include aiclib.c as part of our - * "module dependencies are hard" work around. - */ -#include "aiclib.c" - #include /* __setup */ #include /* For fetching system memory size */ #include /* For block_size() */ @@ -372,8 +366,6 @@ static int ahd_linux_run_command(struct ahd_softc*, struct ahd_linux_device *, struct scsi_cmnd *); static void ahd_linux_setup_tag_info_global(char *p); -static aic_option_callback_t ahd_linux_setup_tag_info; -static aic_option_callback_t ahd_linux_setup_iocell_info; static int aic79xx_setup(char *c); static int ahd_linux_unit; @@ -907,6 +899,86 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) } } +static char * +ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, + void (*callback)(u_long, int, int, int32_t), + u_long callback_arg) +{ + char *tok_end; + char *tok_end2; + int i; + int instance; + int targ; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + /* All options use a ':' name/arg separator */ + if (*opt_arg != ':') + return (opt_arg); + opt_arg++; + instance = -1; + targ = -1; + done = FALSE; + /* + * Restore separator that may be in + * the middle of our option argument. + */ + tok_end = strchr(opt_arg, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*opt_arg) { + case '{': + if (instance == -1) { + instance = 0; + } else { + if (depth > 1) { + if (targ == -1) + targ = 0; + } else { + printf("Malformed Option %s\n", + opt_name); + done = TRUE; + } + } + opt_arg++; + break; + case '}': + if (targ != -1) + targ = -1; + else if (instance != -1) + instance = -1; + opt_arg++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (targ >= 0) + targ++; + else if (instance >= 0) + instance++; + opt_arg++; + break; + case '\0': + done = TRUE; + break; + default: + tok_end = end; + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(opt_arg, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) + tok_end = tok_end2; + } + callback(callback_arg, instance, targ, + simple_strtol(opt_arg, NULL, 0)); + opt_arg = tok_end; + break; + } + } + return (opt_arg); +} + /* * Handle Linux boot parameters. This routine allows for assigning a value * to a parameter with a ':' between the parameter and the value. @@ -964,18 +1036,18 @@ aic79xx_setup(char *s) if (strncmp(p, "global_tag_depth", n) == 0) { ahd_linux_setup_tag_info_global(p + n); } else if (strncmp(p, "tag_info", n) == 0) { - s = aic_parse_brace_option("tag_info", p + n, end, + s = ahd_parse_brace_option("tag_info", p + n, end, 2, ahd_linux_setup_tag_info, 0); } else if (strncmp(p, "slewrate", n) == 0) { - s = aic_parse_brace_option("slewrate", + s = ahd_parse_brace_option("slewrate", p + n, end, 1, ahd_linux_setup_iocell_info, AIC79XX_SLEWRATE_INDEX); } else if (strncmp(p, "precomp", n) == 0) { - s = aic_parse_brace_option("precomp", + s = ahd_parse_brace_option("precomp", p + n, end, 1, ahd_linux_setup_iocell_info, AIC79XX_PRECOMP_INDEX); } else if (strncmp(p, "amplitude", n) == 0) { - s = aic_parse_brace_option("amplitude", + s = ahd_parse_brace_option("amplitude", p + n, end, 1, ahd_linux_setup_iocell_info, AIC79XX_AMPLITUDE_INDEX); } else if (p[n] == ':') { diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 32be1f55998..39a27840fce 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -53,6 +53,49 @@ static void ahd_dump_device_state(struct info_str *info, static int ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length); +/* + * Table of syncrates that don't follow the "divisible by 4" + * rule. This table will be expanded in future SCSI specs. + */ +static struct { + u_int period_factor; + u_int period; /* in 100ths of ns */ +} scsi_syncrates[] = { + { 0x08, 625 }, /* FAST-160 */ + { 0x09, 1250 }, /* FAST-80 */ + { 0x0a, 2500 }, /* FAST-40 40MHz */ + { 0x0b, 3030 }, /* FAST-40 33MHz */ + { 0x0c, 5000 } /* FAST-20 */ +}; + +/* + * Return the frequency in kHz corresponding to the given + * sync period factor. + */ +static u_int +ahd_calc_syncsrate(u_int period_factor) +{ + int i; + int num_syncrates; + + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); + /* See if the period is in the "exception" table */ + for (i = 0; i < num_syncrates; i++) { + + if (period_factor == scsi_syncrates[i].period_factor) { + /* Period in kHz */ + return (100000000 / scsi_syncrates[i].period); + } + } + + /* + * Wasn't in the table, so use the standard + * 4 times conversion. + */ + return (10000000 / (period_factor * 4 * 10)); +} + + static void copy_mem_info(struct info_str *info, char *data, int len) { @@ -109,7 +152,7 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) speed = 3300; freq = 0; if (tinfo->offset != 0) { - freq = aic_calc_syncsrate(tinfo->period); + freq = ahd_calc_syncsrate(tinfo->period); speed = freq; } speed *= (0x01 << tinfo->width); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 22434849de4..4096d523d08 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -125,12 +125,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; -/* - * Include aiclib.c as part of our - * "module dependencies are hard" work around. - */ -#include "aiclib.c" - #include /* __setup */ #include /* For fetching system memory size */ #include /* For block_size() */ @@ -391,7 +385,6 @@ static int ahc_linux_run_command(struct ahc_softc*, struct ahc_linux_device *, struct scsi_cmnd *); static void ahc_linux_setup_tag_info_global(char *p); -static aic_option_callback_t ahc_linux_setup_tag_info; static int aic7xxx_setup(char *s); static int ahc_linux_unit; @@ -920,6 +913,86 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) } } +static char * +ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, + void (*callback)(u_long, int, int, int32_t), + u_long callback_arg) +{ + char *tok_end; + char *tok_end2; + int i; + int instance; + int targ; + int done; + char tok_list[] = {'.', ',', '{', '}', '\0'}; + + /* All options use a ':' name/arg separator */ + if (*opt_arg != ':') + return (opt_arg); + opt_arg++; + instance = -1; + targ = -1; + done = FALSE; + /* + * Restore separator that may be in + * the middle of our option argument. + */ + tok_end = strchr(opt_arg, '\0'); + if (tok_end < end) + *tok_end = ','; + while (!done) { + switch (*opt_arg) { + case '{': + if (instance == -1) { + instance = 0; + } else { + if (depth > 1) { + if (targ == -1) + targ = 0; + } else { + printf("Malformed Option %s\n", + opt_name); + done = TRUE; + } + } + opt_arg++; + break; + case '}': + if (targ != -1) + targ = -1; + else if (instance != -1) + instance = -1; + opt_arg++; + break; + case ',': + case '.': + if (instance == -1) + done = TRUE; + else if (targ >= 0) + targ++; + else if (instance >= 0) + instance++; + opt_arg++; + break; + case '\0': + done = TRUE; + break; + default: + tok_end = end; + for (i = 0; tok_list[i]; i++) { + tok_end2 = strchr(opt_arg, tok_list[i]); + if ((tok_end2) && (tok_end2 < tok_end)) + tok_end = tok_end2; + } + callback(callback_arg, instance, targ, + simple_strtol(opt_arg, NULL, 0)); + opt_arg = tok_end; + break; + } + } + return (opt_arg); +} + /* * Handle Linux boot parameters. This routine allows for assigning a value * to a parameter with a ':' between the parameter and the value. @@ -974,7 +1047,7 @@ aic7xxx_setup(char *s) if (strncmp(p, "global_tag_depth", n) == 0) { ahc_linux_setup_tag_info_global(p + n); } else if (strncmp(p, "tag_info", n) == 0) { - s = aic_parse_brace_option("tag_info", p + n, end, + s = ahc_parse_brace_option("tag_info", p + n, end, 2, ahc_linux_setup_tag_info, 0); } else if (p[n] == ':') { *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 3802c91f0b0..04a3506cf34 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -54,6 +54,49 @@ static void ahc_dump_device_state(struct info_str *info, static int ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length); +/* + * Table of syncrates that don't follow the "divisible by 4" + * rule. This table will be expanded in future SCSI specs. + */ +static struct { + u_int period_factor; + u_int period; /* in 100ths of ns */ +} scsi_syncrates[] = { + { 0x08, 625 }, /* FAST-160 */ + { 0x09, 1250 }, /* FAST-80 */ + { 0x0a, 2500 }, /* FAST-40 40MHz */ + { 0x0b, 3030 }, /* FAST-40 33MHz */ + { 0x0c, 5000 } /* FAST-20 */ +}; + +/* + * Return the frequency in kHz corresponding to the given + * sync period factor. + */ +static u_int +ahc_calc_syncsrate(u_int period_factor) +{ + int i; + int num_syncrates; + + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); + /* See if the period is in the "exception" table */ + for (i = 0; i < num_syncrates; i++) { + + if (period_factor == scsi_syncrates[i].period_factor) { + /* Period in kHz */ + return (100000000 / scsi_syncrates[i].period); + } + } + + /* + * Wasn't in the table, so use the standard + * 4 times conversion. + */ + return (10000000 / (period_factor * 4 * 10)); +} + + static void copy_mem_info(struct info_str *info, char *data, int len) { @@ -106,7 +149,7 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo) speed = 3300; freq = 0; if (tinfo->offset != 0) { - freq = aic_calc_syncsrate(tinfo->period); + freq = ahc_calc_syncsrate(tinfo->period); speed = freq; } speed *= (0x01 << tinfo->width); diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c index 4d44a921118..828ae3d9a51 100644 --- a/drivers/scsi/aic7xxx/aiclib.c +++ b/drivers/scsi/aic7xxx/aiclib.c @@ -32,124 +32,3 @@ #include "aiclib.h" - -/* - * Table of syncrates that don't follow the "divisible by 4" - * rule. This table will be expanded in future SCSI specs. - */ -static struct { - u_int period_factor; - u_int period; /* in 100ths of ns */ -} scsi_syncrates[] = { - { 0x08, 625 }, /* FAST-160 */ - { 0x09, 1250 }, /* FAST-80 */ - { 0x0a, 2500 }, /* FAST-40 40MHz */ - { 0x0b, 3030 }, /* FAST-40 33MHz */ - { 0x0c, 5000 } /* FAST-20 */ -}; - -/* - * Return the frequency in kHz corresponding to the given - * sync period factor. - */ -u_int -aic_calc_syncsrate(u_int period_factor) -{ - int i; - int num_syncrates; - - num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); - /* See if the period is in the "exception" table */ - for (i = 0; i < num_syncrates; i++) { - - if (period_factor == scsi_syncrates[i].period_factor) { - /* Period in kHz */ - return (100000000 / scsi_syncrates[i].period); - } - } - - /* - * Wasn't in the table, so use the standard - * 4 times conversion. - */ - return (10000000 / (period_factor * 4 * 10)); -} - -char * -aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, - aic_option_callback_t *callback, u_long callback_arg) -{ - char *tok_end; - char *tok_end2; - int i; - int instance; - int targ; - int done; - char tok_list[] = {'.', ',', '{', '}', '\0'}; - - /* All options use a ':' name/arg separator */ - if (*opt_arg != ':') - return (opt_arg); - opt_arg++; - instance = -1; - targ = -1; - done = FALSE; - /* - * Restore separator that may be in - * the middle of our option argument. - */ - tok_end = strchr(opt_arg, '\0'); - if (tok_end < end) - *tok_end = ','; - while (!done) { - switch (*opt_arg) { - case '{': - if (instance == -1) { - instance = 0; - } else { - if (depth > 1) { - if (targ == -1) - targ = 0; - } else { - printf("Malformed Option %s\n", - opt_name); - done = TRUE; - } - } - opt_arg++; - break; - case '}': - if (targ != -1) - targ = -1; - else if (instance != -1) - instance = -1; - opt_arg++; - break; - case ',': - case '.': - if (instance == -1) - done = TRUE; - else if (targ >= 0) - targ++; - else if (instance >= 0) - instance++; - opt_arg++; - break; - case '\0': - done = TRUE; - break; - default: - tok_end = end; - for (i = 0; tok_list[i]; i++) { - tok_end2 = strchr(opt_arg, tok_list[i]); - if ((tok_end2) && (tok_end2 < tok_end)) - tok_end = tok_end2; - } - callback(callback_arg, instance, targ, - simple_strtol(opt_arg, NULL, 0)); - opt_arg = tok_end; - break; - } - } - return (opt_arg); -} diff --git a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h index e7d94cbaf2a..3bfbf0fe1ec 100644 --- a/drivers/scsi/aic7xxx/aiclib.h +++ b/drivers/scsi/aic7xxx/aiclib.h @@ -141,28 +141,6 @@ aic_sector_div(sector_t capacity, int heads, int sectors) return (int)capacity; } -/**************************** Module Library Hack *****************************/ -/* - * What we'd like to do is have a single "scsi library" module that both the - * aic7xxx and aic79xx drivers could load and depend on. A cursory examination - * of implementing module dependencies in Linux (handling the install and - * initrd cases) does not look promissing. For now, we just duplicate this - * code in both drivers using a simple symbol renaming scheme that hides this - * hack from the drivers. - */ -#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x -#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix) -#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX) - -#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate) - -u_int aic_calc_syncsrate(u_int /*period_factor*/); - -typedef void aic_option_callback_t(u_long, int, int, int32_t); -char * aic_parse_brace_option(char *opt_name, char *opt_arg, - char *end, int depth, - aic_option_callback_t *, u_long); - static __inline uint32_t scsi_4btoul(uint8_t *bytes) { From 69218ee5186aded6c78e12e083e073d000ff2e9b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Aug 2005 16:26:15 +0200 Subject: [PATCH 08/32] [SCSI] fusion: extended config header support Acked by: Moore, Eric Dean Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 90 +++++++++++++++++++++---------- drivers/message/fusion/mptbase.h | 5 +- drivers/message/fusion/mptctl.c | 12 ++--- drivers/message/fusion/mptscsih.c | 18 +++---- 4 files changed, 81 insertions(+), 44 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index ffbe6f4720e..28420276680 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -491,10 +491,21 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) pCfg->status = status; if (status == MPI_IOCSTATUS_SUCCESS) { - pCfg->hdr->PageVersion = pReply->Header.PageVersion; - pCfg->hdr->PageLength = pReply->Header.PageLength; - pCfg->hdr->PageNumber = pReply->Header.PageNumber; - pCfg->hdr->PageType = pReply->Header.PageType; + if ((pReply->Header.PageType & + MPI_CONFIG_PAGETYPE_MASK) == + MPI_CONFIG_PAGETYPE_EXTENDED) { + pCfg->cfghdr.ehdr->ExtPageLength = + le16_to_cpu(pReply->ExtPageLength); + pCfg->cfghdr.ehdr->ExtPageType = + pReply->ExtPageType; + } + pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; + + /* If this is a regular header, save PageLength. */ + /* LMP Do this better so not using a reserved field! */ + pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; + pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; + pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; } } @@ -3819,7 +3830,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) hdr.PageLength = 0; hdr.PageNumber = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.physAddr = -1; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; @@ -3863,7 +3874,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) hdr.PageLength = 0; hdr.PageNumber = 1; hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.physAddr = -1; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; @@ -3930,7 +3941,7 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) hdr.PageLength = 0; hdr.PageNumber = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.physAddr = -1; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; @@ -4012,7 +4023,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc) hdr.PageLength = 0; hdr.PageNumber = 2; hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.physAddr = -1; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; @@ -4102,7 +4113,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) header.PageLength = 0; header.PageNumber = 0; header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = portnum; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4168,7 +4179,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) header.PageLength = 0; header.PageNumber = 2; header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = portnum; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4236,7 +4247,7 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) header.PageLength = 0; header.PageNumber = 1; header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = portnum; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4245,8 +4256,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) if (mpt_config(ioc, &cfg) != 0) return -EFAULT; - ioc->spi_data.sdp1version = cfg.hdr->PageVersion; - ioc->spi_data.sdp1length = cfg.hdr->PageLength; + ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion; + ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength; header.PageVersion = 0; header.PageLength = 0; @@ -4255,8 +4266,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) if (mpt_config(ioc, &cfg) != 0) return -EFAULT; - ioc->spi_data.sdp0version = cfg.hdr->PageVersion; - ioc->spi_data.sdp0length = cfg.hdr->PageLength; + ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion; + ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength; dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n", ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); @@ -4298,7 +4309,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) header.PageLength = 0; header.PageNumber = 2; header.PageType = MPI_CONFIG_PAGETYPE_IOC; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4394,7 +4405,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) header.PageLength = 0; header.PageNumber = 3; header.PageType = MPI_CONFIG_PAGETYPE_IOC; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4446,7 +4457,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) header.PageLength = 0; header.PageNumber = 4; header.PageType = MPI_CONFIG_PAGETYPE_IOC; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4498,7 +4509,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) header.PageLength = 0; header.PageNumber = 1; header.PageType = MPI_CONFIG_PAGETYPE_IOC; - cfg.hdr = &header; + cfg.cfghdr.hdr = &header; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -4647,10 +4658,11 @@ int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) { Config_t *pReq; + ConfigExtendedPageHeader_t *pExtHdr = NULL; MPT_FRAME_HDR *mf; unsigned long flags; int ii, rc; - u32 flagsLength; + int flagsLength; int in_isr; /* Prevent calling wait_event() (below), if caller happens @@ -4675,16 +4687,30 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) pReq->Reserved = 0; pReq->ChainOffset = 0; pReq->Function = MPI_FUNCTION_CONFIG; + + /* Assume page type is not extended and clear "reserved" fields. */ pReq->ExtPageLength = 0; pReq->ExtPageType = 0; pReq->MsgFlags = 0; + for (ii=0; ii < 8; ii++) pReq->Reserved2[ii] = 0; - pReq->Header.PageVersion = pCfg->hdr->PageVersion; - pReq->Header.PageLength = pCfg->hdr->PageLength; - pReq->Header.PageNumber = pCfg->hdr->PageNumber; - pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); + pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion; + pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength; + pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber; + pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); + + if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { + pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr; + pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength); + pReq->ExtPageType = pExtHdr->ExtPageType; + pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; + + /* Page Length must be treated as a reserved field for the extended header. */ + pReq->Header.PageLength = 0; + } + pReq->PageAddress = cpu_to_le32(pCfg->pageAddr); /* Add a SGE to the config request. @@ -4694,13 +4720,21 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) else flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; - flagsLength |= pCfg->hdr->PageLength * 4; + if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { + flagsLength |= pExtHdr->ExtPageLength * 4; + + dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", + ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action)); + } + else { + flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; + + dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", + ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); + } mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); - dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", - ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); - /* Append pCfg pointer to end of mf */ *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 848fb236b17..f4827d92373 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -915,7 +915,10 @@ struct scsi_cmnd; typedef struct _x_config_parms { struct list_head linkage; /* linked list */ struct timer_list timer; /* timer function for this request */ - ConfigPageHeader_t *hdr; + union { + ConfigExtendedPageHeader_t *ehdr; + ConfigPageHeader_t *hdr; + } cfghdr; dma_addr_t physAddr; int wait_done; /* wait for this request */ u32 pageAddr; /* properly formatted */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 05ea5944c48..e63a3fd6b70 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -2324,7 +2324,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) hdr.PageLength = 0; hdr.PageNumber = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; @@ -2333,7 +2333,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) strncpy(karg.serial_number, " ", 24); if (mpt_config(ioc, &cfg) == 0) { - if (cfg.hdr->PageLength > 0) { + if (cfg.cfghdr.hdr->PageLength > 0) { /* Issue the second config page request */ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; @@ -2479,7 +2479,7 @@ mptctl_hp_targetinfo(unsigned long arg) hdr.PageNumber = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; cfg.dir = 0; cfg.timeout = 0; @@ -2527,15 +2527,15 @@ mptctl_hp_targetinfo(unsigned long arg) hdr.PageNumber = 3; hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - cfg.hdr = &hdr; + cfg.cfghdr.hdr = &hdr; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; cfg.timeout = 0; cfg.physAddr = -1; - if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) { + if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) { /* Issue the second config page request */ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - data_sz = (int) cfg.hdr->PageLength * 4; + data_sz = (int) cfg.cfghdr.hdr->PageLength * 4; pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent( ioc->pcidev, data_sz, &page_dma); if (pg3_alloc) { diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b9d4f78725b..b774f45dfde 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -3955,7 +3955,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) header1.PageLength = ioc->spi_data.sdp1length; header1.PageNumber = 1; header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; - cfg.hdr = &header1; + cfg.cfghdr.hdr = &header1; cfg.physAddr = cfg1_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; @@ -4353,7 +4353,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) /* Prep cfg structure */ cfg.pageAddr = (bus<<8) | id; - cfg.hdr = NULL; + cfg.cfghdr.hdr = NULL; /* Prep SDP0 header */ @@ -4399,7 +4399,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz); cfg1_dma_addr = dvbuf_dma + sz; - /* Skip this ID? Set cfg.hdr to force config page write + /* Skip this ID? Set cfg.cfghdr.hdr to force config page write */ { ScsiCfgData *pspi_data = &hd->ioc->spi_data; @@ -4417,7 +4417,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) dv.cmd = MPT_SET_MAX; mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); - cfg.hdr = &header1; + cfg.cfghdr.hdr = &header1; /* Save the final negotiated settings to * SCSI device page 1. @@ -4483,7 +4483,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) dv.cmd = MPT_SET_MIN; mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); - cfg.hdr = &header1; + cfg.cfghdr.hdr = &header1; cfg.physAddr = cfg1_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; @@ -4637,7 +4637,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) u32 sdp0_info; u32 sdp0_nego; - cfg.hdr = &header0; + cfg.cfghdr.hdr = &header0; cfg.physAddr = cfg0_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; cfg.dir = 0; @@ -4722,7 +4722,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) * 4) release * 5) update nego parms to target struct */ - cfg.hdr = &header1; + cfg.cfghdr.hdr = &header1; cfg.physAddr = cfg1_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; @@ -5121,7 +5121,7 @@ target_done: /* Set if cfg1_dma_addr contents is valid */ - if ((cfg.hdr != NULL) && (retcode == 0)){ + if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){ /* If disk, not U320, disable QAS */ if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) { @@ -5137,7 +5137,7 @@ target_done: * skip save of the final negotiated settings to * SCSI device page 1. * - cfg.hdr = &header1; + cfg.cfghdr.hdr = &header1; cfg.physAddr = cfg1_dma_addr; cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; cfg.dir = 1; From ccf3b7bd26b242b39d54148ea2117295721681d3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Aug 2005 16:24:26 +0200 Subject: [PATCH 09/32] [SCSI] fusion: update LSI headers Acked by: Moore, Eric Dean Signed-off-by: James Bottomley --- drivers/message/fusion/lsi/mpi.h | 19 +- drivers/message/fusion/lsi/mpi_cnfg.h | 85 +++++++-- drivers/message/fusion/lsi/mpi_history.txt | 67 ++++--- drivers/message/fusion/lsi/mpi_init.h | 203 ++++++++++++++++++++- drivers/message/fusion/lsi/mpi_ioc.h | 11 +- drivers/message/fusion/lsi/mpi_targ.h | 74 +++++++- 6 files changed, 415 insertions(+), 44 deletions(-) diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 9f98334e507..b61e3d17507 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -6,7 +6,7 @@ * Title: MPI Message independent structures and definitions * Creation Date: July 27, 2000 * - * mpi.h Version: 01.05.07 + * mpi.h Version: 01.05.08 * * Version History * --------------- @@ -71,6 +71,9 @@ * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and * TargetAssistExtended requests. * Removed EEDP IOCStatus codes. + * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and + * TargetAssistExtended requests. + * Added EEDP IOCStatus codes. * -------------------------------------------------------------------------- */ @@ -101,7 +104,7 @@ /* Note: The major versions of 0xe0 through 0xff are reserved */ /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT (0x09) +#define MPI_HEADER_VERSION_UNIT (0x0A) #define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_SHIFT (8) @@ -292,10 +295,13 @@ #define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D) #define MPI_FUNCTION_DIAG_RELEASE (0x1E) +#define MPI_FUNCTION_SCSI_IO_32 (0x1F) + #define MPI_FUNCTION_LAN_SEND (0x20) #define MPI_FUNCTION_LAN_RECEIVE (0x21) #define MPI_FUNCTION_LAN_RESET (0x22) +#define MPI_FUNCTION_TARGET_ASSIST_EXTENDED (0x23) #define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) #define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) @@ -680,6 +686,15 @@ typedef struct _MSG_DEFAULT_REPLY #define MPI_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) #define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) +/****************************************************************************/ +/* For use by SCSI Initiator and SCSI Target end-to-end data protection */ +/****************************************************************************/ + +#define MPI_IOCSTATUS_EEDP_GUARD_ERROR (0x004D) +#define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E) +#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F) + + /****************************************************************************/ /* SCSI Target values */ /****************************************************************************/ diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index 15b12b06799..d8339896f73 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h @@ -6,7 +6,7 @@ * Title: MPI Config message, structures, and Pages * Creation Date: July 27, 2000 * - * mpi_cnfg.h Version: 01.05.08 + * mpi_cnfg.h Version: 01.05.09 * * Version History * --------------- @@ -232,6 +232,23 @@ * New physical mapping mode in SAS IO Unit Page 2. * Added CONFIG_PAGE_SAS_ENCLOSURE_0. * Added Slot and Enclosure fields to SAS Device Page 0. + * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1. + * Added more RAID type defines to IOC Page 2. + * Added Port Enable Delay settings to BIOS Page 1. + * Added Bad Block Table Full define to RAID Volume Page 0. + * Added Previous State defines to RAID Physical Disk + * Page 0. + * Added Max Sata Targets define for DiscoveryStatus field + * of SAS IO Unit Page 0. + * Added Device Self Test to Control Flags of SAS IO Unit + * Page 1. + * Added Direct Attach Starting Slot Number define for SAS + * IO Unit Page 2. + * Added new fields in SAS Device Page 2 for enclosure + * mapping. + * Added OwnerDevHandle and Flags field to SAS PHY Page 0. + * Added IOC GPIO Flags define to SAS Enclosure Page 0. + * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. * -------------------------------------------------------------------------- */ @@ -477,6 +494,7 @@ typedef struct _MSG_CONFIG_REPLY #define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626) #define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642) #define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640) +#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646) /* SCSI */ #define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) #define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) @@ -769,9 +787,13 @@ typedef struct _CONFIG_PAGE_IOC_1 } CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1, IOCPage1_t, MPI_POINTER pIOCPage1_t; -#define MPI_IOCPAGE1_PAGEVERSION (0x02) +#define MPI_IOCPAGE1_PAGEVERSION (0x03) /* defines for the Flags field */ +#define MPI_IOCPAGE1_EEDP_MODE_MASK (0x07000000) +#define MPI_IOCPAGE1_EEDP_MODE_OFF (0x00000000) +#define MPI_IOCPAGE1_EEDP_MODE_T10 (0x01000000) +#define MPI_IOCPAGE1_EEDP_MODE_LSI_1 (0x02000000) #define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE (0x00000010) #define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001) @@ -795,6 +817,11 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL #define MPI_RAID_VOL_TYPE_IS (0x00) #define MPI_RAID_VOL_TYPE_IME (0x01) #define MPI_RAID_VOL_TYPE_IM (0x02) +#define MPI_RAID_VOL_TYPE_RAID_5 (0x03) +#define MPI_RAID_VOL_TYPE_RAID_6 (0x04) +#define MPI_RAID_VOL_TYPE_RAID_10 (0x05) +#define MPI_RAID_VOL_TYPE_RAID_50 (0x06) +#define MPI_RAID_VOL_TYPE_UNKNOWN (0xFF) /* IOC Page 2 Volume Flags values */ @@ -820,13 +847,17 @@ typedef struct _CONFIG_PAGE_IOC_2 } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, IOCPage2_t, MPI_POINTER pIOCPage2_t; -#define MPI_IOCPAGE2_PAGEVERSION (0x02) +#define MPI_IOCPAGE2_PAGEVERSION (0x03) /* IOC Page 2 Capabilities flags */ #define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001) #define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002) #define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004) +#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT (0x00000008) +#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010) +#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020) +#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040) #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) @@ -945,7 +976,7 @@ typedef struct _CONFIG_PAGE_BIOS_1 } CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1, BIOSPage1_t, MPI_POINTER pBIOSPage1_t; -#define MPI_BIOSPAGE1_PAGEVERSION (0x01) +#define MPI_BIOSPAGE1_PAGEVERSION (0x02) /* values for the BiosOptions field */ #define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400) @@ -954,6 +985,8 @@ typedef struct _CONFIG_PAGE_BIOS_1 #define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) /* values for the IOCSettings field */ +#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000) +#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20) #define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) #define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) #define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) @@ -1167,6 +1200,7 @@ typedef struct _CONFIG_PAGE_BIOS_2 #define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER (0x03) #define MPI_BIOSPAGE2_FORM_FC_WWN (0x04) #define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05) +#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06) /**************************************************************************** @@ -1957,11 +1991,11 @@ typedef struct _RAID_VOL0_STATUS RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t; /* RAID Volume Page 0 VolumeStatus defines */ - #define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01) #define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02) #define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04) #define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08) +#define MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x10) #define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00) #define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01) @@ -2025,7 +2059,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; -#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x04) +#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05) /* values for RAID Volume Page 0 InactiveStatus field */ #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) @@ -2104,6 +2138,8 @@ typedef struct _RAID_PHYS_DISK0_STATUS #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01) #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02) #define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x04) +#define MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00) +#define MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x08) #define MPI_PHYSDISK0_STATUS_ONLINE (0x00) #define MPI_PHYSDISK0_STATUS_MISSING (0x01) @@ -2132,7 +2168,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0 } CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0, RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t; -#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x01) +#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x02) typedef struct _RAID_PHYS_DISK1_PATH @@ -2263,7 +2299,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; -#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x02) +#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03) /* values for SAS IO Unit Page 0 PortFlags */ #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) @@ -2299,6 +2335,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 #define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200) #define MPI_SAS_IOUNIT0_DS_TABLE_LINK (0x00000400) #define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800) +#define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS (0x00001000) typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA @@ -2336,6 +2373,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04) /* values for SAS IO Unit Page 1 ControlFlags */ +#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) @@ -2345,9 +2383,8 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 #define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) #define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00) #define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01) -#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x10) +#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02) -#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100) #define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) #define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) #define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) @@ -2390,7 +2427,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; -#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x03) +#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04) /* values for SAS IO Unit Page 2 Status field */ #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) @@ -2406,6 +2443,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 #define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02) #define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10) +#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20) typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3 @@ -2584,11 +2622,19 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2 { CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ U64 PhysicalIdentifier; /* 08h */ - U32 Reserved1; /* 10h */ + U32 EnclosureMapping; /* 10h */ } CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2, SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t; -#define MPI_SASDEVICE2_PAGEVERSION (0x00) +#define MPI_SASDEVICE2_PAGEVERSION (0x01) + +/* defines for SAS Device Page 2 EnclosureMapping field */ +#define MPI_SASDEVICE2_ENC_MAP_MASK_MISSING_COUNT (0x0000000F) +#define MPI_SASDEVICE2_ENC_MAP_SHIFT_MISSING_COUNT (0) +#define MPI_SASDEVICE2_ENC_MAP_MASK_NUM_SLOTS (0x000007F0) +#define MPI_SASDEVICE2_ENC_MAP_SHIFT_NUM_SLOTS (4) +#define MPI_SASDEVICE2_ENC_MAP_MASK_START_INDEX (0x001FF800) +#define MPI_SASDEVICE2_ENC_MAP_SHIFT_START_INDEX (11) /**************************************************************************** @@ -2598,7 +2644,8 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2 typedef struct _CONFIG_PAGE_SAS_PHY_0 { CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ - U32 Reserved1; /* 08h */ + U16 OwnerDevHandle; /* 08h */ + U16 Reserved1; /* 0Ah */ U64 SASAddress; /* 0Ch */ U16 AttachedDevHandle; /* 14h */ U8 AttachedPhyIdentifier; /* 16h */ @@ -2607,12 +2654,12 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0 U8 ProgrammedLinkRate; /* 20h */ U8 HwLinkRate; /* 21h */ U8 ChangeCount; /* 22h */ - U8 Reserved3; /* 23h */ + U8 Flags; /* 23h */ U32 PhyInfo; /* 24h */ } CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0, SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t; -#define MPI_SASPHY0_PAGEVERSION (0x00) +#define MPI_SASPHY0_PAGEVERSION (0x01) /* values for SAS PHY Page 0 ProgrammedLinkRate field */ #define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0) @@ -2632,6 +2679,9 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0 #define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08) #define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09) +/* values for SAS PHY Page 0 Flags field */ +#define MPI_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01) + /* values for SAS PHY Page 0 PhyInfo field */ #define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000) #define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000) @@ -2690,7 +2740,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0 } CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0, SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t; -#define MPI_SASENCLOSURE0_PAGEVERSION (0x00) +#define MPI_SASENCLOSURE0_PAGEVERSION (0x01) /* values for SAS Enclosure Page 0 Flags field */ #define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID (0x0020) @@ -2702,6 +2752,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0 #define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002) #define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003) #define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004) +#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005) /**************************************************************************** diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index c9edbee41ed..1a30ef16adb 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -6,17 +6,17 @@ Copyright (c) 2000-2005 LSI Logic Corporation. --------------------------------------- - Header Set Release Version: 01.05.09 + Header Set Release Version: 01.05.10 Header Set Release Date: 03-11-05 --------------------------------------- Filename Current version Prior version ---------- --------------- ------------- - mpi.h 01.05.07 01.05.06 - mpi_ioc.h 01.05.08 01.05.07 - mpi_cnfg.h 01.05.08 01.05.07 - mpi_init.h 01.05.04 01.05.03 - mpi_targ.h 01.05.04 01.05.03 + mpi.h 01.05.08 01.05.07 + mpi_ioc.h 01.05.09 01.05.08 + mpi_cnfg.h 01.05.09 01.05.08 + mpi_init.h 01.05.05 01.05.04 + mpi_targ.h 01.05.05 01.05.04 mpi_fc.h 01.05.01 01.05.01 mpi_lan.h 01.05.01 01.05.01 mpi_raid.h 01.05.02 01.05.02 @@ -24,7 +24,7 @@ mpi_inb.h 01.05.01 01.05.01 mpi_sas.h 01.05.01 01.05.01 mpi_type.h 01.05.01 01.05.01 - mpi_history.txt 01.05.09 01.05.08 + mpi_history.txt 01.05.09 01.05.09 * Date Version Description @@ -88,6 +88,9 @@ mpi.h * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and * TargetAssistExtended requests. * Removed EEDP IOCStatus codes. + * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and + * TargetAssistExtended requests. + * Added EEDP IOCStatus codes. * -------------------------------------------------------------------------- mpi_ioc.h @@ -159,6 +162,8 @@ mpi_ioc.h * Reply and IOC Init Request. * 03-11-05 01.05.08 Added family code for 1068E family. * Removed IOCFacts Reply EEDP Capability bit. + * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. + * Added Max SATA Targets to SAS Discovery Error event. * -------------------------------------------------------------------------- mpi_cnfg.h @@ -380,6 +385,23 @@ mpi_cnfg.h * New physical mapping mode in SAS IO Unit Page 2. * Added CONFIG_PAGE_SAS_ENCLOSURE_0. * Added Slot and Enclosure fields to SAS Device Page 0. + * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1. + * Added more RAID type defines to IOC Page 2. + * Added Port Enable Delay settings to BIOS Page 1. + * Added Bad Block Table Full define to RAID Volume Page 0. + * Added Previous State defines to RAID Physical Disk + * Page 0. + * Added Max Sata Targets define for DiscoveryStatus field + * of SAS IO Unit Page 0. + * Added Device Self Test to Control Flags of SAS IO Unit + * Page 1. + * Added Direct Attach Starting Slot Number define for SAS + * IO Unit Page 2. + * Added new fields in SAS Device Page 2 for enclosure + * mapping. + * Added OwnerDevHandle and Flags field to SAS PHY Page 0. + * Added IOC GPIO Flags define to SAS Enclosure Page 0. + * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. * -------------------------------------------------------------------------- mpi_init.h @@ -418,6 +440,8 @@ mpi_init.h * Modified SCSI Enclosure Processor Request and Reply to * support Enclosure/Slot addressing rather than WWID * addressing. + * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. + * Added four new defines for SEP SlotStatus. * -------------------------------------------------------------------------- mpi_targ.h @@ -461,6 +485,7 @@ mpi_targ.h * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added. * 02-22-05 01.05.03 Changed a comment. * 03-11-05 01.05.04 Removed TargetAssistExtended Request. + * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. * -------------------------------------------------------------------------- mpi_fc.h @@ -571,20 +596,20 @@ mpi_type.h mpi_history.txt Parts list history -Filename 01.05.09 ----------- -------- -mpi.h 01.05.07 -mpi_ioc.h 01.05.08 -mpi_cnfg.h 01.05.08 -mpi_init.h 01.05.04 -mpi_targ.h 01.05.04 -mpi_fc.h 01.05.01 -mpi_lan.h 01.05.01 -mpi_raid.h 01.05.02 -mpi_tool.h 01.05.03 -mpi_inb.h 01.05.01 -mpi_sas.h 01.05.01 -mpi_type.h 01.05.01 +Filename 01.05.10 01.05.09 +---------- -------- -------- +mpi.h 01.05.08 01.05.07 +mpi_ioc.h 01.05.09 01.05.08 +mpi_cnfg.h 01.05.09 01.05.08 +mpi_init.h 01.05.05 01.05.04 +mpi_targ.h 01.05.05 01.05.04 +mpi_fc.h 01.05.01 01.05.01 +mpi_lan.h 01.05.01 01.05.01 +mpi_raid.h 01.05.02 01.05.02 +mpi_tool.h 01.05.03 01.05.03 +mpi_inb.h 01.05.01 01.05.01 +mpi_sas.h 01.05.01 01.05.01 +mpi_type.h 01.05.01 01.05.01 Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 ---------- -------- -------- -------- -------- -------- -------- diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index aca035801a8..d5af75afbd9 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h @@ -6,7 +6,7 @@ * Title: MPI initiator mode messages and structures * Creation Date: June 8, 2000 * - * mpi_init.h Version: 01.05.04 + * mpi_init.h Version: 01.05.05 * * Version History * --------------- @@ -48,6 +48,8 @@ * Modified SCSI Enclosure Processor Request and Reply to * support Enclosure/Slot addressing rather than WWID * addressing. + * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. + * Added four new defines for SEP SlotStatus. * -------------------------------------------------------------------------- */ @@ -202,6 +204,197 @@ typedef struct _MSG_SCSI_IO_REPLY #define MPI_SCSI_TASKTAG_UNKNOWN (0xFFFF) +/****************************************************************************/ +/* SCSI IO 32 messages and associated structures */ +/****************************************************************************/ + +typedef struct +{ + U8 CDB[20]; /* 00h */ + U32 PrimaryReferenceTag; /* 14h */ + U16 PrimaryApplicationTag; /* 18h */ + U16 PrimaryApplicationTagMask; /* 1Ah */ + U32 TransferLength; /* 1Ch */ +} MPI_SCSI_IO32_CDB_EEDP32, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP32, + MpiScsiIo32CdbEedp32_t, MPI_POINTER pMpiScsiIo32CdbEedp32_t; + +typedef struct +{ + U8 CDB[16]; /* 00h */ + U32 DataLength; /* 10h */ + U32 PrimaryReferenceTag; /* 14h */ + U16 PrimaryApplicationTag; /* 18h */ + U16 PrimaryApplicationTagMask; /* 1Ah */ + U32 TransferLength; /* 1Ch */ +} MPI_SCSI_IO32_CDB_EEDP16, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP16, + MpiScsiIo32CdbEedp16_t, MPI_POINTER pMpiScsiIo32CdbEedp16_t; + +typedef union +{ + U8 CDB32[32]; + MPI_SCSI_IO32_CDB_EEDP32 EEDP32; + MPI_SCSI_IO32_CDB_EEDP16 EEDP16; + SGE_SIMPLE_UNION SGE; +} MPI_SCSI_IO32_CDB_UNION, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_UNION, + MpiScsiIo32Cdb_t, MPI_POINTER pMpiScsiIo32Cdb_t; + +typedef struct +{ + U8 TargetID; /* 00h */ + U8 Bus; /* 01h */ + U16 Reserved1; /* 02h */ + U32 Reserved2; /* 04h */ +} MPI_SCSI_IO32_BUS_TARGET_ID_FORM, MPI_POINTER PTR_MPI_SCSI_IO32_BUS_TARGET_ID_FORM, + MpiScsiIo32BusTargetIdForm_t, MPI_POINTER pMpiScsiIo32BusTargetIdForm_t; + +typedef union +{ + MPI_SCSI_IO32_BUS_TARGET_ID_FORM SCSIID; + U64 WWID; +} MPI_SCSI_IO32_ADDRESS, MPI_POINTER PTR_MPI_SCSI_IO32_ADDRESS, + MpiScsiIo32Address_t, MPI_POINTER pMpiScsiIo32Address_t; + +typedef struct _MSG_SCSI_IO32_REQUEST +{ + U8 Port; /* 00h */ + U8 Reserved1; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U8 CDBLength; /* 04h */ + U8 SenseBufferLength; /* 05h */ + U8 Flags; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 LUN[8]; /* 0Ch */ + U32 Control; /* 14h */ + MPI_SCSI_IO32_CDB_UNION CDB; /* 18h */ + U32 DataLength; /* 38h */ + U32 BidirectionalDataLength; /* 3Ch */ + U32 SecondaryReferenceTag; /* 40h */ + U16 SecondaryApplicationTag; /* 44h */ + U16 Reserved2; /* 46h */ + U16 EEDPFlags; /* 48h */ + U16 ApplicationTagTranslationMask; /* 4Ah */ + U32 EEDPBlockSize; /* 4Ch */ + MPI_SCSI_IO32_ADDRESS DeviceAddress; /* 50h */ + U8 SGLOffset0; /* 58h */ + U8 SGLOffset1; /* 59h */ + U8 SGLOffset2; /* 5Ah */ + U8 SGLOffset3; /* 5Bh */ + U32 Reserved3; /* 5Ch */ + U32 Reserved4; /* 60h */ + U32 SenseBufferLowAddr; /* 64h */ + SGE_IO_UNION SGL; /* 68h */ +} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST, + SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t; + +/* SCSI IO 32 MsgFlags bits */ +#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01) +#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00) +#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01) + +#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02) +#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00) +#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_IOC (0x02) + +#define MPI_SCSIIO32_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04) +#define MPI_SCSIIO32_MSGFLGS_SGL_OFFSETS_CHAINS (0x08) +#define MPI_SCSIIO32_MSGFLGS_MULTICAST (0x10) +#define MPI_SCSIIO32_MSGFLGS_BIDIRECTIONAL (0x20) +#define MPI_SCSIIO32_MSGFLGS_LARGE_CDB (0x40) + +/* SCSI IO 32 Flags bits */ +#define MPI_SCSIIO32_FLAGS_FORM_MASK (0x03) +#define MPI_SCSIIO32_FLAGS_FORM_SCSIID (0x00) +#define MPI_SCSIIO32_FLAGS_FORM_WWID (0x01) + +/* SCSI IO 32 LUN fields */ +#define MPI_SCSIIO32_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF) +#define MPI_SCSIIO32_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000) +#define MPI_SCSIIO32_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF) +#define MPI_SCSIIO32_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000) +#define MPI_SCSIIO32_LUN_LEVEL_1_WORD (0xFF00) +#define MPI_SCSIIO32_LUN_LEVEL_1_DWORD (0x0000FF00) + +/* SCSI IO 32 Control bits */ +#define MPI_SCSIIO32_CONTROL_DATADIRECTION_MASK (0x03000000) +#define MPI_SCSIIO32_CONTROL_NODATATRANSFER (0x00000000) +#define MPI_SCSIIO32_CONTROL_WRITE (0x01000000) +#define MPI_SCSIIO32_CONTROL_READ (0x02000000) +#define MPI_SCSIIO32_CONTROL_BIDIRECTIONAL (0x03000000) + +#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_MASK (0xFC000000) +#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_SHIFT (26) + +#define MPI_SCSIIO32_CONTROL_TASKATTRIBUTE_MASK (0x00000700) +#define MPI_SCSIIO32_CONTROL_SIMPLEQ (0x00000000) +#define MPI_SCSIIO32_CONTROL_HEADOFQ (0x00000100) +#define MPI_SCSIIO32_CONTROL_ORDEREDQ (0x00000200) +#define MPI_SCSIIO32_CONTROL_ACAQ (0x00000400) +#define MPI_SCSIIO32_CONTROL_UNTAGGED (0x00000500) +#define MPI_SCSIIO32_CONTROL_NO_DISCONNECT (0x00000700) + +#define MPI_SCSIIO32_CONTROL_TASKMANAGE_MASK (0x00FF0000) +#define MPI_SCSIIO32_CONTROL_OBSOLETE (0x00800000) +#define MPI_SCSIIO32_CONTROL_CLEAR_ACA_RSV (0x00400000) +#define MPI_SCSIIO32_CONTROL_TARGET_RESET (0x00200000) +#define MPI_SCSIIO32_CONTROL_LUN_RESET_RSV (0x00100000) +#define MPI_SCSIIO32_CONTROL_RESERVED (0x00080000) +#define MPI_SCSIIO32_CONTROL_CLR_TASK_SET_RSV (0x00040000) +#define MPI_SCSIIO32_CONTROL_ABORT_TASK_SET (0x00020000) +#define MPI_SCSIIO32_CONTROL_RESERVED2 (0x00010000) + +/* SCSI IO 32 EEDPFlags */ +#define MPI_SCSIIO32_EEDPFLAGS_MASK_OP (0x0007) +#define MPI_SCSIIO32_EEDPFLAGS_NOOP_OP (0x0000) +#define MPI_SCSIIO32_EEDPFLAGS_CHK_OP (0x0001) +#define MPI_SCSIIO32_EEDPFLAGS_STRIP_OP (0x0002) +#define MPI_SCSIIO32_EEDPFLAGS_CHKRM_OP (0x0003) +#define MPI_SCSIIO32_EEDPFLAGS_INSERT_OP (0x0004) +#define MPI_SCSIIO32_EEDPFLAGS_REPLACE_OP (0x0006) +#define MPI_SCSIIO32_EEDPFLAGS_CHKREGEN_OP (0x0007) + +#define MPI_SCSIIO32_EEDPFLAGS_PASS_REF_TAG (0x0008) +#define MPI_SCSIIO32_EEDPFLAGS_8_9THS_MODE (0x0010) + +#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_MASK (0x0700) +#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_GUARD (0x0100) +#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_REFTAG (0x0200) +#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_LBATAG (0x0400) +#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_SHIFT (8) + +#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_APPTAG (0x1000) +#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_APPTAG (0x2000) +#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_REFTAG (0x4000) +#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_REFTAG (0x8000) + + +/* SCSIIO32 IO reply structure */ +typedef struct _MSG_SCSIIO32_IO_REPLY +{ + U8 Port; /* 00h */ + U8 Reserved1; /* 01h */ + U8 MsgLength; /* 02h */ + U8 Function; /* 03h */ + U8 CDBLength; /* 04h */ + U8 SenseBufferLength; /* 05h */ + U8 Flags; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U8 SCSIStatus; /* 0Ch */ + U8 SCSIState; /* 0Dh */ + U16 IOCStatus; /* 0Eh */ + U32 IOCLogInfo; /* 10h */ + U32 TransferCount; /* 14h */ + U32 SenseCount; /* 18h */ + U32 ResponseInfo; /* 1Ch */ + U16 TaskTag; /* 20h */ + U16 Reserved2; /* 22h */ + U32 BidirectionalTransferCount; /* 24h */ +} MSG_SCSIIO32_IO_REPLY, MPI_POINTER PTR_MSG_SCSIIO32_IO_REPLY, + SCSIIO32Reply_t, MPI_POINTER pSCSIIO32Reply_t; + + /****************************************************************************/ /* SCSI Task Management messages */ /****************************************************************************/ @@ -310,10 +503,14 @@ typedef struct _MSG_SEP_REQUEST #define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) #define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) #define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200) +#define MPI_SEP_REQ_SLOTSTATUS_REQ_CONSISTENCY_CHECK (0x00001000) +#define MPI_SEP_REQ_SLOTSTATUS_DISABLE (0x00002000) +#define MPI_SEP_REQ_SLOTSTATUS_REQ_RESERVED_DEVICE (0x00004000) #define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) #define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000) #define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000) #define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000) +#define MPI_SEP_REQ_SLOTSTATUS_ACTIVE (0x00800000) #define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000) #define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000) #define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000) @@ -352,11 +549,15 @@ typedef struct _MSG_SEP_REPLY #define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) #define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) #define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200) +#define MPI_SEP_REPLY_SLOTSTATUS_CONSISTENCY_CHECK (0x00001000) +#define MPI_SEP_REPLY_SLOTSTATUS_DISABLE (0x00002000) +#define MPI_SEP_REPLY_SLOTSTATUS_RESERVED_DEVICE (0x00004000) #define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000) #define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) #define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000) #define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000) #define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000) +#define MPI_SEP_REPLY_SLOTSTATUS_ACTIVE (0x00800000) #define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000) #define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000) #define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000) diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index f91eb4efe8c..93b70e2b426 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h @@ -6,7 +6,7 @@ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: August 11, 2000 * - * mpi_ioc.h Version: 01.05.08 + * mpi_ioc.h Version: 01.05.09 * * Version History * --------------- @@ -81,6 +81,8 @@ * Reply and IOC Init Request. * 03-11-05 01.05.08 Added family code for 1068E family. * Removed IOCFacts Reply EEDP Capability bit. + * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. + * Added Max SATA Targets to SAS Discovery Error event. * -------------------------------------------------------------------------- */ @@ -261,7 +263,11 @@ typedef struct _MSG_IOC_FACTS_REPLY #define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) #define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) #define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) - +#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040) +#define MPI_IOCFACTS_CAPABILITY_BIDIRECTIONAL (0x00000080) +#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) +#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200) +#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400) /***************************************************************************** @@ -677,6 +683,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200) #define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400) #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) +#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) /***************************************************************************** diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index 623901fd82b..3f462859cee 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h @@ -6,7 +6,7 @@ * Title: MPI Target mode messages and structures * Creation Date: June 22, 2000 * - * mpi_targ.h Version: 01.05.04 + * mpi_targ.h Version: 01.05.05 * * Version History * --------------- @@ -53,6 +53,7 @@ * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added. * 02-22-05 01.05.03 Changed a comment. * 03-11-05 01.05.04 Removed TargetAssistExtended Request. + * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. * -------------------------------------------------------------------------- */ @@ -370,6 +371,77 @@ typedef struct _MSG_TARGET_ERROR_REPLY TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t; +/****************************************************************************/ +/* Target Assist Extended Request */ +/****************************************************************************/ + +typedef struct _MSG_TARGET_ASSIST_EXT_REQUEST +{ + U8 StatusCode; /* 00h */ + U8 TargetAssistFlags; /* 01h */ + U8 ChainOffset; /* 02h */ + U8 Function; /* 03h */ + U16 QueueTag; /* 04h */ + U8 Reserved1; /* 06h */ + U8 MsgFlags; /* 07h */ + U32 MsgContext; /* 08h */ + U32 ReplyWord; /* 0Ch */ + U8 LUN[8]; /* 10h */ + U32 RelativeOffset; /* 18h */ + U32 Reserved2; /* 1Ch */ + U32 Reserved3; /* 20h */ + U32 PrimaryReferenceTag; /* 24h */ + U16 PrimaryApplicationTag; /* 28h */ + U16 PrimaryApplicationTagMask; /* 2Ah */ + U32 Reserved4; /* 2Ch */ + U32 DataLength; /* 30h */ + U32 BidirectionalDataLength; /* 34h */ + U32 SecondaryReferenceTag; /* 38h */ + U16 SecondaryApplicationTag; /* 3Ch */ + U16 Reserved5; /* 3Eh */ + U16 EEDPFlags; /* 40h */ + U16 ApplicationTagTranslationMask; /* 42h */ + U32 EEDPBlockSize; /* 44h */ + U8 SGLOffset0; /* 48h */ + U8 SGLOffset1; /* 49h */ + U8 SGLOffset2; /* 4Ah */ + U8 SGLOffset3; /* 4Bh */ + U32 Reserved6; /* 4Ch */ + SGE_IO_UNION SGL[1]; /* 50h */ +} MSG_TARGET_ASSIST_EXT_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_EXT_REQUEST, + TargetAssistExtRequest_t, MPI_POINTER pTargetAssistExtRequest_t; + +/* see the defines after MSG_TARGET_ASSIST_REQUEST for TargetAssistFlags */ + +/* defines for the MsgFlags field */ +#define TARGET_ASSIST_EXT_MSGFLAGS_BIDIRECTIONAL (0x20) +#define TARGET_ASSIST_EXT_MSGFLAGS_MULTICAST (0x10) +#define TARGET_ASSIST_EXT_MSGFLAGS_SGL_OFFSET_CHAINS (0x08) + +/* defines for the EEDPFlags field */ +#define TARGET_ASSIST_EXT_EEDP_MASK_OP (0x0007) +#define TARGET_ASSIST_EXT_EEDP_NOOP_OP (0x0000) +#define TARGET_ASSIST_EXT_EEDP_CHK_OP (0x0001) +#define TARGET_ASSIST_EXT_EEDP_STRIP_OP (0x0002) +#define TARGET_ASSIST_EXT_EEDP_CHKRM_OP (0x0003) +#define TARGET_ASSIST_EXT_EEDP_INSERT_OP (0x0004) +#define TARGET_ASSIST_EXT_EEDP_REPLACE_OP (0x0006) +#define TARGET_ASSIST_EXT_EEDP_CHKREGEN_OP (0x0007) + +#define TARGET_ASSIST_EXT_EEDP_PASS_REF_TAG (0x0008) + +#define TARGET_ASSIST_EXT_EEDP_T10_CHK_MASK (0x0700) +#define TARGET_ASSIST_EXT_EEDP_T10_CHK_GUARD (0x0100) +#define TARGET_ASSIST_EXT_EEDP_T10_CHK_APPTAG (0x0200) +#define TARGET_ASSIST_EXT_EEDP_T10_CHK_REFTAG (0x0400) +#define TARGET_ASSIST_EXT_EEDP_T10_CHK_SHIFT (8) + +#define TARGET_ASSIST_EXT_EEDP_INC_SEC_APPTAG (0x1000) +#define TARGET_ASSIST_EXT_EEDP_INC_PRI_APPTAG (0x2000) +#define TARGET_ASSIST_EXT_EEDP_INC_SEC_REFTAG (0x4000) +#define TARGET_ASSIST_EXT_EEDP_INC_PRI_REFTAG (0x8000) + + /****************************************************************************/ /* Target Status Send Request */ /****************************************************************************/ From 637fa99b86a00a0b5767a982b83a512ff48ad6d2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Aug 2005 16:25:44 +0200 Subject: [PATCH 10/32] [SCSI] fusion: endianess fixes Assorted endianess fixes. I'll work on full endianess annotations later. Acked by: Moore, Eric Dean Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 6 +++--- drivers/message/fusion/mptctl.c | 2 +- drivers/message/fusion/mptscsih.c | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 28420276680..35444ba4e78 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -2185,7 +2185,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); facts->IOCStatus = le16_to_cpu(facts->IOCStatus); facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); - status = facts->IOCStatus & MPI_IOCSTATUS_MASK; + status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK; /* CHECKME! IOCStatus, IOCLogInfo */ facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); @@ -4823,8 +4823,8 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) pReq->Reserved3 = 0; pReq->NumAddressBytes = 0x01; pReq->Reserved4 = 0; - pReq->DataLength = 0x04; - pdev = (struct pci_dev *) ioc->pcidev; + pReq->DataLength = cpu_to_le16(0x04); + pdev = ioc->pcidev; if (pdev->devfn & 1) pReq->DeviceAddr = 0xB2; else diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index e63a3fd6b70..7577c2417e2 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -242,7 +242,7 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) /* Set the command status to GOOD if IOC Status is GOOD * OR if SCSI I/O cmd and data underrun or recovered error. */ - iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK; + iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK; if (iocStatus == MPI_IOCSTATUS_SUCCESS) ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b774f45dfde..cd4e8c0853d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -3447,7 +3447,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) * some type of error occurred. */ MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr; - if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS) + if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS) completionCode = MPT_SCANDV_GOOD; else completionCode = MPT_SCANDV_SOME_ERROR; @@ -3996,9 +3996,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " "offset=0 negoFlags=%x request=%x config=%x\n", id, flags, requested, configuration)); - pcfg1Data->RequestedParameters = le32_to_cpu(requested); + pcfg1Data->RequestedParameters = cpu_to_le32(requested); pcfg1Data->Reserved = 0; - pcfg1Data->Configuration = le32_to_cpu(configuration); + pcfg1Data->Configuration = cpu_to_le32(configuration); cfg.pageAddr = (bus<<8) | id; mpt_config(hd->ioc, &cfg); } @@ -5248,7 +5248,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) /* Update tmax values with those from Device Page 0.*/ pPage0 = (SCSIDevicePage0_t *) pPage; if (pPage0) { - val = cpu_to_le32(pPage0->NegotiatedParameters); + val = le32_to_cpu(pPage0->NegotiatedParameters); dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0; dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16; dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8; @@ -5276,12 +5276,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) dv->now.offset, &val, &configuration, dv->now.flags); dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); - pPage1->RequestedParameters = le32_to_cpu(val); + pPage1->RequestedParameters = cpu_to_le32(val); pPage1->Reserved = 0; - pPage1->Configuration = le32_to_cpu(configuration); + pPage1->Configuration = cpu_to_le32(configuration); } - ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n", + ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n", id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); break; @@ -5301,9 +5301,9 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) offset, &val, &configuration, negoFlags); dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", id, width, factor, offset, negoFlags, val, configuration)); - pPage1->RequestedParameters = le32_to_cpu(val); + pPage1->RequestedParameters = cpu_to_le32(val); pPage1->Reserved = 0; - pPage1->Configuration = le32_to_cpu(configuration); + pPage1->Configuration = cpu_to_le32(configuration); } ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n", id, width, factor, offset, val, configuration, negoFlags)); @@ -5377,12 +5377,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) if (pPage1) { mptscsih_setDevicePage1Flags (width, factor, offset, &val, &configuration, dv->now.flags); - dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n", + dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n", id, width, offset, factor, dv->now.flags, val, configuration)); - pPage1->RequestedParameters = le32_to_cpu(val); + pPage1->RequestedParameters = cpu_to_le32(val); pPage1->Reserved = 0; - pPage1->Configuration = le32_to_cpu(configuration); + pPage1->Configuration = cpu_to_le32(configuration); } ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n", From c6678e0cfb41b029c3600c54b5bb65954de1230a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 18 Aug 2005 16:24:53 +0200 Subject: [PATCH 11/32] [SCSI] fusion: whitespace fixes Acked by: Moore, Eric Dean Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 225 ++++++++++++++++-------------- drivers/message/fusion/mptscsih.c | 98 +++++++------ drivers/message/fusion/mptspi.c | 6 +- 3 files changed, 174 insertions(+), 155 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 35444ba4e78..f517d0692d5 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -218,8 +218,7 @@ pci_enable_io_access(struct pci_dev *pdev) * (also referred to as a IO Controller or IOC). * This routine must clear the interrupt from the adapter and does * so by reading the reply FIFO. Multiple replies may be processed - * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR - * which is currently set to 32 in mptbase.h. + * per single call to this routine. * * This routine handles register-level access of the adapter but * dispatches (calls) a protocol-specific callback routine to handle @@ -279,11 +278,11 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx; mf = MPT_INDEX_2_MFPTR(ioc, req_idx); - dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n", - ioc->name, mr, req_idx)); + dmfprintk((MYIOC_s_INFO_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(mr) - /* Check/log IOC log info + /* Check/log IOC log info */ ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus); if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { @@ -345,7 +344,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth)) || (mf < ioc->req_frames)) ) { printk(MYIOC_s_WARN_FMT - "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx); + "mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf); cb_idx = 0; pa = 0; freeme = 0; @@ -399,7 +398,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) * @mf: Pointer to original MPT request frame * @reply: Pointer to MPT reply frame (NULL if TurboReply) * - * Returns 1 indicating original alloc'd request frame ptr + * Returns 1 indicating original alloc'd request frame ptr * should be freed, or 0 if it shouldn't. */ static int @@ -408,28 +407,17 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) int freereq = 1; u8 func; - dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name)); - - if ((mf == NULL) || - (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { - printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n", - ioc->name, (void *)mf); - return 1; - } - - if (reply == NULL) { - dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n", - ioc->name)); - return 1; - } + dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name)); +#if defined(MPT_DEBUG_MSG_FRAME) if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf)); DBG_DUMP_REQUEST_FRAME_HDR(mf) } +#endif func = reply->u.hdr.Function; - dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n", + dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n", ioc->name, func)); if (func == MPI_FUNCTION_EVENT_NOTIFICATION) { @@ -448,8 +436,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) * Hmmm... It seems that EventNotificationReply is an exception * to the rule of one reply per request. */ - if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) + if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { freereq = 0; + devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", + ioc->name, pEvReply)); + } else { + devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", + ioc->name, pEvReply)); + } #ifdef CONFIG_PROC_FS // LogEvent(ioc, pEvReply); @@ -716,7 +710,7 @@ mpt_device_driver_deregister(int cb_idx) if (dd_cbfunc->remove) dd_cbfunc->remove(ioc->pcidev); } - + MptDeviceDriverHandlers[cb_idx] = NULL; } @@ -829,7 +823,7 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) } #endif - mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; + mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; dsgprintk((MYIOC_s_INFO_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); } @@ -931,7 +925,7 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, /* Make sure there are no doorbells */ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); - + CHIPREG_WRITE32(&ioc->chip->Doorbell, ((MPI_FUNCTION_HANDSHAKE<name, ii)); + ioc->name, ii)); CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { return -2; } - + /* Send request via doorbell handshake */ req_as_bytes = (u8 *) req; for (ii = 0; ii < reqBytes/4; ii++) { @@ -999,9 +993,9 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) if (ioc->id == iocid) { *iocpp =ioc; return iocid; - } + } } - + *iocpp = NULL; return -1; } @@ -1043,9 +1037,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) if (pci_enable_device(pdev)) return r; - + dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n")); - + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { dprintk((KERN_INFO MYNAM ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); @@ -1070,7 +1064,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ ioc->reply_sz = MPT_REPLY_FRAME_SIZE; - + ioc->pcidev = pdev; ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); @@ -1099,7 +1093,7 @@ 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; for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { @@ -1154,7 +1148,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->prod_name = "LSIFC909"; ioc->bus_type = FC; } - if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) { + else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) { ioc->prod_name = "LSIFC929"; ioc->bus_type = FC; } @@ -1333,7 +1327,7 @@ mpt_detach(struct pci_dev *pdev) remove_proc_entry(pname, NULL); sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); remove_proc_entry(pname, NULL); - + /* call per device driver remove entry point */ for(ii=0; iiremove(pdev); } } - + /* Disable interrupts! */ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); @@ -1414,7 +1408,7 @@ mpt_resume(struct pci_dev *pdev) u32 device_state = pdev->current_state; int recovery_state; int ii; - + printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), device_state); @@ -1545,7 +1539,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0) break; } - + if (ii == 5) { dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc)); @@ -1553,7 +1547,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { MptDisplayIocCapabilities(ioc); } - + if (alt_ioc_ready) { if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); @@ -1624,7 +1618,7 @@ 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) */ - dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", + dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", ioc->alt_ioc->name)); CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); ioc->alt_ioc->active = 1; @@ -1681,7 +1675,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) /* Find IM volumes */ - if (ioc->facts.MsgVersion >= 0x0102) + if (ioc->facts.MsgVersion >= MPI_VERSION_01_02) mpt_findImVolumes(ioc); /* Check, and possibly reset, the coalescing value @@ -1711,7 +1705,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) } if (alt_ioc_ready && MptResetHandlers[ii]) { - dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", + drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", ioc->name, ioc->alt_ioc->name, ii)); rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); handlers++; @@ -1744,8 +1738,8 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x," " searching for devfn match on %x or %x\n", - ioc->name, pci_name(pdev), 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) { @@ -1872,36 +1866,39 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) static void mpt_adapter_dispose(MPT_ADAPTER *ioc) { - if (ioc != NULL) { - int sz_first, sz_last; + int sz_first, sz_last; - sz_first = ioc->alloc_total; + if (ioc == NULL) + return; - mpt_adapter_disable(ioc); + sz_first = ioc->alloc_total; - if (ioc->pci_irq != -1) { - free_irq(ioc->pci_irq, ioc); - ioc->pci_irq = -1; - } + mpt_adapter_disable(ioc); - if (ioc->memmap != NULL) - iounmap(ioc->memmap); + if (ioc->pci_irq != -1) { + free_irq(ioc->pci_irq, ioc); + ioc->pci_irq = -1; + } + + if (ioc->memmap != NULL) { + iounmap(ioc->memmap); + ioc->memmap = NULL; + } #if defined(CONFIG_MTRR) && 0 - if (ioc->mtrr_reg > 0) { - mtrr_del(ioc->mtrr_reg, 0, 0); - dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name)); - } + if (ioc->mtrr_reg > 0) { + mtrr_del(ioc->mtrr_reg, 0, 0); + dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name)); + } #endif - /* Zap the adapter lookup ptr! */ - list_del(&ioc->list); + /* Zap the adapter lookup ptr! */ + list_del(&ioc->list); - sz_last = ioc->alloc_total; - dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", - ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); - kfree(ioc); - } + sz_last = ioc->alloc_total; + dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", + ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); + kfree(ioc); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1988,7 +1985,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) } /* Is it already READY? */ - if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) + if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) return 0; /* @@ -2006,7 +2003,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) * Hmmm... Did it get left operational? */ if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { - dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n", + dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n", ioc->name)); /* Check WhoInit. @@ -2015,8 +2012,8 @@ 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; - dprintk((KERN_WARNING MYNAM - ": whoinit 0x%x\n statefault %d force %d\n", + dinitprintk((KERN_INFO MYNAM + ": whoinit 0x%x statefault %d force %d\n", whoinit, statefault, force)); if (whoinit == MPI_WHOINIT_PCI_PEER) return -4; @@ -2151,8 +2148,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) get_facts.Function = MPI_FUNCTION_IOC_FACTS; /* Assert: All other get_facts fields are zero! */ - dinitprintk((MYIOC_s_INFO_FMT - "Sending get IocFacts request req_sz=%d reply_sz=%d\n", + dinitprintk((MYIOC_s_INFO_FMT + "Sending get IocFacts request req_sz=%d reply_sz=%d\n", ioc->name, req_sz, reply_sz)); /* No non-zero fields in the get_facts request are greater than @@ -2232,7 +2229,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) if ( sz & 0x02 ) sz += 2; facts->FWImageSize = sz; - + if (!facts->RequestFrameSize) { /* Something is wrong! */ printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n", @@ -2251,7 +2248,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) ioc->NBShiftFactor = shiftFactor; dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", ioc->name, vv, shiftFactor, r)); - + if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { /* * Set values for this IOC's request & reply frame sizes, @@ -2272,7 +2269,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) return r; } } else { - printk(MYIOC_s_ERR_FMT + printk(MYIOC_s_ERR_FMT "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n", ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32))); @@ -2424,9 +2421,11 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n", ioc->name, &ioc_init)); - - if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) + + if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) { + printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r); return r; + } /* YIKES! SUPER IMPORTANT!!! * Poll IocState until _OPERATIONAL while IOC is doing @@ -2451,7 +2450,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) state = mpt_GetIocState(ioc, 1); count++; } - dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", + dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", ioc->name, count)); return r; @@ -2540,7 +2539,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc) int sz; sz = ioc->facts.FWImageSize; - dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", + dinitprintk((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); @@ -2584,9 +2583,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) mpt_alloc_fw_memory(ioc, sz); - dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n", + dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n", ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); - + if (ioc->cached_fw == NULL) { /* Major Failure. */ @@ -2616,14 +2615,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((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n", + dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n", prequest, sgeoffset)); DBG_DUMP_FW_REQUEST_FRAME(prequest) ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); - dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii)); + dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii)); cmdStatus = -EFAULT; if (ii == 0) { @@ -2638,10 +2637,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) cmdStatus = 0; } } - dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n", + dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n", ioc->name, cmdStatus)); - + if (cmdStatus) { ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n", @@ -2772,8 +2771,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) fwSize = (pExtImage->ImageSize + 3) >> 2; ptrFw = (u32 *)pExtImage; - ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n", - ioc->name, fwSize*4, ptrFw, load_addr)); + ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n", + ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr)); CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); while (fwSize--) { @@ -2856,9 +2855,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag) * 0 else * * Returns: - * 1 - hard reset, READY - * 0 - no reset due to History bit, READY - * -1 - no reset due to History bit but not READY + * 1 - hard reset, READY + * 0 - no reset due to History bit, READY + * -1 - no reset due to History bit but not READY * OR reset but failed to come READY * -2 - no reset, could not enter DIAG mode * -3 - reset but bad FW bit @@ -3001,7 +3000,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) * */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); - mdelay (1); + mdelay(1); /* * Now hit the reset bit in the Diagnostic register @@ -3181,7 +3180,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) u32 state; int cntdn, count; - drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n", + drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n", ioc->name, reset_type)); CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<reply_frames = (MPT_FRAME_HDR *) mem; ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); + dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n", + ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); + alloc_dma += reply_sz; mem += reply_sz; @@ -3393,7 +3395,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc) ioc->req_frames = (MPT_FRAME_HDR *) mem; ioc->req_frames_dma = alloc_dma; - dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n", + dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n", ioc->name, mem, (void *)(ulong)alloc_dma)); ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); @@ -3419,7 +3421,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc) ioc->ChainBuffer = mem; ioc->ChainBufferDMA = alloc_dma; - dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n", + dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n", ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA)); /* Initialize the free chain Q. @@ -3524,7 +3526,7 @@ out_fail: */ static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, - int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) + int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) { MPIDefaultReply_t *mptReply; int failcnt = 0; @@ -3599,7 +3601,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, */ if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) failcnt++; - + dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n", ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : "")); @@ -3758,7 +3760,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) } dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n", - ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), + ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); /* @@ -4133,6 +4135,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) ioc->spi_data.minSyncFactor = MPT_ASYNC; ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN; rc = 1; + ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n", + ioc->name, ioc->spi_data.minSyncFactor)); } else { /* Save the Port Page 0 data */ @@ -4142,7 +4146,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; - dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n", + ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n", ioc->name, pPP0->Capabilities)); } ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; @@ -4151,6 +4155,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) ioc->spi_data.maxSyncOffset = (u8) (data >> 16); data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK; ioc->spi_data.minSyncFactor = (u8) (data >> 8); + ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n", + ioc->name, ioc->spi_data.minSyncFactor)); } else { ioc->spi_data.maxSyncOffset = 0; ioc->spi_data.minSyncFactor = MPT_ASYNC; @@ -4163,8 +4169,11 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) || (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) { - if (ioc->spi_data.minSyncFactor < MPT_ULTRA) + if (ioc->spi_data.minSyncFactor < MPT_ULTRA) { ioc->spi_data.minSyncFactor = MPT_ULTRA; + ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n", + ioc->name, ioc->spi_data.minSyncFactor)); + } } } if (pbuf) { @@ -4591,13 +4600,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); if (evnp == NULL) { - dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", + devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", ioc->name)); return 0; } memset(evnp, 0, sizeof(*evnp)); - dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch)); + devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp)); evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; evnp->ChainOffset = 0; @@ -4621,8 +4630,10 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) EventAck_t *pAck; if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { - printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n", - ioc->name); + printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK " + "request frame for Event=%x EventContext=%x EventData=%x!\n", + ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext), + le32_to_cpu(evnp->Data[0])); return -1; } memset(pAck, 0, sizeof(*pAck)); @@ -5538,6 +5549,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply * If needed, send (a single) EventAck. */ if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { + devtprintk((MYIOC_s_WARN_FMT + "EventAck required\n",ioc->name)); if ((ii = SendEventAck(ioc, pEventReply)) != 0) { devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n", ioc->name, ii)); @@ -5618,7 +5631,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) case 0x00080000: desc = "Outbound DMA Overrun"; break; - + case 0x00090000: desc = "Task Management"; break; @@ -5634,7 +5647,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) case 0x000C0000: desc = "Untagged Table Size"; break; - + } printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); @@ -5726,7 +5739,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) break; case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ - /* This error is checked in scsi_io_done(). Skip. + /* This error is checked in scsi_io_done(). Skip. desc = "SCSI Data Underrun"; */ break; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index cd4e8c0853d..4a003dc5fde 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -281,12 +281,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex) offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer; chain_idx = offset / ioc->req_sz; rc = SUCCESS; - dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n", - ioc->name, *retIndex, chainBuf)); + dsgprintk((MYIOC_s_ERR_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((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n", + dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n", ioc->name)); } spin_unlock_irqrestore(&ioc->FreeQlock, flags); @@ -432,7 +432,7 @@ nextSGEset: */ pReq->ChainOffset = 0; RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03; - dsgprintk((MYIOC_s_ERR_FMT + dsgprintk((MYIOC_s_INFO_FMT "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset)); ioc->RequestNB[req_idx] = RequestNB; } @@ -491,11 +491,12 @@ nextSGEset: /* NOTE: psge points to the beginning of the chain element * in current buffer. Get a chain buffer. */ - dsgprintk((MYIOC_s_INFO_FMT - "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n", - ioc->name, pReq->CDB[0], SCpnt)); - if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) + if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) { + dfailprintk((MYIOC_s_INFO_FMT + "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n", + ioc->name, pReq->CDB[0], SCpnt)); return FAILED; + } /* Update the tracking arrays. * If chainSge == NULL, update ReqToChain, else ChainToChain @@ -577,14 +578,20 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) return 1; } - dmfprintk((MYIOC_s_INFO_FMT - "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n", - ioc->name, mf, mr, sc, req_idx)); - sc->result = DID_OK << 16; /* Set default reply as OK */ pScsiReq = (SCSIIORequest_t *) mf; pScsiReply = (SCSIIOReply_t *) mr; + if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){ + dmfprintk((MYIOC_s_INFO_FMT + "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n", + ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag)); + }else{ + dmfprintk((MYIOC_s_INFO_FMT + "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n", + ioc->name, mf, mr, sc, req_idx)); + } + if (pScsiReply == NULL) { /* special context reply handling */ ; @@ -658,8 +665,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) /* Sufficient data transfer occurred */ sc->result = (DID_OK << 16) | scsi_status; } else if ( xfer_cnt == 0 ) { - /* A CRC Error causes this condition; retry */ - sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | + /* A CRC Error causes this condition; retry */ + sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION << 1); sc->sense_buffer[0] = 0x70; sc->sense_buffer[2] = NO_SENSE; @@ -668,7 +675,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) } else { sc->result = DID_SOFT_ERROR << 16; } - dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target)); + dreplyprintk((KERN_NOTICE + "RESIDUAL_MISMATCH: result=%x on id=%d\n", + sc->result, sc->device->id)); break; case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ @@ -796,7 +805,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) return 1; } - /* * mptscsih_flush_running_cmds - For each command found, search * Scsi_Host instance taskQ and reply to OS. @@ -1017,7 +1025,7 @@ mptscsih_remove(struct pci_dev *pdev) scsi_host_put(host); mpt_detach(pdev); - + } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -1072,7 +1080,7 @@ mptscsih_resume(struct pci_dev *pdev) MPT_SCSI_HOST *hd; mpt_resume(pdev); - + if(!host) return 0; @@ -1214,8 +1222,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off int size = 0; if (func) { - /* - * write is not supported + /* + * write is not supported */ } else { if (start) @@ -1535,17 +1543,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in */ if (mptscsih_tm_pending_wait(hd) == FAILED) { if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { - dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: " + dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: " "Timed out waiting for last TM (%d) to complete! \n", hd->ioc->name, hd->tmPending)); return FAILED; } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { - dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: " + dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " "Timed out waiting for last TM (%d) to complete! \n", hd->ioc->name, hd->tmPending)); return FAILED; } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { - dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: " + dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " "Timed out waiting for last TM (%d) to complete! \n", hd->ioc->name, hd->tmPending)); if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) @@ -1631,8 +1639,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) { dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", hd->ioc->name)); - //return FAILED; - return -999; + return FAILED; } dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n", hd->ioc->name, mf)); @@ -1661,9 +1668,8 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun pScsiTm->TaskMsgContext = ctx2abort; - dtmprintk((MYIOC_s_INFO_FMT - "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", - hd->ioc->name, ctx2abort, type)); + dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", + hd->ioc->name, ctx2abort, type)); DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); @@ -1902,13 +1908,13 @@ 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){ - dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " + dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: " "Can't locate host! (sc=%p)\n", SCpnt ) ); return FAILED; } - printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n", + printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n", hd->ioc->name, SCpnt); /* If our attempts to reset the host failed, then return a failed @@ -1924,7 +1930,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) hd->tmState = TM_STATE_NONE; } - dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " + dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: " "Status = %s\n", (status == SUCCESS) ? "SUCCESS" : "FAILED" ) ); @@ -1951,8 +1957,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) if (hd->tmState == TM_STATE_NONE) { hd->tmState = TM_STATE_IN_PROGRESS; hd->tmPending = 1; - status = SUCCESS; spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + status = SUCCESS; break; } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -1980,7 +1986,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) spin_lock_irqsave(&hd->ioc->FreeQlock, flags); if(hd->tmPending == 0) { status = SUCCESS; - spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); + spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); break; } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); @@ -2318,10 +2324,10 @@ mptscsih_slave_configure(struct scsi_device *device) if (pTarget == NULL) { /* Driver doesn't know about this device. * Kernel may generate a "Dummy Lun 0" which - * may become a real Lun if a + * may become a real Lun if a * "scsi add-single-device" command is executed - * while the driver is active (hot-plug a - * device). LSI Raid controllers need + * while the driver is active (hot-plug a + * device). LSI Raid controllers need * queue_depth set to DEV_HIGH for this reason. */ scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, @@ -2691,7 +2697,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * * If the peripheral qualifier filter is enabled then if the target reports a 0x1 * (i.e. The targer is capable of supporting the specified peripheral device type * on this logical unit; however, the physical device is not currently connected - * to this logical unit) it will be converted to a 0x3 (i.e. The target is not + * to this logical unit) it will be converted to a 0x3 (i.e. The target is not * capable of supporting a physical device on this logical unit). This is to work * around a bug in th emid-layer in some distributions in which the mid-layer will * continue to try to communicate to the LUN and evntually create a dummy LUN. @@ -3194,8 +3200,8 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) /* Get a MF for this command. */ if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { - dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", - ioc->name)); + dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", + ioc->name)); return -EAGAIN; } @@ -3289,7 +3295,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) /* Get a MF for this command. */ if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { - dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", + dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", ioc->name)); return -EAGAIN; } @@ -4596,8 +4602,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) if ((pbuf1[56] & 0x02) == 0) { pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; - ddvprintk((MYIOC_s_NOTE_FMT - "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", + ddvprintk((MYIOC_s_NOTE_FMT + "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", ioc->name, id, pbuf1[56])); } } @@ -4673,7 +4679,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) if (!firstPass) doFallback = 1; } else { - ddvprintk((MYIOC_s_NOTE_FMT + ddvprintk((MYIOC_s_NOTE_FMT "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; mptscsih_initTarget(hd, @@ -4689,8 +4695,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) } else if (rc == MPT_SCANDV_ISSUE_SENSE) doFallback = 1; /* set fallback flag */ - else if ((rc == MPT_SCANDV_DID_RESET) || - (rc == MPT_SCANDV_SENSE) || + else if ((rc == MPT_SCANDV_DID_RESET) || + (rc == MPT_SCANDV_SENSE) || (rc == MPT_SCANDV_FALLBACK)) doFallback = 1; /* set fallback flag */ else @@ -5126,7 +5132,7 @@ target_done: */ if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) { hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; - ddvprintk((MYIOC_s_NOTE_FMT + ddvprintk((MYIOC_s_NOTE_FMT "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor)); } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index dfa8806b1e1..587d1274fd7 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -162,15 +162,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) u8 *mem; int error=0; int r; - + if ((r = mpt_attach(pdev,id)) != 0) return r; - + ioc = pci_get_drvdata(pdev); ioc->DoneCtx = mptspiDoneCtx; ioc->TaskCtx = mptspiTaskCtx; ioc->InternalCtx = mptspiInternalCtx; - + /* Added sanity check on readiness of the MPT adapter. */ if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { From 7524f9b9e72cd36f0a70defcd424eba81c180f42 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:08:00 -0700 Subject: [PATCH 12/32] [SCSI] qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask. In order to efficiently utilise the ISP's IOCB request-queue, use the dma_get_required_mask() function to determine the use of command-type 2 or 3 IOCBs when queueing SCSI commands. This applies to ISP2[123]xx chips only, as the ISP24xx uses command-type 7 IOCBs which use 64bit DSDs. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 9000659bfbc..995e521b07d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1113,36 +1113,23 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha) { - /* Assume 32bit DMA address */ + /* Assume a 32bit DMA mask. */ ha->flags.enable_64bit_addressing = 0; - /* - * Given the two variants pci_set_dma_mask(), allow the compiler to - * assist in setting the proper dma mask. - */ - if (sizeof(dma_addr_t) > 4) { - if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) { + if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) { + /* Any upper-dword bits set? */ + if (MSD(dma_get_required_mask(&ha->pdev->dev)) && + !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { + /* Ok, a 64bit DMA mask is applicable. */ ha->flags.enable_64bit_addressing = 1; ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64; ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64; - - if (pci_set_consistent_dma_mask(ha->pdev, - DMA_64BIT_MASK)) { - qla_printk(KERN_DEBUG, ha, - "Failed to set 64 bit PCI consistent mask; " - "using 32 bit.\n"); - pci_set_consistent_dma_mask(ha->pdev, - DMA_32BIT_MASK); - } - } else { - qla_printk(KERN_DEBUG, ha, - "Failed to set 64 bit PCI DMA mask, falling back " - "to 32 bit MASK.\n"); - pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK); + return; } - } else { - pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK); } + + dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK); + pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK); } static int From ad3e0edaceb9771be7ffbd7aa24fb444a7ed85bf Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:08:10 -0700 Subject: [PATCH 13/32] [SCSI] qla2xxx: Export class-of-service (COS) information. Export COS information for the fc_host and fc_remote_port objects added by the driver. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 4 ++++ drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_init.c | 7 +++++++ drivers/scsi/qla2xxx/qla_mbx.c | 14 ++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 659a5d63467..d05280eecc6 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -304,10 +304,13 @@ struct fc_function_template qla2xxx_transport_functions = { .show_host_node_name = 1, .show_host_port_name = 1, + .show_host_supported_classes = 1, + .get_host_port_id = qla2x00_get_host_port_id, .show_host_port_id = 1, .dd_fcrport_size = sizeof(struct fc_port *), + .show_rport_supported_classes = 1, .get_starget_node_name = qla2x00_get_starget_node_name, .show_starget_node_name = 1, @@ -329,4 +332,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha) be64_to_cpu(*(uint64_t *)ha->init_cb->node_name); fc_host_port_name(ha->host) = be64_to_cpu(*(uint64_t *)ha->init_cb->port_name); + fc_host_supported_classes(ha->host) = FC_COS_CLASS3; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 1c6d366f4fa..38848c38ad8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1673,6 +1673,7 @@ typedef struct fc_port { uint8_t cur_path; /* current path id */ struct fc_rport *rport; + u32 supported_classes; } fc_port_t; /* diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a6d2559217c..09b23f70fd6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1697,6 +1697,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags) fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; atomic_set(&fcport->state, FCS_UNCONFIGURED); fcport->flags = FCF_RLC_SUPPORT; + fcport->supported_classes = FC_COS_UNSPECIFIED; return (fcport); } @@ -2075,6 +2076,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) return; } rport->dd_data = fcport; + rport->supported_classes = fcport->supported_classes; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; if (fcport->port_type == FCT_INITIATOR) @@ -2794,6 +2796,11 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, } } + if (mb[10] & BIT_0) + fcport->supported_classes |= FC_COS_CLASS2; + if (mb[10] & BIT_1) + fcport->supported_classes |= FC_COS_CLASS3; + rval = QLA_SUCCESS; break; } else if (mb[0] == MBS_LOOP_ID_USED) { diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 409ea0ac403..774309a77c0 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -19,6 +19,7 @@ #include "qla_def.h" #include +#include static void qla2x00_mbx_sem_timeout(unsigned long data) @@ -1326,6 +1327,10 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) fcport->port_type = FCT_INITIATOR; else fcport->port_type = FCT_TARGET; + + /* Passback COS information. */ + fcport->supported_classes = (pd->options & BIT_4) ? + FC_COS_CLASS2: FC_COS_CLASS3; } gpd_error_out: @@ -1661,6 +1666,13 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, mb[1] |= BIT_1; } else mb[1] = BIT_0; + + /* Passback COS information. */ + mb[10] = 0; + if (lg->io_parameter[7] || lg->io_parameter[8]) + mb[10] |= BIT_0; /* Class 2. */ + if (lg->io_parameter[9] || lg->io_parameter[10]) + mb[10] |= BIT_1; /* Class 3. */ } dma_pool_free(ha->s_dma_pool, lg, lg_dma); @@ -1723,6 +1735,8 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, mb[2] = mcp->mb[2]; mb[6] = mcp->mb[6]; mb[7] = mcp->mb[7]; + /* COS retrieved from Get-Port-Database mailbox command. */ + mb[10] = 0; } if (rval != QLA_SUCCESS) { From cca5335caf2d19ef8bd6b833445d2c6ca652a89b Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:08:30 -0700 Subject: [PATCH 14/32] [SCSI] qla2xxx: Add FDMI support. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dbg.h | 7 + drivers/scsi/qla2xxx/qla_def.h | 151 ++++++++- drivers/scsi/qla2xxx/qla_gbl.h | 4 + drivers/scsi/qla2xxx/qla_gs.c | 564 ++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_init.c | 6 + drivers/scsi/qla2xxx/qla_isr.c | 2 + drivers/scsi/qla2xxx/qla_mbx.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 10 + 8 files changed, 741 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index b8d90e97e01..9684e7a91fa 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -81,6 +81,7 @@ #define DEBUG2_3_11(x) do {x;} while (0); #define DEBUG2_9_10(x) do {x;} while (0); #define DEBUG2_11(x) do {x;} while (0); +#define DEBUG2_13(x) do {x;} while (0); #else #define DEBUG2(x) do {} while (0); #endif @@ -169,8 +170,14 @@ #if defined(QL_DEBUG_LEVEL_13) #define DEBUG13(x) do {x;} while (0) +#if !defined(DEBUG2_13) +#define DEBUG2_13(x) do {x;} while(0) +#endif #else #define DEBUG13(x) do {} while (0) +#if !defined(QL_DEBUG_LEVEL_2) +#define DEBUG2_13(x) do {} while(0) +#endif #endif #if defined(QL_DEBUG_LEVEL_14) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 38848c38ad8..cdef86e49c6 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -214,6 +214,7 @@ * valid range of an N-PORT id is 0 through 0x7ef. */ #define NPH_LAST_HANDLE 0x7ef +#define NPH_MGMT_SERVER 0x7fa /* FFFFFA */ #define NPH_SNS 0x7fc /* FFFFFC */ #define NPH_FABRIC_CONTROLLER 0x7fd /* FFFFFD */ #define NPH_F_PORT 0x7fe /* FFFFFE */ @@ -1131,10 +1132,7 @@ typedef struct { uint8_t link_down_timeout; - uint8_t adapter_id_0[4]; - uint8_t adapter_id_1[4]; - uint8_t adapter_id_2[4]; - uint8_t adapter_id_3[4]; + uint8_t adapter_id[16]; uint8_t alt1_boot_node_name[WWN_SIZE]; uint16_t alt1_boot_lun_number; @@ -1728,6 +1726,8 @@ typedef struct fc_port { #define CT_REJECT_RESPONSE 0x8001 #define CT_ACCEPT_RESPONSE 0x8002 +#define CT_REASON_CANNOT_PERFORM 0x09 +#define CT_EXPL_ALREADY_REGISTERED 0x10 #define NS_N_PORT_TYPE 0x01 #define NS_NL_PORT_TYPE 0x02 @@ -1769,6 +1769,100 @@ typedef struct fc_port { #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) #define RSNN_NN_RSP_SIZE 16 +/* + * HBA attribute types. + */ +#define FDMI_HBA_ATTR_COUNT 9 +#define FDMI_HBA_NODE_NAME 1 +#define FDMI_HBA_MANUFACTURER 2 +#define FDMI_HBA_SERIAL_NUMBER 3 +#define FDMI_HBA_MODEL 4 +#define FDMI_HBA_MODEL_DESCRIPTION 5 +#define FDMI_HBA_HARDWARE_VERSION 6 +#define FDMI_HBA_DRIVER_VERSION 7 +#define FDMI_HBA_OPTION_ROM_VERSION 8 +#define FDMI_HBA_FIRMWARE_VERSION 9 +#define FDMI_HBA_OS_NAME_AND_VERSION 0xa +#define FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH 0xb + +struct ct_fdmi_hba_attr { + uint16_t type; + uint16_t len; + union { + uint8_t node_name[WWN_SIZE]; + uint8_t manufacturer[32]; + uint8_t serial_num[8]; + uint8_t model[16]; + uint8_t model_desc[80]; + uint8_t hw_version[16]; + uint8_t driver_version[32]; + uint8_t orom_version[16]; + uint8_t fw_version[16]; + uint8_t os_version[128]; + uint8_t max_ct_len[4]; + } a; +}; + +struct ct_fdmi_hba_attributes { + uint32_t count; + struct ct_fdmi_hba_attr entry[FDMI_HBA_ATTR_COUNT]; +}; + +/* + * Port attribute types. + */ +#define FDMI_PORT_ATTR_COUNT 5 +#define FDMI_PORT_FC4_TYPES 1 +#define FDMI_PORT_SUPPORT_SPEED 2 +#define FDMI_PORT_CURRENT_SPEED 3 +#define FDMI_PORT_MAX_FRAME_SIZE 4 +#define FDMI_PORT_OS_DEVICE_NAME 5 +#define FDMI_PORT_HOST_NAME 6 + +struct ct_fdmi_port_attr { + uint16_t type; + uint16_t len; + union { + uint8_t fc4_types[32]; + uint32_t sup_speed; + uint32_t cur_speed; + uint32_t max_frame_size; + uint8_t os_dev_name[32]; + uint8_t host_name[32]; + } a; +}; + +/* + * Port Attribute Block. + */ +struct ct_fdmi_port_attributes { + uint32_t count; + struct ct_fdmi_port_attr entry[FDMI_PORT_ATTR_COUNT]; +}; + +/* FDMI definitions. */ +#define GRHL_CMD 0x100 +#define GHAT_CMD 0x101 +#define GRPL_CMD 0x102 +#define GPAT_CMD 0x110 + +#define RHBA_CMD 0x200 +#define RHBA_RSP_SIZE 16 + +#define RHAT_CMD 0x201 +#define RPRT_CMD 0x210 + +#define RPA_CMD 0x211 +#define RPA_RSP_SIZE 16 + +#define DHBA_CMD 0x300 +#define DHBA_REQ_SIZE (16 + 8) +#define DHBA_RSP_SIZE 16 + +#define DHAT_CMD 0x301 +#define DPRT_CMD 0x310 +#define DPA_CMD 0x311 + /* CT command header -- request/response common fields */ struct ct_cmd_hdr { uint8_t revision; @@ -1826,6 +1920,43 @@ struct ct_sns_req { uint8_t name_len; uint8_t sym_node_name[255]; } rsnn_nn; + + struct { + uint8_t hba_indentifier[8]; + } ghat; + + struct { + uint8_t hba_identifier[8]; + uint32_t entry_count; + uint8_t port_name[8]; + struct ct_fdmi_hba_attributes attrs; + } rhba; + + struct { + uint8_t hba_identifier[8]; + struct ct_fdmi_hba_attributes attrs; + } rhat; + + struct { + uint8_t port_name[8]; + struct ct_fdmi_port_attributes attrs; + } rpa; + + struct { + uint8_t port_name[8]; + } dhba; + + struct { + uint8_t port_name[8]; + } dhat; + + struct { + uint8_t port_name[8]; + } dprt; + + struct { + uint8_t port_name[8]; + } dpa; } req; }; @@ -1883,6 +2014,12 @@ struct ct_sns_rsp { struct { uint8_t fc4_types[32]; } gft_id; + + struct { + uint32_t entry_count; + uint8_t port_name[8]; + struct ct_fdmi_hba_attributes attrs; + } ghat; } rsp; }; @@ -2033,6 +2170,8 @@ struct isp_operations { uint16_t (*calc_req_entries) (uint16_t); void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t); void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t); + void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t, + uint32_t); uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t, uint32_t); @@ -2112,6 +2251,7 @@ typedef struct scsi_qla_host { #define IOCTL_ERROR_RECOVERY 23 #define LOOP_RESET_NEEDED 24 #define BEACON_BLINK_NEEDED 25 +#define REGISTER_FDMI_NEEDED 26 uint32_t device_flags; #define DFLG_LOCAL_DEVICES BIT_0 @@ -2205,6 +2345,7 @@ typedef struct scsi_qla_host { int port_down_retry_count; uint8_t mbx_count; uint16_t last_loop_id; + uint16_t mgmt_svr_loop_id; uint32_t login_retry_count; @@ -2319,6 +2460,7 @@ typedef struct scsi_qla_host { uint8_t model_number[16+1]; #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" char *model_desc; + uint8_t adapter_id[16+1]; uint8_t *node_name; uint8_t *port_name; @@ -2378,6 +2520,7 @@ typedef struct scsi_qla_host { #define QLA_SUSPENDED 0x106 #define QLA_BUSY 0x107 #define QLA_RSCNS_HANDLED 0x108 +#define QLA_ALREADY_REGISTERED 0x109 /* * Stat info for all adpaters diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 665c203e067..3e1e5fe850a 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -79,6 +79,7 @@ extern int ql2xplogiabsentdevice; extern int ql2xenablezio; extern int ql2xintrdelaytimer; extern int ql2xloginretrycount; +extern int ql2xfdmienable; extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); @@ -269,6 +270,9 @@ extern int qla2x00_rft_id(scsi_qla_host_t *); extern int qla2x00_rff_id(scsi_qla_host_t *); extern int qla2x00_rnn_id(scsi_qla_host_t *); extern int qla2x00_rsnn_nn(scsi_qla_host_t *); +extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); +extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); +extern int qla2x00_fdmi_register(scsi_qla_host_t *); /* * Global Function Prototypes in qla_rscn.c source file. diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 31ce4f62da1..e7b138c2e33 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1099,3 +1099,567 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *ha) return (rval); } + +/** + * qla2x00_mgmt_svr_login() - Login to fabric Managment Service. + * @ha: HA context + * + * Returns 0 on success. + */ +static int +qla2x00_mgmt_svr_login(scsi_qla_host_t *ha) +{ + int ret; + uint16_t mb[MAILBOX_REGISTER_COUNT]; + + ret = QLA_SUCCESS; + if (ha->flags.management_server_logged_in) + return ret; + + ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa, + mb, BIT_1); + if (mb[0] != MBS_COMMAND_COMPLETE) { + DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: " + "loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x\n", + __func__, ha->host_no, ha->mgmt_svr_loop_id, mb[0], mb[1], + mb[2], mb[6], mb[7])); + ret = QLA_FUNCTION_FAILED; + } else + ha->flags.management_server_logged_in = 1; + + return ret; +} + +/** + * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. + * @ha: HA context + * @req_size: request size in bytes + * @rsp_size: response size in bytes + * + * Returns a pointer to the @ha's ms_iocb. + */ +void * +qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, + uint32_t rsp_size) +{ + ms_iocb_entry_t *ms_pkt; + + ms_pkt = ha->ms_iocb; + memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); + + ms_pkt->entry_type = MS_IOCB_TYPE; + ms_pkt->entry_count = 1; + SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id); + ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); + ms_pkt->timeout = __constant_cpu_to_le16(59); + ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); + ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); + ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); + ms_pkt->req_bytecount = cpu_to_le32(req_size); + + ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); + ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); + ms_pkt->dseg_req_length = ms_pkt->req_bytecount; + + ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); + ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); + ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; + + return ms_pkt; +} + +/** + * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. + * @ha: HA context + * @req_size: request size in bytes + * @rsp_size: response size in bytes + * + * Returns a pointer to the @ha's ms_iocb. + */ +void * +qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, + uint32_t rsp_size) +{ + struct ct_entry_24xx *ct_pkt; + + ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; + memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); + + ct_pkt->entry_type = CT_IOCB_TYPE; + ct_pkt->entry_count = 1; + ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); + ct_pkt->timeout = __constant_cpu_to_le16(59); + ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); + ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); + ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); + ct_pkt->cmd_byte_count = cpu_to_le32(req_size); + + ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); + ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); + ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; + + ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); + ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); + ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; + + return ct_pkt; +} + +static inline ms_iocb_entry_t * +qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size) +{ + ms_iocb_entry_t *ms_pkt = ha->ms_iocb; + struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; + + if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { + ct_pkt->cmd_byte_count = cpu_to_le32(req_size); + ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; + } else { + ms_pkt->req_bytecount = cpu_to_le32(req_size); + ms_pkt->dseg_req_length = ms_pkt->req_bytecount; + } + + return ms_pkt; +} + +/** + * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. + * @ct_req: CT request buffer + * @cmd: GS command + * @rsp_size: response size in bytes + * + * Returns a pointer to the intitialized @ct_req. + */ +static inline struct ct_sns_req * +qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd, + uint16_t rsp_size) +{ + memset(ct_req, 0, sizeof(struct ct_sns_pkt)); + + ct_req->header.revision = 0x01; + ct_req->header.gs_type = 0xFA; + ct_req->header.gs_subtype = 0x10; + ct_req->command = cpu_to_be16(cmd); + ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); + + return ct_req; +} + +/** + * qla2x00_fdmi_rhba() - + * @ha: HA context + * + * Returns 0 on success. + */ +static int +qla2x00_fdmi_rhba(scsi_qla_host_t *ha) +{ + int rval, alen; + uint32_t size, sn; + + ms_iocb_entry_t *ms_pkt; + struct ct_sns_req *ct_req; + struct ct_sns_rsp *ct_rsp; + uint8_t *entries; + struct ct_fdmi_hba_attr *eiter; + + /* Issue RHBA */ + /* Prepare common MS IOCB */ + /* Request size adjusted after CT preparation */ + ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE); + + /* Prepare CT request */ + ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, + RHBA_RSP_SIZE); + ct_rsp = &ha->ct_sns->p.rsp; + + /* Prepare FDMI command arguments -- attribute block, attributes. */ + memcpy(ct_req->req.rhba.hba_identifier, ha->port_name, WWN_SIZE); + ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1); + memcpy(ct_req->req.rhba.port_name, ha->port_name, WWN_SIZE); + size = 2 * WWN_SIZE + 4 + 4; + + /* Attributes */ + ct_req->req.rhba.attrs.count = + __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT); + entries = ct_req->req.rhba.hba_identifier; + + /* Nodename. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME); + eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE); + memcpy(eiter->a.node_name, ha->node_name, WWN_SIZE); + size += 4 + WWN_SIZE; + + DEBUG13(printk("%s(%ld): NODENAME=%02x%02x%02x%02x%02x%02x%02x%02x.\n", + __func__, ha->host_no, + eiter->a.node_name[0], eiter->a.node_name[1], eiter->a.node_name[2], + eiter->a.node_name[3], eiter->a.node_name[4], eiter->a.node_name[5], + eiter->a.node_name[6], eiter->a.node_name[7])); + + /* Manufacturer. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER); + strcpy(eiter->a.manufacturer, "QLogic Corporation"); + alen = strlen(eiter->a.manufacturer); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): MANUFACTURER=%s.\n", __func__, ha->host_no, + eiter->a.manufacturer)); + + /* Serial number. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); + sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; + sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000); + alen = strlen(eiter->a.serial_num); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): SERIALNO=%s.\n", __func__, ha->host_no, + eiter->a.serial_num)); + + /* Model name. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL); + strcpy(eiter->a.model, ha->model_number); + alen = strlen(eiter->a.model); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): MODEL_NAME=%s.\n", __func__, ha->host_no, + eiter->a.model)); + + /* Model description. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); + if (ha->model_desc) + strncpy(eiter->a.model_desc, ha->model_desc, 80); + alen = strlen(eiter->a.model_desc); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): MODEL_DESC=%s.\n", __func__, ha->host_no, + eiter->a.model_desc)); + + /* Hardware version. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); + strcpy(eiter->a.hw_version, ha->adapter_id); + alen = strlen(eiter->a.hw_version); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): HARDWAREVER=%s.\n", __func__, ha->host_no, + eiter->a.hw_version)); + + /* Driver version. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION); + strcpy(eiter->a.driver_version, qla2x00_version_str); + alen = strlen(eiter->a.driver_version); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): DRIVERVER=%s.\n", __func__, ha->host_no, + eiter->a.driver_version)); + + /* Option ROM version. */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); + strcpy(eiter->a.orom_version, "0.00"); + alen = strlen(eiter->a.orom_version); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): OPTROMVER=%s.\n", __func__, ha->host_no, + eiter->a.orom_version)); + + /* Firmware version */ + eiter = (struct ct_fdmi_hba_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); + ha->isp_ops.fw_version_str(ha, eiter->a.fw_version); + alen = strlen(eiter->a.fw_version); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): FIRMWAREVER=%s.\n", __func__, ha->host_no, + eiter->a.fw_version)); + + /* Update MS request size. */ + qla2x00_update_ms_fdmi_iocb(ha, size + 16); + + DEBUG13(printk("%s(%ld): RHBA identifier=" + "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__, + ha->host_no, ct_req->req.rhba.hba_identifier[0], + ct_req->req.rhba.hba_identifier[1], + ct_req->req.rhba.hba_identifier[2], + ct_req->req.rhba.hba_identifier[3], + ct_req->req.rhba.hba_identifier[4], + ct_req->req.rhba.hba_identifier[5], + ct_req->req.rhba.hba_identifier[6], + ct_req->req.rhba.hba_identifier[7], size)); + DEBUG13(qla2x00_dump_buffer(entries, size)); + + /* Execute MS IOCB */ + rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, + sizeof(ms_iocb_entry_t)); + if (rval != QLA_SUCCESS) { + /*EMPTY*/ + DEBUG2_3(printk("scsi(%ld): RHBA issue IOCB failed (%d).\n", + ha->host_no, rval)); + } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RHBA") != + QLA_SUCCESS) { + rval = QLA_FUNCTION_FAILED; + if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && + ct_rsp->header.explanation_code == + CT_EXPL_ALREADY_REGISTERED) { + DEBUG2_13(printk("%s(%ld): HBA already registered.\n", + __func__, ha->host_no)); + rval = QLA_ALREADY_REGISTERED; + } + } else { + DEBUG2(printk("scsi(%ld): RHBA exiting normally.\n", + ha->host_no)); + } + + return rval; +} + +/** + * qla2x00_fdmi_dhba() - + * @ha: HA context + * + * Returns 0 on success. + */ +static int +qla2x00_fdmi_dhba(scsi_qla_host_t *ha) +{ + int rval; + + ms_iocb_entry_t *ms_pkt; + struct ct_sns_req *ct_req; + struct ct_sns_rsp *ct_rsp; + + /* Issue RPA */ + /* Prepare common MS IOCB */ + ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE, + DHBA_RSP_SIZE); + + /* Prepare CT request */ + ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD, + DHBA_RSP_SIZE); + ct_rsp = &ha->ct_sns->p.rsp; + + /* Prepare FDMI command arguments -- portname. */ + memcpy(ct_req->req.dhba.port_name, ha->port_name, WWN_SIZE); + + DEBUG13(printk("%s(%ld): DHBA portname=" + "%02x%02x%02x%02x%02x%02x%02x%02x.\n", __func__, ha->host_no, + ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1], + ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3], + ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5], + ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7])); + + /* Execute MS IOCB */ + rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, + sizeof(ms_iocb_entry_t)); + if (rval != QLA_SUCCESS) { + /*EMPTY*/ + DEBUG2_3(printk("scsi(%ld): DHBA issue IOCB failed (%d).\n", + ha->host_no, rval)); + } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "DHBA") != + QLA_SUCCESS) { + rval = QLA_FUNCTION_FAILED; + } else { + DEBUG2(printk("scsi(%ld): DHBA exiting normally.\n", + ha->host_no)); + } + + return rval; +} + +/** + * qla2x00_fdmi_rpa() - + * @ha: HA context + * + * Returns 0 on success. + */ +static int +qla2x00_fdmi_rpa(scsi_qla_host_t *ha) +{ + int rval, alen; + uint32_t size, max_frame_size; + + ms_iocb_entry_t *ms_pkt; + struct ct_sns_req *ct_req; + struct ct_sns_rsp *ct_rsp; + uint8_t *entries; + struct ct_fdmi_port_attr *eiter; + struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; + + /* Issue RPA */ + /* Prepare common MS IOCB */ + /* Request size adjusted after CT preparation */ + ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE); + + /* Prepare CT request */ + ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, + RPA_RSP_SIZE); + ct_rsp = &ha->ct_sns->p.rsp; + + /* Prepare FDMI command arguments -- attribute block, attributes. */ + memcpy(ct_req->req.rpa.port_name, ha->port_name, WWN_SIZE); + size = WWN_SIZE + 4; + + /* Attributes */ + ct_req->req.rpa.attrs.count = + __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); + entries = ct_req->req.rpa.port_name; + + /* FC4 types. */ + eiter = (struct ct_fdmi_port_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES); + eiter->len = __constant_cpu_to_be16(4 + 32); + eiter->a.fc4_types[2] = 0x01; + size += 4 + 32; + + DEBUG13(printk("%s(%ld): FC4_TYPES=%02x %02x.\n", __func__, ha->host_no, + eiter->a.fc4_types[2], eiter->a.fc4_types[1])); + + /* Supported speed. */ + eiter = (struct ct_fdmi_port_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); + eiter->len = __constant_cpu_to_be16(4 + 4); + if (IS_QLA25XX(ha)) + eiter->a.sup_speed = __constant_cpu_to_be32(4); + else if (IS_QLA24XX(ha)) + eiter->a.sup_speed = __constant_cpu_to_be32(8); + else if (IS_QLA23XX(ha)) + eiter->a.sup_speed = __constant_cpu_to_be32(2); + else + eiter->a.sup_speed = __constant_cpu_to_be32(1); + size += 4 + 4; + + DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no, + eiter->a.sup_speed)); + + /* Current speed. */ + eiter = (struct ct_fdmi_port_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); + eiter->len = __constant_cpu_to_be16(4 + 4); + switch (ha->link_data_rate) { + case 0: + eiter->a.cur_speed = __constant_cpu_to_be32(1); + break; + case 1: + eiter->a.cur_speed = __constant_cpu_to_be32(2); + break; + case 3: + eiter->a.cur_speed = __constant_cpu_to_be32(8); + break; + case 4: + eiter->a.cur_speed = __constant_cpu_to_be32(4); + break; + } + size += 4 + 4; + + DEBUG13(printk("%s(%ld): CURRENT_SPEED=%x.\n", __func__, ha->host_no, + eiter->a.cur_speed)); + + /* Max frame size. */ + eiter = (struct ct_fdmi_port_attr *) (entries + size); + eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); + eiter->len = __constant_cpu_to_be16(4 + 4); + max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ? + (uint32_t) icb24->frame_payload_size: + (uint32_t) ha->init_cb->frame_payload_size; + eiter->a.max_frame_size = cpu_to_be32(max_frame_size); + size += 4 + 4; + + DEBUG13(printk("%s(%ld): MAX_FRAME_SIZE=%x.\n", __func__, ha->host_no, + eiter->a.max_frame_size)); + + /* 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); + alen = strlen(eiter->a.os_dev_name); + alen += (alen & 3) ? (4 - (alen & 3)) : 4; + eiter->len = cpu_to_be16(4 + alen); + size += 4 + alen; + + DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, + eiter->a.os_dev_name)); + + /* Update MS request size. */ + qla2x00_update_ms_fdmi_iocb(ha, size + 16); + + DEBUG13(printk("%s(%ld): RPA portname=" + "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__, + ha->host_no, ct_req->req.rpa.port_name[0], + ct_req->req.rpa.port_name[1], ct_req->req.rpa.port_name[2], + ct_req->req.rpa.port_name[3], ct_req->req.rpa.port_name[4], + ct_req->req.rpa.port_name[5], ct_req->req.rpa.port_name[6], + ct_req->req.rpa.port_name[7], size)); + DEBUG13(qla2x00_dump_buffer(entries, size)); + + /* Execute MS IOCB */ + rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, + sizeof(ms_iocb_entry_t)); + if (rval != QLA_SUCCESS) { + /*EMPTY*/ + DEBUG2_3(printk("scsi(%ld): RPA issue IOCB failed (%d).\n", + ha->host_no, rval)); + } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RPA") != + QLA_SUCCESS) { + rval = QLA_FUNCTION_FAILED; + } else { + DEBUG2(printk("scsi(%ld): RPA exiting normally.\n", + ha->host_no)); + } + + return rval; +} + +/** + * qla2x00_fdmi_register() - + * @ha: HA context + * + * Returns 0 on success. + */ +int +qla2x00_fdmi_register(scsi_qla_host_t *ha) +{ + int rval; + + rval = qla2x00_mgmt_svr_login(ha); + if (rval) + return rval; + + rval = qla2x00_fdmi_rhba(ha); + if (rval) { + if (rval != QLA_ALREADY_REGISTERED) + return rval; + + rval = qla2x00_fdmi_dhba(ha); + if (rval) + return rval; + + rval = qla2x00_fdmi_rhba(ha); + if (rval) + return rval; + } + rval = qla2x00_fdmi_rpa(ha); + + return rval; +} diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 09b23f70fd6..e38d0cf7363 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -88,6 +88,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) ha->mbx_flags = 0; ha->isp_abort_cnt = 0; ha->beacon_blink_led = 0; + set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); rval = ha->isp_ops.pci_config(ha); @@ -2132,6 +2133,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) return (QLA_SUCCESS); } do { + /* FDMI support. */ + if (ql2xfdmienable && + test_and_clear_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags)) + qla2x00_fdmi_register(ha); + /* Ensure we are logged into the SNS. */ if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) loop_id = NPH_SNS; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f910de6dd43..c255bb0268a 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -451,6 +451,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) ha->flags.management_server_logged_in = 0; ha->link_data_rate = 0; + if (ql2xfdmienable) + set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); /* Update AEN queue. */ qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 774309a77c0..284eb847e50 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -252,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) mb0 = RD_REG_WORD(®->isp24.mailbox0); ictrl = RD_REG_DWORD(®->isp24.ictrl); } else { - mb0 = RD_MAILBOX_REG(ha, reg->isp, 0); + mb0 = RD_MAILBOX_REG(ha, ®->isp, 0); ictrl = RD_REG_WORD(®->isp.ictrl); } printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n", diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 995e521b07d..0fc37d810e0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -88,6 +88,12 @@ static void qla2x00_free_device(scsi_qla_host_t *); static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); +int ql2xfdmienable; +module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR); +MODULE_PARM_DESC(ql2xfdmienable, + "Enables FDMI registratons " + "Default is 0 - no FDMI. 1 - perfom FDMI."); + /* * SCSI host template entry points */ @@ -1303,6 +1309,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->prev_topology = 0; ha->ports = MAX_BUSES; ha->init_cb_size = sizeof(init_cb_t); + ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; /* Assign ISP specific operations. */ ha->isp_ops.pci_config = qla2100_pci_config; @@ -1325,6 +1332,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_32; ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_32; ha->isp_ops.prep_ms_iocb = qla2x00_prep_ms_iocb; + ha->isp_ops.prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb; ha->isp_ops.read_nvram = qla2x00_read_nvram_data; ha->isp_ops.write_nvram = qla2x00_write_nvram_data; ha->isp_ops.fw_dump = qla2100_fw_dump; @@ -1362,6 +1370,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->response_q_length = RESPONSE_ENTRY_CNT_2300; ha->last_loop_id = SNS_LAST_LOOP_ID_2300; ha->init_cb_size = sizeof(struct init_cb_24xx); + ha->mgmt_svr_loop_id = 10; ha->isp_ops.pci_config = qla24xx_pci_config; ha->isp_ops.reset_chip = qla24xx_reset_chip; ha->isp_ops.chip_diag = qla24xx_chip_diag; @@ -1382,6 +1391,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ha->isp_ops.fabric_login = qla24xx_login_fabric; ha->isp_ops.fabric_logout = qla24xx_fabric_logout; ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb; + ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb; ha->isp_ops.read_nvram = qla24xx_read_nvram_data; ha->isp_ops.write_nvram = qla24xx_write_nvram_data; ha->isp_ops.fw_dump = qla24xx_fw_dump; From f7d289f62e2ea911ecb710015efd45c687fa81ce Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:08:40 -0700 Subject: [PATCH 15/32] [SCSI] qla2xxx: Correct domain/area exclusion logic. In an FL topology, limit port recognition to those devices not within the same area and domain of the ISP. The firmware will recogonize such devices during local-loop discovery. Some devices may respond to a PLOGI before they have completed their fabric login or they may not be a public device. In this case they will report: domain == 00 area == 00 alpa == which is valid. Exclude such devices from local loop discovery. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e38d0cf7363..d12255fb938 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1900,7 +1900,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha) continue; /* Bypass if not same domain and area of adapter. */ - if (area != ha->d_id.b.area || domain != ha->d_id.b.domain) + if (area && domain && + (area != ha->d_id.b.area || domain != ha->d_id.b.domain)) continue; /* Bypass invalid local loop ID. */ @@ -2400,6 +2401,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) if (new_fcport->d_id.b24 == ha->d_id.b24) continue; + /* Bypass if same domain and area of adapter. */ + if (((new_fcport->d_id.b24 & 0xffff00) == + (ha->d_id.b24 & 0xffff00)) && ha->current_topology == + ISP_CFG_FL) + continue; + /* Bypass reserved domain fields. */ if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0) continue; From c00c72ae01c03d3d172150392419040f8d55ab04 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:08:50 -0700 Subject: [PATCH 16/32] [SCSI] qla2xxx: Simplify redundant target/device reset logic. Remove redundant qla2x00_target_reset() function in favour of the equivalent qla2x00_device_reset(). Update callers of old function. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_gbl.h | 3 -- drivers/scsi/qla2xxx/qla_mbx.c | 52 ---------------------------------- drivers/scsi/qla2xxx/qla_os.c | 2 +- 3 files changed, 1 insertion(+), 56 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 3e1e5fe850a..5deaa7e6ee6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -147,9 +147,6 @@ extern int qla2x00_abort_target(fc_port_t *); #endif -extern int -qla2x00_target_reset(scsi_qla_host_t *, struct fc_port *); - extern int qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, uint8_t *, uint16_t *); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 284eb847e50..953156faafd 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -983,58 +983,6 @@ qla2x00_abort_target(fc_port_t *fcport) } #endif -/* - * qla2x00_target_reset - * Issue target reset mailbox command. - * - * Input: - * ha = adapter block pointer. - * TARGET_QUEUE_LOCK must be released. - * ADAPTER_STATE_LOCK must be released. - * - * Returns: - * qla2x00 local function return status code. - * - * Context: - * Kernel context. - */ -int -qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport) -{ - int rval; - mbx_cmd_t mc; - mbx_cmd_t *mcp = &mc; - - DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);) - - if (atomic_read(&fcport->state) != FCS_ONLINE) - return 0; - - mcp->mb[0] = MBC_TARGET_RESET; - if (HAS_EXTENDED_IDS(ha)) - mcp->mb[1] = fcport->loop_id; - else - mcp->mb[1] = fcport->loop_id << 8; - mcp->mb[2] = ha->loop_reset_delay; - mcp->out_mb = MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_0; - mcp->tov = 30; - mcp->flags = 0; - rval = qla2x00_mailbox_command(ha, mcp); - - if (rval != QLA_SUCCESS) { - /*EMPTY*/ - DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n", - ha->host_no, rval);) - } else { - /*EMPTY*/ - DEBUG11(printk("qla2x00_target_reset(%ld): done.\n", - ha->host_no);) - } - - return rval; -} - /* * qla2x00_get_adapter_id * Get adapter ID and topology. diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0fc37d810e0..29cf3f51093 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1022,7 +1022,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) if (fcport->port_type != FCT_TARGET) continue; - status = qla2x00_target_reset(ha, fcport); + status = qla2x00_device_reset(ha, fcport); if (status != QLA_SUCCESS) break; } From 06c22bd13f4eb55e291d5a31280b2ae5a70ad00d Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:09:00 -0700 Subject: [PATCH 17/32] [SCSI] qla2xxx: Correct LED scheme definition. Original implementation used an overloaded bit in the EFI parameters. The correct bit is BIT_4 of the special_options section of NVRAM. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 4 ++-- drivers/scsi/qla2xxx/qla_init.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index cdef86e49c6..b7f82b757cb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -914,7 +914,7 @@ typedef struct { * MSB BIT 1 = * MSB BIT 2 = * MSB BIT 3 = - * MSB BIT 4 = + * MSB BIT 4 = LED mode * MSB BIT 5 = enable 50 ohm termination * MSB BIT 6 = Data Rate (2300 only) * MSB BIT 7 = Data Rate (2300 only) @@ -1036,7 +1036,7 @@ typedef struct { * MSB BIT 1 = * MSB BIT 2 = * MSB BIT 3 = - * MSB BIT 4 = + * MSB BIT 4 = LED mode * MSB BIT 5 = enable 50 ohm termination * MSB BIT 6 = Data Rate (2300 only) * MSB BIT 7 = Data Rate (2300 only) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d12255fb938..c619583e646 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1564,7 +1564,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0); ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); - ha->flags.enable_led_scheme = ((nv->efi_parameters & BIT_3) ? 1 : 0); + ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; ha->operating_mode = (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; From c32c4cb9fbe3bdc2a90c6eaae5ae30521d4ba9fc Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:09:10 -0700 Subject: [PATCH 18/32] [SCSI] qla2xxx: Remove RISC pause/release barriers during flash manipulation. Remove unnecessary RISC pause/release barriers during ISP24xx flash manipulation. The ISP24xx can arbitrate flash access requests during RISC executions. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_sup.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index d7f5c608009..c14abf743b7 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -468,21 +468,12 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) { uint32_t i; - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - - /* Pause RISC. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ /* Dword reads to flash. */ for (i = 0; i < dwords; i++, faddr++) dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, flash_data_to_access_addr(faddr))); - /* Release RISC pause. */ - WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - return dwptr; } @@ -532,10 +523,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, ret = QLA_SUCCESS; - /* Pause RISC. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - 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)); @@ -599,10 +586,6 @@ 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. */ - /* Release RISC pause. */ - WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - return ret; } @@ -630,11 +613,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, { uint32_t i; uint32_t *dwptr; - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - - /* Pause RISC. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ /* Dword reads to flash. */ dwptr = (uint32_t *)buf; @@ -642,10 +620,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, nvram_data_to_access_addr(naddr))); - /* Release RISC pause. */ - WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - return buf; } @@ -690,10 +664,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, ret = QLA_SUCCESS; - /* Pause RISC. */ - WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - /* Enable flash write. */ WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); @@ -728,9 +698,5 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ - /* Release RISC pause. */ - WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); - RD_REG_DWORD(®->hccr); /* PCI Posting. */ - return ret; } From 131736d34ebc3251d79ddfd08a5e57a3e86decd4 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:09:20 -0700 Subject: [PATCH 19/32] [SCSI] qla2xxx: Remove redundant call to pci_unmap_sg(). In a corner-case failure where the request-q does not contain enough entries for a given request, pci_unmap_sg() would be called twice. Remove direct call and let the failure-path logic handle the unmapping. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_iocb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index ebdc3c54d15..37f82e2cd7f 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -810,12 +810,8 @@ qla24xx_start_scsi(srb_t *sp) ha->req_q_cnt = ha->request_q_length - (ha->req_ring_index - cnt); } - if (ha->req_q_cnt < (req_cnt + 2)) { - if (cmd->use_sg) - pci_unmap_sg(ha->pdev, sg, cmd->use_sg, - cmd->sc_data_direction); + if (ha->req_q_cnt < (req_cnt + 2)) goto queuing_error; - } /* Build command packet. */ ha->current_outstanding_cmd = handle; From ce7e4af7f507c156c3fd3dbb41ffe4a77c700b54 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:09:30 -0700 Subject: [PATCH 20/32] [SCSI] qla2xxx: Add change_queue_depth/type() API support. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 29cf3f51093..413ccc152de 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -111,6 +111,9 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *); static int qla2x00_loop_reset(scsi_qla_host_t *ha); static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); +static int qla2x00_change_queue_depth(struct scsi_device *, int); +static int qla2x00_change_queue_type(struct scsi_device *, int); + static struct scsi_host_template qla2x00_driver_template = { .module = THIS_MODULE, .name = "qla2xxx", @@ -125,6 +128,8 @@ static struct scsi_host_template qla2x00_driver_template = { .slave_alloc = qla2xxx_slave_alloc, .slave_destroy = qla2xxx_slave_destroy, + .change_queue_depth = qla2x00_change_queue_depth, + .change_queue_type = qla2x00_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, @@ -151,6 +156,8 @@ static struct scsi_host_template qla24xx_driver_template = { .slave_alloc = qla2xxx_slave_alloc, .slave_destroy = qla2xxx_slave_destroy, + .change_queue_depth = qla2x00_change_queue_depth, + .change_queue_type = qla2x00_change_queue_type, .this_id = -1, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, @@ -1109,6 +1116,28 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) sdev->hostdata = NULL; } +static int +qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth) +{ + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); + return sdev->queue_depth; +} + +static int +qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type) +{ + if (sdev->tagged_supported) { + scsi_set_tag_type(sdev, tag_type); + if (tag_type) + scsi_activate_tcq(sdev, sdev->queue_depth); + else + scsi_deactivate_tcq(sdev, sdev->queue_depth); + } else + tag_type = 0; + + return tag_type; +} + /** * qla2x00_config_dma_addressing() - Configure OS DMA addressing method. * @ha: HA context From afb046e2be724a90f21f7cf0ba50e328005bd038 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:09:40 -0700 Subject: [PATCH 21/32] [SCSI] qla2xxx: Add host attributes. Export additional host information via the shost_attrs member in the scsi_host template. Attributes include: driver version, firmware version, ISP serial number, ISP type, ISP product ID, HBA model name, HBA model description, PCI interconnect information, and HBA port state. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 132 ++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 2 + drivers/scsi/qla2xxx/qla_os.c | 2 + 3 files changed, 136 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index d05280eecc6..fe0fce71adc 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -211,6 +211,138 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); } +/* Scsi_Host attributes. */ + +static ssize_t +qla2x00_drvr_version_show(struct class_device *cdev, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); +} + +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)); + char fw_str[30]; + + return snprintf(buf, PAGE_SIZE, "%s\n", + ha->isp_ops.fw_version_str(ha, fw_str)); +} + +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)); + uint32_t sn; + + sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; + return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, + sn % 100000); +} + +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)); + return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name); +} + +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)); + 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]); +} + +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)); + 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)); + return snprintf(buf, PAGE_SIZE, "%s\n", + ha->model_desc ? ha->model_desc: ""); +} + +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)); + char pci_info[30]; + + return snprintf(buf, PAGE_SIZE, "%s\n", + ha->isp_ops.pci_info_str(ha, pci_info)); +} + +static ssize_t +qla2x00_state_show(struct class_device *cdev, char *buf) +{ + scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); + int len = 0; + + if (atomic_read(&ha->loop_state) == LOOP_DOWN || + atomic_read(&ha->loop_state) == LOOP_DEAD) + len = snprintf(buf, PAGE_SIZE, "Link Down\n"); + else if (atomic_read(&ha->loop_state) != LOOP_READY || + test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || + test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) + len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n"); + else { + len = snprintf(buf, PAGE_SIZE, "Link Up - "); + + switch (ha->current_topology) { + case ISP_CFG_NL: + len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); + break; + case ISP_CFG_FL: + len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n"); + break; + case ISP_CFG_N: + len += snprintf(buf + len, PAGE_SIZE-len, + "N_Port to N_Port\n"); + break; + case ISP_CFG_F: + len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n"); + break; + default: + len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); + break; + } + } + return len; +} + +static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, + NULL); +static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); +static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); +static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); +static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL); +static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL); +static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL); +static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL); +static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL); + +struct class_device_attribute *qla2x00_host_attrs[] = { + &class_device_attr_driver_version, + &class_device_attr_fw_version, + &class_device_attr_serial_num, + &class_device_attr_isp_name, + &class_device_attr_isp_id, + &class_device_attr_model_name, + &class_device_attr_model_desc, + &class_device_attr_pci_info, + &class_device_attr_state, + NULL, +}; + /* Host attributes. */ static void diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 5deaa7e6ee6..95fb0c4941a 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -290,6 +290,8 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *); /* * Global Function Prototypes in qla_attr.c source file. */ +struct class_device_attribute; +extern struct class_device_attribute *qla2x00_host_attrs[]; struct fc_function_template; extern struct fc_function_template qla2xxx_transport_functions; extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 413ccc152de..14f2f9077c8 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -140,6 +140,7 @@ static struct scsi_host_template qla2x00_driver_template = { * which equates to 0x800000 sectors. */ .max_sectors = 0xFFFF, + .shost_attrs = qla2x00_host_attrs, }; static struct scsi_host_template qla24xx_driver_template = { @@ -164,6 +165,7 @@ static struct scsi_host_template qla24xx_driver_template = { .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, + .shost_attrs = qla2x00_host_attrs, }; static struct scsi_transport_template *qla2xxx_transport_template = NULL; From 86cd6baa8294dc5b2cedd84fb5cf3944eaf5271f Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:10:00 -0700 Subject: [PATCH 22/32] [SCSI] qla2xxx: Remove bad call to fc_remove_host() during probe failure. fc_remove_host() should only be called after a scsi_host has been successfully added via scsi_add_host() -- any failures while qla2xxx probing would result in an incorrect call to fc_remove_host() during cleanup. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 14f2f9077c8..5a542655d44 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1586,8 +1586,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) return 0; probe_failed: - fc_remove_host(ha->host); - qla2x00_free_device(ha); scsi_host_put(host); From fe74c71f6bb63376d92bc606597f0818f5b11c2e Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:10:10 -0700 Subject: [PATCH 23/32] [SCSI] qla2xxx: Replace schedule_timeout(). From: Nishanth Aravamudan Replace schedule_timeout() with msleep()/msleep_interruptible() as appropriate, to guarantee the task delays as expected. Signed-off-by: Nishanth Aravamudan Signed-off-by: Domen Puncer Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5a542655d44..af9b4e77cbf 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -502,14 +502,13 @@ qc24_fail_command: static int qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) { -#define ABORT_POLLING_PERIOD HZ -#define ABORT_WAIT_ITER ((10 * HZ) / (ABORT_POLLING_PERIOD)) +#define ABORT_POLLING_PERIOD 1000 +#define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) unsigned long wait_iter = ABORT_WAIT_ITER; int ret = QLA_SUCCESS; while (CMD_SP(cmd)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(ABORT_POLLING_PERIOD); + msleep(ABORT_POLLING_PERIOD); if (--wait_iter) break; @@ -1960,7 +1959,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha) { struct list_head *fcpl, *fcptemp; fc_port_t *fcport; - unsigned long wtime;/* max wait time if mbx cmd is busy. */ + unsigned int wtime;/* max wait time if mbx cmd is busy. */ if (ha == NULL) { /* error */ @@ -1969,11 +1968,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) } /* Make sure all other threads are stopped. */ - wtime = 60 * HZ; - while (ha->dpc_wait && wtime) { - set_current_state(TASK_INTERRUPTIBLE); - wtime = schedule_timeout(wtime); - } + wtime = 60 * 1000; + while (ha->dpc_wait && wtime) + wtime = msleep_interruptible(wtime); /* free ioctl memory */ qla2x00_free_ioctl_mem(ha); @@ -2504,15 +2501,15 @@ qla2x00_timer(scsi_qla_host_t *ha) int qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) { - const unsigned int step = HZ/10; + const unsigned int step = 100; /* msecs */ + unsigned int iterations = jiffies_to_msecs(timeout)/100; do { if (!down_trylock(sema)) return 0; - set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(step)) + if (msleep_interruptible(step)) break; - } while ((timeout -= step) > 0); + } while (--iterations >= 0); return -ETIMEDOUT; } From f6ef3b1872915c6d69ca36cf4ca16269cb9a73ad Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:10:20 -0700 Subject: [PATCH 24/32] [SCSI] qla2xxx: Stop firmware execution at unintialization time. On ISP24xx parts, stop execution of firmware during ISP tear-down. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_gbl.h | 3 +++ drivers/scsi/qla2xxx/qla_mbx.c | 29 +++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_os.c | 14 ++++++++------ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b7f82b757cb..b455c31405e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -631,6 +631,7 @@ typedef struct { #define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */ #define MBC_READ_RAM_EXTENDED 0xf /* Read RAM extended. */ #define MBC_IOCB_COMMAND 0x12 /* Execute IOCB command. */ +#define MBC_STOP_FIRMWARE 0x14 /* Stop firmware. */ #define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */ #define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ #define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 95fb0c4941a..1ed32e7b547 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -213,6 +213,9 @@ qla2x00_get_serdes_params(scsi_qla_host_t *, uint16_t *, uint16_t *, extern int qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); +extern int +qla2x00_stop_firmware(scsi_qla_host_t *); + /* * Global Function Prototypes in qla_isr.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 953156faafd..13e1c904707 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -2427,3 +2427,32 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, return rval; } + +int +qla2x00_stop_firmware(scsi_qla_host_t *ha) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + + if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) + return QLA_FUNCTION_FAILED; + + DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); + + mcp->mb[0] = MBC_STOP_FIRMWARE; + mcp->out_mb = MBX_0; + mcp->in_mb = MBX_0; + mcp->tov = 5; + mcp->flags = 0; + rval = qla2x00_mailbox_command(ha, mcp); + + if (rval != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, + ha->host_no, rval)); + } 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 af9b4e77cbf..8982978c42f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -79,7 +79,7 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xloginretrycount, "Specify an alternate value for the NVRAM login retry count."); -int ql2xfwloadbin; +int ql2xfwloadbin=1; module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xfwloadbin, "Load ISP2xxx firmware image via hotplug."); @@ -1626,10 +1626,6 @@ qla2x00_free_device(scsi_qla_host_t *ha) if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) qla2x00_cancel_io_descriptors(ha); - /* turn-off interrupts on the card */ - if (ha->interrupts_on) - ha->isp_ops.disable_intrs(ha); - /* Disable timer */ if (ha->timer_active) qla2x00_stop_timer(ha); @@ -1649,8 +1645,14 @@ qla2x00_free_device(scsi_qla_host_t *ha) } } - qla2x00_mem_free(ha); + /* Stop currently executing firmware. */ + qla2x00_stop_firmware(ha); + /* turn-off interrupts on the card */ + if (ha->interrupts_on) + ha->isp_ops.disable_intrs(ha); + + qla2x00_mem_free(ha); ha->flags.online = 0; From 1aab60c25e9a500b9f15c1dfd775e70e7bde555c Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 26 Aug 2005 19:10:30 -0700 Subject: [PATCH 25/32] [SCSI] qla2xxx: Update version number to 8.01.00-k. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index e3cd3618bc5..eae7d6edd53 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -19,9 +19,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.00b5-k" +#define QLA2XXX_VERSION "8.01.00-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 5 +#define QLA_DRIVER_BETA_VER 0 From 4dddbc26c3895ecdab1f4b16435685b47f96f599 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 6 Sep 2005 17:11:54 -0500 Subject: [PATCH 26/32] [SCSI] ibmvscsi: handle large scatter/gather lists The maximum size of a scatter-gather list that the current IBM VSCSI Client can handle is 10. This patch adds large scatter-gather support to the client so that it is capable of handling up to SG_ALL(255) number of requests in the scatter-gather list. Signed-off-by: Linda Xie Acked by: Dave C Boutcher Rejections fixed up and Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.c | 166 ++++++++++++++++++++++--------- drivers/scsi/ibmvscsi/ibmvscsi.h | 2 + 2 files changed, 121 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e3e6752c410..1b911dadf64 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -87,7 +87,7 @@ static int max_channel = 3; static int init_timeout = 5; static int max_requests = 50; -#define IBMVSCSI_VERSION "1.5.6" +#define IBMVSCSI_VERSION "1.5.7" MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); @@ -145,6 +145,8 @@ static int initialize_event_pool(struct event_pool *pool, sizeof(*evt->xfer_iu) * i; evt->xfer_iu = pool->iu_storage + i; evt->hostdata = hostdata; + evt->ext_list = NULL; + evt->ext_list_token = 0; } return 0; @@ -161,9 +163,16 @@ static void release_event_pool(struct event_pool *pool, struct ibmvscsi_host_data *hostdata) { int i, in_use = 0; - for (i = 0; i < pool->size; ++i) + for (i = 0; i < pool->size; ++i) { if (atomic_read(&pool->events[i].free) != 1) ++in_use; + if (pool->events[i].ext_list) { + dma_free_coherent(hostdata->dev, + SG_ALL * sizeof(struct memory_descriptor), + pool->events[i].ext_list, + pool->events[i].ext_list_token); + } + } if (in_use) printk(KERN_WARNING "ibmvscsi: releasing event pool with %d " @@ -286,24 +295,41 @@ static void set_srp_direction(struct scsi_cmnd *cmd, } else { if (cmd->sc_data_direction == DMA_TO_DEVICE) { srp_cmd->data_out_format = SRP_INDIRECT_BUFFER; - srp_cmd->data_out_count = numbuf; + srp_cmd->data_out_count = + numbuf < MAX_INDIRECT_BUFS ? + numbuf: MAX_INDIRECT_BUFS; } else { srp_cmd->data_in_format = SRP_INDIRECT_BUFFER; - srp_cmd->data_in_count = numbuf; + srp_cmd->data_in_count = + numbuf < MAX_INDIRECT_BUFS ? + numbuf: MAX_INDIRECT_BUFS; } } } +static void unmap_sg_list(int num_entries, + struct device *dev, + struct memory_descriptor *md) +{ + int i; + + for (i = 0; i < num_entries; ++i) { + dma_unmap_single(dev, + md[i].virtual_address, + md[i].length, DMA_BIDIRECTIONAL); + } +} + /** * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format * @cmd: srp_cmd whose additional_data member will be unmapped * @dev: device for which the memory is mapped * */ -static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev) +static void unmap_cmd_data(struct srp_cmd *cmd, + struct srp_event_struct *evt_struct, + struct device *dev) { - int i; - if ((cmd->data_out_format == SRP_NO_BUFFER) && (cmd->data_in_format == SRP_NO_BUFFER)) return; @@ -318,15 +344,34 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev) (struct indirect_descriptor *)cmd->additional_data; int num_mapped = indirect->head.length / sizeof(indirect->list[0]); - for (i = 0; i < num_mapped; ++i) { - struct memory_descriptor *data = &indirect->list[i]; - dma_unmap_single(dev, - data->virtual_address, - data->length, DMA_BIDIRECTIONAL); + + if (num_mapped <= MAX_INDIRECT_BUFS) { + unmap_sg_list(num_mapped, dev, &indirect->list[0]); + return; } + + unmap_sg_list(num_mapped, dev, evt_struct->ext_list); } } +static int map_sg_list(int num_entries, + struct scatterlist *sg, + struct memory_descriptor *md) +{ + int i; + u64 total_length = 0; + + for (i = 0; i < num_entries; ++i) { + struct memory_descriptor *descr = md + i; + struct scatterlist *sg_entry = &sg[i]; + descr->virtual_address = sg_dma_address(sg_entry); + descr->length = sg_dma_len(sg_entry); + descr->memory_handle = 0; + total_length += sg_dma_len(sg_entry); + } + return total_length; +} + /** * map_sg_data: - Maps dma for a scatterlist and initializes decriptor fields * @cmd: Scsi_Cmnd with the scatterlist @@ -337,10 +382,11 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev) * Returns 1 on success. */ static int map_sg_data(struct scsi_cmnd *cmd, + struct srp_event_struct *evt_struct, struct srp_cmd *srp_cmd, struct device *dev) { - int i, sg_mapped; + int sg_mapped; u64 total_length = 0; struct scatterlist *sg = cmd->request_buffer; struct memory_descriptor *data = @@ -363,27 +409,46 @@ static int map_sg_data(struct scsi_cmnd *cmd, return 1; } - if (sg_mapped > MAX_INDIRECT_BUFS) { + if (sg_mapped > SG_ALL) { printk(KERN_ERR "ibmvscsi: More than %d mapped sg entries, got %d\n", - MAX_INDIRECT_BUFS, sg_mapped); + SG_ALL, sg_mapped); return 0; } indirect->head.virtual_address = 0; indirect->head.length = sg_mapped * sizeof(indirect->list[0]); indirect->head.memory_handle = 0; - for (i = 0; i < sg_mapped; ++i) { - struct memory_descriptor *descr = &indirect->list[i]; - struct scatterlist *sg_entry = &sg[i]; - descr->virtual_address = sg_dma_address(sg_entry); - descr->length = sg_dma_len(sg_entry); - descr->memory_handle = 0; - total_length += sg_dma_len(sg_entry); - } - indirect->total_length = total_length; - return 1; + if (sg_mapped <= MAX_INDIRECT_BUFS) { + total_length = map_sg_list(sg_mapped, sg, &indirect->list[0]); + indirect->total_length = total_length; + return 1; + } + + /* get indirect table */ + if (!evt_struct->ext_list) { + evt_struct->ext_list =(struct memory_descriptor*) + dma_alloc_coherent(dev, + SG_ALL * sizeof(struct memory_descriptor), + &evt_struct->ext_list_token, 0); + if (!evt_struct->ext_list) { + printk(KERN_ERR + "ibmvscsi: Can't allocate memory for indirect table\n"); + return 0; + + } + } + + total_length = map_sg_list(sg_mapped, sg, evt_struct->ext_list); + + indirect->total_length = total_length; + indirect->head.virtual_address = evt_struct->ext_list_token; + indirect->head.length = sg_mapped * sizeof(indirect->list[0]); + memcpy(indirect->list, evt_struct->ext_list, + MAX_INDIRECT_BUFS * sizeof(struct memory_descriptor)); + + return 1; } /** @@ -428,6 +493,7 @@ static int map_single_data(struct scsi_cmnd *cmd, * Returns 1 on success. */ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, + struct srp_event_struct *evt_struct, struct srp_cmd *srp_cmd, struct device *dev) { switch (cmd->sc_data_direction) { @@ -450,7 +516,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, if (!cmd->request_buffer) return 1; if (cmd->use_sg) - return map_sg_data(cmd, srp_cmd, dev); + return map_sg_data(cmd, evt_struct, srp_cmd, dev); return map_single_data(cmd, srp_cmd, dev); } @@ -486,6 +552,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, printk(KERN_WARNING "ibmvscsi: Warning, request_limit exceeded\n"); unmap_cmd_data(&evt_struct->iu.srp.cmd, + evt_struct, hostdata->dev); free_event_struct(&hostdata->pool, evt_struct); return SCSI_MLQUEUE_HOST_BUSY; @@ -513,7 +580,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, return 0; send_error: - unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev); + unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); if ((cmnd = evt_struct->cmnd) != NULL) { cmnd->result = DID_ERROR << 16; @@ -551,6 +618,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) rsp->sense_and_response_data, rsp->sense_data_list_length); unmap_cmd_data(&evt_struct->iu.srp.cmd, + evt_struct, evt_struct->hostdata->dev); if (rsp->doover) @@ -583,6 +651,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, { struct srp_cmd *srp_cmd; struct srp_event_struct *evt_struct; + struct indirect_descriptor *indirect; struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata; u16 lun = lun_from_dev(cmnd->device); @@ -591,6 +660,19 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, if (!evt_struct) return SCSI_MLQUEUE_HOST_BUSY; + /* Set up the actual SRP IU */ + srp_cmd = &evt_struct->iu.srp.cmd; + memset(srp_cmd, 0x00, sizeof(*srp_cmd)); + srp_cmd->type = SRP_CMD_TYPE; + memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); + srp_cmd->lun = ((u64) lun) << 48; + + if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) { + printk(KERN_ERR "ibmvscsi: couldn't convert cmd to srp_cmd\n"); + free_event_struct(&hostdata->pool, evt_struct); + return SCSI_MLQUEUE_HOST_BUSY; + } + init_event_struct(evt_struct, handle_cmd_rsp, VIOSRP_SRP_FORMAT, @@ -599,24 +681,11 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, evt_struct->cmnd = cmnd; evt_struct->cmnd_done = done; - /* Set up the actual SRP IU */ - srp_cmd = &evt_struct->iu.srp.cmd; - memset(srp_cmd, 0x00, sizeof(*srp_cmd)); - srp_cmd->type = SRP_CMD_TYPE; - memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); - srp_cmd->lun = ((u64) lun) << 48; - - if (!map_data_for_srp_cmd(cmnd, srp_cmd, hostdata->dev)) { - printk(KERN_ERR "ibmvscsi: couldn't convert cmd to srp_cmd\n"); - free_event_struct(&hostdata->pool, evt_struct); - return SCSI_MLQUEUE_HOST_BUSY; - } - /* Fix up dma address of the buffer itself */ - if ((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) || - (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) { - struct indirect_descriptor *indirect = - (struct indirect_descriptor *)srp_cmd->additional_data; + indirect = (struct indirect_descriptor *)srp_cmd->additional_data; + if (((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) || + (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) && + (indirect->head.virtual_address == 0)) { indirect->head.virtual_address = evt_struct->crq.IU_data_ptr + offsetof(struct srp_cmd, additional_data) + offsetof(struct indirect_descriptor, list); @@ -931,7 +1000,8 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) cmd->result = (DID_ABORT << 16); list_del(&found_evt->list); - unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev); + unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt, + found_evt->hostdata->dev); free_event_struct(&found_evt->hostdata->pool, found_evt); spin_unlock_irqrestore(hostdata->host->host_lock, flags); atomic_inc(&hostdata->request_limit); @@ -1023,7 +1093,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) if (tmp_evt->cmnd) tmp_evt->cmnd->result = (DID_RESET << 16); list_del(&tmp_evt->list); - unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt->hostdata->dev); + unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt, + tmp_evt->hostdata->dev); free_event_struct(&tmp_evt->hostdata->pool, tmp_evt); atomic_inc(&hostdata->request_limit); @@ -1052,6 +1123,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata) if (tmp_evt->cmnd) { tmp_evt->cmnd->result = (DID_ERROR << 16); unmap_cmd_data(&tmp_evt->iu.srp.cmd, + tmp_evt, tmp_evt->hostdata->dev); if (tmp_evt->cmnd_done) tmp_evt->cmnd_done(tmp_evt->cmnd); @@ -1356,7 +1428,7 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 16, .can_queue = 1, /* Updated after SRP_LOGIN */ .this_id = -1, - .sg_tablesize = MAX_INDIRECT_BUFS, + .sg_tablesize = SG_ALL, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = ibmvscsi_attrs, }; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 1030b703c30..8bec0438dc8 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -68,6 +68,8 @@ struct srp_event_struct { void (*cmnd_done) (struct scsi_cmnd *); struct completion comp; union viosrp_iu *sync_srp; + struct memory_descriptor *ext_list; + dma_addr_t ext_list_token; }; /* a pool of event structs for use */ From e47373ec1c9aab9ee134f4e2b8249957e9f4c7ef Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 30 Mar 2005 15:05:45 -0500 Subject: [PATCH 27/32] [SCSI] return success after retries in scsi_eh_tur The problem lies in the way the error handler uses TEST UNIT READY to tell whether error recovery has succeeded. The scsi_eh_tur function gives up after one round of retrying; after that it decides that more error recovery is needed. However TUR is liable to report sense data indicating a retry is needed when in fact error recovery has succeeded. A typical example might be SK=2, ASC=4, ASCQ=1 (Logical unit in process of becoming ready). The mere fact that we were able to get a sensible reply to the TUR should indicate that the device is working well enough to stop error recovery. I ran across a case back in January where this happened. A CD-ROM drive timed out the INQUIRY command, and a device reset fixed the blockage. But then the drive kept responding with 2/4/1 -- because it was spinning up I suppose -- until the error handler gave up and placed it offline. If the initial INQUIRY had received the 2/4/1 instead, everything would have worked okay. It doesn't seem reasonable for things to fail just because the error handler had started running. Signed-off-by: Alan Stern Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index e9c451ba71f..688bce74078 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -776,9 +776,11 @@ retry_tur: __FUNCTION__, scmd, rtn)); if (rtn == SUCCESS) return 0; - else if (rtn == NEEDS_RETRY) + else if (rtn == NEEDS_RETRY) { if (retry_cnt--) goto retry_tur; + return 0; + } return 1; } From 4451e472627881e3e2240b224f127c99be500f91 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 12 Jul 2005 10:45:17 -0400 Subject: [PATCH 28/32] [SCSI] sd: pause in sd_spinup_disk for slow USB devices This patch adds a delay tailored for USB flash devices that are slow to initialize their firmware. The symptom is a repeated Unit Attention with ASC=0x28 (Not Ready to Ready transition). The patch will wait for up to 5 seconds for such devices to become ready. Normal devices won't send the repeated Unit Attention sense key and hence won't trigger the patch. This fixes a problem with James Roberts-Thomson's USB device, and I've seen several reports of other devices exhibiting the same symptoms -- presumably they will be helped as well. Signed-off-by: Alan Stern Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0410e1bf109..41ba0809f79 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -984,7 +984,7 @@ static void sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, struct scsi_request *SRpnt, unsigned char *buffer) { unsigned char cmd[10]; - unsigned long spintime_value = 0; + unsigned long spintime_expire = 0; int retries, spintime; unsigned int the_result; struct scsi_sense_hdr sshdr; @@ -1071,12 +1071,27 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, scsi_wait_req(SRpnt, (void *)cmd, (void *) buffer, 0/*512*/, SD_TIMEOUT, SD_MAX_RETRIES); - spintime_value = jiffies; + spintime_expire = jiffies + 100 * HZ; + spintime = 1; } - spintime = 1; /* Wait 1 second for next try */ msleep(1000); printk("."); + + /* + * Wait for USB flash devices with slow firmware. + * Yes, this sense key/ASC combination shouldn't + * occur here. It's characteristic of these devices. + */ + } else if (sense_valid && + sshdr.sense_key == UNIT_ATTENTION && + sshdr.asc == 0x28) { + if (!spintime) { + spintime_expire = jiffies + 5 * HZ; + spintime = 1; + } + /* Wait 1 second for next try */ + msleep(1000); } else { /* we don't understand the sense code, so it's * probably pointless to loop */ @@ -1088,8 +1103,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, break; } - } while (spintime && - time_after(spintime_value + 100 * HZ, jiffies)); + } while (spintime && time_before_eq(jiffies, spintime_expire)); if (spintime) { if (scsi_status_is_good(the_result)) From 4869040512082b761de2d7c35975d01044f8bfea Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 6 Sep 2005 18:08:14 +1000 Subject: [PATCH 29/32] [SCSI] Universal Xport no attach blacklist On Fri, Dec 13, 2002 at 12:24:39AM +1100, Anton Blanchard wrote: > We tested 2.5.51 on a ppc64 box, qlogic 2312 and a fastt700 array. I > had CONFIG_SCSI_REPORT_LUNS and unfortunately it thought the management > LUN was a disk: > > Vendor: IBM Model: Universal Xport Rev: 0520 > Type: Direct-Access ANSI SCSI revision: 03 > > ... > > SCSI device sdaj: drive cache: write through > SCSI device sdaj: 40960 512-byte hdwr sectors (21 MB) > sdaj: unknown partition table > Attached scsi disk sdaj at scsi2, channel 0, id 0, lun 31 > > ... > > end_request: I/O error, dev sdaj, sector 0 Three years later... It looks like SGI use the same FC vendor and they already have a workaround for this issue. The following patch adds the IBM version of it. Signed-off-by: Anton Blanchard 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 b444ec2e1c6..07b554affcf 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -192,6 +192,7 @@ static struct { {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ From 32993523dc59759ae6cb349e4d231d4cd2165329 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 6 Sep 2005 14:03:44 +0200 Subject: [PATCH 30/32] [SCSI] fix SCSI_IOCTL_PROBE_HOST This returns always false with new-style drivers right now. Make it return always true instead, as a host must be present if we are able to call the ioctl (without a host attached there would be no device node to call on..) Signed-off-by: James Bottomley --- drivers/scsi/scsi_ioctl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index f5bf5c07be9..946c31fa646 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -30,20 +30,20 @@ #define MAX_BUF PAGE_SIZE -/* - * If we are told to probe a host, we will return 0 if the host is not - * present, 1 if the host is present, and will return an identifying - * string at *arg, if arg is non null, filling to the length stored at - * (int *) arg +/** + * ioctl_probe -- return host identification + * @host: host to identify + * @buffer: userspace buffer for identification + * + * Return an identifying string at @buffer, if @buffer is non-NULL, filling + * to the length stored at * (int *) @buffer. */ - static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) { unsigned int len, slen; const char *string; - int temp = host->hostt->present; - if (temp && buffer) { + if (buffer) { if (get_user(len, (unsigned int __user *) buffer)) return -EFAULT; @@ -59,7 +59,7 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) return -EFAULT; } } - return temp; + return 1; } /* From c5478def7a3a2dba9ceda452c2aa3539514d30a9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 6 Sep 2005 14:04:26 +0200 Subject: [PATCH 31/32] [SCSI] switch EH thread startup to the kthread API Signed-off-by: James Bottomley --- drivers/scsi/hosts.c | 23 ++++++++--------------- drivers/scsi/scsi_error.c | 29 ++--------------------------- include/scsi/scsi_host.h | 2 -- 3 files changed, 10 insertions(+), 44 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 8640ad1c17e..85503fad789 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -225,15 +226,8 @@ static void scsi_host_dev_release(struct device *dev) struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; - if (shost->ehandler) { - DECLARE_COMPLETION(sem); - shost->eh_notify = &sem; - shost->eh_kill = 1; - up(shost->eh_wait); - wait_for_completion(&sem); - shost->eh_notify = NULL; - } - + if (shost->ehandler) + kthread_stop(shost->ehandler); if (shost->work_q) destroy_workqueue(shost->work_q); @@ -263,7 +257,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) { struct Scsi_Host *shost; int gfp_mask = GFP_KERNEL, rval; - DECLARE_COMPLETION(complete); if (sht->unchecked_isa_dma && privsize) gfp_mask |= __GFP_DMA; @@ -369,12 +362,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", shost->host_no); - shost->eh_notify = &complete; - rval = kernel_thread(scsi_error_handler, shost, 0); - if (rval < 0) + shost->ehandler = kthread_run(scsi_error_handler, shost, + "scsi_eh_%d", shost->host_no); + if (IS_ERR(shost->ehandler)) { + rval = PTR_ERR(shost->ehandler); goto fail_destroy_freelist; - wait_for_completion(&complete); - shost->eh_notify = NULL; + } scsi_proc_hostdir_add(shost->hostt); return shost; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 688bce74078..ebe74ccb518 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1585,16 +1586,8 @@ int scsi_error_handler(void *data) int rtn; DECLARE_MUTEX_LOCKED(sem); - /* - * Flush resources - */ - - daemonize("scsi_eh_%d", shost->host_no); - current->flags |= PF_NOFREEZE; - shost->eh_wait = &sem; - shost->ehandler = current; /* * Wake up the thread that created us. @@ -1602,8 +1595,6 @@ int scsi_error_handler(void *data) SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of" " scsi_eh_%d\n",shost->host_no)); - complete(shost->eh_notify); - while (1) { /* * If we get a signal, it means we are supposed to go @@ -1624,7 +1615,7 @@ int scsi_error_handler(void *data) * semaphores isn't unreasonable. */ down_interruptible(&sem); - if (shost->eh_kill) + if (kthread_should_stop()) break; SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" @@ -1663,22 +1654,6 @@ int scsi_error_handler(void *data) * Make sure that nobody tries to wake us up again. */ shost->eh_wait = NULL; - - /* - * Knock this down too. From this point on, the host is flying - * without a pilot. If this is because the module is being unloaded, - * that's fine. If the user sent a signal to this thing, we are - * potentially in real danger. - */ - shost->eh_active = 0; - shost->ehandler = NULL; - - /* - * If anyone is waiting for us to exit (i.e. someone trying to unload - * a driver), then wake up that process to let them know we are on - * the way out the door. - */ - complete_and_exit(shost->eh_notify, 0); return 0; } diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index ac1b6125e3a..916144be208 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -467,12 +467,10 @@ struct Scsi_Host { struct task_struct * ehandler; /* Error recovery thread. */ struct semaphore * eh_wait; /* The error recovery thread waits on this. */ - struct completion * eh_notify; /* wait for eh to begin or end */ struct semaphore * eh_action; /* Wait for specific actions on the host. */ unsigned int eh_active:1; /* Indicates the eh thread is awake and active if this is true. */ - unsigned int eh_kill:1; /* set when killing the eh thread */ wait_queue_head_t host_wait; struct scsi_host_template *hostt; struct scsi_transport_template *transportt; From fe1b2d544d71300f8e2d151c3c77a130d13a58be Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 6 Sep 2005 14:15:37 +0200 Subject: [PATCH 32/32] [SCSI] unexport scsi_add_timer/scsi_delete_timer Signed-off-by: James Bottomley --- Documentation/scsi/scsi_mid_low_api.txt | 41 ------------------------- drivers/scsi/scsi_error.c | 2 -- drivers/scsi/scsi_priv.h | 3 ++ include/scsi/scsi_eh.h | 3 -- 4 files changed, 3 insertions(+), 46 deletions(-) diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 7536823c0cb..44df89c9c04 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt @@ -373,13 +373,11 @@ Summary: scsi_activate_tcq - turn on tag command queueing scsi_add_device - creates new scsi device (lu) instance scsi_add_host - perform sysfs registration and SCSI bus scan. - scsi_add_timer - (re-)start timer on a SCSI command. scsi_adjust_queue_depth - change the queue depth on a SCSI device scsi_assign_lock - replace default host_lock with given lock scsi_bios_ptable - return copy of block device's partition table scsi_block_requests - prevent further commands being queued to given host scsi_deactivate_tcq - turn off tag command queueing - scsi_delete_timer - cancel timer on a SCSI command. scsi_host_alloc - return a new scsi_host instance whose refcount==1 scsi_host_get - increments Scsi_Host instance's refcount scsi_host_put - decrements Scsi_Host instance's refcount (free if 0) @@ -457,27 +455,6 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost, int scsi_add_host(struct Scsi_Host *shost, struct device * dev) -/** - * scsi_add_timer - (re-)start timer on a SCSI command. - * @scmd: pointer to scsi command instance - * @timeout: duration of timeout in "jiffies" - * @complete: pointer to function to call if timeout expires - * - * Returns nothing - * - * Might block: no - * - * Notes: Each scsi command has its own timer, and as it is added - * to the queue, we set up the timer. When the command completes, - * we cancel the timer. An LLD can use this function to change - * the existing timeout value. - * - * Defined in: drivers/scsi/scsi_error.c - **/ -void scsi_add_timer(struct scsi_cmnd *scmd, int timeout, - void (*complete)(struct scsi_cmnd *)) - - /** * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device * @sdev: pointer to SCSI device to change queue depth on @@ -565,24 +542,6 @@ void scsi_block_requests(struct Scsi_Host * shost) void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) -/** - * scsi_delete_timer - cancel timer on a SCSI command. - * @scmd: pointer to scsi command instance - * - * Returns 1 if able to cancel timer else 0 (i.e. too late or already - * cancelled). - * - * Might block: no [may in the future if it invokes del_timer_sync()] - * - * Notes: All commands issued by upper levels already have a timeout - * associated with them. An LLD can use this function to cancel the - * timer. - * - * Defined in: drivers/scsi/scsi_error.c - **/ -int scsi_delete_timer(struct scsi_cmnd *scmd) - - /** * scsi_host_alloc - create a scsi host adapter instance and perform basic * initialization. diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index ebe74ccb518..ae28bcb7924 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -116,7 +116,6 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout, add_timer(&scmd->eh_timeout); } -EXPORT_SYMBOL(scsi_add_timer); /** * scsi_delete_timer - Delete/cancel timer for a given function. @@ -144,7 +143,6 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) return rtn; } -EXPORT_SYMBOL(scsi_delete_timer); /** * scsi_times_out - Timeout function for normal scsi commands. diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index d30d7f4e63e..ee6de1768e5 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -63,6 +63,9 @@ extern int __init scsi_init_devinfo(void); extern void scsi_exit_devinfo(void); /* scsi_error.c */ +extern void scsi_add_timer(struct scsi_cmnd *, int, + void (*)(struct scsi_cmnd *)); +extern int scsi_delete_timer(struct scsi_cmnd *); extern void scsi_times_out(struct scsi_cmnd *cmd); extern int scsi_error_handler(void *host); extern int scsi_decide_disposition(struct scsi_cmnd *cmd); diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 80557f879e3..4b71095be68 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -27,9 +27,6 @@ struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ }; -extern void scsi_add_timer(struct scsi_cmnd *, int, - void (*)(struct scsi_cmnd *)); -extern int scsi_delete_timer(struct scsi_cmnd *); extern void scsi_report_bus_reset(struct Scsi_Host *, int); extern void scsi_report_device_reset(struct Scsi_Host *, int, int); extern int scsi_block_when_processing_errors(struct scsi_device *);