aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-09-06 18:52:54 -0400
committerJames Bottomley <jejb@titanic.(none)>2005-09-06 18:52:54 -0400
commit17fa53da1239b8712c5cebbd72a74c713b6c2db9 (patch)
tree8cf55e47ce681a6c899ccf8e06abeccecb20d38b
parent3173d8c342971a03857d8af749a3f57da7d06b57 (diff)
parentfe1b2d544d71300f8e2d151c3c77a130d13a58be (diff)
Merge by hand (conflicts in sd.c)
-rw-r--r--Documentation/scsi/scsi_mid_low_api.txt41
-rw-r--r--drivers/base/attribute_container.c67
-rw-r--r--drivers/message/fusion/lsi/mpi.h19
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h85
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt67
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h203
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h11
-rw-r--r--drivers/message/fusion/lsi/mpi_targ.h74
-rw-r--r--drivers/message/fusion/mptbase.c321
-rw-r--r--drivers/message/fusion/mptbase.h5
-rw-r--r--drivers/message/fusion/mptctl.c14
-rw-r--r--drivers/message/fusion/mptscsih.c140
-rw-r--r--drivers/message/fusion/mptspi.c6
-rw-r--r--drivers/scsi/Kconfig6
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/aacraid/aachba.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c96
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_proc.c45
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c89
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_proc.c45
-rw-r--r--drivers/scsi/aic7xxx/aiclib.c121
-rw-r--r--drivers/scsi/aic7xxx/aiclib.h22
-rw-r--r--drivers/scsi/hosts.c23
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c156
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c136
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h157
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h12
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c564
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c24
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c97
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c117
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c34
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/raid_class.c250
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_error.c35
-rw-r--r--drivers/scsi/scsi_ioctl.c18
-rw-r--r--drivers/scsi/scsi_priv.h3
-rw-r--r--drivers/scsi/sd.c24
-rw-r--r--drivers/scsi/sg.c8
-rw-r--r--drivers/scsi/st.c8
-rw-r--r--include/linux/attribute_container.h4
-rw-r--r--include/linux/raid_class.h59
-rw-r--r--include/scsi/scsi_eh.h3
-rw-r--r--include/scsi/scsi_host.h2
49 files changed, 2482 insertions, 755 deletions
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 7536823c0cb1..44df89c9c049 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -373,13 +373,11 @@ Summary:
373 scsi_activate_tcq - turn on tag command queueing 373 scsi_activate_tcq - turn on tag command queueing
374 scsi_add_device - creates new scsi device (lu) instance 374 scsi_add_device - creates new scsi device (lu) instance
375 scsi_add_host - perform sysfs registration and SCSI bus scan. 375 scsi_add_host - perform sysfs registration and SCSI bus scan.
376 scsi_add_timer - (re-)start timer on a SCSI command.
377 scsi_adjust_queue_depth - change the queue depth on a SCSI device 376 scsi_adjust_queue_depth - change the queue depth on a SCSI device
378 scsi_assign_lock - replace default host_lock with given lock 377 scsi_assign_lock - replace default host_lock with given lock
379 scsi_bios_ptable - return copy of block device's partition table 378 scsi_bios_ptable - return copy of block device's partition table
380 scsi_block_requests - prevent further commands being queued to given host 379 scsi_block_requests - prevent further commands being queued to given host
381 scsi_deactivate_tcq - turn off tag command queueing 380 scsi_deactivate_tcq - turn off tag command queueing
382 scsi_delete_timer - cancel timer on a SCSI command.
383 scsi_host_alloc - return a new scsi_host instance whose refcount==1 381 scsi_host_alloc - return a new scsi_host instance whose refcount==1
384 scsi_host_get - increments Scsi_Host instance's refcount 382 scsi_host_get - increments Scsi_Host instance's refcount
385 scsi_host_put - decrements Scsi_Host instance's refcount (free if 0) 383 scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
@@ -458,27 +456,6 @@ int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
458 456
459 457
460/** 458/**
461 * scsi_add_timer - (re-)start timer on a SCSI command.
462 * @scmd: pointer to scsi command instance
463 * @timeout: duration of timeout in "jiffies"
464 * @complete: pointer to function to call if timeout expires
465 *
466 * Returns nothing
467 *
468 * Might block: no
469 *
470 * Notes: Each scsi command has its own timer, and as it is added
471 * to the queue, we set up the timer. When the command completes,
472 * we cancel the timer. An LLD can use this function to change
473 * the existing timeout value.
474 *
475 * Defined in: drivers/scsi/scsi_error.c
476 **/
477void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
478 void (*complete)(struct scsi_cmnd *))
479
480
481/**
482 * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device 459 * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device
483 * @sdev: pointer to SCSI device to change queue depth on 460 * @sdev: pointer to SCSI device to change queue depth on
484 * @tagged: 0 - no tagged queuing 461 * @tagged: 0 - no tagged queuing
@@ -566,24 +543,6 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
566 543
567 544
568/** 545/**
569 * scsi_delete_timer - cancel timer on a SCSI command.
570 * @scmd: pointer to scsi command instance
571 *
572 * Returns 1 if able to cancel timer else 0 (i.e. too late or already
573 * cancelled).
574 *
575 * Might block: no [may in the future if it invokes del_timer_sync()]
576 *
577 * Notes: All commands issued by upper levels already have a timeout
578 * associated with them. An LLD can use this function to cancel the
579 * timer.
580 *
581 * Defined in: drivers/scsi/scsi_error.c
582 **/
583int scsi_delete_timer(struct scsi_cmnd *scmd)
584
585
586/**
587 * scsi_host_alloc - create a scsi host adapter instance and perform basic 546 * scsi_host_alloc - create a scsi host adapter instance and perform basic
588 * initialization. 547 * initialization.
589 * @sht: pointer to scsi host template 548 * @sht: pointer to scsi host template
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index ebcae5c34133..373e7b728fa7 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -22,11 +22,26 @@
22/* This is a private structure used to tie the classdev and the 22/* This is a private structure used to tie the classdev and the
23 * container .. it should never be visible outside this file */ 23 * container .. it should never be visible outside this file */
24struct internal_container { 24struct internal_container {
25 struct list_head node; 25 struct klist_node node;
26 struct attribute_container *cont; 26 struct attribute_container *cont;
27 struct class_device classdev; 27 struct class_device classdev;
28}; 28};
29 29
30static void internal_container_klist_get(struct klist_node *n)
31{
32 struct internal_container *ic =
33 container_of(n, struct internal_container, node);
34 class_device_get(&ic->classdev);
35}
36
37static void internal_container_klist_put(struct klist_node *n)
38{
39 struct internal_container *ic =
40 container_of(n, struct internal_container, node);
41 class_device_put(&ic->classdev);
42}
43
44
30/** 45/**
31 * attribute_container_classdev_to_container - given a classdev, return the container 46 * attribute_container_classdev_to_container - given a classdev, return the container
32 * 47 *
@@ -57,8 +72,8 @@ int
57attribute_container_register(struct attribute_container *cont) 72attribute_container_register(struct attribute_container *cont)
58{ 73{
59 INIT_LIST_HEAD(&cont->node); 74 INIT_LIST_HEAD(&cont->node);
60 INIT_LIST_HEAD(&cont->containers); 75 klist_init(&cont->containers,internal_container_klist_get,
61 spin_lock_init(&cont->containers_lock); 76 internal_container_klist_put);
62 77
63 down(&attribute_container_mutex); 78 down(&attribute_container_mutex);
64 list_add_tail(&cont->node, &attribute_container_list); 79 list_add_tail(&cont->node, &attribute_container_list);
@@ -78,13 +93,13 @@ attribute_container_unregister(struct attribute_container *cont)
78{ 93{
79 int retval = -EBUSY; 94 int retval = -EBUSY;
80 down(&attribute_container_mutex); 95 down(&attribute_container_mutex);
81 spin_lock(&cont->containers_lock); 96 spin_lock(&cont->containers.k_lock);
82 if (!list_empty(&cont->containers)) 97 if (!list_empty(&cont->containers.k_list))
83 goto out; 98 goto out;
84 retval = 0; 99 retval = 0;
85 list_del(&cont->node); 100 list_del(&cont->node);
86 out: 101 out:
87 spin_unlock(&cont->containers_lock); 102 spin_unlock(&cont->containers.k_lock);
88 up(&attribute_container_mutex); 103 up(&attribute_container_mutex);
89 return retval; 104 return retval;
90 105
@@ -143,7 +158,6 @@ attribute_container_add_device(struct device *dev,
143 continue; 158 continue;
144 } 159 }
145 memset(ic, 0, sizeof(struct internal_container)); 160 memset(ic, 0, sizeof(struct internal_container));
146 INIT_LIST_HEAD(&ic->node);
147 ic->cont = cont; 161 ic->cont = cont;
148 class_device_initialize(&ic->classdev); 162 class_device_initialize(&ic->classdev);
149 ic->classdev.dev = get_device(dev); 163 ic->classdev.dev = get_device(dev);
@@ -154,13 +168,22 @@ attribute_container_add_device(struct device *dev,
154 fn(cont, dev, &ic->classdev); 168 fn(cont, dev, &ic->classdev);
155 else 169 else
156 attribute_container_add_class_device(&ic->classdev); 170 attribute_container_add_class_device(&ic->classdev);
157 spin_lock(&cont->containers_lock); 171 klist_add_tail(&ic->node, &cont->containers);
158 list_add_tail(&ic->node, &cont->containers);
159 spin_unlock(&cont->containers_lock);
160 } 172 }
161 up(&attribute_container_mutex); 173 up(&attribute_container_mutex);
162} 174}
163 175
176/* FIXME: can't break out of this unless klist_iter_exit is also
177 * called before doing the break
178 */
179#define klist_for_each_entry(pos, head, member, iter) \
180 for (klist_iter_init(head, iter); (pos = ({ \
181 struct klist_node *n = klist_next(iter); \
182 n ? container_of(n, typeof(*pos), member) : \
183 ({ klist_iter_exit(iter) ; NULL; }); \
184 }) ) != NULL; )
185
186
164/** 187/**
165 * attribute_container_remove_device - make device eligible for removal. 188 * attribute_container_remove_device - make device eligible for removal.
166 * 189 *
@@ -187,18 +210,19 @@ attribute_container_remove_device(struct device *dev,
187 210
188 down(&attribute_container_mutex); 211 down(&attribute_container_mutex);
189 list_for_each_entry(cont, &attribute_container_list, node) { 212 list_for_each_entry(cont, &attribute_container_list, node) {
190 struct internal_container *ic, *tmp; 213 struct internal_container *ic;
214 struct klist_iter iter;
191 215
192 if (attribute_container_no_classdevs(cont)) 216 if (attribute_container_no_classdevs(cont))
193 continue; 217 continue;
194 218
195 if (!cont->match(cont, dev)) 219 if (!cont->match(cont, dev))
196 continue; 220 continue;
197 spin_lock(&cont->containers_lock); 221
198 list_for_each_entry_safe(ic, tmp, &cont->containers, node) { 222 klist_for_each_entry(ic, &cont->containers, node, &iter) {
199 if (dev != ic->classdev.dev) 223 if (dev != ic->classdev.dev)
200 continue; 224 continue;
201 list_del(&ic->node); 225 klist_del(&ic->node);
202 if (fn) 226 if (fn)
203 fn(cont, dev, &ic->classdev); 227 fn(cont, dev, &ic->classdev);
204 else { 228 else {
@@ -206,7 +230,6 @@ attribute_container_remove_device(struct device *dev,
206 class_device_unregister(&ic->classdev); 230 class_device_unregister(&ic->classdev);
207 } 231 }
208 } 232 }
209 spin_unlock(&cont->containers_lock);
210 } 233 }
211 up(&attribute_container_mutex); 234 up(&attribute_container_mutex);
212} 235}
@@ -232,7 +255,8 @@ attribute_container_device_trigger(struct device *dev,
232 255
233 down(&attribute_container_mutex); 256 down(&attribute_container_mutex);
234 list_for_each_entry(cont, &attribute_container_list, node) { 257 list_for_each_entry(cont, &attribute_container_list, node) {
235 struct internal_container *ic, *tmp; 258 struct internal_container *ic;
259 struct klist_iter iter;
236 260
237 if (!cont->match(cont, dev)) 261 if (!cont->match(cont, dev))
238 continue; 262 continue;
@@ -242,12 +266,10 @@ attribute_container_device_trigger(struct device *dev,
242 continue; 266 continue;
243 } 267 }
244 268
245 spin_lock(&cont->containers_lock); 269 klist_for_each_entry(ic, &cont->containers, node, &iter) {
246 list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
247 if (dev == ic->classdev.dev) 270 if (dev == ic->classdev.dev)
248 fn(cont, dev, &ic->classdev); 271 fn(cont, dev, &ic->classdev);
249 } 272 }
250 spin_unlock(&cont->containers_lock);
251 } 273 }
252 up(&attribute_container_mutex); 274 up(&attribute_container_mutex);
253} 275}
@@ -397,15 +419,16 @@ attribute_container_find_class_device(struct attribute_container *cont,
397{ 419{
398 struct class_device *cdev = NULL; 420 struct class_device *cdev = NULL;
399 struct internal_container *ic; 421 struct internal_container *ic;
422 struct klist_iter iter;
400 423
401 spin_lock(&cont->containers_lock); 424 klist_for_each_entry(ic, &cont->containers, node, &iter) {
402 list_for_each_entry(ic, &cont->containers, node) {
403 if (ic->classdev.dev == dev) { 425 if (ic->classdev.dev == dev) {
404 cdev = &ic->classdev; 426 cdev = &ic->classdev;
427 /* FIXME: must exit iterator then break */
428 klist_iter_exit(&iter);
405 break; 429 break;
406 } 430 }
407 } 431 }
408 spin_unlock(&cont->containers_lock);
409 432
410 return cdev; 433 return cdev;
411} 434}
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 9f98334e5076..b61e3d175070 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -6,7 +6,7 @@
6 * Title: MPI Message independent structures and definitions 6 * Title: MPI Message independent structures and definitions
7 * Creation Date: July 27, 2000 7 * Creation Date: July 27, 2000
8 * 8 *
9 * mpi.h Version: 01.05.07 9 * mpi.h Version: 01.05.08
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -71,6 +71,9 @@
71 * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and 71 * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
72 * TargetAssistExtended requests. 72 * TargetAssistExtended requests.
73 * Removed EEDP IOCStatus codes. 73 * Removed EEDP IOCStatus codes.
74 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
75 * TargetAssistExtended requests.
76 * Added EEDP IOCStatus codes.
74 * -------------------------------------------------------------------------- 77 * --------------------------------------------------------------------------
75 */ 78 */
76 79
@@ -101,7 +104,7 @@
101/* Note: The major versions of 0xe0 through 0xff are reserved */ 104/* Note: The major versions of 0xe0 through 0xff are reserved */
102 105
103/* versioning for this MPI header set */ 106/* versioning for this MPI header set */
104#define MPI_HEADER_VERSION_UNIT (0x09) 107#define MPI_HEADER_VERSION_UNIT (0x0A)
105#define MPI_HEADER_VERSION_DEV (0x00) 108#define MPI_HEADER_VERSION_DEV (0x00)
106#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) 109#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
107#define MPI_HEADER_VERSION_UNIT_SHIFT (8) 110#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
@@ -292,10 +295,13 @@
292#define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D) 295#define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D)
293#define MPI_FUNCTION_DIAG_RELEASE (0x1E) 296#define MPI_FUNCTION_DIAG_RELEASE (0x1E)
294 297
298#define MPI_FUNCTION_SCSI_IO_32 (0x1F)
299
295#define MPI_FUNCTION_LAN_SEND (0x20) 300#define MPI_FUNCTION_LAN_SEND (0x20)
296#define MPI_FUNCTION_LAN_RECEIVE (0x21) 301#define MPI_FUNCTION_LAN_RECEIVE (0x21)
297#define MPI_FUNCTION_LAN_RESET (0x22) 302#define MPI_FUNCTION_LAN_RESET (0x22)
298 303
304#define MPI_FUNCTION_TARGET_ASSIST_EXTENDED (0x23)
299#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) 305#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24)
300#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) 306#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25)
301 307
@@ -681,6 +687,15 @@ typedef struct _MSG_DEFAULT_REPLY
681#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) 687#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
682 688
683/****************************************************************************/ 689/****************************************************************************/
690/* For use by SCSI Initiator and SCSI Target end-to-end data protection */
691/****************************************************************************/
692
693#define MPI_IOCSTATUS_EEDP_GUARD_ERROR (0x004D)
694#define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E)
695#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
696
697
698/****************************************************************************/
684/* SCSI Target values */ 699/* SCSI Target values */
685/****************************************************************************/ 700/****************************************************************************/
686 701
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index 15b12b06799d..d8339896f734 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -6,7 +6,7 @@
6 * Title: MPI Config message, structures, and Pages 6 * Title: MPI Config message, structures, and Pages
7 * Creation Date: July 27, 2000 7 * Creation Date: July 27, 2000
8 * 8 *
9 * mpi_cnfg.h Version: 01.05.08 9 * mpi_cnfg.h Version: 01.05.09
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -232,6 +232,23 @@
232 * New physical mapping mode in SAS IO Unit Page 2. 232 * New physical mapping mode in SAS IO Unit Page 2.
233 * Added CONFIG_PAGE_SAS_ENCLOSURE_0. 233 * Added CONFIG_PAGE_SAS_ENCLOSURE_0.
234 * Added Slot and Enclosure fields to SAS Device Page 0. 234 * Added Slot and Enclosure fields to SAS Device Page 0.
235 * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
236 * Added more RAID type defines to IOC Page 2.
237 * Added Port Enable Delay settings to BIOS Page 1.
238 * Added Bad Block Table Full define to RAID Volume Page 0.
239 * Added Previous State defines to RAID Physical Disk
240 * Page 0.
241 * Added Max Sata Targets define for DiscoveryStatus field
242 * of SAS IO Unit Page 0.
243 * Added Device Self Test to Control Flags of SAS IO Unit
244 * Page 1.
245 * Added Direct Attach Starting Slot Number define for SAS
246 * IO Unit Page 2.
247 * Added new fields in SAS Device Page 2 for enclosure
248 * mapping.
249 * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
250 * Added IOC GPIO Flags define to SAS Enclosure Page 0.
251 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
235 * -------------------------------------------------------------------------- 252 * --------------------------------------------------------------------------
236 */ 253 */
237 254
@@ -477,6 +494,7 @@ typedef struct _MSG_CONFIG_REPLY
477#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626) 494#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
478#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642) 495#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642)
479#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640) 496#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
497#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646)
480/* SCSI */ 498/* SCSI */
481#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) 499#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
482#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) 500#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
@@ -769,9 +787,13 @@ typedef struct _CONFIG_PAGE_IOC_1
769} CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1, 787} CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
770 IOCPage1_t, MPI_POINTER pIOCPage1_t; 788 IOCPage1_t, MPI_POINTER pIOCPage1_t;
771 789
772#define MPI_IOCPAGE1_PAGEVERSION (0x02) 790#define MPI_IOCPAGE1_PAGEVERSION (0x03)
773 791
774/* defines for the Flags field */ 792/* defines for the Flags field */
793#define MPI_IOCPAGE1_EEDP_MODE_MASK (0x07000000)
794#define MPI_IOCPAGE1_EEDP_MODE_OFF (0x00000000)
795#define MPI_IOCPAGE1_EEDP_MODE_T10 (0x01000000)
796#define MPI_IOCPAGE1_EEDP_MODE_LSI_1 (0x02000000)
775#define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE (0x00000010) 797#define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE (0x00000010)
776#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001) 798#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001)
777 799
@@ -795,6 +817,11 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
795#define MPI_RAID_VOL_TYPE_IS (0x00) 817#define MPI_RAID_VOL_TYPE_IS (0x00)
796#define MPI_RAID_VOL_TYPE_IME (0x01) 818#define MPI_RAID_VOL_TYPE_IME (0x01)
797#define MPI_RAID_VOL_TYPE_IM (0x02) 819#define MPI_RAID_VOL_TYPE_IM (0x02)
820#define MPI_RAID_VOL_TYPE_RAID_5 (0x03)
821#define MPI_RAID_VOL_TYPE_RAID_6 (0x04)
822#define MPI_RAID_VOL_TYPE_RAID_10 (0x05)
823#define MPI_RAID_VOL_TYPE_RAID_50 (0x06)
824#define MPI_RAID_VOL_TYPE_UNKNOWN (0xFF)
798 825
799/* IOC Page 2 Volume Flags values */ 826/* IOC Page 2 Volume Flags values */
800 827
@@ -820,13 +847,17 @@ typedef struct _CONFIG_PAGE_IOC_2
820} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, 847} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
821 IOCPage2_t, MPI_POINTER pIOCPage2_t; 848 IOCPage2_t, MPI_POINTER pIOCPage2_t;
822 849
823#define MPI_IOCPAGE2_PAGEVERSION (0x02) 850#define MPI_IOCPAGE2_PAGEVERSION (0x03)
824 851
825/* IOC Page 2 Capabilities flags */ 852/* IOC Page 2 Capabilities flags */
826 853
827#define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001) 854#define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001)
828#define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002) 855#define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002)
829#define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004) 856#define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004)
857#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT (0x00000008)
858#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010)
859#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020)
860#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040)
830#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) 861#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000)
831#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) 862#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000)
832#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) 863#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000)
@@ -945,7 +976,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
945} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1, 976} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
946 BIOSPage1_t, MPI_POINTER pBIOSPage1_t; 977 BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
947 978
948#define MPI_BIOSPAGE1_PAGEVERSION (0x01) 979#define MPI_BIOSPAGE1_PAGEVERSION (0x02)
949 980
950/* values for the BiosOptions field */ 981/* values for the BiosOptions field */
951#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400) 982#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
@@ -954,6 +985,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
954#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) 985#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
955 986
956/* values for the IOCSettings field */ 987/* values for the IOCSettings field */
988#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000)
989#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20)
957#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) 990#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
958#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) 991#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
959#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) 992#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
@@ -1167,6 +1200,7 @@ typedef struct _CONFIG_PAGE_BIOS_2
1167#define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER (0x03) 1200#define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER (0x03)
1168#define MPI_BIOSPAGE2_FORM_FC_WWN (0x04) 1201#define MPI_BIOSPAGE2_FORM_FC_WWN (0x04)
1169#define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05) 1202#define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05)
1203#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06)
1170 1204
1171 1205
1172/**************************************************************************** 1206/****************************************************************************
@@ -1957,11 +1991,11 @@ typedef struct _RAID_VOL0_STATUS
1957 RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t; 1991 RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
1958 1992
1959/* RAID Volume Page 0 VolumeStatus defines */ 1993/* RAID Volume Page 0 VolumeStatus defines */
1960
1961#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01) 1994#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01)
1962#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02) 1995#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02)
1963#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04) 1996#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04)
1964#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08) 1997#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08)
1998#define MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x10)
1965 1999
1966#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00) 2000#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00)
1967#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01) 2001#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01)
@@ -2025,7 +2059,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
2025} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, 2059} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
2026 RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; 2060 RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
2027 2061
2028#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x04) 2062#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05)
2029 2063
2030/* values for RAID Volume Page 0 InactiveStatus field */ 2064/* values for RAID Volume Page 0 InactiveStatus field */
2031#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) 2065#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
@@ -2104,6 +2138,8 @@ typedef struct _RAID_PHYS_DISK0_STATUS
2104#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01) 2138#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01)
2105#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02) 2139#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02)
2106#define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x04) 2140#define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x04)
2141#define MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00)
2142#define MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x08)
2107 2143
2108#define MPI_PHYSDISK0_STATUS_ONLINE (0x00) 2144#define MPI_PHYSDISK0_STATUS_ONLINE (0x00)
2109#define MPI_PHYSDISK0_STATUS_MISSING (0x01) 2145#define MPI_PHYSDISK0_STATUS_MISSING (0x01)
@@ -2132,7 +2168,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
2132} CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0, 2168} CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
2133 RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t; 2169 RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
2134 2170
2135#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x01) 2171#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x02)
2136 2172
2137 2173
2138typedef struct _RAID_PHYS_DISK1_PATH 2174typedef struct _RAID_PHYS_DISK1_PATH
@@ -2263,7 +2299,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
2263} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, 2299} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
2264 SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; 2300 SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
2265 2301
2266#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x02) 2302#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03)
2267 2303
2268/* values for SAS IO Unit Page 0 PortFlags */ 2304/* values for SAS IO Unit Page 0 PortFlags */
2269#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) 2305#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
@@ -2299,6 +2335,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
2299#define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200) 2335#define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200)
2300#define MPI_SAS_IOUNIT0_DS_TABLE_LINK (0x00000400) 2336#define MPI_SAS_IOUNIT0_DS_TABLE_LINK (0x00000400)
2301#define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800) 2337#define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800)
2338#define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS (0x00001000)
2302 2339
2303 2340
2304typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA 2341typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
@@ -2336,6 +2373,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2336#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04) 2373#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04)
2337 2374
2338/* values for SAS IO Unit Page 1 ControlFlags */ 2375/* values for SAS IO Unit Page 1 ControlFlags */
2376#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
2339#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) 2377#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
2340#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) 2378#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
2341#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) 2379#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
@@ -2345,9 +2383,8 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2345#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) 2383#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
2346#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00) 2384#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
2347#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01) 2385#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
2348#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x10) 2386#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
2349 2387
2350#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100)
2351#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) 2388#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
2352#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) 2389#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
2353#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) 2390#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
@@ -2390,7 +2427,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
2390} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, 2427} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
2391 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; 2428 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
2392 2429
2393#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x03) 2430#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04)
2394 2431
2395/* values for SAS IO Unit Page 2 Status field */ 2432/* values for SAS IO Unit Page 2 Status field */
2396#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) 2433#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
@@ -2406,6 +2443,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
2406#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02) 2443#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02)
2407 2444
2408#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10) 2445#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10)
2446#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20)
2409 2447
2410 2448
2411typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3 2449typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
@@ -2584,11 +2622,19 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
2584{ 2622{
2585 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ 2623 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
2586 U64 PhysicalIdentifier; /* 08h */ 2624 U64 PhysicalIdentifier; /* 08h */
2587 U32 Reserved1; /* 10h */ 2625 U32 EnclosureMapping; /* 10h */
2588} CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2, 2626} CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2,
2589 SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t; 2627 SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t;
2590 2628
2591#define MPI_SASDEVICE2_PAGEVERSION (0x00) 2629#define MPI_SASDEVICE2_PAGEVERSION (0x01)
2630
2631/* defines for SAS Device Page 2 EnclosureMapping field */
2632#define MPI_SASDEVICE2_ENC_MAP_MASK_MISSING_COUNT (0x0000000F)
2633#define MPI_SASDEVICE2_ENC_MAP_SHIFT_MISSING_COUNT (0)
2634#define MPI_SASDEVICE2_ENC_MAP_MASK_NUM_SLOTS (0x000007F0)
2635#define MPI_SASDEVICE2_ENC_MAP_SHIFT_NUM_SLOTS (4)
2636#define MPI_SASDEVICE2_ENC_MAP_MASK_START_INDEX (0x001FF800)
2637#define MPI_SASDEVICE2_ENC_MAP_SHIFT_START_INDEX (11)
2592 2638
2593 2639
2594/**************************************************************************** 2640/****************************************************************************
@@ -2598,7 +2644,8 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
2598typedef struct _CONFIG_PAGE_SAS_PHY_0 2644typedef struct _CONFIG_PAGE_SAS_PHY_0
2599{ 2645{
2600 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ 2646 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
2601 U32 Reserved1; /* 08h */ 2647 U16 OwnerDevHandle; /* 08h */
2648 U16 Reserved1; /* 0Ah */
2602 U64 SASAddress; /* 0Ch */ 2649 U64 SASAddress; /* 0Ch */
2603 U16 AttachedDevHandle; /* 14h */ 2650 U16 AttachedDevHandle; /* 14h */
2604 U8 AttachedPhyIdentifier; /* 16h */ 2651 U8 AttachedPhyIdentifier; /* 16h */
@@ -2607,12 +2654,12 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
2607 U8 ProgrammedLinkRate; /* 20h */ 2654 U8 ProgrammedLinkRate; /* 20h */
2608 U8 HwLinkRate; /* 21h */ 2655 U8 HwLinkRate; /* 21h */
2609 U8 ChangeCount; /* 22h */ 2656 U8 ChangeCount; /* 22h */
2610 U8 Reserved3; /* 23h */ 2657 U8 Flags; /* 23h */
2611 U32 PhyInfo; /* 24h */ 2658 U32 PhyInfo; /* 24h */
2612} CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0, 2659} CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
2613 SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t; 2660 SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
2614 2661
2615#define MPI_SASPHY0_PAGEVERSION (0x00) 2662#define MPI_SASPHY0_PAGEVERSION (0x01)
2616 2663
2617/* values for SAS PHY Page 0 ProgrammedLinkRate field */ 2664/* values for SAS PHY Page 0 ProgrammedLinkRate field */
2618#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0) 2665#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0)
@@ -2632,6 +2679,9 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
2632#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08) 2679#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08)
2633#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09) 2680#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09)
2634 2681
2682/* values for SAS PHY Page 0 Flags field */
2683#define MPI_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01)
2684
2635/* values for SAS PHY Page 0 PhyInfo field */ 2685/* values for SAS PHY Page 0 PhyInfo field */
2636#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000) 2686#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000)
2637#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000) 2687#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000)
@@ -2690,7 +2740,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
2690} CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0, 2740} CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0,
2691 SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t; 2741 SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t;
2692 2742
2693#define MPI_SASENCLOSURE0_PAGEVERSION (0x00) 2743#define MPI_SASENCLOSURE0_PAGEVERSION (0x01)
2694 2744
2695/* values for SAS Enclosure Page 0 Flags field */ 2745/* values for SAS Enclosure Page 0 Flags field */
2696#define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID (0x0020) 2746#define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID (0x0020)
@@ -2702,6 +2752,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
2702#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002) 2752#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002)
2703#define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003) 2753#define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003)
2704#define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004) 2754#define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
2755#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
2705 2756
2706 2757
2707/**************************************************************************** 2758/****************************************************************************
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index c9edbee41edf..1a30ef16adb4 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -6,17 +6,17 @@
6 Copyright (c) 2000-2005 LSI Logic Corporation. 6 Copyright (c) 2000-2005 LSI Logic Corporation.
7 7
8 --------------------------------------- 8 ---------------------------------------
9 Header Set Release Version: 01.05.09 9 Header Set Release Version: 01.05.10
10 Header Set Release Date: 03-11-05 10 Header Set Release Date: 03-11-05
11 --------------------------------------- 11 ---------------------------------------
12 12
13 Filename Current version Prior version 13 Filename Current version Prior version
14 ---------- --------------- ------------- 14 ---------- --------------- -------------
15 mpi.h 01.05.07 01.05.06 15 mpi.h 01.05.08 01.05.07
16 mpi_ioc.h 01.05.08 01.05.07 16 mpi_ioc.h 01.05.09 01.05.08
17 mpi_cnfg.h 01.05.08 01.05.07 17 mpi_cnfg.h 01.05.09 01.05.08
18 mpi_init.h 01.05.04 01.05.03 18 mpi_init.h 01.05.05 01.05.04
19 mpi_targ.h 01.05.04 01.05.03 19 mpi_targ.h 01.05.05 01.05.04
20 mpi_fc.h 01.05.01 01.05.01 20 mpi_fc.h 01.05.01 01.05.01
21 mpi_lan.h 01.05.01 01.05.01 21 mpi_lan.h 01.05.01 01.05.01
22 mpi_raid.h 01.05.02 01.05.02 22 mpi_raid.h 01.05.02 01.05.02
@@ -24,7 +24,7 @@
24 mpi_inb.h 01.05.01 01.05.01 24 mpi_inb.h 01.05.01 01.05.01
25 mpi_sas.h 01.05.01 01.05.01 25 mpi_sas.h 01.05.01 01.05.01
26 mpi_type.h 01.05.01 01.05.01 26 mpi_type.h 01.05.01 01.05.01
27 mpi_history.txt 01.05.09 01.05.08 27 mpi_history.txt 01.05.09 01.05.09
28 28
29 29
30 * Date Version Description 30 * Date Version Description
@@ -88,6 +88,9 @@ mpi.h
88 * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and 88 * 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
89 * TargetAssistExtended requests. 89 * TargetAssistExtended requests.
90 * Removed EEDP IOCStatus codes. 90 * Removed EEDP IOCStatus codes.
91 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
92 * TargetAssistExtended requests.
93 * Added EEDP IOCStatus codes.
91 * -------------------------------------------------------------------------- 94 * --------------------------------------------------------------------------
92 95
93mpi_ioc.h 96mpi_ioc.h
@@ -159,6 +162,8 @@ mpi_ioc.h
159 * Reply and IOC Init Request. 162 * Reply and IOC Init Request.
160 * 03-11-05 01.05.08 Added family code for 1068E family. 163 * 03-11-05 01.05.08 Added family code for 1068E family.
161 * Removed IOCFacts Reply EEDP Capability bit. 164 * Removed IOCFacts Reply EEDP Capability bit.
165 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
166 * Added Max SATA Targets to SAS Discovery Error event.
162 * -------------------------------------------------------------------------- 167 * --------------------------------------------------------------------------
163 168
164mpi_cnfg.h 169mpi_cnfg.h
@@ -380,6 +385,23 @@ mpi_cnfg.h
380 * New physical mapping mode in SAS IO Unit Page 2. 385 * New physical mapping mode in SAS IO Unit Page 2.
381 * Added CONFIG_PAGE_SAS_ENCLOSURE_0. 386 * Added CONFIG_PAGE_SAS_ENCLOSURE_0.
382 * Added Slot and Enclosure fields to SAS Device Page 0. 387 * Added Slot and Enclosure fields to SAS Device Page 0.
388 * 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
389 * Added more RAID type defines to IOC Page 2.
390 * Added Port Enable Delay settings to BIOS Page 1.
391 * Added Bad Block Table Full define to RAID Volume Page 0.
392 * Added Previous State defines to RAID Physical Disk
393 * Page 0.
394 * Added Max Sata Targets define for DiscoveryStatus field
395 * of SAS IO Unit Page 0.
396 * Added Device Self Test to Control Flags of SAS IO Unit
397 * Page 1.
398 * Added Direct Attach Starting Slot Number define for SAS
399 * IO Unit Page 2.
400 * Added new fields in SAS Device Page 2 for enclosure
401 * mapping.
402 * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
403 * Added IOC GPIO Flags define to SAS Enclosure Page 0.
404 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
383 * -------------------------------------------------------------------------- 405 * --------------------------------------------------------------------------
384 406
385mpi_init.h 407mpi_init.h
@@ -418,6 +440,8 @@ mpi_init.h
418 * Modified SCSI Enclosure Processor Request and Reply to 440 * Modified SCSI Enclosure Processor Request and Reply to
419 * support Enclosure/Slot addressing rather than WWID 441 * support Enclosure/Slot addressing rather than WWID
420 * addressing. 442 * addressing.
443 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
444 * Added four new defines for SEP SlotStatus.
421 * -------------------------------------------------------------------------- 445 * --------------------------------------------------------------------------
422 446
423mpi_targ.h 447mpi_targ.h
@@ -461,6 +485,7 @@ mpi_targ.h
461 * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added. 485 * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
462 * 02-22-05 01.05.03 Changed a comment. 486 * 02-22-05 01.05.03 Changed a comment.
463 * 03-11-05 01.05.04 Removed TargetAssistExtended Request. 487 * 03-11-05 01.05.04 Removed TargetAssistExtended Request.
488 * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
464 * -------------------------------------------------------------------------- 489 * --------------------------------------------------------------------------
465 490
466mpi_fc.h 491mpi_fc.h
@@ -571,20 +596,20 @@ mpi_type.h
571 596
572mpi_history.txt Parts list history 597mpi_history.txt Parts list history
573 598
574Filename 01.05.09 599Filename 01.05.10 01.05.09
575---------- -------- 600---------- -------- --------
576mpi.h 01.05.07 601mpi.h 01.05.08 01.05.07
577mpi_ioc.h 01.05.08 602mpi_ioc.h 01.05.09 01.05.08
578mpi_cnfg.h 01.05.08 603mpi_cnfg.h 01.05.09 01.05.08
579mpi_init.h 01.05.04 604mpi_init.h 01.05.05 01.05.04
580mpi_targ.h 01.05.04 605mpi_targ.h 01.05.05 01.05.04
581mpi_fc.h 01.05.01 606mpi_fc.h 01.05.01 01.05.01
582mpi_lan.h 01.05.01 607mpi_lan.h 01.05.01 01.05.01
583mpi_raid.h 01.05.02 608mpi_raid.h 01.05.02 01.05.02
584mpi_tool.h 01.05.03 609mpi_tool.h 01.05.03 01.05.03
585mpi_inb.h 01.05.01 610mpi_inb.h 01.05.01 01.05.01
586mpi_sas.h 01.05.01 611mpi_sas.h 01.05.01 01.05.01
587mpi_type.h 01.05.01 612mpi_type.h 01.05.01 01.05.01
588 613
589Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 614Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
590---------- -------- -------- -------- -------- -------- -------- 615---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index aca035801a86..d5af75afbd94 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -6,7 +6,7 @@
6 * Title: MPI initiator mode messages and structures 6 * Title: MPI initiator mode messages and structures
7 * Creation Date: June 8, 2000 7 * Creation Date: June 8, 2000
8 * 8 *
9 * mpi_init.h Version: 01.05.04 9 * mpi_init.h Version: 01.05.05
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -48,6 +48,8 @@
48 * Modified SCSI Enclosure Processor Request and Reply to 48 * Modified SCSI Enclosure Processor Request and Reply to
49 * support Enclosure/Slot addressing rather than WWID 49 * support Enclosure/Slot addressing rather than WWID
50 * addressing. 50 * addressing.
51 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
52 * Added four new defines for SEP SlotStatus.
51 * -------------------------------------------------------------------------- 53 * --------------------------------------------------------------------------
52 */ 54 */
53 55
@@ -203,6 +205,197 @@ typedef struct _MSG_SCSI_IO_REPLY
203 205
204 206
205/****************************************************************************/ 207/****************************************************************************/
208/* SCSI IO 32 messages and associated structures */
209/****************************************************************************/
210
211typedef struct
212{
213 U8 CDB[20]; /* 00h */
214 U32 PrimaryReferenceTag; /* 14h */
215 U16 PrimaryApplicationTag; /* 18h */
216 U16 PrimaryApplicationTagMask; /* 1Ah */
217 U32 TransferLength; /* 1Ch */
218} MPI_SCSI_IO32_CDB_EEDP32, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP32,
219 MpiScsiIo32CdbEedp32_t, MPI_POINTER pMpiScsiIo32CdbEedp32_t;
220
221typedef struct
222{
223 U8 CDB[16]; /* 00h */
224 U32 DataLength; /* 10h */
225 U32 PrimaryReferenceTag; /* 14h */
226 U16 PrimaryApplicationTag; /* 18h */
227 U16 PrimaryApplicationTagMask; /* 1Ah */
228 U32 TransferLength; /* 1Ch */
229} MPI_SCSI_IO32_CDB_EEDP16, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP16,
230 MpiScsiIo32CdbEedp16_t, MPI_POINTER pMpiScsiIo32CdbEedp16_t;
231
232typedef union
233{
234 U8 CDB32[32];
235 MPI_SCSI_IO32_CDB_EEDP32 EEDP32;
236 MPI_SCSI_IO32_CDB_EEDP16 EEDP16;
237 SGE_SIMPLE_UNION SGE;
238} MPI_SCSI_IO32_CDB_UNION, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_UNION,
239 MpiScsiIo32Cdb_t, MPI_POINTER pMpiScsiIo32Cdb_t;
240
241typedef struct
242{
243 U8 TargetID; /* 00h */
244 U8 Bus; /* 01h */
245 U16 Reserved1; /* 02h */
246 U32 Reserved2; /* 04h */
247} MPI_SCSI_IO32_BUS_TARGET_ID_FORM, MPI_POINTER PTR_MPI_SCSI_IO32_BUS_TARGET_ID_FORM,
248 MpiScsiIo32BusTargetIdForm_t, MPI_POINTER pMpiScsiIo32BusTargetIdForm_t;
249
250typedef union
251{
252 MPI_SCSI_IO32_BUS_TARGET_ID_FORM SCSIID;
253 U64 WWID;
254} MPI_SCSI_IO32_ADDRESS, MPI_POINTER PTR_MPI_SCSI_IO32_ADDRESS,
255 MpiScsiIo32Address_t, MPI_POINTER pMpiScsiIo32Address_t;
256
257typedef struct _MSG_SCSI_IO32_REQUEST
258{
259 U8 Port; /* 00h */
260 U8 Reserved1; /* 01h */
261 U8 ChainOffset; /* 02h */
262 U8 Function; /* 03h */
263 U8 CDBLength; /* 04h */
264 U8 SenseBufferLength; /* 05h */
265 U8 Flags; /* 06h */
266 U8 MsgFlags; /* 07h */
267 U32 MsgContext; /* 08h */
268 U8 LUN[8]; /* 0Ch */
269 U32 Control; /* 14h */
270 MPI_SCSI_IO32_CDB_UNION CDB; /* 18h */
271 U32 DataLength; /* 38h */
272 U32 BidirectionalDataLength; /* 3Ch */
273 U32 SecondaryReferenceTag; /* 40h */
274 U16 SecondaryApplicationTag; /* 44h */
275 U16 Reserved2; /* 46h */
276 U16 EEDPFlags; /* 48h */
277 U16 ApplicationTagTranslationMask; /* 4Ah */
278 U32 EEDPBlockSize; /* 4Ch */
279 MPI_SCSI_IO32_ADDRESS DeviceAddress; /* 50h */
280 U8 SGLOffset0; /* 58h */
281 U8 SGLOffset1; /* 59h */
282 U8 SGLOffset2; /* 5Ah */
283 U8 SGLOffset3; /* 5Bh */
284 U32 Reserved3; /* 5Ch */
285 U32 Reserved4; /* 60h */
286 U32 SenseBufferLowAddr; /* 64h */
287 SGE_IO_UNION SGL; /* 68h */
288} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
289 SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
290
291/* SCSI IO 32 MsgFlags bits */
292#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
293#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00)
294#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01)
295
296#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
297#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
298#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_IOC (0x02)
299
300#define MPI_SCSIIO32_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
301#define MPI_SCSIIO32_MSGFLGS_SGL_OFFSETS_CHAINS (0x08)
302#define MPI_SCSIIO32_MSGFLGS_MULTICAST (0x10)
303#define MPI_SCSIIO32_MSGFLGS_BIDIRECTIONAL (0x20)
304#define MPI_SCSIIO32_MSGFLGS_LARGE_CDB (0x40)
305
306/* SCSI IO 32 Flags bits */
307#define MPI_SCSIIO32_FLAGS_FORM_MASK (0x03)
308#define MPI_SCSIIO32_FLAGS_FORM_SCSIID (0x00)
309#define MPI_SCSIIO32_FLAGS_FORM_WWID (0x01)
310
311/* SCSI IO 32 LUN fields */
312#define MPI_SCSIIO32_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF)
313#define MPI_SCSIIO32_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000)
314#define MPI_SCSIIO32_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF)
315#define MPI_SCSIIO32_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000)
316#define MPI_SCSIIO32_LUN_LEVEL_1_WORD (0xFF00)
317#define MPI_SCSIIO32_LUN_LEVEL_1_DWORD (0x0000FF00)
318
319/* SCSI IO 32 Control bits */
320#define MPI_SCSIIO32_CONTROL_DATADIRECTION_MASK (0x03000000)
321#define MPI_SCSIIO32_CONTROL_NODATATRANSFER (0x00000000)
322#define MPI_SCSIIO32_CONTROL_WRITE (0x01000000)
323#define MPI_SCSIIO32_CONTROL_READ (0x02000000)
324#define MPI_SCSIIO32_CONTROL_BIDIRECTIONAL (0x03000000)
325
326#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_MASK (0xFC000000)
327#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_SHIFT (26)
328
329#define MPI_SCSIIO32_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
330#define MPI_SCSIIO32_CONTROL_SIMPLEQ (0x00000000)
331#define MPI_SCSIIO32_CONTROL_HEADOFQ (0x00000100)
332#define MPI_SCSIIO32_CONTROL_ORDEREDQ (0x00000200)
333#define MPI_SCSIIO32_CONTROL_ACAQ (0x00000400)
334#define MPI_SCSIIO32_CONTROL_UNTAGGED (0x00000500)
335#define MPI_SCSIIO32_CONTROL_NO_DISCONNECT (0x00000700)
336
337#define MPI_SCSIIO32_CONTROL_TASKMANAGE_MASK (0x00FF0000)
338#define MPI_SCSIIO32_CONTROL_OBSOLETE (0x00800000)
339#define MPI_SCSIIO32_CONTROL_CLEAR_ACA_RSV (0x00400000)
340#define MPI_SCSIIO32_CONTROL_TARGET_RESET (0x00200000)
341#define MPI_SCSIIO32_CONTROL_LUN_RESET_RSV (0x00100000)
342#define MPI_SCSIIO32_CONTROL_RESERVED (0x00080000)
343#define MPI_SCSIIO32_CONTROL_CLR_TASK_SET_RSV (0x00040000)
344#define MPI_SCSIIO32_CONTROL_ABORT_TASK_SET (0x00020000)
345#define MPI_SCSIIO32_CONTROL_RESERVED2 (0x00010000)
346
347/* SCSI IO 32 EEDPFlags */
348#define MPI_SCSIIO32_EEDPFLAGS_MASK_OP (0x0007)
349#define MPI_SCSIIO32_EEDPFLAGS_NOOP_OP (0x0000)
350#define MPI_SCSIIO32_EEDPFLAGS_CHK_OP (0x0001)
351#define MPI_SCSIIO32_EEDPFLAGS_STRIP_OP (0x0002)
352#define MPI_SCSIIO32_EEDPFLAGS_CHKRM_OP (0x0003)
353#define MPI_SCSIIO32_EEDPFLAGS_INSERT_OP (0x0004)
354#define MPI_SCSIIO32_EEDPFLAGS_REPLACE_OP (0x0006)
355#define MPI_SCSIIO32_EEDPFLAGS_CHKREGEN_OP (0x0007)
356
357#define MPI_SCSIIO32_EEDPFLAGS_PASS_REF_TAG (0x0008)
358#define MPI_SCSIIO32_EEDPFLAGS_8_9THS_MODE (0x0010)
359
360#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_MASK (0x0700)
361#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_GUARD (0x0100)
362#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_REFTAG (0x0200)
363#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_LBATAG (0x0400)
364#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_SHIFT (8)
365
366#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_APPTAG (0x1000)
367#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_APPTAG (0x2000)
368#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_REFTAG (0x4000)
369#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
370
371
372/* SCSIIO32 IO reply structure */
373typedef struct _MSG_SCSIIO32_IO_REPLY
374{
375 U8 Port; /* 00h */
376 U8 Reserved1; /* 01h */
377 U8 MsgLength; /* 02h */
378 U8 Function; /* 03h */
379 U8 CDBLength; /* 04h */
380 U8 SenseBufferLength; /* 05h */
381 U8 Flags; /* 06h */
382 U8 MsgFlags; /* 07h */
383 U32 MsgContext; /* 08h */
384 U8 SCSIStatus; /* 0Ch */
385 U8 SCSIState; /* 0Dh */
386 U16 IOCStatus; /* 0Eh */
387 U32 IOCLogInfo; /* 10h */
388 U32 TransferCount; /* 14h */
389 U32 SenseCount; /* 18h */
390 U32 ResponseInfo; /* 1Ch */
391 U16 TaskTag; /* 20h */
392 U16 Reserved2; /* 22h */
393 U32 BidirectionalTransferCount; /* 24h */
394} MSG_SCSIIO32_IO_REPLY, MPI_POINTER PTR_MSG_SCSIIO32_IO_REPLY,
395 SCSIIO32Reply_t, MPI_POINTER pSCSIIO32Reply_t;
396
397
398/****************************************************************************/
206/* SCSI Task Management messages */ 399/* SCSI Task Management messages */
207/****************************************************************************/ 400/****************************************************************************/
208 401
@@ -310,10 +503,14 @@ typedef struct _MSG_SEP_REQUEST
310#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) 503#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
311#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) 504#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
312#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200) 505#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
506#define MPI_SEP_REQ_SLOTSTATUS_REQ_CONSISTENCY_CHECK (0x00001000)
507#define MPI_SEP_REQ_SLOTSTATUS_DISABLE (0x00002000)
508#define MPI_SEP_REQ_SLOTSTATUS_REQ_RESERVED_DEVICE (0x00004000)
313#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) 509#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
314#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000) 510#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
315#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000) 511#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000)
316#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000) 512#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000)
513#define MPI_SEP_REQ_SLOTSTATUS_ACTIVE (0x00800000)
317#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000) 514#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
318#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000) 515#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000)
319#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000) 516#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000)
@@ -352,11 +549,15 @@ typedef struct _MSG_SEP_REPLY
352#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) 549#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
353#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) 550#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
354#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200) 551#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
552#define MPI_SEP_REPLY_SLOTSTATUS_CONSISTENCY_CHECK (0x00001000)
553#define MPI_SEP_REPLY_SLOTSTATUS_DISABLE (0x00002000)
554#define MPI_SEP_REPLY_SLOTSTATUS_RESERVED_DEVICE (0x00004000)
355#define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000) 555#define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000)
356#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) 556#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
357#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000) 557#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
358#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000) 558#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000)
359#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000) 559#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000)
560#define MPI_SEP_REPLY_SLOTSTATUS_ACTIVE (0x00800000)
360#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000) 561#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000)
361#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000) 562#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000)
362#define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000) 563#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 f91eb4efe8cc..93b70e2b4266 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -6,7 +6,7 @@
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages 6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: August 11, 2000 7 * Creation Date: August 11, 2000
8 * 8 *
9 * mpi_ioc.h Version: 01.05.08 9 * mpi_ioc.h Version: 01.05.09
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -81,6 +81,8 @@
81 * Reply and IOC Init Request. 81 * Reply and IOC Init Request.
82 * 03-11-05 01.05.08 Added family code for 1068E family. 82 * 03-11-05 01.05.08 Added family code for 1068E family.
83 * Removed IOCFacts Reply EEDP Capability bit. 83 * Removed IOCFacts Reply EEDP Capability bit.
84 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
85 * Added Max SATA Targets to SAS Discovery Error event.
84 * -------------------------------------------------------------------------- 86 * --------------------------------------------------------------------------
85 */ 87 */
86 88
@@ -261,7 +263,11 @@ typedef struct _MSG_IOC_FACTS_REPLY
261#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) 263#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
262#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) 264#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
263#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) 265#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
264 266#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040)
267#define MPI_IOCFACTS_CAPABILITY_BIDIRECTIONAL (0x00000080)
268#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
269#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200)
270#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400)
265 271
266 272
267/***************************************************************************** 273/*****************************************************************************
@@ -677,6 +683,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
677#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200) 683#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200)
678#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400) 684#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400)
679#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) 685#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
686#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
680 687
681 688
682/***************************************************************************** 689/*****************************************************************************
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
index 623901fd82be..3f462859ceea 100644
--- a/drivers/message/fusion/lsi/mpi_targ.h
+++ b/drivers/message/fusion/lsi/mpi_targ.h
@@ -6,7 +6,7 @@
6 * Title: MPI Target mode messages and structures 6 * Title: MPI Target mode messages and structures
7 * Creation Date: June 22, 2000 7 * Creation Date: June 22, 2000
8 * 8 *
9 * mpi_targ.h Version: 01.05.04 9 * mpi_targ.h Version: 01.05.05
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -53,6 +53,7 @@
53 * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added. 53 * 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
54 * 02-22-05 01.05.03 Changed a comment. 54 * 02-22-05 01.05.03 Changed a comment.
55 * 03-11-05 01.05.04 Removed TargetAssistExtended Request. 55 * 03-11-05 01.05.04 Removed TargetAssistExtended Request.
56 * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
56 * -------------------------------------------------------------------------- 57 * --------------------------------------------------------------------------
57 */ 58 */
58 59
@@ -371,6 +372,77 @@ typedef struct _MSG_TARGET_ERROR_REPLY
371 372
372 373
373/****************************************************************************/ 374/****************************************************************************/
375/* Target Assist Extended Request */
376/****************************************************************************/
377
378typedef struct _MSG_TARGET_ASSIST_EXT_REQUEST
379{
380 U8 StatusCode; /* 00h */
381 U8 TargetAssistFlags; /* 01h */
382 U8 ChainOffset; /* 02h */
383 U8 Function; /* 03h */
384 U16 QueueTag; /* 04h */
385 U8 Reserved1; /* 06h */
386 U8 MsgFlags; /* 07h */
387 U32 MsgContext; /* 08h */
388 U32 ReplyWord; /* 0Ch */
389 U8 LUN[8]; /* 10h */
390 U32 RelativeOffset; /* 18h */
391 U32 Reserved2; /* 1Ch */
392 U32 Reserved3; /* 20h */
393 U32 PrimaryReferenceTag; /* 24h */
394 U16 PrimaryApplicationTag; /* 28h */
395 U16 PrimaryApplicationTagMask; /* 2Ah */
396 U32 Reserved4; /* 2Ch */
397 U32 DataLength; /* 30h */
398 U32 BidirectionalDataLength; /* 34h */
399 U32 SecondaryReferenceTag; /* 38h */
400 U16 SecondaryApplicationTag; /* 3Ch */
401 U16 Reserved5; /* 3Eh */
402 U16 EEDPFlags; /* 40h */
403 U16 ApplicationTagTranslationMask; /* 42h */
404 U32 EEDPBlockSize; /* 44h */
405 U8 SGLOffset0; /* 48h */
406 U8 SGLOffset1; /* 49h */
407 U8 SGLOffset2; /* 4Ah */
408 U8 SGLOffset3; /* 4Bh */
409 U32 Reserved6; /* 4Ch */
410 SGE_IO_UNION SGL[1]; /* 50h */
411} MSG_TARGET_ASSIST_EXT_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_EXT_REQUEST,
412 TargetAssistExtRequest_t, MPI_POINTER pTargetAssistExtRequest_t;
413
414/* see the defines after MSG_TARGET_ASSIST_REQUEST for TargetAssistFlags */
415
416/* defines for the MsgFlags field */
417#define TARGET_ASSIST_EXT_MSGFLAGS_BIDIRECTIONAL (0x20)
418#define TARGET_ASSIST_EXT_MSGFLAGS_MULTICAST (0x10)
419#define TARGET_ASSIST_EXT_MSGFLAGS_SGL_OFFSET_CHAINS (0x08)
420
421/* defines for the EEDPFlags field */
422#define TARGET_ASSIST_EXT_EEDP_MASK_OP (0x0007)
423#define TARGET_ASSIST_EXT_EEDP_NOOP_OP (0x0000)
424#define TARGET_ASSIST_EXT_EEDP_CHK_OP (0x0001)
425#define TARGET_ASSIST_EXT_EEDP_STRIP_OP (0x0002)
426#define TARGET_ASSIST_EXT_EEDP_CHKRM_OP (0x0003)
427#define TARGET_ASSIST_EXT_EEDP_INSERT_OP (0x0004)
428#define TARGET_ASSIST_EXT_EEDP_REPLACE_OP (0x0006)
429#define TARGET_ASSIST_EXT_EEDP_CHKREGEN_OP (0x0007)
430
431#define TARGET_ASSIST_EXT_EEDP_PASS_REF_TAG (0x0008)
432
433#define TARGET_ASSIST_EXT_EEDP_T10_CHK_MASK (0x0700)
434#define TARGET_ASSIST_EXT_EEDP_T10_CHK_GUARD (0x0100)
435#define TARGET_ASSIST_EXT_EEDP_T10_CHK_APPTAG (0x0200)
436#define TARGET_ASSIST_EXT_EEDP_T10_CHK_REFTAG (0x0400)
437#define TARGET_ASSIST_EXT_EEDP_T10_CHK_SHIFT (8)
438
439#define TARGET_ASSIST_EXT_EEDP_INC_SEC_APPTAG (0x1000)
440#define TARGET_ASSIST_EXT_EEDP_INC_PRI_APPTAG (0x2000)
441#define TARGET_ASSIST_EXT_EEDP_INC_SEC_REFTAG (0x4000)
442#define TARGET_ASSIST_EXT_EEDP_INC_PRI_REFTAG (0x8000)
443
444
445/****************************************************************************/
374/* Target Status Send Request */ 446/* Target Status Send Request */
375/****************************************************************************/ 447/****************************************************************************/
376 448
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index ffbe6f4720e1..f517d0692d5f 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)
218 * (also referred to as a IO Controller or IOC). 218 * (also referred to as a IO Controller or IOC).
219 * This routine must clear the interrupt from the adapter and does 219 * This routine must clear the interrupt from the adapter and does
220 * so by reading the reply FIFO. Multiple replies may be processed 220 * so by reading the reply FIFO. Multiple replies may be processed
221 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR 221 * per single call to this routine.
222 * which is currently set to 32 in mptbase.h.
223 * 222 *
224 * This routine handles register-level access of the adapter but 223 * This routine handles register-level access of the adapter but
225 * dispatches (calls) a protocol-specific callback routine to handle 224 * dispatches (calls) a protocol-specific callback routine to handle
@@ -279,11 +278,11 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
279 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx; 278 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
280 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 279 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
281 280
282 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n", 281 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
283 ioc->name, mr, req_idx)); 282 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
284 DBG_DUMP_REPLY_FRAME(mr) 283 DBG_DUMP_REPLY_FRAME(mr)
285 284
286 /* Check/log IOC log info 285 /* Check/log IOC log info
287 */ 286 */
288 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus); 287 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
289 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 288 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
@@ -345,7 +344,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
345 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth)) 344 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
346 || (mf < ioc->req_frames)) ) { 345 || (mf < ioc->req_frames)) ) {
347 printk(MYIOC_s_WARN_FMT 346 printk(MYIOC_s_WARN_FMT
348 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx); 347 "mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
349 cb_idx = 0; 348 cb_idx = 0;
350 pa = 0; 349 pa = 0;
351 freeme = 0; 350 freeme = 0;
@@ -399,7 +398,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
399 * @mf: Pointer to original MPT request frame 398 * @mf: Pointer to original MPT request frame
400 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 399 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
401 * 400 *
402 * Returns 1 indicating original alloc'd request frame ptr 401 * Returns 1 indicating original alloc'd request frame ptr
403 * should be freed, or 0 if it shouldn't. 402 * should be freed, or 0 if it shouldn't.
404 */ 403 */
405static int 404static int
@@ -408,28 +407,17 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
408 int freereq = 1; 407 int freereq = 1;
409 u8 func; 408 u8 func;
410 409
411 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name)); 410 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
412
413 if ((mf == NULL) ||
414 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
415 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
416 ioc->name, (void *)mf);
417 return 1;
418 }
419
420 if (reply == NULL) {
421 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
422 ioc->name));
423 return 1;
424 }
425 411
412#if defined(MPT_DEBUG_MSG_FRAME)
426 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { 413 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
427 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf)); 414 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
428 DBG_DUMP_REQUEST_FRAME_HDR(mf) 415 DBG_DUMP_REQUEST_FRAME_HDR(mf)
429 } 416 }
417#endif
430 418
431 func = reply->u.hdr.Function; 419 func = reply->u.hdr.Function;
432 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n", 420 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
433 ioc->name, func)); 421 ioc->name, func));
434 422
435 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) { 423 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
@@ -448,8 +436,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
448 * Hmmm... It seems that EventNotificationReply is an exception 436 * Hmmm... It seems that EventNotificationReply is an exception
449 * to the rule of one reply per request. 437 * to the rule of one reply per request.
450 */ 438 */
451 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) 439 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
452 freereq = 0; 440 freereq = 0;
441 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
442 ioc->name, pEvReply));
443 } else {
444 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
445 ioc->name, pEvReply));
446 }
453 447
454#ifdef CONFIG_PROC_FS 448#ifdef CONFIG_PROC_FS
455// LogEvent(ioc, pEvReply); 449// LogEvent(ioc, pEvReply);
@@ -491,10 +485,21 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
491 485
492 pCfg->status = status; 486 pCfg->status = status;
493 if (status == MPI_IOCSTATUS_SUCCESS) { 487 if (status == MPI_IOCSTATUS_SUCCESS) {
494 pCfg->hdr->PageVersion = pReply->Header.PageVersion; 488 if ((pReply->Header.PageType &
495 pCfg->hdr->PageLength = pReply->Header.PageLength; 489 MPI_CONFIG_PAGETYPE_MASK) ==
496 pCfg->hdr->PageNumber = pReply->Header.PageNumber; 490 MPI_CONFIG_PAGETYPE_EXTENDED) {
497 pCfg->hdr->PageType = pReply->Header.PageType; 491 pCfg->cfghdr.ehdr->ExtPageLength =
492 le16_to_cpu(pReply->ExtPageLength);
493 pCfg->cfghdr.ehdr->ExtPageType =
494 pReply->ExtPageType;
495 }
496 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
497
498 /* If this is a regular header, save PageLength. */
499 /* LMP Do this better so not using a reserved field! */
500 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
501 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
502 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
498 } 503 }
499 } 504 }
500 505
@@ -705,7 +710,7 @@ mpt_device_driver_deregister(int cb_idx)
705 if (dd_cbfunc->remove) 710 if (dd_cbfunc->remove)
706 dd_cbfunc->remove(ioc->pcidev); 711 dd_cbfunc->remove(ioc->pcidev);
707 } 712 }
708 713
709 MptDeviceDriverHandlers[cb_idx] = NULL; 714 MptDeviceDriverHandlers[cb_idx] = NULL;
710} 715}
711 716
@@ -818,7 +823,7 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
818 } 823 }
819#endif 824#endif
820 825
821 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; 826 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
822 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])); 827 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]));
823 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); 828 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
824} 829}
@@ -920,7 +925,7 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
920 925
921 /* Make sure there are no doorbells */ 926 /* Make sure there are no doorbells */
922 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
923 928
924 CHIPREG_WRITE32(&ioc->chip->Doorbell, 929 CHIPREG_WRITE32(&ioc->chip->Doorbell,
925 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 930 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
926 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 931 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
@@ -935,14 +940,14 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
935 return -5; 940 return -5;
936 941
937 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n", 942 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
938 ioc->name, ii)); 943 ioc->name, ii));
939 944
940 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 945 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
941 946
942 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 947 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
943 return -2; 948 return -2;
944 } 949 }
945 950
946 /* Send request via doorbell handshake */ 951 /* Send request via doorbell handshake */
947 req_as_bytes = (u8 *) req; 952 req_as_bytes = (u8 *) req;
948 for (ii = 0; ii < reqBytes/4; ii++) { 953 for (ii = 0; ii < reqBytes/4; ii++) {
@@ -988,9 +993,9 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
988 if (ioc->id == iocid) { 993 if (ioc->id == iocid) {
989 *iocpp =ioc; 994 *iocpp =ioc;
990 return iocid; 995 return iocid;
991 } 996 }
992 } 997 }
993 998
994 *iocpp = NULL; 999 *iocpp = NULL;
995 return -1; 1000 return -1;
996} 1001}
@@ -1032,9 +1037,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1032 1037
1033 if (pci_enable_device(pdev)) 1038 if (pci_enable_device(pdev))
1034 return r; 1039 return r;
1035 1040
1036 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n")); 1041 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1037 1042
1038 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { 1043 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1039 dprintk((KERN_INFO MYNAM 1044 dprintk((KERN_INFO MYNAM
1040 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n")); 1045 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
@@ -1059,7 +1064,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1059 ioc->alloc_total = sizeof(MPT_ADAPTER); 1064 ioc->alloc_total = sizeof(MPT_ADAPTER);
1060 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1065 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1061 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1066 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1062 1067
1063 ioc->pcidev = pdev; 1068 ioc->pcidev = pdev;
1064 ioc->diagPending = 0; 1069 ioc->diagPending = 0;
1065 spin_lock_init(&ioc->diagLock); 1070 spin_lock_init(&ioc->diagLock);
@@ -1088,7 +1093,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1088 /* Find lookup slot. */ 1093 /* Find lookup slot. */
1089 INIT_LIST_HEAD(&ioc->list); 1094 INIT_LIST_HEAD(&ioc->list);
1090 ioc->id = mpt_ids++; 1095 ioc->id = mpt_ids++;
1091 1096
1092 mem_phys = msize = 0; 1097 mem_phys = msize = 0;
1093 port = psize = 0; 1098 port = psize = 0;
1094 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { 1099 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
@@ -1143,7 +1148,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1143 ioc->prod_name = "LSIFC909"; 1148 ioc->prod_name = "LSIFC909";
1144 ioc->bus_type = FC; 1149 ioc->bus_type = FC;
1145 } 1150 }
1146 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) { 1151 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1147 ioc->prod_name = "LSIFC929"; 1152 ioc->prod_name = "LSIFC929";
1148 ioc->bus_type = FC; 1153 ioc->bus_type = FC;
1149 } 1154 }
@@ -1322,7 +1327,7 @@ mpt_detach(struct pci_dev *pdev)
1322 remove_proc_entry(pname, NULL); 1327 remove_proc_entry(pname, NULL);
1323 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); 1328 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1324 remove_proc_entry(pname, NULL); 1329 remove_proc_entry(pname, NULL);
1325 1330
1326 /* call per device driver remove entry point */ 1331 /* call per device driver remove entry point */
1327 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) { 1332 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1328 if(MptDeviceDriverHandlers[ii] && 1333 if(MptDeviceDriverHandlers[ii] &&
@@ -1330,7 +1335,7 @@ mpt_detach(struct pci_dev *pdev)
1330 MptDeviceDriverHandlers[ii]->remove(pdev); 1335 MptDeviceDriverHandlers[ii]->remove(pdev);
1331 } 1336 }
1332 } 1337 }
1333 1338
1334 /* Disable interrupts! */ 1339 /* Disable interrupts! */
1335 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1340 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1336 1341
@@ -1403,7 +1408,7 @@ mpt_resume(struct pci_dev *pdev)
1403 u32 device_state = pdev->current_state; 1408 u32 device_state = pdev->current_state;
1404 int recovery_state; 1409 int recovery_state;
1405 int ii; 1410 int ii;
1406 1411
1407 printk(MYIOC_s_INFO_FMT 1412 printk(MYIOC_s_INFO_FMT
1408 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", 1413 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1409 ioc->name, pdev, pci_name(pdev), device_state); 1414 ioc->name, pdev, pci_name(pdev), device_state);
@@ -1534,7 +1539,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1534 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0) 1539 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1535 break; 1540 break;
1536 } 1541 }
1537 1542
1538 1543
1539 if (ii == 5) { 1544 if (ii == 5) {
1540 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc)); 1545 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1542,7 +1547,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1542 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 1547 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1543 MptDisplayIocCapabilities(ioc); 1548 MptDisplayIocCapabilities(ioc);
1544 } 1549 }
1545 1550
1546 if (alt_ioc_ready) { 1551 if (alt_ioc_ready) {
1547 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 1552 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1548 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); 1553 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1613,7 +1618,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1613 1618
1614 if (reset_alt_ioc_active && ioc->alt_ioc) { 1619 if (reset_alt_ioc_active && ioc->alt_ioc) {
1615 /* (re)Enable alt-IOC! (reply interrupt) */ 1620 /* (re)Enable alt-IOC! (reply interrupt) */
1616 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", 1621 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1617 ioc->alt_ioc->name)); 1622 ioc->alt_ioc->name));
1618 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); 1623 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1619 ioc->alt_ioc->active = 1; 1624 ioc->alt_ioc->active = 1;
@@ -1670,7 +1675,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1670 1675
1671 /* Find IM volumes 1676 /* Find IM volumes
1672 */ 1677 */
1673 if (ioc->facts.MsgVersion >= 0x0102) 1678 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1674 mpt_findImVolumes(ioc); 1679 mpt_findImVolumes(ioc);
1675 1680
1676 /* Check, and possibly reset, the coalescing value 1681 /* Check, and possibly reset, the coalescing value
@@ -1700,7 +1705,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1700 } 1705 }
1701 1706
1702 if (alt_ioc_ready && MptResetHandlers[ii]) { 1707 if (alt_ioc_ready && MptResetHandlers[ii]) {
1703 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n", 1708 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1704 ioc->name, ioc->alt_ioc->name, ii)); 1709 ioc->name, ioc->alt_ioc->name, ii));
1705 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET); 1710 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1706 handlers++; 1711 handlers++;
@@ -1733,8 +1738,8 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1733 1738
1734 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x," 1739 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1735 " searching for devfn match on %x or %x\n", 1740 " searching for devfn match on %x or %x\n",
1736 ioc->name, pci_name(pdev), pdev->devfn, 1741 ioc->name, pci_name(pdev), pdev->bus->number,
1737 func-1, func+1)); 1742 pdev->devfn, func-1, func+1));
1738 1743
1739 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1)); 1744 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1740 if (!peer) { 1745 if (!peer) {
@@ -1861,36 +1866,39 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
1861static void 1866static void
1862mpt_adapter_dispose(MPT_ADAPTER *ioc) 1867mpt_adapter_dispose(MPT_ADAPTER *ioc)
1863{ 1868{
1864 if (ioc != NULL) { 1869 int sz_first, sz_last;
1865 int sz_first, sz_last;
1866 1870
1867 sz_first = ioc->alloc_total; 1871 if (ioc == NULL)
1872 return;
1868 1873
1869 mpt_adapter_disable(ioc); 1874 sz_first = ioc->alloc_total;
1870 1875
1871 if (ioc->pci_irq != -1) { 1876 mpt_adapter_disable(ioc);
1872 free_irq(ioc->pci_irq, ioc);
1873 ioc->pci_irq = -1;
1874 }
1875 1877
1876 if (ioc->memmap != NULL) 1878 if (ioc->pci_irq != -1) {
1877 iounmap(ioc->memmap); 1879 free_irq(ioc->pci_irq, ioc);
1880 ioc->pci_irq = -1;
1881 }
1882
1883 if (ioc->memmap != NULL) {
1884 iounmap(ioc->memmap);
1885 ioc->memmap = NULL;
1886 }
1878 1887
1879#if defined(CONFIG_MTRR) && 0 1888#if defined(CONFIG_MTRR) && 0
1880 if (ioc->mtrr_reg > 0) { 1889 if (ioc->mtrr_reg > 0) {
1881 mtrr_del(ioc->mtrr_reg, 0, 0); 1890 mtrr_del(ioc->mtrr_reg, 0, 0);
1882 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name)); 1891 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1883 } 1892 }
1884#endif 1893#endif
1885 1894
1886 /* Zap the adapter lookup ptr! */ 1895 /* Zap the adapter lookup ptr! */
1887 list_del(&ioc->list); 1896 list_del(&ioc->list);
1888 1897
1889 sz_last = ioc->alloc_total; 1898 sz_last = ioc->alloc_total;
1890 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", 1899 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1891 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); 1900 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1892 kfree(ioc); 1901 kfree(ioc);
1893 }
1894} 1902}
1895 1903
1896/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1904/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1977,7 +1985,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1977 } 1985 }
1978 1986
1979 /* Is it already READY? */ 1987 /* Is it already READY? */
1980 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 1988 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
1981 return 0; 1989 return 0;
1982 1990
1983 /* 1991 /*
@@ -1995,7 +2003,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1995 * Hmmm... Did it get left operational? 2003 * Hmmm... Did it get left operational?
1996 */ 2004 */
1997 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { 2005 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
1998 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n", 2006 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
1999 ioc->name)); 2007 ioc->name));
2000 2008
2001 /* Check WhoInit. 2009 /* Check WhoInit.
@@ -2004,8 +2012,8 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2004 * Else, fall through to KickStart case 2012 * Else, fall through to KickStart case
2005 */ 2013 */
2006 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT; 2014 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2007 dprintk((KERN_WARNING MYNAM 2015 dinitprintk((KERN_INFO MYNAM
2008 ": whoinit 0x%x\n statefault %d force %d\n", 2016 ": whoinit 0x%x statefault %d force %d\n",
2009 whoinit, statefault, force)); 2017 whoinit, statefault, force));
2010 if (whoinit == MPI_WHOINIT_PCI_PEER) 2018 if (whoinit == MPI_WHOINIT_PCI_PEER)
2011 return -4; 2019 return -4;
@@ -2140,8 +2148,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2140 get_facts.Function = MPI_FUNCTION_IOC_FACTS; 2148 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2141 /* Assert: All other get_facts fields are zero! */ 2149 /* Assert: All other get_facts fields are zero! */
2142 2150
2143 dinitprintk((MYIOC_s_INFO_FMT 2151 dinitprintk((MYIOC_s_INFO_FMT
2144 "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 2152 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2145 ioc->name, req_sz, reply_sz)); 2153 ioc->name, req_sz, reply_sz));
2146 2154
2147 /* No non-zero fields in the get_facts request are greater than 2155 /* No non-zero fields in the get_facts request are greater than
@@ -2174,7 +2182,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2174 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); 2182 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2175 facts->IOCStatus = le16_to_cpu(facts->IOCStatus); 2183 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2176 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); 2184 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2177 status = facts->IOCStatus & MPI_IOCSTATUS_MASK; 2185 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2178 /* CHECKME! IOCStatus, IOCLogInfo */ 2186 /* CHECKME! IOCStatus, IOCLogInfo */
2179 2187
2180 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); 2188 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
@@ -2221,7 +2229,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2221 if ( sz & 0x02 ) 2229 if ( sz & 0x02 )
2222 sz += 2; 2230 sz += 2;
2223 facts->FWImageSize = sz; 2231 facts->FWImageSize = sz;
2224 2232
2225 if (!facts->RequestFrameSize) { 2233 if (!facts->RequestFrameSize) {
2226 /* Something is wrong! */ 2234 /* Something is wrong! */
2227 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n", 2235 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
@@ -2240,7 +2248,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2240 ioc->NBShiftFactor = shiftFactor; 2248 ioc->NBShiftFactor = shiftFactor;
2241 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", 2249 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2242 ioc->name, vv, shiftFactor, r)); 2250 ioc->name, vv, shiftFactor, r));
2243 2251
2244 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2252 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2245 /* 2253 /*
2246 * Set values for this IOC's request & reply frame sizes, 2254 * Set values for this IOC's request & reply frame sizes,
@@ -2261,7 +2269,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2261 return r; 2269 return r;
2262 } 2270 }
2263 } else { 2271 } else {
2264 printk(MYIOC_s_ERR_FMT 2272 printk(MYIOC_s_ERR_FMT
2265 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n", 2273 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2266 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t, 2274 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2267 RequestFrameSize)/sizeof(u32))); 2275 RequestFrameSize)/sizeof(u32)));
@@ -2413,9 +2421,11 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2413 2421
2414 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n", 2422 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2415 ioc->name, &ioc_init)); 2423 ioc->name, &ioc_init));
2416 2424
2417 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) 2425 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2426 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2418 return r; 2427 return r;
2428 }
2419 2429
2420 /* YIKES! SUPER IMPORTANT!!! 2430 /* YIKES! SUPER IMPORTANT!!!
2421 * Poll IocState until _OPERATIONAL while IOC is doing 2431 * Poll IocState until _OPERATIONAL while IOC is doing
@@ -2440,7 +2450,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2440 state = mpt_GetIocState(ioc, 1); 2450 state = mpt_GetIocState(ioc, 1);
2441 count++; 2451 count++;
2442 } 2452 }
2443 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", 2453 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2444 ioc->name, count)); 2454 ioc->name, count));
2445 2455
2446 return r; 2456 return r;
@@ -2529,7 +2539,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
2529 int sz; 2539 int sz;
2530 2540
2531 sz = ioc->facts.FWImageSize; 2541 sz = ioc->facts.FWImageSize;
2532 dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", 2542 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2533 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 2543 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2534 pci_free_consistent(ioc->pcidev, sz, 2544 pci_free_consistent(ioc->pcidev, sz,
2535 ioc->cached_fw, ioc->cached_fw_dma); 2545 ioc->cached_fw, ioc->cached_fw_dma);
@@ -2573,9 +2583,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2573 2583
2574 mpt_alloc_fw_memory(ioc, sz); 2584 mpt_alloc_fw_memory(ioc, sz);
2575 2585
2576 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n", 2586 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2577 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 2587 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2578 2588
2579 if (ioc->cached_fw == NULL) { 2589 if (ioc->cached_fw == NULL) {
2580 /* Major Failure. 2590 /* Major Failure.
2581 */ 2591 */
@@ -2605,14 +2615,14 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2605 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma); 2615 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2606 2616
2607 sgeoffset += sizeof(u32) + sizeof(dma_addr_t); 2617 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2608 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n", 2618 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2609 prequest, sgeoffset)); 2619 prequest, sgeoffset));
2610 DBG_DUMP_FW_REQUEST_FRAME(prequest) 2620 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2611 2621
2612 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, 2622 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2613 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); 2623 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2614 2624
2615 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii)); 2625 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2616 2626
2617 cmdStatus = -EFAULT; 2627 cmdStatus = -EFAULT;
2618 if (ii == 0) { 2628 if (ii == 0) {
@@ -2627,10 +2637,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2627 cmdStatus = 0; 2637 cmdStatus = 0;
2628 } 2638 }
2629 } 2639 }
2630 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n", 2640 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2631 ioc->name, cmdStatus)); 2641 ioc->name, cmdStatus));
2632 2642
2633 2643
2634 if (cmdStatus) { 2644 if (cmdStatus) {
2635 2645
2636 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n", 2646 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
@@ -2761,8 +2771,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2761 fwSize = (pExtImage->ImageSize + 3) >> 2; 2771 fwSize = (pExtImage->ImageSize + 3) >> 2;
2762 ptrFw = (u32 *)pExtImage; 2772 ptrFw = (u32 *)pExtImage;
2763 2773
2764 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n", 2774 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2765 ioc->name, fwSize*4, ptrFw, load_addr)); 2775 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2766 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); 2776 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2767 2777
2768 while (fwSize--) { 2778 while (fwSize--) {
@@ -2845,9 +2855,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2845 * 0 else 2855 * 0 else
2846 * 2856 *
2847 * Returns: 2857 * Returns:
2848 * 1 - hard reset, READY 2858 * 1 - hard reset, READY
2849 * 0 - no reset due to History bit, READY 2859 * 0 - no reset due to History bit, READY
2850 * -1 - no reset due to History bit but not READY 2860 * -1 - no reset due to History bit but not READY
2851 * OR reset but failed to come READY 2861 * OR reset but failed to come READY
2852 * -2 - no reset, could not enter DIAG mode 2862 * -2 - no reset, could not enter DIAG mode
2853 * -3 - reset but bad FW bit 2863 * -3 - reset but bad FW bit
@@ -2990,7 +3000,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2990 * 3000 *
2991 */ 3001 */
2992 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); 3002 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
2993 mdelay (1); 3003 mdelay(1);
2994 3004
2995 /* 3005 /*
2996 * Now hit the reset bit in the Diagnostic register 3006 * Now hit the reset bit in the Diagnostic register
@@ -3170,7 +3180,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3170 u32 state; 3180 u32 state;
3171 int cntdn, count; 3181 int cntdn, count;
3172 3182
3173 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n", 3183 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3174 ioc->name, reset_type)); 3184 ioc->name, reset_type));
3175 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT); 3185 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3176 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 3186 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
@@ -3374,6 +3384,9 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
3374 ioc->reply_frames = (MPT_FRAME_HDR *) mem; 3384 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3375 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 3385 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3376 3386
3387 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3388 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3389
3377 alloc_dma += reply_sz; 3390 alloc_dma += reply_sz;
3378 mem += reply_sz; 3391 mem += reply_sz;
3379 3392
@@ -3382,7 +3395,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
3382 ioc->req_frames = (MPT_FRAME_HDR *) mem; 3395 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3383 ioc->req_frames_dma = alloc_dma; 3396 ioc->req_frames_dma = alloc_dma;
3384 3397
3385 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n", 3398 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3386 ioc->name, mem, (void *)(ulong)alloc_dma)); 3399 ioc->name, mem, (void *)(ulong)alloc_dma));
3387 3400
3388 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 3401 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
@@ -3408,7 +3421,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
3408 ioc->ChainBuffer = mem; 3421 ioc->ChainBuffer = mem;
3409 ioc->ChainBufferDMA = alloc_dma; 3422 ioc->ChainBufferDMA = alloc_dma;
3410 3423
3411 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n", 3424 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3412 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA)); 3425 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3413 3426
3414 /* Initialize the free chain Q. 3427 /* Initialize the free chain Q.
@@ -3513,7 +3526,7 @@ out_fail:
3513 */ 3526 */
3514static int 3527static int
3515mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, 3528mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3516 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) 3529 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3517{ 3530{
3518 MPIDefaultReply_t *mptReply; 3531 MPIDefaultReply_t *mptReply;
3519 int failcnt = 0; 3532 int failcnt = 0;
@@ -3588,7 +3601,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3588 */ 3601 */
3589 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) 3602 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3590 failcnt++; 3603 failcnt++;
3591 3604
3592 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n", 3605 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3593 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : "")); 3606 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3594 3607
@@ -3747,7 +3760,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3747 } 3760 }
3748 3761
3749 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n", 3762 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3750 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), 3763 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3751 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 3764 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3752 3765
3753 /* 3766 /*
@@ -3819,7 +3832,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
3819 hdr.PageLength = 0; 3832 hdr.PageLength = 0;
3820 hdr.PageNumber = 0; 3833 hdr.PageNumber = 0;
3821 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 3834 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3822 cfg.hdr = &hdr; 3835 cfg.cfghdr.hdr = &hdr;
3823 cfg.physAddr = -1; 3836 cfg.physAddr = -1;
3824 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 3837 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3825 cfg.dir = 0; 3838 cfg.dir = 0;
@@ -3863,7 +3876,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
3863 hdr.PageLength = 0; 3876 hdr.PageLength = 0;
3864 hdr.PageNumber = 1; 3877 hdr.PageNumber = 1;
3865 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 3878 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3866 cfg.hdr = &hdr; 3879 cfg.cfghdr.hdr = &hdr;
3867 cfg.physAddr = -1; 3880 cfg.physAddr = -1;
3868 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 3881 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3869 cfg.dir = 0; 3882 cfg.dir = 0;
@@ -3930,7 +3943,7 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
3930 hdr.PageLength = 0; 3943 hdr.PageLength = 0;
3931 hdr.PageNumber = 0; 3944 hdr.PageNumber = 0;
3932 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; 3945 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
3933 cfg.hdr = &hdr; 3946 cfg.cfghdr.hdr = &hdr;
3934 cfg.physAddr = -1; 3947 cfg.physAddr = -1;
3935 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 3948 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3936 cfg.dir = 0; 3949 cfg.dir = 0;
@@ -4012,7 +4025,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
4012 hdr.PageLength = 0; 4025 hdr.PageLength = 0;
4013 hdr.PageNumber = 2; 4026 hdr.PageNumber = 2;
4014 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT; 4027 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4015 cfg.hdr = &hdr; 4028 cfg.cfghdr.hdr = &hdr;
4016 cfg.physAddr = -1; 4029 cfg.physAddr = -1;
4017 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4030 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4018 cfg.dir = 0; 4031 cfg.dir = 0;
@@ -4102,7 +4115,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4102 header.PageLength = 0; 4115 header.PageLength = 0;
4103 header.PageNumber = 0; 4116 header.PageNumber = 0;
4104 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 4117 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4105 cfg.hdr = &header; 4118 cfg.cfghdr.hdr = &header;
4106 cfg.physAddr = -1; 4119 cfg.physAddr = -1;
4107 cfg.pageAddr = portnum; 4120 cfg.pageAddr = portnum;
4108 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4121 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4122,6 +4135,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4122 ioc->spi_data.minSyncFactor = MPT_ASYNC; 4135 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4123 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN; 4136 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4124 rc = 1; 4137 rc = 1;
4138 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4139 ioc->name, ioc->spi_data.minSyncFactor));
4125 } else { 4140 } else {
4126 /* Save the Port Page 0 data 4141 /* Save the Port Page 0 data
4127 */ 4142 */
@@ -4131,7 +4146,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4131 4146
4132 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { 4147 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4133 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; 4148 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4134 dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n", 4149 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4135 ioc->name, pPP0->Capabilities)); 4150 ioc->name, pPP0->Capabilities));
4136 } 4151 }
4137 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; 4152 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
@@ -4140,6 +4155,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4140 ioc->spi_data.maxSyncOffset = (u8) (data >> 16); 4155 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4141 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK; 4156 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4142 ioc->spi_data.minSyncFactor = (u8) (data >> 8); 4157 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4158 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4159 ioc->name, ioc->spi_data.minSyncFactor));
4143 } else { 4160 } else {
4144 ioc->spi_data.maxSyncOffset = 0; 4161 ioc->spi_data.maxSyncOffset = 0;
4145 ioc->spi_data.minSyncFactor = MPT_ASYNC; 4162 ioc->spi_data.minSyncFactor = MPT_ASYNC;
@@ -4152,8 +4169,11 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4152 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) || 4169 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4153 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) { 4170 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4154 4171
4155 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) 4172 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4156 ioc->spi_data.minSyncFactor = MPT_ULTRA; 4173 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4174 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4175 ioc->name, ioc->spi_data.minSyncFactor));
4176 }
4157 } 4177 }
4158 } 4178 }
4159 if (pbuf) { 4179 if (pbuf) {
@@ -4168,7 +4188,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4168 header.PageLength = 0; 4188 header.PageLength = 0;
4169 header.PageNumber = 2; 4189 header.PageNumber = 2;
4170 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 4190 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4171 cfg.hdr = &header; 4191 cfg.cfghdr.hdr = &header;
4172 cfg.physAddr = -1; 4192 cfg.physAddr = -1;
4173 cfg.pageAddr = portnum; 4193 cfg.pageAddr = portnum;
4174 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4194 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4236,7 +4256,7 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4236 header.PageLength = 0; 4256 header.PageLength = 0;
4237 header.PageNumber = 1; 4257 header.PageNumber = 1;
4238 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 4258 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4239 cfg.hdr = &header; 4259 cfg.cfghdr.hdr = &header;
4240 cfg.physAddr = -1; 4260 cfg.physAddr = -1;
4241 cfg.pageAddr = portnum; 4261 cfg.pageAddr = portnum;
4242 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4262 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4245,8 +4265,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4245 if (mpt_config(ioc, &cfg) != 0) 4265 if (mpt_config(ioc, &cfg) != 0)
4246 return -EFAULT; 4266 return -EFAULT;
4247 4267
4248 ioc->spi_data.sdp1version = cfg.hdr->PageVersion; 4268 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4249 ioc->spi_data.sdp1length = cfg.hdr->PageLength; 4269 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4250 4270
4251 header.PageVersion = 0; 4271 header.PageVersion = 0;
4252 header.PageLength = 0; 4272 header.PageLength = 0;
@@ -4255,8 +4275,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4255 if (mpt_config(ioc, &cfg) != 0) 4275 if (mpt_config(ioc, &cfg) != 0)
4256 return -EFAULT; 4276 return -EFAULT;
4257 4277
4258 ioc->spi_data.sdp0version = cfg.hdr->PageVersion; 4278 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4259 ioc->spi_data.sdp0length = cfg.hdr->PageLength; 4279 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4260 4280
4261 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n", 4281 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4262 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); 4282 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
@@ -4298,7 +4318,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4298 header.PageLength = 0; 4318 header.PageLength = 0;
4299 header.PageNumber = 2; 4319 header.PageNumber = 2;
4300 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 4320 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4301 cfg.hdr = &header; 4321 cfg.cfghdr.hdr = &header;
4302 cfg.physAddr = -1; 4322 cfg.physAddr = -1;
4303 cfg.pageAddr = 0; 4323 cfg.pageAddr = 0;
4304 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4324 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4394,7 +4414,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4394 header.PageLength = 0; 4414 header.PageLength = 0;
4395 header.PageNumber = 3; 4415 header.PageNumber = 3;
4396 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 4416 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4397 cfg.hdr = &header; 4417 cfg.cfghdr.hdr = &header;
4398 cfg.physAddr = -1; 4418 cfg.physAddr = -1;
4399 cfg.pageAddr = 0; 4419 cfg.pageAddr = 0;
4400 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4420 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4446,7 +4466,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4446 header.PageLength = 0; 4466 header.PageLength = 0;
4447 header.PageNumber = 4; 4467 header.PageNumber = 4;
4448 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 4468 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4449 cfg.hdr = &header; 4469 cfg.cfghdr.hdr = &header;
4450 cfg.physAddr = -1; 4470 cfg.physAddr = -1;
4451 cfg.pageAddr = 0; 4471 cfg.pageAddr = 0;
4452 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4472 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4498,7 +4518,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4498 header.PageLength = 0; 4518 header.PageLength = 0;
4499 header.PageNumber = 1; 4519 header.PageNumber = 1;
4500 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 4520 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4501 cfg.hdr = &header; 4521 cfg.cfghdr.hdr = &header;
4502 cfg.physAddr = -1; 4522 cfg.physAddr = -1;
4503 cfg.pageAddr = 0; 4523 cfg.pageAddr = 0;
4504 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4524 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4580,13 +4600,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4580 4600
4581 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); 4601 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4582 if (evnp == NULL) { 4602 if (evnp == NULL) {
4583 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", 4603 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4584 ioc->name)); 4604 ioc->name));
4585 return 0; 4605 return 0;
4586 } 4606 }
4587 memset(evnp, 0, sizeof(*evnp)); 4607 memset(evnp, 0, sizeof(*evnp));
4588 4608
4589 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch)); 4609 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
4590 4610
4591 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 4611 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4592 evnp->ChainOffset = 0; 4612 evnp->ChainOffset = 0;
@@ -4610,8 +4630,10 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4610 EventAck_t *pAck; 4630 EventAck_t *pAck;
4611 4631
4612 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 4632 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4613 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n", 4633 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
4614 ioc->name); 4634 "request frame for Event=%x EventContext=%x EventData=%x!\n",
4635 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
4636 le32_to_cpu(evnp->Data[0]));
4615 return -1; 4637 return -1;
4616 } 4638 }
4617 memset(pAck, 0, sizeof(*pAck)); 4639 memset(pAck, 0, sizeof(*pAck));
@@ -4647,10 +4669,11 @@ int
4647mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 4669mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4648{ 4670{
4649 Config_t *pReq; 4671 Config_t *pReq;
4672 ConfigExtendedPageHeader_t *pExtHdr = NULL;
4650 MPT_FRAME_HDR *mf; 4673 MPT_FRAME_HDR *mf;
4651 unsigned long flags; 4674 unsigned long flags;
4652 int ii, rc; 4675 int ii, rc;
4653 u32 flagsLength; 4676 int flagsLength;
4654 int in_isr; 4677 int in_isr;
4655 4678
4656 /* Prevent calling wait_event() (below), if caller happens 4679 /* Prevent calling wait_event() (below), if caller happens
@@ -4675,16 +4698,30 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4675 pReq->Reserved = 0; 4698 pReq->Reserved = 0;
4676 pReq->ChainOffset = 0; 4699 pReq->ChainOffset = 0;
4677 pReq->Function = MPI_FUNCTION_CONFIG; 4700 pReq->Function = MPI_FUNCTION_CONFIG;
4701
4702 /* Assume page type is not extended and clear "reserved" fields. */
4678 pReq->ExtPageLength = 0; 4703 pReq->ExtPageLength = 0;
4679 pReq->ExtPageType = 0; 4704 pReq->ExtPageType = 0;
4680 pReq->MsgFlags = 0; 4705 pReq->MsgFlags = 0;
4706
4681 for (ii=0; ii < 8; ii++) 4707 for (ii=0; ii < 8; ii++)
4682 pReq->Reserved2[ii] = 0; 4708 pReq->Reserved2[ii] = 0;
4683 4709
4684 pReq->Header.PageVersion = pCfg->hdr->PageVersion; 4710 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
4685 pReq->Header.PageLength = pCfg->hdr->PageLength; 4711 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
4686 pReq->Header.PageNumber = pCfg->hdr->PageNumber; 4712 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
4687 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 4713 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4714
4715 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
4716 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
4717 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
4718 pReq->ExtPageType = pExtHdr->ExtPageType;
4719 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
4720
4721 /* Page Length must be treated as a reserved field for the extended header. */
4722 pReq->Header.PageLength = 0;
4723 }
4724
4688 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr); 4725 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4689 4726
4690 /* Add a SGE to the config request. 4727 /* Add a SGE to the config request.
@@ -4694,12 +4731,20 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4694 else 4731 else
4695 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 4732 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4696 4733
4697 flagsLength |= pCfg->hdr->PageLength * 4; 4734 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
4735 flagsLength |= pExtHdr->ExtPageLength * 4;
4698 4736
4699 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 4737 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4738 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
4739 }
4740 else {
4741 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
4742
4743 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4744 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4745 }
4700 4746
4701 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n", 4747 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4702 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4703 4748
4704 /* Append pCfg pointer to end of mf 4749 /* Append pCfg pointer to end of mf
4705 */ 4750 */
@@ -4789,8 +4834,8 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4789 pReq->Reserved3 = 0; 4834 pReq->Reserved3 = 0;
4790 pReq->NumAddressBytes = 0x01; 4835 pReq->NumAddressBytes = 0x01;
4791 pReq->Reserved4 = 0; 4836 pReq->Reserved4 = 0;
4792 pReq->DataLength = 0x04; 4837 pReq->DataLength = cpu_to_le16(0x04);
4793 pdev = (struct pci_dev *) ioc->pcidev; 4838 pdev = ioc->pcidev;
4794 if (pdev->devfn & 1) 4839 if (pdev->devfn & 1)
4795 pReq->DeviceAddr = 0xB2; 4840 pReq->DeviceAddr = 0xB2;
4796 else 4841 else
@@ -5504,6 +5549,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5504 * If needed, send (a single) EventAck. 5549 * If needed, send (a single) EventAck.
5505 */ 5550 */
5506 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { 5551 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5552 devtprintk((MYIOC_s_WARN_FMT
5553 "EventAck required\n",ioc->name));
5507 if ((ii = SendEventAck(ioc, pEventReply)) != 0) { 5554 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5508 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n", 5555 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5509 ioc->name, ii)); 5556 ioc->name, ii));
@@ -5584,7 +5631,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5584 case 0x00080000: 5631 case 0x00080000:
5585 desc = "Outbound DMA Overrun"; 5632 desc = "Outbound DMA Overrun";
5586 break; 5633 break;
5587 5634
5588 case 0x00090000: 5635 case 0x00090000:
5589 desc = "Task Management"; 5636 desc = "Task Management";
5590 break; 5637 break;
@@ -5600,7 +5647,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5600 case 0x000C0000: 5647 case 0x000C0000:
5601 desc = "Untagged Table Size"; 5648 desc = "Untagged Table Size";
5602 break; 5649 break;
5603 5650
5604 } 5651 }
5605 5652
5606 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); 5653 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
@@ -5692,7 +5739,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5692 break; 5739 break;
5693 5740
5694 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 5741 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5695 /* This error is checked in scsi_io_done(). Skip. 5742 /* This error is checked in scsi_io_done(). Skip.
5696 desc = "SCSI Data Underrun"; 5743 desc = "SCSI Data Underrun";
5697 */ 5744 */
5698 break; 5745 break;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 848fb236b175..f4827d923731 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -915,7 +915,10 @@ struct scsi_cmnd;
915typedef struct _x_config_parms { 915typedef struct _x_config_parms {
916 struct list_head linkage; /* linked list */ 916 struct list_head linkage; /* linked list */
917 struct timer_list timer; /* timer function for this request */ 917 struct timer_list timer; /* timer function for this request */
918 ConfigPageHeader_t *hdr; 918 union {
919 ConfigExtendedPageHeader_t *ehdr;
920 ConfigPageHeader_t *hdr;
921 } cfghdr;
919 dma_addr_t physAddr; 922 dma_addr_t physAddr;
920 int wait_done; /* wait for this request */ 923 int wait_done; /* wait for this request */
921 u32 pageAddr; /* properly formatted */ 924 u32 pageAddr; /* properly formatted */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 05ea5944c487..7577c2417e2e 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)
242 /* Set the command status to GOOD if IOC Status is GOOD 242 /* Set the command status to GOOD if IOC Status is GOOD
243 * OR if SCSI I/O cmd and data underrun or recovered error. 243 * OR if SCSI I/O cmd and data underrun or recovered error.
244 */ 244 */
245 iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK; 245 iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK;
246 if (iocStatus == MPI_IOCSTATUS_SUCCESS) 246 if (iocStatus == MPI_IOCSTATUS_SUCCESS)
247 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD; 247 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
248 248
@@ -2324,7 +2324,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2324 hdr.PageLength = 0; 2324 hdr.PageLength = 0;
2325 hdr.PageNumber = 0; 2325 hdr.PageNumber = 0;
2326 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; 2326 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2327 cfg.hdr = &hdr; 2327 cfg.cfghdr.hdr = &hdr;
2328 cfg.physAddr = -1; 2328 cfg.physAddr = -1;
2329 cfg.pageAddr = 0; 2329 cfg.pageAddr = 0;
2330 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 2330 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -2333,7 +2333,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2333 2333
2334 strncpy(karg.serial_number, " ", 24); 2334 strncpy(karg.serial_number, " ", 24);
2335 if (mpt_config(ioc, &cfg) == 0) { 2335 if (mpt_config(ioc, &cfg) == 0) {
2336 if (cfg.hdr->PageLength > 0) { 2336 if (cfg.cfghdr.hdr->PageLength > 0) {
2337 /* Issue the second config page request */ 2337 /* Issue the second config page request */
2338 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 2338 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2339 2339
@@ -2479,7 +2479,7 @@ mptctl_hp_targetinfo(unsigned long arg)
2479 hdr.PageNumber = 0; 2479 hdr.PageNumber = 0;
2480 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 2480 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2481 2481
2482 cfg.hdr = &hdr; 2482 cfg.cfghdr.hdr = &hdr;
2483 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 2483 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2484 cfg.dir = 0; 2484 cfg.dir = 0;
2485 cfg.timeout = 0; 2485 cfg.timeout = 0;
@@ -2527,15 +2527,15 @@ mptctl_hp_targetinfo(unsigned long arg)
2527 hdr.PageNumber = 3; 2527 hdr.PageNumber = 3;
2528 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 2528 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2529 2529
2530 cfg.hdr = &hdr; 2530 cfg.cfghdr.hdr = &hdr;
2531 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 2531 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2532 cfg.dir = 0; 2532 cfg.dir = 0;
2533 cfg.timeout = 0; 2533 cfg.timeout = 0;
2534 cfg.physAddr = -1; 2534 cfg.physAddr = -1;
2535 if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) { 2535 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2536 /* Issue the second config page request */ 2536 /* Issue the second config page request */
2537 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 2537 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2538 data_sz = (int) cfg.hdr->PageLength * 4; 2538 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2539 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent( 2539 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2540 ioc->pcidev, data_sz, &page_dma); 2540 ioc->pcidev, data_sz, &page_dma);
2541 if (pg3_alloc) { 2541 if (pg3_alloc) {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index b9d4f78725b4..4a003dc5fde8 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -281,12 +281,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
281 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer; 281 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
282 chain_idx = offset / ioc->req_sz; 282 chain_idx = offset / ioc->req_sz;
283 rc = SUCCESS; 283 rc = SUCCESS;
284 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n", 284 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
285 ioc->name, *retIndex, chainBuf)); 285 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
286 } else { 286 } else {
287 rc = FAILED; 287 rc = FAILED;
288 chain_idx = MPT_HOST_NO_CHAIN; 288 chain_idx = MPT_HOST_NO_CHAIN;
289 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n", 289 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
290 ioc->name)); 290 ioc->name));
291 } 291 }
292 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 292 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
@@ -432,7 +432,7 @@ nextSGEset:
432 */ 432 */
433 pReq->ChainOffset = 0; 433 pReq->ChainOffset = 0;
434 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03; 434 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
435 dsgprintk((MYIOC_s_ERR_FMT 435 dsgprintk((MYIOC_s_INFO_FMT
436 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset)); 436 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
437 ioc->RequestNB[req_idx] = RequestNB; 437 ioc->RequestNB[req_idx] = RequestNB;
438 } 438 }
@@ -491,11 +491,12 @@ nextSGEset:
491 /* NOTE: psge points to the beginning of the chain element 491 /* NOTE: psge points to the beginning of the chain element
492 * in current buffer. Get a chain buffer. 492 * in current buffer. Get a chain buffer.
493 */ 493 */
494 dsgprintk((MYIOC_s_INFO_FMT 494 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
495 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n", 495 dfailprintk((MYIOC_s_INFO_FMT
496 ioc->name, pReq->CDB[0], SCpnt)); 496 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
497 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) 497 ioc->name, pReq->CDB[0], SCpnt));
498 return FAILED; 498 return FAILED;
499 }
499 500
500 /* Update the tracking arrays. 501 /* Update the tracking arrays.
501 * If chainSge == NULL, update ReqToChain, else ChainToChain 502 * 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)
577 return 1; 578 return 1;
578 } 579 }
579 580
580 dmfprintk((MYIOC_s_INFO_FMT
581 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
582 ioc->name, mf, mr, sc, req_idx));
583
584 sc->result = DID_OK << 16; /* Set default reply as OK */ 581 sc->result = DID_OK << 16; /* Set default reply as OK */
585 pScsiReq = (SCSIIORequest_t *) mf; 582 pScsiReq = (SCSIIORequest_t *) mf;
586 pScsiReply = (SCSIIOReply_t *) mr; 583 pScsiReply = (SCSIIOReply_t *) mr;
587 584
585 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
586 dmfprintk((MYIOC_s_INFO_FMT
587 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
588 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
589 }else{
590 dmfprintk((MYIOC_s_INFO_FMT
591 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
592 ioc->name, mf, mr, sc, req_idx));
593 }
594
588 if (pScsiReply == NULL) { 595 if (pScsiReply == NULL) {
589 /* special context reply handling */ 596 /* special context reply handling */
590 ; 597 ;
@@ -658,8 +665,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
658 /* Sufficient data transfer occurred */ 665 /* Sufficient data transfer occurred */
659 sc->result = (DID_OK << 16) | scsi_status; 666 sc->result = (DID_OK << 16) | scsi_status;
660 } else if ( xfer_cnt == 0 ) { 667 } else if ( xfer_cnt == 0 ) {
661 /* A CRC Error causes this condition; retry */ 668 /* A CRC Error causes this condition; retry */
662 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | 669 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
663 (CHECK_CONDITION << 1); 670 (CHECK_CONDITION << 1);
664 sc->sense_buffer[0] = 0x70; 671 sc->sense_buffer[0] = 0x70;
665 sc->sense_buffer[2] = NO_SENSE; 672 sc->sense_buffer[2] = NO_SENSE;
@@ -668,7 +675,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
668 } else { 675 } else {
669 sc->result = DID_SOFT_ERROR << 16; 676 sc->result = DID_SOFT_ERROR << 16;
670 } 677 }
671 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target)); 678 dreplyprintk((KERN_NOTICE
679 "RESIDUAL_MISMATCH: result=%x on id=%d\n",
680 sc->result, sc->device->id));
672 break; 681 break;
673 682
674 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 683 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)
796 return 1; 805 return 1;
797} 806}
798 807
799
800/* 808/*
801 * mptscsih_flush_running_cmds - For each command found, search 809 * mptscsih_flush_running_cmds - For each command found, search
802 * Scsi_Host instance taskQ and reply to OS. 810 * Scsi_Host instance taskQ and reply to OS.
@@ -1017,7 +1025,7 @@ mptscsih_remove(struct pci_dev *pdev)
1017 scsi_host_put(host); 1025 scsi_host_put(host);
1018 1026
1019 mpt_detach(pdev); 1027 mpt_detach(pdev);
1020 1028
1021} 1029}
1022 1030
1023/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1031/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1072,7 +1080,7 @@ mptscsih_resume(struct pci_dev *pdev)
1072 MPT_SCSI_HOST *hd; 1080 MPT_SCSI_HOST *hd;
1073 1081
1074 mpt_resume(pdev); 1082 mpt_resume(pdev);
1075 1083
1076 if(!host) 1084 if(!host)
1077 return 0; 1085 return 0;
1078 1086
@@ -1214,8 +1222,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
1214 int size = 0; 1222 int size = 0;
1215 1223
1216 if (func) { 1224 if (func) {
1217 /* 1225 /*
1218 * write is not supported 1226 * write is not supported
1219 */ 1227 */
1220 } else { 1228 } else {
1221 if (start) 1229 if (start)
@@ -1535,17 +1543,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1535 */ 1543 */
1536 if (mptscsih_tm_pending_wait(hd) == FAILED) { 1544 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1537 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { 1545 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1538 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: " 1546 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1539 "Timed out waiting for last TM (%d) to complete! \n", 1547 "Timed out waiting for last TM (%d) to complete! \n",
1540 hd->ioc->name, hd->tmPending)); 1548 hd->ioc->name, hd->tmPending));
1541 return FAILED; 1549 return FAILED;
1542 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { 1550 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1543 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: " 1551 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1544 "Timed out waiting for last TM (%d) to complete! \n", 1552 "Timed out waiting for last TM (%d) to complete! \n",
1545 hd->ioc->name, hd->tmPending)); 1553 hd->ioc->name, hd->tmPending));
1546 return FAILED; 1554 return FAILED;
1547 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 1555 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1548 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: " 1556 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1549 "Timed out waiting for last TM (%d) to complete! \n", 1557 "Timed out waiting for last TM (%d) to complete! \n",
1550 hd->ioc->name, hd->tmPending)); 1558 hd->ioc->name, hd->tmPending));
1551 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) 1559 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
1631 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) { 1639 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1632 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", 1640 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1633 hd->ioc->name)); 1641 hd->ioc->name));
1634 //return FAILED; 1642 return FAILED;
1635 return -999;
1636 } 1643 }
1637 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n", 1644 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1638 hd->ioc->name, mf)); 1645 hd->ioc->name, mf));
@@ -1661,9 +1668,8 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
1661 1668
1662 pScsiTm->TaskMsgContext = ctx2abort; 1669 pScsiTm->TaskMsgContext = ctx2abort;
1663 1670
1664 dtmprintk((MYIOC_s_INFO_FMT 1671 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1665 "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", 1672 hd->ioc->name, ctx2abort, type));
1666 hd->ioc->name, ctx2abort, type));
1667 1673
1668 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); 1674 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1669 1675
@@ -1902,13 +1908,13 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1902 1908
1903 /* If we can't locate the host to reset, then we failed. */ 1909 /* If we can't locate the host to reset, then we failed. */
1904 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1910 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1905 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " 1911 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1906 "Can't locate host! (sc=%p)\n", 1912 "Can't locate host! (sc=%p)\n",
1907 SCpnt ) ); 1913 SCpnt ) );
1908 return FAILED; 1914 return FAILED;
1909 } 1915 }
1910 1916
1911 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n", 1917 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1912 hd->ioc->name, SCpnt); 1918 hd->ioc->name, SCpnt);
1913 1919
1914 /* If our attempts to reset the host failed, then return a failed 1920 /* If our attempts to reset the host failed, then return a failed
@@ -1924,7 +1930,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1924 hd->tmState = TM_STATE_NONE; 1930 hd->tmState = TM_STATE_NONE;
1925 } 1931 }
1926 1932
1927 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " 1933 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1928 "Status = %s\n", 1934 "Status = %s\n",
1929 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) ); 1935 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1930 1936
@@ -1951,8 +1957,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1951 if (hd->tmState == TM_STATE_NONE) { 1957 if (hd->tmState == TM_STATE_NONE) {
1952 hd->tmState = TM_STATE_IN_PROGRESS; 1958 hd->tmState = TM_STATE_IN_PROGRESS;
1953 hd->tmPending = 1; 1959 hd->tmPending = 1;
1954 status = SUCCESS;
1955 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1960 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1961 status = SUCCESS;
1956 break; 1962 break;
1957 } 1963 }
1958 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1964 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -1980,7 +1986,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1980 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 1986 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1981 if(hd->tmPending == 0) { 1987 if(hd->tmPending == 0) {
1982 status = SUCCESS; 1988 status = SUCCESS;
1983 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1989 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1984 break; 1990 break;
1985 } 1991 }
1986 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1992 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -2318,10 +2324,10 @@ mptscsih_slave_configure(struct scsi_device *device)
2318 if (pTarget == NULL) { 2324 if (pTarget == NULL) {
2319 /* Driver doesn't know about this device. 2325 /* Driver doesn't know about this device.
2320 * Kernel may generate a "Dummy Lun 0" which 2326 * Kernel may generate a "Dummy Lun 0" which
2321 * may become a real Lun if a 2327 * may become a real Lun if a
2322 * "scsi add-single-device" command is executed 2328 * "scsi add-single-device" command is executed
2323 * while the driver is active (hot-plug a 2329 * while the driver is active (hot-plug a
2324 * device). LSI Raid controllers need 2330 * device). LSI Raid controllers need
2325 * queue_depth set to DEV_HIGH for this reason. 2331 * queue_depth set to DEV_HIGH for this reason.
2326 */ 2332 */
2327 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, 2333 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 *
2691 * If the peripheral qualifier filter is enabled then if the target reports a 0x1 2697 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2692 * (i.e. The targer is capable of supporting the specified peripheral device type 2698 * (i.e. The targer is capable of supporting the specified peripheral device type
2693 * on this logical unit; however, the physical device is not currently connected 2699 * on this logical unit; however, the physical device is not currently connected
2694 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not 2700 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2695 * capable of supporting a physical device on this logical unit). This is to work 2701 * capable of supporting a physical device on this logical unit). This is to work
2696 * around a bug in th emid-layer in some distributions in which the mid-layer will 2702 * around a bug in th emid-layer in some distributions in which the mid-layer will
2697 * continue to try to communicate to the LUN and evntually create a dummy LUN. 2703 * 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)
3194 /* Get a MF for this command. 3200 /* Get a MF for this command.
3195 */ 3201 */
3196 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { 3202 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3197 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", 3203 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3198 ioc->name)); 3204 ioc->name));
3199 return -EAGAIN; 3205 return -EAGAIN;
3200 } 3206 }
3201 3207
@@ -3289,7 +3295,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3289 /* Get a MF for this command. 3295 /* Get a MF for this command.
3290 */ 3296 */
3291 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { 3297 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3292 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", 3298 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3293 ioc->name)); 3299 ioc->name));
3294 return -EAGAIN; 3300 return -EAGAIN;
3295 } 3301 }
@@ -3447,7 +3453,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3447 * some type of error occurred. 3453 * some type of error occurred.
3448 */ 3454 */
3449 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr; 3455 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3450 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS) 3456 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3451 completionCode = MPT_SCANDV_GOOD; 3457 completionCode = MPT_SCANDV_GOOD;
3452 else 3458 else
3453 completionCode = MPT_SCANDV_SOME_ERROR; 3459 completionCode = MPT_SCANDV_SOME_ERROR;
@@ -3955,7 +3961,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3955 header1.PageLength = ioc->spi_data.sdp1length; 3961 header1.PageLength = ioc->spi_data.sdp1length;
3956 header1.PageNumber = 1; 3962 header1.PageNumber = 1;
3957 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 3963 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3958 cfg.hdr = &header1; 3964 cfg.cfghdr.hdr = &header1;
3959 cfg.physAddr = cfg1_dma_addr; 3965 cfg.physAddr = cfg1_dma_addr;
3960 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 3966 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3961 cfg.dir = 1; 3967 cfg.dir = 1;
@@ -3996,9 +4002,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3996 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " 4002 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
3997 "offset=0 negoFlags=%x request=%x config=%x\n", 4003 "offset=0 negoFlags=%x request=%x config=%x\n",
3998 id, flags, requested, configuration)); 4004 id, flags, requested, configuration));
3999 pcfg1Data->RequestedParameters = le32_to_cpu(requested); 4005 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
4000 pcfg1Data->Reserved = 0; 4006 pcfg1Data->Reserved = 0;
4001 pcfg1Data->Configuration = le32_to_cpu(configuration); 4007 pcfg1Data->Configuration = cpu_to_le32(configuration);
4002 cfg.pageAddr = (bus<<8) | id; 4008 cfg.pageAddr = (bus<<8) | id;
4003 mpt_config(hd->ioc, &cfg); 4009 mpt_config(hd->ioc, &cfg);
4004 } 4010 }
@@ -4353,7 +4359,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4353 /* Prep cfg structure 4359 /* Prep cfg structure
4354 */ 4360 */
4355 cfg.pageAddr = (bus<<8) | id; 4361 cfg.pageAddr = (bus<<8) | id;
4356 cfg.hdr = NULL; 4362 cfg.cfghdr.hdr = NULL;
4357 4363
4358 /* Prep SDP0 header 4364 /* Prep SDP0 header
4359 */ 4365 */
@@ -4399,7 +4405,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4399 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz); 4405 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4400 cfg1_dma_addr = dvbuf_dma + sz; 4406 cfg1_dma_addr = dvbuf_dma + sz;
4401 4407
4402 /* Skip this ID? Set cfg.hdr to force config page write 4408 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4403 */ 4409 */
4404 { 4410 {
4405 ScsiCfgData *pspi_data = &hd->ioc->spi_data; 4411 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
@@ -4417,7 +4423,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4417 4423
4418 dv.cmd = MPT_SET_MAX; 4424 dv.cmd = MPT_SET_MAX;
4419 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 4425 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4420 cfg.hdr = &header1; 4426 cfg.cfghdr.hdr = &header1;
4421 4427
4422 /* Save the final negotiated settings to 4428 /* Save the final negotiated settings to
4423 * SCSI device page 1. 4429 * SCSI device page 1.
@@ -4483,7 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4483 dv.cmd = MPT_SET_MIN; 4489 dv.cmd = MPT_SET_MIN;
4484 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 4490 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4485 4491
4486 cfg.hdr = &header1; 4492 cfg.cfghdr.hdr = &header1;
4487 cfg.physAddr = cfg1_dma_addr; 4493 cfg.physAddr = cfg1_dma_addr;
4488 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 4494 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4489 cfg.dir = 1; 4495 cfg.dir = 1;
@@ -4596,8 +4602,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4596 if ((pbuf1[56] & 0x02) == 0) { 4602 if ((pbuf1[56] & 0x02) == 0) {
4597 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; 4603 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4598 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; 4604 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4599 ddvprintk((MYIOC_s_NOTE_FMT 4605 ddvprintk((MYIOC_s_NOTE_FMT
4600 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", 4606 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4601 ioc->name, id, pbuf1[56])); 4607 ioc->name, id, pbuf1[56]));
4602 } 4608 }
4603 } 4609 }
@@ -4637,7 +4643,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4637 u32 sdp0_info; 4643 u32 sdp0_info;
4638 u32 sdp0_nego; 4644 u32 sdp0_nego;
4639 4645
4640 cfg.hdr = &header0; 4646 cfg.cfghdr.hdr = &header0;
4641 cfg.physAddr = cfg0_dma_addr; 4647 cfg.physAddr = cfg0_dma_addr;
4642 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4648 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4643 cfg.dir = 0; 4649 cfg.dir = 0;
@@ -4673,7 +4679,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4673 if (!firstPass) 4679 if (!firstPass)
4674 doFallback = 1; 4680 doFallback = 1;
4675 } else { 4681 } else {
4676 ddvprintk((MYIOC_s_NOTE_FMT 4682 ddvprintk((MYIOC_s_NOTE_FMT
4677 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); 4683 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4678 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; 4684 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4679 mptscsih_initTarget(hd, 4685 mptscsih_initTarget(hd,
@@ -4689,8 +4695,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4689 4695
4690 } else if (rc == MPT_SCANDV_ISSUE_SENSE) 4696 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4691 doFallback = 1; /* set fallback flag */ 4697 doFallback = 1; /* set fallback flag */
4692 else if ((rc == MPT_SCANDV_DID_RESET) || 4698 else if ((rc == MPT_SCANDV_DID_RESET) ||
4693 (rc == MPT_SCANDV_SENSE) || 4699 (rc == MPT_SCANDV_SENSE) ||
4694 (rc == MPT_SCANDV_FALLBACK)) 4700 (rc == MPT_SCANDV_FALLBACK))
4695 doFallback = 1; /* set fallback flag */ 4701 doFallback = 1; /* set fallback flag */
4696 else 4702 else
@@ -4722,7 +4728,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4722 * 4) release 4728 * 4) release
4723 * 5) update nego parms to target struct 4729 * 5) update nego parms to target struct
4724 */ 4730 */
4725 cfg.hdr = &header1; 4731 cfg.cfghdr.hdr = &header1;
4726 cfg.physAddr = cfg1_dma_addr; 4732 cfg.physAddr = cfg1_dma_addr;
4727 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 4733 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4728 cfg.dir = 1; 4734 cfg.dir = 1;
@@ -5121,12 +5127,12 @@ target_done:
5121 5127
5122 /* Set if cfg1_dma_addr contents is valid 5128 /* Set if cfg1_dma_addr contents is valid
5123 */ 5129 */
5124 if ((cfg.hdr != NULL) && (retcode == 0)){ 5130 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5125 /* If disk, not U320, disable QAS 5131 /* If disk, not U320, disable QAS
5126 */ 5132 */
5127 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) { 5133 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5128 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; 5134 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5129 ddvprintk((MYIOC_s_NOTE_FMT 5135 ddvprintk((MYIOC_s_NOTE_FMT
5130 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor)); 5136 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5131 } 5137 }
5132 5138
@@ -5137,7 +5143,7 @@ target_done:
5137 * skip save of the final negotiated settings to 5143 * skip save of the final negotiated settings to
5138 * SCSI device page 1. 5144 * SCSI device page 1.
5139 * 5145 *
5140 cfg.hdr = &header1; 5146 cfg.cfghdr.hdr = &header1;
5141 cfg.physAddr = cfg1_dma_addr; 5147 cfg.physAddr = cfg1_dma_addr;
5142 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 5148 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5143 cfg.dir = 1; 5149 cfg.dir = 1;
@@ -5248,7 +5254,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5248 /* Update tmax values with those from Device Page 0.*/ 5254 /* Update tmax values with those from Device Page 0.*/
5249 pPage0 = (SCSIDevicePage0_t *) pPage; 5255 pPage0 = (SCSIDevicePage0_t *) pPage;
5250 if (pPage0) { 5256 if (pPage0) {
5251 val = cpu_to_le32(pPage0->NegotiatedParameters); 5257 val = le32_to_cpu(pPage0->NegotiatedParameters);
5252 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0; 5258 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5253 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16; 5259 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5254 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8; 5260 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
@@ -5276,12 +5282,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5276 dv->now.offset, &val, &configuration, dv->now.flags); 5282 dv->now.offset, &val, &configuration, dv->now.flags);
5277 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", 5283 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5278 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); 5284 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5279 pPage1->RequestedParameters = le32_to_cpu(val); 5285 pPage1->RequestedParameters = cpu_to_le32(val);
5280 pPage1->Reserved = 0; 5286 pPage1->Reserved = 0;
5281 pPage1->Configuration = le32_to_cpu(configuration); 5287 pPage1->Configuration = cpu_to_le32(configuration);
5282 } 5288 }
5283 5289
5284 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n", 5290 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5285 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); 5291 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5286 break; 5292 break;
5287 5293
@@ -5301,9 +5307,9 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5301 offset, &val, &configuration, negoFlags); 5307 offset, &val, &configuration, negoFlags);
5302 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", 5308 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5303 id, width, factor, offset, negoFlags, val, configuration)); 5309 id, width, factor, offset, negoFlags, val, configuration));
5304 pPage1->RequestedParameters = le32_to_cpu(val); 5310 pPage1->RequestedParameters = cpu_to_le32(val);
5305 pPage1->Reserved = 0; 5311 pPage1->Reserved = 0;
5306 pPage1->Configuration = le32_to_cpu(configuration); 5312 pPage1->Configuration = cpu_to_le32(configuration);
5307 } 5313 }
5308 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n", 5314 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5309 id, width, factor, offset, val, configuration, negoFlags)); 5315 id, width, factor, offset, val, configuration, negoFlags));
@@ -5377,12 +5383,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5377 if (pPage1) { 5383 if (pPage1) {
5378 mptscsih_setDevicePage1Flags (width, factor, offset, &val, 5384 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5379 &configuration, dv->now.flags); 5385 &configuration, dv->now.flags);
5380 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n", 5386 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5381 id, width, offset, factor, dv->now.flags, val, configuration)); 5387 id, width, offset, factor, dv->now.flags, val, configuration));
5382 5388
5383 pPage1->RequestedParameters = le32_to_cpu(val); 5389 pPage1->RequestedParameters = cpu_to_le32(val);
5384 pPage1->Reserved = 0; 5390 pPage1->Reserved = 0;
5385 pPage1->Configuration = le32_to_cpu(configuration); 5391 pPage1->Configuration = cpu_to_le32(configuration);
5386 } 5392 }
5387 5393
5388 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n", 5394 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index dfa8806b1e13..587d1274fd74 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)
162 u8 *mem; 162 u8 *mem;
163 int error=0; 163 int error=0;
164 int r; 164 int r;
165 165
166 if ((r = mpt_attach(pdev,id)) != 0) 166 if ((r = mpt_attach(pdev,id)) != 0)
167 return r; 167 return r;
168 168
169 ioc = pci_get_drvdata(pdev); 169 ioc = pci_get_drvdata(pdev);
170 ioc->DoneCtx = mptspiDoneCtx; 170 ioc->DoneCtx = mptspiDoneCtx;
171 ioc->TaskCtx = mptspiTaskCtx; 171 ioc->TaskCtx = mptspiTaskCtx;
172 ioc->InternalCtx = mptspiInternalCtx; 172 ioc->InternalCtx = mptspiInternalCtx;
173 173
174 /* Added sanity check on readiness of the MPT adapter. 174 /* Added sanity check on readiness of the MPT adapter.
175 */ 175 */
176 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 176 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 12c208fb18c5..b3ae796eb624 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1,5 +1,11 @@
1menu "SCSI device support" 1menu "SCSI device support"
2 2
3config RAID_ATTRS
4 tristate "RAID Transport Class"
5 default n
6 ---help---
7 Provides RAID
8
3config SCSI 9config SCSI
4 tristate "SCSI device support" 10 tristate "SCSI device support"
5 ---help--- 11 ---help---
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 3746fb9fa2f5..85f9e6bb34b9 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -22,6 +22,8 @@ subdir-$(CONFIG_PCMCIA) += pcmcia
22 22
23obj-$(CONFIG_SCSI) += scsi_mod.o 23obj-$(CONFIG_SCSI) += scsi_mod.o
24 24
25obj-$(CONFIG_RAID_ATTRS) += raid_class.o
26
25# --- NOTE ORDERING HERE --- 27# --- NOTE ORDERING HERE ---
26# For kernel non-modular link, transport attributes need to 28# For kernel non-modular link, transport attributes need to
27# be initialised before drivers 29# be initialised before drivers
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 83bfab73ff65..a8e3dfcd0dc7 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)
972 fibsize = sizeof(struct aac_read64) + 972 fibsize = sizeof(struct aac_read64) +
973 ((le32_to_cpu(readcmd->sg.count) - 1) * 973 ((le32_to_cpu(readcmd->sg.count) - 1) *
974 sizeof (struct sgentry64)); 974 sizeof (struct sgentry64));
975 BUG_ON (fibsize > (sizeof(struct hw_fib) - 975 BUG_ON (fibsize > (dev->max_fib_size -
976 sizeof(struct aac_fibhdr))); 976 sizeof(struct aac_fibhdr)));
977 /* 977 /*
978 * Now send the Fib to the adapter 978 * Now send the Fib to the adapter
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 3feb739cd554..6b6d4e287793 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -48,12 +48,6 @@
48 48
49static struct scsi_transport_template *ahd_linux_transport_template = NULL; 49static struct scsi_transport_template *ahd_linux_transport_template = NULL;
50 50
51/*
52 * Include aiclib.c as part of our
53 * "module dependencies are hard" work around.
54 */
55#include "aiclib.c"
56
57#include <linux/init.h> /* __setup */ 51#include <linux/init.h> /* __setup */
58#include <linux/mm.h> /* For fetching system memory size */ 52#include <linux/mm.h> /* For fetching system memory size */
59#include <linux/blkdev.h> /* For block_size() */ 53#include <linux/blkdev.h> /* For block_size() */
@@ -372,8 +366,6 @@ static int ahd_linux_run_command(struct ahd_softc*,
372 struct ahd_linux_device *, 366 struct ahd_linux_device *,
373 struct scsi_cmnd *); 367 struct scsi_cmnd *);
374static void ahd_linux_setup_tag_info_global(char *p); 368static void ahd_linux_setup_tag_info_global(char *p);
375static aic_option_callback_t ahd_linux_setup_tag_info;
376static aic_option_callback_t ahd_linux_setup_iocell_info;
377static int aic79xx_setup(char *c); 369static int aic79xx_setup(char *c);
378 370
379static int ahd_linux_unit; 371static int ahd_linux_unit;
@@ -907,6 +899,86 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
907 } 899 }
908} 900}
909 901
902static char *
903ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
904 void (*callback)(u_long, int, int, int32_t),
905 u_long callback_arg)
906{
907 char *tok_end;
908 char *tok_end2;
909 int i;
910 int instance;
911 int targ;
912 int done;
913 char tok_list[] = {'.', ',', '{', '}', '\0'};
914
915 /* All options use a ':' name/arg separator */
916 if (*opt_arg != ':')
917 return (opt_arg);
918 opt_arg++;
919 instance = -1;
920 targ = -1;
921 done = FALSE;
922 /*
923 * Restore separator that may be in
924 * the middle of our option argument.
925 */
926 tok_end = strchr(opt_arg, '\0');
927 if (tok_end < end)
928 *tok_end = ',';
929 while (!done) {
930 switch (*opt_arg) {
931 case '{':
932 if (instance == -1) {
933 instance = 0;
934 } else {
935 if (depth > 1) {
936 if (targ == -1)
937 targ = 0;
938 } else {
939 printf("Malformed Option %s\n",
940 opt_name);
941 done = TRUE;
942 }
943 }
944 opt_arg++;
945 break;
946 case '}':
947 if (targ != -1)
948 targ = -1;
949 else if (instance != -1)
950 instance = -1;
951 opt_arg++;
952 break;
953 case ',':
954 case '.':
955 if (instance == -1)
956 done = TRUE;
957 else if (targ >= 0)
958 targ++;
959 else if (instance >= 0)
960 instance++;
961 opt_arg++;
962 break;
963 case '\0':
964 done = TRUE;
965 break;
966 default:
967 tok_end = end;
968 for (i = 0; tok_list[i]; i++) {
969 tok_end2 = strchr(opt_arg, tok_list[i]);
970 if ((tok_end2) && (tok_end2 < tok_end))
971 tok_end = tok_end2;
972 }
973 callback(callback_arg, instance, targ,
974 simple_strtol(opt_arg, NULL, 0));
975 opt_arg = tok_end;
976 break;
977 }
978 }
979 return (opt_arg);
980}
981
910/* 982/*
911 * Handle Linux boot parameters. This routine allows for assigning a value 983 * Handle Linux boot parameters. This routine allows for assigning a value
912 * to a parameter with a ':' between the parameter and the value. 984 * to a parameter with a ':' between the parameter and the value.
@@ -964,18 +1036,18 @@ aic79xx_setup(char *s)
964 if (strncmp(p, "global_tag_depth", n) == 0) { 1036 if (strncmp(p, "global_tag_depth", n) == 0) {
965 ahd_linux_setup_tag_info_global(p + n); 1037 ahd_linux_setup_tag_info_global(p + n);
966 } else if (strncmp(p, "tag_info", n) == 0) { 1038 } else if (strncmp(p, "tag_info", n) == 0) {
967 s = aic_parse_brace_option("tag_info", p + n, end, 1039 s = ahd_parse_brace_option("tag_info", p + n, end,
968 2, ahd_linux_setup_tag_info, 0); 1040 2, ahd_linux_setup_tag_info, 0);
969 } else if (strncmp(p, "slewrate", n) == 0) { 1041 } else if (strncmp(p, "slewrate", n) == 0) {
970 s = aic_parse_brace_option("slewrate", 1042 s = ahd_parse_brace_option("slewrate",
971 p + n, end, 1, ahd_linux_setup_iocell_info, 1043 p + n, end, 1, ahd_linux_setup_iocell_info,
972 AIC79XX_SLEWRATE_INDEX); 1044 AIC79XX_SLEWRATE_INDEX);
973 } else if (strncmp(p, "precomp", n) == 0) { 1045 } else if (strncmp(p, "precomp", n) == 0) {
974 s = aic_parse_brace_option("precomp", 1046 s = ahd_parse_brace_option("precomp",
975 p + n, end, 1, ahd_linux_setup_iocell_info, 1047 p + n, end, 1, ahd_linux_setup_iocell_info,
976 AIC79XX_PRECOMP_INDEX); 1048 AIC79XX_PRECOMP_INDEX);
977 } else if (strncmp(p, "amplitude", n) == 0) { 1049 } else if (strncmp(p, "amplitude", n) == 0) {
978 s = aic_parse_brace_option("amplitude", 1050 s = ahd_parse_brace_option("amplitude",
979 p + n, end, 1, ahd_linux_setup_iocell_info, 1051 p + n, end, 1, ahd_linux_setup_iocell_info,
980 AIC79XX_AMPLITUDE_INDEX); 1052 AIC79XX_AMPLITUDE_INDEX);
981 } else if (p[n] == ':') { 1053 } else if (p[n] == ':') {
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
index 32be1f55998c..39a27840fce6 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,
53static int ahd_proc_write_seeprom(struct ahd_softc *ahd, 53static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
54 char *buffer, int length); 54 char *buffer, int length);
55 55
56/*
57 * Table of syncrates that don't follow the "divisible by 4"
58 * rule. This table will be expanded in future SCSI specs.
59 */
60static struct {
61 u_int period_factor;
62 u_int period; /* in 100ths of ns */
63} scsi_syncrates[] = {
64 { 0x08, 625 }, /* FAST-160 */
65 { 0x09, 1250 }, /* FAST-80 */
66 { 0x0a, 2500 }, /* FAST-40 40MHz */
67 { 0x0b, 3030 }, /* FAST-40 33MHz */
68 { 0x0c, 5000 } /* FAST-20 */
69};
70
71/*
72 * Return the frequency in kHz corresponding to the given
73 * sync period factor.
74 */
75static u_int
76ahd_calc_syncsrate(u_int period_factor)
77{
78 int i;
79 int num_syncrates;
80
81 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
82 /* See if the period is in the "exception" table */
83 for (i = 0; i < num_syncrates; i++) {
84
85 if (period_factor == scsi_syncrates[i].period_factor) {
86 /* Period in kHz */
87 return (100000000 / scsi_syncrates[i].period);
88 }
89 }
90
91 /*
92 * Wasn't in the table, so use the standard
93 * 4 times conversion.
94 */
95 return (10000000 / (period_factor * 4 * 10));
96}
97
98
56static void 99static void
57copy_mem_info(struct info_str *info, char *data, int len) 100copy_mem_info(struct info_str *info, char *data, int len)
58{ 101{
@@ -109,7 +152,7 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
109 speed = 3300; 152 speed = 3300;
110 freq = 0; 153 freq = 0;
111 if (tinfo->offset != 0) { 154 if (tinfo->offset != 0) {
112 freq = aic_calc_syncsrate(tinfo->period); 155 freq = ahd_calc_syncsrate(tinfo->period);
113 speed = freq; 156 speed = freq;
114 } 157 }
115 speed *= (0x01 << tinfo->width); 158 speed *= (0x01 << tinfo->width);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 54173887e160..c932b3b94490 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -125,12 +125,6 @@
125 125
126static struct scsi_transport_template *ahc_linux_transport_template = NULL; 126static struct scsi_transport_template *ahc_linux_transport_template = NULL;
127 127
128/*
129 * Include aiclib.c as part of our
130 * "module dependencies are hard" work around.
131 */
132#include "aiclib.c"
133
134#include <linux/init.h> /* __setup */ 128#include <linux/init.h> /* __setup */
135#include <linux/mm.h> /* For fetching system memory size */ 129#include <linux/mm.h> /* For fetching system memory size */
136#include <linux/blkdev.h> /* For block_size() */ 130#include <linux/blkdev.h> /* For block_size() */
@@ -391,7 +385,6 @@ static int ahc_linux_run_command(struct ahc_softc*,
391 struct ahc_linux_device *, 385 struct ahc_linux_device *,
392 struct scsi_cmnd *); 386 struct scsi_cmnd *);
393static void ahc_linux_setup_tag_info_global(char *p); 387static void ahc_linux_setup_tag_info_global(char *p);
394static aic_option_callback_t ahc_linux_setup_tag_info;
395static int aic7xxx_setup(char *s); 388static int aic7xxx_setup(char *s);
396 389
397static int ahc_linux_unit; 390static int ahc_linux_unit;
@@ -920,6 +913,86 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
920 } 913 }
921} 914}
922 915
916static char *
917ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
918 void (*callback)(u_long, int, int, int32_t),
919 u_long callback_arg)
920{
921 char *tok_end;
922 char *tok_end2;
923 int i;
924 int instance;
925 int targ;
926 int done;
927 char tok_list[] = {'.', ',', '{', '}', '\0'};
928
929 /* All options use a ':' name/arg separator */
930 if (*opt_arg != ':')
931 return (opt_arg);
932 opt_arg++;
933 instance = -1;
934 targ = -1;
935 done = FALSE;
936 /*
937 * Restore separator that may be in
938 * the middle of our option argument.
939 */
940 tok_end = strchr(opt_arg, '\0');
941 if (tok_end < end)
942 *tok_end = ',';
943 while (!done) {
944 switch (*opt_arg) {
945 case '{':
946 if (instance == -1) {
947 instance = 0;
948 } else {
949 if (depth > 1) {
950 if (targ == -1)
951 targ = 0;
952 } else {
953 printf("Malformed Option %s\n",
954 opt_name);
955 done = TRUE;
956 }
957 }
958 opt_arg++;
959 break;
960 case '}':
961 if (targ != -1)
962 targ = -1;
963 else if (instance != -1)
964 instance = -1;
965 opt_arg++;
966 break;
967 case ',':
968 case '.':
969 if (instance == -1)
970 done = TRUE;
971 else if (targ >= 0)
972 targ++;
973 else if (instance >= 0)
974 instance++;
975 opt_arg++;
976 break;
977 case '\0':
978 done = TRUE;
979 break;
980 default:
981 tok_end = end;
982 for (i = 0; tok_list[i]; i++) {
983 tok_end2 = strchr(opt_arg, tok_list[i]);
984 if ((tok_end2) && (tok_end2 < tok_end))
985 tok_end = tok_end2;
986 }
987 callback(callback_arg, instance, targ,
988 simple_strtol(opt_arg, NULL, 0));
989 opt_arg = tok_end;
990 break;
991 }
992 }
993 return (opt_arg);
994}
995
923/* 996/*
924 * Handle Linux boot parameters. This routine allows for assigning a value 997 * Handle Linux boot parameters. This routine allows for assigning a value
925 * to a parameter with a ':' between the parameter and the value. 998 * to a parameter with a ':' between the parameter and the value.
@@ -974,7 +1047,7 @@ aic7xxx_setup(char *s)
974 if (strncmp(p, "global_tag_depth", n) == 0) { 1047 if (strncmp(p, "global_tag_depth", n) == 0) {
975 ahc_linux_setup_tag_info_global(p + n); 1048 ahc_linux_setup_tag_info_global(p + n);
976 } else if (strncmp(p, "tag_info", n) == 0) { 1049 } else if (strncmp(p, "tag_info", n) == 0) {
977 s = aic_parse_brace_option("tag_info", p + n, end, 1050 s = ahc_parse_brace_option("tag_info", p + n, end,
978 2, ahc_linux_setup_tag_info, 0); 1051 2, ahc_linux_setup_tag_info, 0);
979 } else if (p[n] == ':') { 1052 } else if (p[n] == ':') {
980 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); 1053 *(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 3802c91f0b07..04a3506cf340 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,
54static int ahc_proc_write_seeprom(struct ahc_softc *ahc, 54static int ahc_proc_write_seeprom(struct ahc_softc *ahc,
55 char *buffer, int length); 55 char *buffer, int length);
56 56
57/*
58 * Table of syncrates that don't follow the "divisible by 4"
59 * rule. This table will be expanded in future SCSI specs.
60 */
61static struct {
62 u_int period_factor;
63 u_int period; /* in 100ths of ns */
64} scsi_syncrates[] = {
65 { 0x08, 625 }, /* FAST-160 */
66 { 0x09, 1250 }, /* FAST-80 */
67 { 0x0a, 2500 }, /* FAST-40 40MHz */
68 { 0x0b, 3030 }, /* FAST-40 33MHz */
69 { 0x0c, 5000 } /* FAST-20 */
70};
71
72/*
73 * Return the frequency in kHz corresponding to the given
74 * sync period factor.
75 */
76static u_int
77ahc_calc_syncsrate(u_int period_factor)
78{
79 int i;
80 int num_syncrates;
81
82 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
83 /* See if the period is in the "exception" table */
84 for (i = 0; i < num_syncrates; i++) {
85
86 if (period_factor == scsi_syncrates[i].period_factor) {
87 /* Period in kHz */
88 return (100000000 / scsi_syncrates[i].period);
89 }
90 }
91
92 /*
93 * Wasn't in the table, so use the standard
94 * 4 times conversion.
95 */
96 return (10000000 / (period_factor * 4 * 10));
97}
98
99
57static void 100static void
58copy_mem_info(struct info_str *info, char *data, int len) 101copy_mem_info(struct info_str *info, char *data, int len)
59{ 102{
@@ -106,7 +149,7 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
106 speed = 3300; 149 speed = 3300;
107 freq = 0; 150 freq = 0;
108 if (tinfo->offset != 0) { 151 if (tinfo->offset != 0) {
109 freq = aic_calc_syncsrate(tinfo->period); 152 freq = ahc_calc_syncsrate(tinfo->period);
110 speed = freq; 153 speed = freq;
111 } 154 }
112 speed *= (0x01 << tinfo->width); 155 speed *= (0x01 << tinfo->width);
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c
index 4d44a9211185..828ae3d9a510 100644
--- a/drivers/scsi/aic7xxx/aiclib.c
+++ b/drivers/scsi/aic7xxx/aiclib.c
@@ -32,124 +32,3 @@
32 32
33#include "aiclib.h" 33#include "aiclib.h"
34 34
35
36/*
37 * Table of syncrates that don't follow the "divisible by 4"
38 * rule. This table will be expanded in future SCSI specs.
39 */
40static struct {
41 u_int period_factor;
42 u_int period; /* in 100ths of ns */
43} scsi_syncrates[] = {
44 { 0x08, 625 }, /* FAST-160 */
45 { 0x09, 1250 }, /* FAST-80 */
46 { 0x0a, 2500 }, /* FAST-40 40MHz */
47 { 0x0b, 3030 }, /* FAST-40 33MHz */
48 { 0x0c, 5000 } /* FAST-20 */
49};
50
51/*
52 * Return the frequency in kHz corresponding to the given
53 * sync period factor.
54 */
55u_int
56aic_calc_syncsrate(u_int period_factor)
57{
58 int i;
59 int num_syncrates;
60
61 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
62 /* See if the period is in the "exception" table */
63 for (i = 0; i < num_syncrates; i++) {
64
65 if (period_factor == scsi_syncrates[i].period_factor) {
66 /* Period in kHz */
67 return (100000000 / scsi_syncrates[i].period);
68 }
69 }
70
71 /*
72 * Wasn't in the table, so use the standard
73 * 4 times conversion.
74 */
75 return (10000000 / (period_factor * 4 * 10));
76}
77
78char *
79aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
80 aic_option_callback_t *callback, u_long callback_arg)
81{
82 char *tok_end;
83 char *tok_end2;
84 int i;
85 int instance;
86 int targ;
87 int done;
88 char tok_list[] = {'.', ',', '{', '}', '\0'};
89
90 /* All options use a ':' name/arg separator */
91 if (*opt_arg != ':')
92 return (opt_arg);
93 opt_arg++;
94 instance = -1;
95 targ = -1;
96 done = FALSE;
97 /*
98 * Restore separator that may be in
99 * the middle of our option argument.
100 */
101 tok_end = strchr(opt_arg, '\0');
102 if (tok_end < end)
103 *tok_end = ',';
104 while (!done) {
105 switch (*opt_arg) {
106 case '{':
107 if (instance == -1) {
108 instance = 0;
109 } else {
110 if (depth > 1) {
111 if (targ == -1)
112 targ = 0;
113 } else {
114 printf("Malformed Option %s\n",
115 opt_name);
116 done = TRUE;
117 }
118 }
119 opt_arg++;
120 break;
121 case '}':
122 if (targ != -1)
123 targ = -1;
124 else if (instance != -1)
125 instance = -1;
126 opt_arg++;
127 break;
128 case ',':
129 case '.':
130 if (instance == -1)
131 done = TRUE;
132 else if (targ >= 0)
133 targ++;
134 else if (instance >= 0)
135 instance++;
136 opt_arg++;
137 break;
138 case '\0':
139 done = TRUE;
140 break;
141 default:
142 tok_end = end;
143 for (i = 0; tok_list[i]; i++) {
144 tok_end2 = strchr(opt_arg, tok_list[i]);
145 if ((tok_end2) && (tok_end2 < tok_end))
146 tok_end = tok_end2;
147 }
148 callback(callback_arg, instance, targ,
149 simple_strtol(opt_arg, NULL, 0));
150 opt_arg = tok_end;
151 break;
152 }
153 }
154 return (opt_arg);
155}
diff --git a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
index e7d94cbaf2a8..3bfbf0fe1ec2 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)
141 return (int)capacity; 141 return (int)capacity;
142} 142}
143 143
144/**************************** Module Library Hack *****************************/
145/*
146 * What we'd like to do is have a single "scsi library" module that both the
147 * aic7xxx and aic79xx drivers could load and depend on. A cursory examination
148 * of implementing module dependencies in Linux (handling the install and
149 * initrd cases) does not look promissing. For now, we just duplicate this
150 * code in both drivers using a simple symbol renaming scheme that hides this
151 * hack from the drivers.
152 */
153#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x
154#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix)
155#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX)
156
157#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate)
158
159u_int aic_calc_syncsrate(u_int /*period_factor*/);
160
161typedef void aic_option_callback_t(u_long, int, int, int32_t);
162char * aic_parse_brace_option(char *opt_name, char *opt_arg,
163 char *end, int depth,
164 aic_option_callback_t *, u_long);
165
166static __inline uint32_t 144static __inline uint32_t
167scsi_4btoul(uint8_t *bytes) 145scsi_4btoul(uint8_t *bytes)
168{ 146{
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 8640ad1c17e2..85503fad789a 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/blkdev.h> 25#include <linux/blkdev.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/kthread.h>
27#include <linux/string.h> 28#include <linux/string.h>
28#include <linux/mm.h> 29#include <linux/mm.h>
29#include <linux/init.h> 30#include <linux/init.h>
@@ -225,15 +226,8 @@ static void scsi_host_dev_release(struct device *dev)
225 struct Scsi_Host *shost = dev_to_shost(dev); 226 struct Scsi_Host *shost = dev_to_shost(dev);
226 struct device *parent = dev->parent; 227 struct device *parent = dev->parent;
227 228
228 if (shost->ehandler) { 229 if (shost->ehandler)
229 DECLARE_COMPLETION(sem); 230 kthread_stop(shost->ehandler);
230 shost->eh_notify = &sem;
231 shost->eh_kill = 1;
232 up(shost->eh_wait);
233 wait_for_completion(&sem);
234 shost->eh_notify = NULL;
235 }
236
237 if (shost->work_q) 231 if (shost->work_q)
238 destroy_workqueue(shost->work_q); 232 destroy_workqueue(shost->work_q);
239 233
@@ -263,7 +257,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
263{ 257{
264 struct Scsi_Host *shost; 258 struct Scsi_Host *shost;
265 int gfp_mask = GFP_KERNEL, rval; 259 int gfp_mask = GFP_KERNEL, rval;
266 DECLARE_COMPLETION(complete);
267 260
268 if (sht->unchecked_isa_dma && privsize) 261 if (sht->unchecked_isa_dma && privsize)
269 gfp_mask |= __GFP_DMA; 262 gfp_mask |= __GFP_DMA;
@@ -369,12 +362,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
369 snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", 362 snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
370 shost->host_no); 363 shost->host_no);
371 364
372 shost->eh_notify = &complete; 365 shost->ehandler = kthread_run(scsi_error_handler, shost,
373 rval = kernel_thread(scsi_error_handler, shost, 0); 366 "scsi_eh_%d", shost->host_no);
374 if (rval < 0) 367 if (IS_ERR(shost->ehandler)) {
368 rval = PTR_ERR(shost->ehandler);
375 goto fail_destroy_freelist; 369 goto fail_destroy_freelist;
376 wait_for_completion(&complete); 370 }
377 shost->eh_notify = NULL;
378 371
379 scsi_proc_hostdir_add(shost->hostt); 372 scsi_proc_hostdir_add(shost->hostt);
380 return shost; 373 return shost;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index e3e6752c4104..1b911dadf64b 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -87,7 +87,7 @@ static int max_channel = 3;
87static int init_timeout = 5; 87static int init_timeout = 5;
88static int max_requests = 50; 88static int max_requests = 50;
89 89
90#define IBMVSCSI_VERSION "1.5.6" 90#define IBMVSCSI_VERSION "1.5.7"
91 91
92MODULE_DESCRIPTION("IBM Virtual SCSI"); 92MODULE_DESCRIPTION("IBM Virtual SCSI");
93MODULE_AUTHOR("Dave Boutcher"); 93MODULE_AUTHOR("Dave Boutcher");
@@ -145,6 +145,8 @@ static int initialize_event_pool(struct event_pool *pool,
145 sizeof(*evt->xfer_iu) * i; 145 sizeof(*evt->xfer_iu) * i;
146 evt->xfer_iu = pool->iu_storage + i; 146 evt->xfer_iu = pool->iu_storage + i;
147 evt->hostdata = hostdata; 147 evt->hostdata = hostdata;
148 evt->ext_list = NULL;
149 evt->ext_list_token = 0;
148 } 150 }
149 151
150 return 0; 152 return 0;
@@ -161,9 +163,16 @@ static void release_event_pool(struct event_pool *pool,
161 struct ibmvscsi_host_data *hostdata) 163 struct ibmvscsi_host_data *hostdata)
162{ 164{
163 int i, in_use = 0; 165 int i, in_use = 0;
164 for (i = 0; i < pool->size; ++i) 166 for (i = 0; i < pool->size; ++i) {
165 if (atomic_read(&pool->events[i].free) != 1) 167 if (atomic_read(&pool->events[i].free) != 1)
166 ++in_use; 168 ++in_use;
169 if (pool->events[i].ext_list) {
170 dma_free_coherent(hostdata->dev,
171 SG_ALL * sizeof(struct memory_descriptor),
172 pool->events[i].ext_list,
173 pool->events[i].ext_list_token);
174 }
175 }
167 if (in_use) 176 if (in_use)
168 printk(KERN_WARNING 177 printk(KERN_WARNING
169 "ibmvscsi: releasing event pool with %d " 178 "ibmvscsi: releasing event pool with %d "
@@ -286,24 +295,41 @@ static void set_srp_direction(struct scsi_cmnd *cmd,
286 } else { 295 } else {
287 if (cmd->sc_data_direction == DMA_TO_DEVICE) { 296 if (cmd->sc_data_direction == DMA_TO_DEVICE) {
288 srp_cmd->data_out_format = SRP_INDIRECT_BUFFER; 297 srp_cmd->data_out_format = SRP_INDIRECT_BUFFER;
289 srp_cmd->data_out_count = numbuf; 298 srp_cmd->data_out_count =
299 numbuf < MAX_INDIRECT_BUFS ?
300 numbuf: MAX_INDIRECT_BUFS;
290 } else { 301 } else {
291 srp_cmd->data_in_format = SRP_INDIRECT_BUFFER; 302 srp_cmd->data_in_format = SRP_INDIRECT_BUFFER;
292 srp_cmd->data_in_count = numbuf; 303 srp_cmd->data_in_count =
304 numbuf < MAX_INDIRECT_BUFS ?
305 numbuf: MAX_INDIRECT_BUFS;
293 } 306 }
294 } 307 }
295} 308}
296 309
310static void unmap_sg_list(int num_entries,
311 struct device *dev,
312 struct memory_descriptor *md)
313{
314 int i;
315
316 for (i = 0; i < num_entries; ++i) {
317 dma_unmap_single(dev,
318 md[i].virtual_address,
319 md[i].length, DMA_BIDIRECTIONAL);
320 }
321}
322
297/** 323/**
298 * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format 324 * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
299 * @cmd: srp_cmd whose additional_data member will be unmapped 325 * @cmd: srp_cmd whose additional_data member will be unmapped
300 * @dev: device for which the memory is mapped 326 * @dev: device for which the memory is mapped
301 * 327 *
302*/ 328*/
303static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev) 329static void unmap_cmd_data(struct srp_cmd *cmd,
330 struct srp_event_struct *evt_struct,
331 struct device *dev)
304{ 332{
305 int i;
306
307 if ((cmd->data_out_format == SRP_NO_BUFFER) && 333 if ((cmd->data_out_format == SRP_NO_BUFFER) &&
308 (cmd->data_in_format == SRP_NO_BUFFER)) 334 (cmd->data_in_format == SRP_NO_BUFFER))
309 return; 335 return;
@@ -318,15 +344,34 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev)
318 (struct indirect_descriptor *)cmd->additional_data; 344 (struct indirect_descriptor *)cmd->additional_data;
319 int num_mapped = indirect->head.length / 345 int num_mapped = indirect->head.length /
320 sizeof(indirect->list[0]); 346 sizeof(indirect->list[0]);
321 for (i = 0; i < num_mapped; ++i) { 347
322 struct memory_descriptor *data = &indirect->list[i]; 348 if (num_mapped <= MAX_INDIRECT_BUFS) {
323 dma_unmap_single(dev, 349 unmap_sg_list(num_mapped, dev, &indirect->list[0]);
324 data->virtual_address, 350 return;
325 data->length, DMA_BIDIRECTIONAL);
326 } 351 }
352
353 unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
327 } 354 }
328} 355}
329 356
357static int map_sg_list(int num_entries,
358 struct scatterlist *sg,
359 struct memory_descriptor *md)
360{
361 int i;
362 u64 total_length = 0;
363
364 for (i = 0; i < num_entries; ++i) {
365 struct memory_descriptor *descr = md + i;
366 struct scatterlist *sg_entry = &sg[i];
367 descr->virtual_address = sg_dma_address(sg_entry);
368 descr->length = sg_dma_len(sg_entry);
369 descr->memory_handle = 0;
370 total_length += sg_dma_len(sg_entry);
371 }
372 return total_length;
373}
374
330/** 375/**
331 * map_sg_data: - Maps dma for a scatterlist and initializes decriptor fields 376 * map_sg_data: - Maps dma for a scatterlist and initializes decriptor fields
332 * @cmd: Scsi_Cmnd with the scatterlist 377 * @cmd: Scsi_Cmnd with the scatterlist
@@ -337,10 +382,11 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev)
337 * Returns 1 on success. 382 * Returns 1 on success.
338*/ 383*/
339static int map_sg_data(struct scsi_cmnd *cmd, 384static int map_sg_data(struct scsi_cmnd *cmd,
385 struct srp_event_struct *evt_struct,
340 struct srp_cmd *srp_cmd, struct device *dev) 386 struct srp_cmd *srp_cmd, struct device *dev)
341{ 387{
342 388
343 int i, sg_mapped; 389 int sg_mapped;
344 u64 total_length = 0; 390 u64 total_length = 0;
345 struct scatterlist *sg = cmd->request_buffer; 391 struct scatterlist *sg = cmd->request_buffer;
346 struct memory_descriptor *data = 392 struct memory_descriptor *data =
@@ -363,27 +409,46 @@ static int map_sg_data(struct scsi_cmnd *cmd,
363 return 1; 409 return 1;
364 } 410 }
365 411
366 if (sg_mapped > MAX_INDIRECT_BUFS) { 412 if (sg_mapped > SG_ALL) {
367 printk(KERN_ERR 413 printk(KERN_ERR
368 "ibmvscsi: More than %d mapped sg entries, got %d\n", 414 "ibmvscsi: More than %d mapped sg entries, got %d\n",
369 MAX_INDIRECT_BUFS, sg_mapped); 415 SG_ALL, sg_mapped);
370 return 0; 416 return 0;
371 } 417 }
372 418
373 indirect->head.virtual_address = 0; 419 indirect->head.virtual_address = 0;
374 indirect->head.length = sg_mapped * sizeof(indirect->list[0]); 420 indirect->head.length = sg_mapped * sizeof(indirect->list[0]);
375 indirect->head.memory_handle = 0; 421 indirect->head.memory_handle = 0;
376 for (i = 0; i < sg_mapped; ++i) { 422
377 struct memory_descriptor *descr = &indirect->list[i]; 423 if (sg_mapped <= MAX_INDIRECT_BUFS) {
378 struct scatterlist *sg_entry = &sg[i]; 424 total_length = map_sg_list(sg_mapped, sg, &indirect->list[0]);
379 descr->virtual_address = sg_dma_address(sg_entry); 425 indirect->total_length = total_length;
380 descr->length = sg_dma_len(sg_entry); 426 return 1;
381 descr->memory_handle = 0;
382 total_length += sg_dma_len(sg_entry);
383 } 427 }
384 indirect->total_length = total_length;
385 428
386 return 1; 429 /* get indirect table */
430 if (!evt_struct->ext_list) {
431 evt_struct->ext_list =(struct memory_descriptor*)
432 dma_alloc_coherent(dev,
433 SG_ALL * sizeof(struct memory_descriptor),
434 &evt_struct->ext_list_token, 0);
435 if (!evt_struct->ext_list) {
436 printk(KERN_ERR
437 "ibmvscsi: Can't allocate memory for indirect table\n");
438 return 0;
439
440 }
441 }
442
443 total_length = map_sg_list(sg_mapped, sg, evt_struct->ext_list);
444
445 indirect->total_length = total_length;
446 indirect->head.virtual_address = evt_struct->ext_list_token;
447 indirect->head.length = sg_mapped * sizeof(indirect->list[0]);
448 memcpy(indirect->list, evt_struct->ext_list,
449 MAX_INDIRECT_BUFS * sizeof(struct memory_descriptor));
450
451 return 1;
387} 452}
388 453
389/** 454/**
@@ -428,6 +493,7 @@ static int map_single_data(struct scsi_cmnd *cmd,
428 * Returns 1 on success. 493 * Returns 1 on success.
429*/ 494*/
430static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, 495static int map_data_for_srp_cmd(struct scsi_cmnd *cmd,
496 struct srp_event_struct *evt_struct,
431 struct srp_cmd *srp_cmd, struct device *dev) 497 struct srp_cmd *srp_cmd, struct device *dev)
432{ 498{
433 switch (cmd->sc_data_direction) { 499 switch (cmd->sc_data_direction) {
@@ -450,7 +516,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd,
450 if (!cmd->request_buffer) 516 if (!cmd->request_buffer)
451 return 1; 517 return 1;
452 if (cmd->use_sg) 518 if (cmd->use_sg)
453 return map_sg_data(cmd, srp_cmd, dev); 519 return map_sg_data(cmd, evt_struct, srp_cmd, dev);
454 return map_single_data(cmd, srp_cmd, dev); 520 return map_single_data(cmd, srp_cmd, dev);
455} 521}
456 522
@@ -486,6 +552,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
486 printk(KERN_WARNING 552 printk(KERN_WARNING
487 "ibmvscsi: Warning, request_limit exceeded\n"); 553 "ibmvscsi: Warning, request_limit exceeded\n");
488 unmap_cmd_data(&evt_struct->iu.srp.cmd, 554 unmap_cmd_data(&evt_struct->iu.srp.cmd,
555 evt_struct,
489 hostdata->dev); 556 hostdata->dev);
490 free_event_struct(&hostdata->pool, evt_struct); 557 free_event_struct(&hostdata->pool, evt_struct);
491 return SCSI_MLQUEUE_HOST_BUSY; 558 return SCSI_MLQUEUE_HOST_BUSY;
@@ -513,7 +580,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
513 return 0; 580 return 0;
514 581
515 send_error: 582 send_error:
516 unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev); 583 unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
517 584
518 if ((cmnd = evt_struct->cmnd) != NULL) { 585 if ((cmnd = evt_struct->cmnd) != NULL) {
519 cmnd->result = DID_ERROR << 16; 586 cmnd->result = DID_ERROR << 16;
@@ -551,6 +618,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct)
551 rsp->sense_and_response_data, 618 rsp->sense_and_response_data,
552 rsp->sense_data_list_length); 619 rsp->sense_data_list_length);
553 unmap_cmd_data(&evt_struct->iu.srp.cmd, 620 unmap_cmd_data(&evt_struct->iu.srp.cmd,
621 evt_struct,
554 evt_struct->hostdata->dev); 622 evt_struct->hostdata->dev);
555 623
556 if (rsp->doover) 624 if (rsp->doover)
@@ -583,6 +651,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
583{ 651{
584 struct srp_cmd *srp_cmd; 652 struct srp_cmd *srp_cmd;
585 struct srp_event_struct *evt_struct; 653 struct srp_event_struct *evt_struct;
654 struct indirect_descriptor *indirect;
586 struct ibmvscsi_host_data *hostdata = 655 struct ibmvscsi_host_data *hostdata =
587 (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata; 656 (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata;
588 u16 lun = lun_from_dev(cmnd->device); 657 u16 lun = lun_from_dev(cmnd->device);
@@ -591,14 +660,6 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
591 if (!evt_struct) 660 if (!evt_struct)
592 return SCSI_MLQUEUE_HOST_BUSY; 661 return SCSI_MLQUEUE_HOST_BUSY;
593 662
594 init_event_struct(evt_struct,
595 handle_cmd_rsp,
596 VIOSRP_SRP_FORMAT,
597 cmnd->timeout_per_command/HZ);
598
599 evt_struct->cmnd = cmnd;
600 evt_struct->cmnd_done = done;
601
602 /* Set up the actual SRP IU */ 663 /* Set up the actual SRP IU */
603 srp_cmd = &evt_struct->iu.srp.cmd; 664 srp_cmd = &evt_struct->iu.srp.cmd;
604 memset(srp_cmd, 0x00, sizeof(*srp_cmd)); 665 memset(srp_cmd, 0x00, sizeof(*srp_cmd));
@@ -606,17 +667,25 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
606 memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); 667 memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd));
607 srp_cmd->lun = ((u64) lun) << 48; 668 srp_cmd->lun = ((u64) lun) << 48;
608 669
609 if (!map_data_for_srp_cmd(cmnd, srp_cmd, hostdata->dev)) { 670 if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
610 printk(KERN_ERR "ibmvscsi: couldn't convert cmd to srp_cmd\n"); 671 printk(KERN_ERR "ibmvscsi: couldn't convert cmd to srp_cmd\n");
611 free_event_struct(&hostdata->pool, evt_struct); 672 free_event_struct(&hostdata->pool, evt_struct);
612 return SCSI_MLQUEUE_HOST_BUSY; 673 return SCSI_MLQUEUE_HOST_BUSY;
613 } 674 }
614 675
676 init_event_struct(evt_struct,
677 handle_cmd_rsp,
678 VIOSRP_SRP_FORMAT,
679 cmnd->timeout_per_command/HZ);
680
681 evt_struct->cmnd = cmnd;
682 evt_struct->cmnd_done = done;
683
615 /* Fix up dma address of the buffer itself */ 684 /* Fix up dma address of the buffer itself */
616 if ((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) || 685 indirect = (struct indirect_descriptor *)srp_cmd->additional_data;
617 (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) { 686 if (((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) ||
618 struct indirect_descriptor *indirect = 687 (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) &&
619 (struct indirect_descriptor *)srp_cmd->additional_data; 688 (indirect->head.virtual_address == 0)) {
620 indirect->head.virtual_address = evt_struct->crq.IU_data_ptr + 689 indirect->head.virtual_address = evt_struct->crq.IU_data_ptr +
621 offsetof(struct srp_cmd, additional_data) + 690 offsetof(struct srp_cmd, additional_data) +
622 offsetof(struct indirect_descriptor, list); 691 offsetof(struct indirect_descriptor, list);
@@ -931,7 +1000,8 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
931 1000
932 cmd->result = (DID_ABORT << 16); 1001 cmd->result = (DID_ABORT << 16);
933 list_del(&found_evt->list); 1002 list_del(&found_evt->list);
934 unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev); 1003 unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt,
1004 found_evt->hostdata->dev);
935 free_event_struct(&found_evt->hostdata->pool, found_evt); 1005 free_event_struct(&found_evt->hostdata->pool, found_evt);
936 spin_unlock_irqrestore(hostdata->host->host_lock, flags); 1006 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
937 atomic_inc(&hostdata->request_limit); 1007 atomic_inc(&hostdata->request_limit);
@@ -1023,7 +1093,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
1023 if (tmp_evt->cmnd) 1093 if (tmp_evt->cmnd)
1024 tmp_evt->cmnd->result = (DID_RESET << 16); 1094 tmp_evt->cmnd->result = (DID_RESET << 16);
1025 list_del(&tmp_evt->list); 1095 list_del(&tmp_evt->list);
1026 unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt->hostdata->dev); 1096 unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt,
1097 tmp_evt->hostdata->dev);
1027 free_event_struct(&tmp_evt->hostdata->pool, 1098 free_event_struct(&tmp_evt->hostdata->pool,
1028 tmp_evt); 1099 tmp_evt);
1029 atomic_inc(&hostdata->request_limit); 1100 atomic_inc(&hostdata->request_limit);
@@ -1052,6 +1123,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata)
1052 if (tmp_evt->cmnd) { 1123 if (tmp_evt->cmnd) {
1053 tmp_evt->cmnd->result = (DID_ERROR << 16); 1124 tmp_evt->cmnd->result = (DID_ERROR << 16);
1054 unmap_cmd_data(&tmp_evt->iu.srp.cmd, 1125 unmap_cmd_data(&tmp_evt->iu.srp.cmd,
1126 tmp_evt,
1055 tmp_evt->hostdata->dev); 1127 tmp_evt->hostdata->dev);
1056 if (tmp_evt->cmnd_done) 1128 if (tmp_evt->cmnd_done)
1057 tmp_evt->cmnd_done(tmp_evt->cmnd); 1129 tmp_evt->cmnd_done(tmp_evt->cmnd);
@@ -1356,7 +1428,7 @@ static struct scsi_host_template driver_template = {
1356 .cmd_per_lun = 16, 1428 .cmd_per_lun = 16,
1357 .can_queue = 1, /* Updated after SRP_LOGIN */ 1429 .can_queue = 1, /* Updated after SRP_LOGIN */
1358 .this_id = -1, 1430 .this_id = -1,
1359 .sg_tablesize = MAX_INDIRECT_BUFS, 1431 .sg_tablesize = SG_ALL,
1360 .use_clustering = ENABLE_CLUSTERING, 1432 .use_clustering = ENABLE_CLUSTERING,
1361 .shost_attrs = ibmvscsi_attrs, 1433 .shost_attrs = ibmvscsi_attrs,
1362}; 1434};
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 1030b703c30e..8bec0438dc8a 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -68,6 +68,8 @@ struct srp_event_struct {
68 void (*cmnd_done) (struct scsi_cmnd *); 68 void (*cmnd_done) (struct scsi_cmnd *);
69 struct completion comp; 69 struct completion comp;
70 union viosrp_iu *sync_srp; 70 union viosrp_iu *sync_srp;
71 struct memory_descriptor *ext_list;
72 dma_addr_t ext_list_token;
71}; 73};
72 74
73/* a pool of event structs for use */ 75/* a pool of event structs for use */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 659a5d63467d..fe0fce71adc7 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)
211 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); 211 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
212} 212}
213 213
214/* Scsi_Host attributes. */
215
216static ssize_t
217qla2x00_drvr_version_show(struct class_device *cdev, char *buf)
218{
219 return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
220}
221
222static ssize_t
223qla2x00_fw_version_show(struct class_device *cdev, char *buf)
224{
225 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
226 char fw_str[30];
227
228 return snprintf(buf, PAGE_SIZE, "%s\n",
229 ha->isp_ops.fw_version_str(ha, fw_str));
230}
231
232static ssize_t
233qla2x00_serial_num_show(struct class_device *cdev, char *buf)
234{
235 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
236 uint32_t sn;
237
238 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
239 return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
240 sn % 100000);
241}
242
243static ssize_t
244qla2x00_isp_name_show(struct class_device *cdev, char *buf)
245{
246 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
247 return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
248}
249
250static ssize_t
251qla2x00_isp_id_show(struct class_device *cdev, char *buf)
252{
253 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
254 return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
255 ha->product_id[0], ha->product_id[1], ha->product_id[2],
256 ha->product_id[3]);
257}
258
259static ssize_t
260qla2x00_model_name_show(struct class_device *cdev, char *buf)
261{
262 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
263 return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);
264}
265
266static ssize_t
267qla2x00_model_desc_show(struct class_device *cdev, char *buf)
268{
269 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
270 return snprintf(buf, PAGE_SIZE, "%s\n",
271 ha->model_desc ? ha->model_desc: "");
272}
273
274static ssize_t
275qla2x00_pci_info_show(struct class_device *cdev, char *buf)
276{
277 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
278 char pci_info[30];
279
280 return snprintf(buf, PAGE_SIZE, "%s\n",
281 ha->isp_ops.pci_info_str(ha, pci_info));
282}
283
284static ssize_t
285qla2x00_state_show(struct class_device *cdev, char *buf)
286{
287 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
288 int len = 0;
289
290 if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
291 atomic_read(&ha->loop_state) == LOOP_DEAD)
292 len = snprintf(buf, PAGE_SIZE, "Link Down\n");
293 else if (atomic_read(&ha->loop_state) != LOOP_READY ||
294 test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
295 test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))
296 len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
297 else {
298 len = snprintf(buf, PAGE_SIZE, "Link Up - ");
299
300 switch (ha->current_topology) {
301 case ISP_CFG_NL:
302 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
303 break;
304 case ISP_CFG_FL:
305 len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
306 break;
307 case ISP_CFG_N:
308 len += snprintf(buf + len, PAGE_SIZE-len,
309 "N_Port to N_Port\n");
310 break;
311 case ISP_CFG_F:
312 len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
313 break;
314 default:
315 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
316 break;
317 }
318 }
319 return len;
320}
321
322static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
323 NULL);
324static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
325static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
326static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
327static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);
328static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
329static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
330static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
331static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
332
333struct class_device_attribute *qla2x00_host_attrs[] = {
334 &class_device_attr_driver_version,
335 &class_device_attr_fw_version,
336 &class_device_attr_serial_num,
337 &class_device_attr_isp_name,
338 &class_device_attr_isp_id,
339 &class_device_attr_model_name,
340 &class_device_attr_model_desc,
341 &class_device_attr_pci_info,
342 &class_device_attr_state,
343 NULL,
344};
345
214/* Host attributes. */ 346/* Host attributes. */
215 347
216static void 348static void
@@ -304,10 +436,13 @@ struct fc_function_template qla2xxx_transport_functions = {
304 436
305 .show_host_node_name = 1, 437 .show_host_node_name = 1,
306 .show_host_port_name = 1, 438 .show_host_port_name = 1,
439 .show_host_supported_classes = 1,
440
307 .get_host_port_id = qla2x00_get_host_port_id, 441 .get_host_port_id = qla2x00_get_host_port_id,
308 .show_host_port_id = 1, 442 .show_host_port_id = 1,
309 443
310 .dd_fcrport_size = sizeof(struct fc_port *), 444 .dd_fcrport_size = sizeof(struct fc_port *),
445 .show_rport_supported_classes = 1,
311 446
312 .get_starget_node_name = qla2x00_get_starget_node_name, 447 .get_starget_node_name = qla2x00_get_starget_node_name,
313 .show_starget_node_name = 1, 448 .show_starget_node_name = 1,
@@ -329,4 +464,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha)
329 be64_to_cpu(*(uint64_t *)ha->init_cb->node_name); 464 be64_to_cpu(*(uint64_t *)ha->init_cb->node_name);
330 fc_host_port_name(ha->host) = 465 fc_host_port_name(ha->host) =
331 be64_to_cpu(*(uint64_t *)ha->init_cb->port_name); 466 be64_to_cpu(*(uint64_t *)ha->init_cb->port_name);
467 fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
332} 468}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index b8d90e97e017..9684e7a91fa9 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -81,6 +81,7 @@
81#define DEBUG2_3_11(x) do {x;} while (0); 81#define DEBUG2_3_11(x) do {x;} while (0);
82#define DEBUG2_9_10(x) do {x;} while (0); 82#define DEBUG2_9_10(x) do {x;} while (0);
83#define DEBUG2_11(x) do {x;} while (0); 83#define DEBUG2_11(x) do {x;} while (0);
84#define DEBUG2_13(x) do {x;} while (0);
84#else 85#else
85#define DEBUG2(x) do {} while (0); 86#define DEBUG2(x) do {} while (0);
86#endif 87#endif
@@ -169,8 +170,14 @@
169 170
170#if defined(QL_DEBUG_LEVEL_13) 171#if defined(QL_DEBUG_LEVEL_13)
171#define DEBUG13(x) do {x;} while (0) 172#define DEBUG13(x) do {x;} while (0)
173#if !defined(DEBUG2_13)
174#define DEBUG2_13(x) do {x;} while(0)
175#endif
172#else 176#else
173#define DEBUG13(x) do {} while (0) 177#define DEBUG13(x) do {} while (0)
178#if !defined(QL_DEBUG_LEVEL_2)
179#define DEBUG2_13(x) do {} while(0)
180#endif
174#endif 181#endif
175 182
176#if defined(QL_DEBUG_LEVEL_14) 183#if defined(QL_DEBUG_LEVEL_14)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 1c6d366f4fad..b455c31405e4 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -214,6 +214,7 @@
214 * valid range of an N-PORT id is 0 through 0x7ef. 214 * valid range of an N-PORT id is 0 through 0x7ef.
215 */ 215 */
216#define NPH_LAST_HANDLE 0x7ef 216#define NPH_LAST_HANDLE 0x7ef
217#define NPH_MGMT_SERVER 0x7fa /* FFFFFA */
217#define NPH_SNS 0x7fc /* FFFFFC */ 218#define NPH_SNS 0x7fc /* FFFFFC */
218#define NPH_FABRIC_CONTROLLER 0x7fd /* FFFFFD */ 219#define NPH_FABRIC_CONTROLLER 0x7fd /* FFFFFD */
219#define NPH_F_PORT 0x7fe /* FFFFFE */ 220#define NPH_F_PORT 0x7fe /* FFFFFE */
@@ -630,6 +631,7 @@ typedef struct {
630#define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */ 631#define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */
631#define MBC_READ_RAM_EXTENDED 0xf /* Read RAM extended. */ 632#define MBC_READ_RAM_EXTENDED 0xf /* Read RAM extended. */
632#define MBC_IOCB_COMMAND 0x12 /* Execute IOCB command. */ 633#define MBC_IOCB_COMMAND 0x12 /* Execute IOCB command. */
634#define MBC_STOP_FIRMWARE 0x14 /* Stop firmware. */
633#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */ 635#define MBC_ABORT_COMMAND 0x15 /* Abort IOCB command. */
634#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */ 636#define MBC_ABORT_DEVICE 0x16 /* Abort device (ID/LUN). */
635#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */ 637#define MBC_ABORT_TARGET 0x17 /* Abort target (ID). */
@@ -913,7 +915,7 @@ typedef struct {
913 * MSB BIT 1 = 915 * MSB BIT 1 =
914 * MSB BIT 2 = 916 * MSB BIT 2 =
915 * MSB BIT 3 = 917 * MSB BIT 3 =
916 * MSB BIT 4 = 918 * MSB BIT 4 = LED mode
917 * MSB BIT 5 = enable 50 ohm termination 919 * MSB BIT 5 = enable 50 ohm termination
918 * MSB BIT 6 = Data Rate (2300 only) 920 * MSB BIT 6 = Data Rate (2300 only)
919 * MSB BIT 7 = Data Rate (2300 only) 921 * MSB BIT 7 = Data Rate (2300 only)
@@ -1035,7 +1037,7 @@ typedef struct {
1035 * MSB BIT 1 = 1037 * MSB BIT 1 =
1036 * MSB BIT 2 = 1038 * MSB BIT 2 =
1037 * MSB BIT 3 = 1039 * MSB BIT 3 =
1038 * MSB BIT 4 = 1040 * MSB BIT 4 = LED mode
1039 * MSB BIT 5 = enable 50 ohm termination 1041 * MSB BIT 5 = enable 50 ohm termination
1040 * MSB BIT 6 = Data Rate (2300 only) 1042 * MSB BIT 6 = Data Rate (2300 only)
1041 * MSB BIT 7 = Data Rate (2300 only) 1043 * MSB BIT 7 = Data Rate (2300 only)
@@ -1131,10 +1133,7 @@ typedef struct {
1131 1133
1132 uint8_t link_down_timeout; 1134 uint8_t link_down_timeout;
1133 1135
1134 uint8_t adapter_id_0[4]; 1136 uint8_t adapter_id[16];
1135 uint8_t adapter_id_1[4];
1136 uint8_t adapter_id_2[4];
1137 uint8_t adapter_id_3[4];
1138 1137
1139 uint8_t alt1_boot_node_name[WWN_SIZE]; 1138 uint8_t alt1_boot_node_name[WWN_SIZE];
1140 uint16_t alt1_boot_lun_number; 1139 uint16_t alt1_boot_lun_number;
@@ -1673,6 +1672,7 @@ typedef struct fc_port {
1673 uint8_t cur_path; /* current path id */ 1672 uint8_t cur_path; /* current path id */
1674 1673
1675 struct fc_rport *rport; 1674 struct fc_rport *rport;
1675 u32 supported_classes;
1676} fc_port_t; 1676} fc_port_t;
1677 1677
1678/* 1678/*
@@ -1727,6 +1727,8 @@ typedef struct fc_port {
1727 1727
1728#define CT_REJECT_RESPONSE 0x8001 1728#define CT_REJECT_RESPONSE 0x8001
1729#define CT_ACCEPT_RESPONSE 0x8002 1729#define CT_ACCEPT_RESPONSE 0x8002
1730#define CT_REASON_CANNOT_PERFORM 0x09
1731#define CT_EXPL_ALREADY_REGISTERED 0x10
1730 1732
1731#define NS_N_PORT_TYPE 0x01 1733#define NS_N_PORT_TYPE 0x01
1732#define NS_NL_PORT_TYPE 0x02 1734#define NS_NL_PORT_TYPE 0x02
@@ -1768,6 +1770,100 @@ typedef struct fc_port {
1768#define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) 1770#define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
1769#define RSNN_NN_RSP_SIZE 16 1771#define RSNN_NN_RSP_SIZE 16
1770 1772
1773/*
1774 * HBA attribute types.
1775 */
1776#define FDMI_HBA_ATTR_COUNT 9
1777#define FDMI_HBA_NODE_NAME 1
1778#define FDMI_HBA_MANUFACTURER 2
1779#define FDMI_HBA_SERIAL_NUMBER 3
1780#define FDMI_HBA_MODEL 4
1781#define FDMI_HBA_MODEL_DESCRIPTION 5
1782#define FDMI_HBA_HARDWARE_VERSION 6
1783#define FDMI_HBA_DRIVER_VERSION 7
1784#define FDMI_HBA_OPTION_ROM_VERSION 8
1785#define FDMI_HBA_FIRMWARE_VERSION 9
1786#define FDMI_HBA_OS_NAME_AND_VERSION 0xa
1787#define FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH 0xb
1788
1789struct ct_fdmi_hba_attr {
1790 uint16_t type;
1791 uint16_t len;
1792 union {
1793 uint8_t node_name[WWN_SIZE];
1794 uint8_t manufacturer[32];
1795 uint8_t serial_num[8];
1796 uint8_t model[16];
1797 uint8_t model_desc[80];
1798 uint8_t hw_version[16];
1799 uint8_t driver_version[32];
1800 uint8_t orom_version[16];
1801 uint8_t fw_version[16];
1802 uint8_t os_version[128];
1803 uint8_t max_ct_len[4];
1804 } a;
1805};
1806
1807struct ct_fdmi_hba_attributes {
1808 uint32_t count;
1809 struct ct_fdmi_hba_attr entry[FDMI_HBA_ATTR_COUNT];
1810};
1811
1812/*
1813 * Port attribute types.
1814 */
1815#define FDMI_PORT_ATTR_COUNT 5
1816#define FDMI_PORT_FC4_TYPES 1
1817#define FDMI_PORT_SUPPORT_SPEED 2
1818#define FDMI_PORT_CURRENT_SPEED 3
1819#define FDMI_PORT_MAX_FRAME_SIZE 4
1820#define FDMI_PORT_OS_DEVICE_NAME 5
1821#define FDMI_PORT_HOST_NAME 6
1822
1823struct ct_fdmi_port_attr {
1824 uint16_t type;
1825 uint16_t len;
1826 union {
1827 uint8_t fc4_types[32];
1828 uint32_t sup_speed;
1829 uint32_t cur_speed;
1830 uint32_t max_frame_size;
1831 uint8_t os_dev_name[32];
1832 uint8_t host_name[32];
1833 } a;
1834};
1835
1836/*
1837 * Port Attribute Block.
1838 */
1839struct ct_fdmi_port_attributes {
1840 uint32_t count;
1841 struct ct_fdmi_port_attr entry[FDMI_PORT_ATTR_COUNT];
1842};
1843
1844/* FDMI definitions. */
1845#define GRHL_CMD 0x100
1846#define GHAT_CMD 0x101
1847#define GRPL_CMD 0x102
1848#define GPAT_CMD 0x110
1849
1850#define RHBA_CMD 0x200
1851#define RHBA_RSP_SIZE 16
1852
1853#define RHAT_CMD 0x201
1854#define RPRT_CMD 0x210
1855
1856#define RPA_CMD 0x211
1857#define RPA_RSP_SIZE 16
1858
1859#define DHBA_CMD 0x300
1860#define DHBA_REQ_SIZE (16 + 8)
1861#define DHBA_RSP_SIZE 16
1862
1863#define DHAT_CMD 0x301
1864#define DPRT_CMD 0x310
1865#define DPA_CMD 0x311
1866
1771/* CT command header -- request/response common fields */ 1867/* CT command header -- request/response common fields */
1772struct ct_cmd_hdr { 1868struct ct_cmd_hdr {
1773 uint8_t revision; 1869 uint8_t revision;
@@ -1825,6 +1921,43 @@ struct ct_sns_req {
1825 uint8_t name_len; 1921 uint8_t name_len;
1826 uint8_t sym_node_name[255]; 1922 uint8_t sym_node_name[255];
1827 } rsnn_nn; 1923 } rsnn_nn;
1924
1925 struct {
1926 uint8_t hba_indentifier[8];
1927 } ghat;
1928
1929 struct {
1930 uint8_t hba_identifier[8];
1931 uint32_t entry_count;
1932 uint8_t port_name[8];
1933 struct ct_fdmi_hba_attributes attrs;
1934 } rhba;
1935
1936 struct {
1937 uint8_t hba_identifier[8];
1938 struct ct_fdmi_hba_attributes attrs;
1939 } rhat;
1940
1941 struct {
1942 uint8_t port_name[8];
1943 struct ct_fdmi_port_attributes attrs;
1944 } rpa;
1945
1946 struct {
1947 uint8_t port_name[8];
1948 } dhba;
1949
1950 struct {
1951 uint8_t port_name[8];
1952 } dhat;
1953
1954 struct {
1955 uint8_t port_name[8];
1956 } dprt;
1957
1958 struct {
1959 uint8_t port_name[8];
1960 } dpa;
1828 } req; 1961 } req;
1829}; 1962};
1830 1963
@@ -1882,6 +2015,12 @@ struct ct_sns_rsp {
1882 struct { 2015 struct {
1883 uint8_t fc4_types[32]; 2016 uint8_t fc4_types[32];
1884 } gft_id; 2017 } gft_id;
2018
2019 struct {
2020 uint32_t entry_count;
2021 uint8_t port_name[8];
2022 struct ct_fdmi_hba_attributes attrs;
2023 } ghat;
1885 } rsp; 2024 } rsp;
1886}; 2025};
1887 2026
@@ -2032,6 +2171,8 @@ struct isp_operations {
2032 uint16_t (*calc_req_entries) (uint16_t); 2171 uint16_t (*calc_req_entries) (uint16_t);
2033 void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t); 2172 void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
2034 void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t); 2173 void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t);
2174 void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
2175 uint32_t);
2035 2176
2036 uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *, 2177 uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *,
2037 uint32_t, uint32_t); 2178 uint32_t, uint32_t);
@@ -2111,6 +2252,7 @@ typedef struct scsi_qla_host {
2111#define IOCTL_ERROR_RECOVERY 23 2252#define IOCTL_ERROR_RECOVERY 23
2112#define LOOP_RESET_NEEDED 24 2253#define LOOP_RESET_NEEDED 24
2113#define BEACON_BLINK_NEEDED 25 2254#define BEACON_BLINK_NEEDED 25
2255#define REGISTER_FDMI_NEEDED 26
2114 2256
2115 uint32_t device_flags; 2257 uint32_t device_flags;
2116#define DFLG_LOCAL_DEVICES BIT_0 2258#define DFLG_LOCAL_DEVICES BIT_0
@@ -2204,6 +2346,7 @@ typedef struct scsi_qla_host {
2204 int port_down_retry_count; 2346 int port_down_retry_count;
2205 uint8_t mbx_count; 2347 uint8_t mbx_count;
2206 uint16_t last_loop_id; 2348 uint16_t last_loop_id;
2349 uint16_t mgmt_svr_loop_id;
2207 2350
2208 uint32_t login_retry_count; 2351 uint32_t login_retry_count;
2209 2352
@@ -2318,6 +2461,7 @@ typedef struct scsi_qla_host {
2318 uint8_t model_number[16+1]; 2461 uint8_t model_number[16+1];
2319#define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 2462#define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
2320 char *model_desc; 2463 char *model_desc;
2464 uint8_t adapter_id[16+1];
2321 2465
2322 uint8_t *node_name; 2466 uint8_t *node_name;
2323 uint8_t *port_name; 2467 uint8_t *port_name;
@@ -2377,6 +2521,7 @@ typedef struct scsi_qla_host {
2377#define QLA_SUSPENDED 0x106 2521#define QLA_SUSPENDED 0x106
2378#define QLA_BUSY 0x107 2522#define QLA_BUSY 0x107
2379#define QLA_RSCNS_HANDLED 0x108 2523#define QLA_RSCNS_HANDLED 0x108
2524#define QLA_ALREADY_REGISTERED 0x109
2380 2525
2381/* 2526/*
2382* Stat info for all adpaters 2527* Stat info for all adpaters
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 665c203e0675..1ed32e7b5472 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -79,6 +79,7 @@ extern int ql2xplogiabsentdevice;
79extern int ql2xenablezio; 79extern int ql2xenablezio;
80extern int ql2xintrdelaytimer; 80extern int ql2xintrdelaytimer;
81extern int ql2xloginretrycount; 81extern int ql2xloginretrycount;
82extern int ql2xfdmienable;
82 83
83extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); 84extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
84 85
@@ -147,9 +148,6 @@ qla2x00_abort_target(fc_port_t *);
147#endif 148#endif
148 149
149extern int 150extern int
150qla2x00_target_reset(scsi_qla_host_t *, struct fc_port *);
151
152extern int
153qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, 151qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
154 uint8_t *, uint16_t *); 152 uint8_t *, uint16_t *);
155 153
@@ -215,6 +213,9 @@ qla2x00_get_serdes_params(scsi_qla_host_t *, uint16_t *, uint16_t *,
215extern int 213extern int
216qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); 214qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
217 215
216extern int
217qla2x00_stop_firmware(scsi_qla_host_t *);
218
218/* 219/*
219 * Global Function Prototypes in qla_isr.c source file. 220 * Global Function Prototypes in qla_isr.c source file.
220 */ 221 */
@@ -269,6 +270,9 @@ extern int qla2x00_rft_id(scsi_qla_host_t *);
269extern int qla2x00_rff_id(scsi_qla_host_t *); 270extern int qla2x00_rff_id(scsi_qla_host_t *);
270extern int qla2x00_rnn_id(scsi_qla_host_t *); 271extern int qla2x00_rnn_id(scsi_qla_host_t *);
271extern int qla2x00_rsnn_nn(scsi_qla_host_t *); 272extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
273extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
274extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
275extern int qla2x00_fdmi_register(scsi_qla_host_t *);
272 276
273/* 277/*
274 * Global Function Prototypes in qla_rscn.c source file. 278 * Global Function Prototypes in qla_rscn.c source file.
@@ -289,6 +293,8 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *);
289/* 293/*
290 * Global Function Prototypes in qla_attr.c source file. 294 * Global Function Prototypes in qla_attr.c source file.
291 */ 295 */
296struct class_device_attribute;
297extern struct class_device_attribute *qla2x00_host_attrs[];
292struct fc_function_template; 298struct fc_function_template;
293extern struct fc_function_template qla2xxx_transport_functions; 299extern struct fc_function_template qla2xxx_transport_functions;
294extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); 300extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 31ce4f62da13..e7b138c2e339 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)
1099 1099
1100 return (rval); 1100 return (rval);
1101} 1101}
1102
1103/**
1104 * qla2x00_mgmt_svr_login() - Login to fabric Managment Service.
1105 * @ha: HA context
1106 *
1107 * Returns 0 on success.
1108 */
1109static int
1110qla2x00_mgmt_svr_login(scsi_qla_host_t *ha)
1111{
1112 int ret;
1113 uint16_t mb[MAILBOX_REGISTER_COUNT];
1114
1115 ret = QLA_SUCCESS;
1116 if (ha->flags.management_server_logged_in)
1117 return ret;
1118
1119 ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
1120 mb, BIT_1);
1121 if (mb[0] != MBS_COMMAND_COMPLETE) {
1122 DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: "
1123 "loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x\n",
1124 __func__, ha->host_no, ha->mgmt_svr_loop_id, mb[0], mb[1],
1125 mb[2], mb[6], mb[7]));
1126 ret = QLA_FUNCTION_FAILED;
1127 } else
1128 ha->flags.management_server_logged_in = 1;
1129
1130 return ret;
1131}
1132
1133/**
1134 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1135 * @ha: HA context
1136 * @req_size: request size in bytes
1137 * @rsp_size: response size in bytes
1138 *
1139 * Returns a pointer to the @ha's ms_iocb.
1140 */
1141void *
1142qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
1143 uint32_t rsp_size)
1144{
1145 ms_iocb_entry_t *ms_pkt;
1146
1147 ms_pkt = ha->ms_iocb;
1148 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
1149
1150 ms_pkt->entry_type = MS_IOCB_TYPE;
1151 ms_pkt->entry_count = 1;
1152 SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id);
1153 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
1154 ms_pkt->timeout = __constant_cpu_to_le16(59);
1155 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1156 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
1157 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
1158 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1159
1160 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1161 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1162 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1163
1164 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1165 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1166 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
1167
1168 return ms_pkt;
1169}
1170
1171/**
1172 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
1173 * @ha: HA context
1174 * @req_size: request size in bytes
1175 * @rsp_size: response size in bytes
1176 *
1177 * Returns a pointer to the @ha's ms_iocb.
1178 */
1179void *
1180qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
1181 uint32_t rsp_size)
1182{
1183 struct ct_entry_24xx *ct_pkt;
1184
1185 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1186 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1187
1188 ct_pkt->entry_type = CT_IOCB_TYPE;
1189 ct_pkt->entry_count = 1;
1190 ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
1191 ct_pkt->timeout = __constant_cpu_to_le16(59);
1192 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1193 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1194 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1195 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1196
1197 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1198 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1199 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1200
1201 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1202 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1203 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1204
1205 return ct_pkt;
1206}
1207
1208static inline ms_iocb_entry_t *
1209qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size)
1210{
1211 ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
1212 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1213
1214 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1215 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1216 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1217 } else {
1218 ms_pkt->req_bytecount = cpu_to_le32(req_size);
1219 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
1220 }
1221
1222 return ms_pkt;
1223}
1224
1225/**
1226 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
1227 * @ct_req: CT request buffer
1228 * @cmd: GS command
1229 * @rsp_size: response size in bytes
1230 *
1231 * Returns a pointer to the intitialized @ct_req.
1232 */
1233static inline struct ct_sns_req *
1234qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
1235 uint16_t rsp_size)
1236{
1237 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1238
1239 ct_req->header.revision = 0x01;
1240 ct_req->header.gs_type = 0xFA;
1241 ct_req->header.gs_subtype = 0x10;
1242 ct_req->command = cpu_to_be16(cmd);
1243 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1244
1245 return ct_req;
1246}
1247
1248/**
1249 * qla2x00_fdmi_rhba() -
1250 * @ha: HA context
1251 *
1252 * Returns 0 on success.
1253 */
1254static int
1255qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
1256{
1257 int rval, alen;
1258 uint32_t size, sn;
1259
1260 ms_iocb_entry_t *ms_pkt;
1261 struct ct_sns_req *ct_req;
1262 struct ct_sns_rsp *ct_rsp;
1263 uint8_t *entries;
1264 struct ct_fdmi_hba_attr *eiter;
1265
1266 /* Issue RHBA */
1267 /* Prepare common MS IOCB */
1268 /* Request size adjusted after CT preparation */
1269 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
1270
1271 /* Prepare CT request */
1272 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
1273 RHBA_RSP_SIZE);
1274 ct_rsp = &ha->ct_sns->p.rsp;
1275
1276 /* Prepare FDMI command arguments -- attribute block, attributes. */
1277 memcpy(ct_req->req.rhba.hba_identifier, ha->port_name, WWN_SIZE);
1278 ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1);
1279 memcpy(ct_req->req.rhba.port_name, ha->port_name, WWN_SIZE);
1280 size = 2 * WWN_SIZE + 4 + 4;
1281
1282 /* Attributes */
1283 ct_req->req.rhba.attrs.count =
1284 __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT);
1285 entries = ct_req->req.rhba.hba_identifier;
1286
1287 /* Nodename. */
1288 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1289 eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME);
1290 eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE);
1291 memcpy(eiter->a.node_name, ha->node_name, WWN_SIZE);
1292 size += 4 + WWN_SIZE;
1293
1294 DEBUG13(printk("%s(%ld): NODENAME=%02x%02x%02x%02x%02x%02x%02x%02x.\n",
1295 __func__, ha->host_no,
1296 eiter->a.node_name[0], eiter->a.node_name[1], eiter->a.node_name[2],
1297 eiter->a.node_name[3], eiter->a.node_name[4], eiter->a.node_name[5],
1298 eiter->a.node_name[6], eiter->a.node_name[7]));
1299
1300 /* Manufacturer. */
1301 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1302 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER);
1303 strcpy(eiter->a.manufacturer, "QLogic Corporation");
1304 alen = strlen(eiter->a.manufacturer);
1305 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1306 eiter->len = cpu_to_be16(4 + alen);
1307 size += 4 + alen;
1308
1309 DEBUG13(printk("%s(%ld): MANUFACTURER=%s.\n", __func__, ha->host_no,
1310 eiter->a.manufacturer));
1311
1312 /* Serial number. */
1313 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1314 eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
1315 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
1316 sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000);
1317 alen = strlen(eiter->a.serial_num);
1318 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1319 eiter->len = cpu_to_be16(4 + alen);
1320 size += 4 + alen;
1321
1322 DEBUG13(printk("%s(%ld): SERIALNO=%s.\n", __func__, ha->host_no,
1323 eiter->a.serial_num));
1324
1325 /* Model name. */
1326 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1327 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL);
1328 strcpy(eiter->a.model, ha->model_number);
1329 alen = strlen(eiter->a.model);
1330 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1331 eiter->len = cpu_to_be16(4 + alen);
1332 size += 4 + alen;
1333
1334 DEBUG13(printk("%s(%ld): MODEL_NAME=%s.\n", __func__, ha->host_no,
1335 eiter->a.model));
1336
1337 /* Model description. */
1338 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1339 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
1340 if (ha->model_desc)
1341 strncpy(eiter->a.model_desc, ha->model_desc, 80);
1342 alen = strlen(eiter->a.model_desc);
1343 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1344 eiter->len = cpu_to_be16(4 + alen);
1345 size += 4 + alen;
1346
1347 DEBUG13(printk("%s(%ld): MODEL_DESC=%s.\n", __func__, ha->host_no,
1348 eiter->a.model_desc));
1349
1350 /* Hardware version. */
1351 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1352 eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
1353 strcpy(eiter->a.hw_version, ha->adapter_id);
1354 alen = strlen(eiter->a.hw_version);
1355 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1356 eiter->len = cpu_to_be16(4 + alen);
1357 size += 4 + alen;
1358
1359 DEBUG13(printk("%s(%ld): HARDWAREVER=%s.\n", __func__, ha->host_no,
1360 eiter->a.hw_version));
1361
1362 /* Driver version. */
1363 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1364 eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
1365 strcpy(eiter->a.driver_version, qla2x00_version_str);
1366 alen = strlen(eiter->a.driver_version);
1367 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1368 eiter->len = cpu_to_be16(4 + alen);
1369 size += 4 + alen;
1370
1371 DEBUG13(printk("%s(%ld): DRIVERVER=%s.\n", __func__, ha->host_no,
1372 eiter->a.driver_version));
1373
1374 /* Option ROM version. */
1375 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1376 eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
1377 strcpy(eiter->a.orom_version, "0.00");
1378 alen = strlen(eiter->a.orom_version);
1379 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1380 eiter->len = cpu_to_be16(4 + alen);
1381 size += 4 + alen;
1382
1383 DEBUG13(printk("%s(%ld): OPTROMVER=%s.\n", __func__, ha->host_no,
1384 eiter->a.orom_version));
1385
1386 /* Firmware version */
1387 eiter = (struct ct_fdmi_hba_attr *) (entries + size);
1388 eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
1389 ha->isp_ops.fw_version_str(ha, eiter->a.fw_version);
1390 alen = strlen(eiter->a.fw_version);
1391 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1392 eiter->len = cpu_to_be16(4 + alen);
1393 size += 4 + alen;
1394
1395 DEBUG13(printk("%s(%ld): FIRMWAREVER=%s.\n", __func__, ha->host_no,
1396 eiter->a.fw_version));
1397
1398 /* Update MS request size. */
1399 qla2x00_update_ms_fdmi_iocb(ha, size + 16);
1400
1401 DEBUG13(printk("%s(%ld): RHBA identifier="
1402 "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__,
1403 ha->host_no, ct_req->req.rhba.hba_identifier[0],
1404 ct_req->req.rhba.hba_identifier[1],
1405 ct_req->req.rhba.hba_identifier[2],
1406 ct_req->req.rhba.hba_identifier[3],
1407 ct_req->req.rhba.hba_identifier[4],
1408 ct_req->req.rhba.hba_identifier[5],
1409 ct_req->req.rhba.hba_identifier[6],
1410 ct_req->req.rhba.hba_identifier[7], size));
1411 DEBUG13(qla2x00_dump_buffer(entries, size));
1412
1413 /* Execute MS IOCB */
1414 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
1415 sizeof(ms_iocb_entry_t));
1416 if (rval != QLA_SUCCESS) {
1417 /*EMPTY*/
1418 DEBUG2_3(printk("scsi(%ld): RHBA issue IOCB failed (%d).\n",
1419 ha->host_no, rval));
1420 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RHBA") !=
1421 QLA_SUCCESS) {
1422 rval = QLA_FUNCTION_FAILED;
1423 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
1424 ct_rsp->header.explanation_code ==
1425 CT_EXPL_ALREADY_REGISTERED) {
1426 DEBUG2_13(printk("%s(%ld): HBA already registered.\n",
1427 __func__, ha->host_no));
1428 rval = QLA_ALREADY_REGISTERED;
1429 }
1430 } else {
1431 DEBUG2(printk("scsi(%ld): RHBA exiting normally.\n",
1432 ha->host_no));
1433 }
1434
1435 return rval;
1436}
1437
1438/**
1439 * qla2x00_fdmi_dhba() -
1440 * @ha: HA context
1441 *
1442 * Returns 0 on success.
1443 */
1444static int
1445qla2x00_fdmi_dhba(scsi_qla_host_t *ha)
1446{
1447 int rval;
1448
1449 ms_iocb_entry_t *ms_pkt;
1450 struct ct_sns_req *ct_req;
1451 struct ct_sns_rsp *ct_rsp;
1452
1453 /* Issue RPA */
1454 /* Prepare common MS IOCB */
1455 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
1456 DHBA_RSP_SIZE);
1457
1458 /* Prepare CT request */
1459 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
1460 DHBA_RSP_SIZE);
1461 ct_rsp = &ha->ct_sns->p.rsp;
1462
1463 /* Prepare FDMI command arguments -- portname. */
1464 memcpy(ct_req->req.dhba.port_name, ha->port_name, WWN_SIZE);
1465
1466 DEBUG13(printk("%s(%ld): DHBA portname="
1467 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", __func__, ha->host_no,
1468 ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1],
1469 ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3],
1470 ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5],
1471 ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]));
1472
1473 /* Execute MS IOCB */
1474 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
1475 sizeof(ms_iocb_entry_t));
1476 if (rval != QLA_SUCCESS) {
1477 /*EMPTY*/
1478 DEBUG2_3(printk("scsi(%ld): DHBA issue IOCB failed (%d).\n",
1479 ha->host_no, rval));
1480 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "DHBA") !=
1481 QLA_SUCCESS) {
1482 rval = QLA_FUNCTION_FAILED;
1483 } else {
1484 DEBUG2(printk("scsi(%ld): DHBA exiting normally.\n",
1485 ha->host_no));
1486 }
1487
1488 return rval;
1489}
1490
1491/**
1492 * qla2x00_fdmi_rpa() -
1493 * @ha: HA context
1494 *
1495 * Returns 0 on success.
1496 */
1497static int
1498qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
1499{
1500 int rval, alen;
1501 uint32_t size, max_frame_size;
1502
1503 ms_iocb_entry_t *ms_pkt;
1504 struct ct_sns_req *ct_req;
1505 struct ct_sns_rsp *ct_rsp;
1506 uint8_t *entries;
1507 struct ct_fdmi_port_attr *eiter;
1508 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
1509
1510 /* Issue RPA */
1511 /* Prepare common MS IOCB */
1512 /* Request size adjusted after CT preparation */
1513 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
1514
1515 /* Prepare CT request */
1516 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
1517 RPA_RSP_SIZE);
1518 ct_rsp = &ha->ct_sns->p.rsp;
1519
1520 /* Prepare FDMI command arguments -- attribute block, attributes. */
1521 memcpy(ct_req->req.rpa.port_name, ha->port_name, WWN_SIZE);
1522 size = WWN_SIZE + 4;
1523
1524 /* Attributes */
1525 ct_req->req.rpa.attrs.count =
1526 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
1527 entries = ct_req->req.rpa.port_name;
1528
1529 /* FC4 types. */
1530 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1531 eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES);
1532 eiter->len = __constant_cpu_to_be16(4 + 32);
1533 eiter->a.fc4_types[2] = 0x01;
1534 size += 4 + 32;
1535
1536 DEBUG13(printk("%s(%ld): FC4_TYPES=%02x %02x.\n", __func__, ha->host_no,
1537 eiter->a.fc4_types[2], eiter->a.fc4_types[1]));
1538
1539 /* Supported speed. */
1540 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1541 eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
1542 eiter->len = __constant_cpu_to_be16(4 + 4);
1543 if (IS_QLA25XX(ha))
1544 eiter->a.sup_speed = __constant_cpu_to_be32(4);
1545 else if (IS_QLA24XX(ha))
1546 eiter->a.sup_speed = __constant_cpu_to_be32(8);
1547 else if (IS_QLA23XX(ha))
1548 eiter->a.sup_speed = __constant_cpu_to_be32(2);
1549 else
1550 eiter->a.sup_speed = __constant_cpu_to_be32(1);
1551 size += 4 + 4;
1552
1553 DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no,
1554 eiter->a.sup_speed));
1555
1556 /* Current speed. */
1557 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1558 eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
1559 eiter->len = __constant_cpu_to_be16(4 + 4);
1560 switch (ha->link_data_rate) {
1561 case 0:
1562 eiter->a.cur_speed = __constant_cpu_to_be32(1);
1563 break;
1564 case 1:
1565 eiter->a.cur_speed = __constant_cpu_to_be32(2);
1566 break;
1567 case 3:
1568 eiter->a.cur_speed = __constant_cpu_to_be32(8);
1569 break;
1570 case 4:
1571 eiter->a.cur_speed = __constant_cpu_to_be32(4);
1572 break;
1573 }
1574 size += 4 + 4;
1575
1576 DEBUG13(printk("%s(%ld): CURRENT_SPEED=%x.\n", __func__, ha->host_no,
1577 eiter->a.cur_speed));
1578
1579 /* Max frame size. */
1580 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1581 eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
1582 eiter->len = __constant_cpu_to_be16(4 + 4);
1583 max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
1584 (uint32_t) icb24->frame_payload_size:
1585 (uint32_t) ha->init_cb->frame_payload_size;
1586 eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
1587 size += 4 + 4;
1588
1589 DEBUG13(printk("%s(%ld): MAX_FRAME_SIZE=%x.\n", __func__, ha->host_no,
1590 eiter->a.max_frame_size));
1591
1592 /* OS device name. */
1593 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1594 eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
1595 sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no);
1596 alen = strlen(eiter->a.os_dev_name);
1597 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1598 eiter->len = cpu_to_be16(4 + alen);
1599 size += 4 + alen;
1600
1601 DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
1602 eiter->a.os_dev_name));
1603
1604 /* Update MS request size. */
1605 qla2x00_update_ms_fdmi_iocb(ha, size + 16);
1606
1607 DEBUG13(printk("%s(%ld): RPA portname="
1608 "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__,
1609 ha->host_no, ct_req->req.rpa.port_name[0],
1610 ct_req->req.rpa.port_name[1], ct_req->req.rpa.port_name[2],
1611 ct_req->req.rpa.port_name[3], ct_req->req.rpa.port_name[4],
1612 ct_req->req.rpa.port_name[5], ct_req->req.rpa.port_name[6],
1613 ct_req->req.rpa.port_name[7], size));
1614 DEBUG13(qla2x00_dump_buffer(entries, size));
1615
1616 /* Execute MS IOCB */
1617 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
1618 sizeof(ms_iocb_entry_t));
1619 if (rval != QLA_SUCCESS) {
1620 /*EMPTY*/
1621 DEBUG2_3(printk("scsi(%ld): RPA issue IOCB failed (%d).\n",
1622 ha->host_no, rval));
1623 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RPA") !=
1624 QLA_SUCCESS) {
1625 rval = QLA_FUNCTION_FAILED;
1626 } else {
1627 DEBUG2(printk("scsi(%ld): RPA exiting normally.\n",
1628 ha->host_no));
1629 }
1630
1631 return rval;
1632}
1633
1634/**
1635 * qla2x00_fdmi_register() -
1636 * @ha: HA context
1637 *
1638 * Returns 0 on success.
1639 */
1640int
1641qla2x00_fdmi_register(scsi_qla_host_t *ha)
1642{
1643 int rval;
1644
1645 rval = qla2x00_mgmt_svr_login(ha);
1646 if (rval)
1647 return rval;
1648
1649 rval = qla2x00_fdmi_rhba(ha);
1650 if (rval) {
1651 if (rval != QLA_ALREADY_REGISTERED)
1652 return rval;
1653
1654 rval = qla2x00_fdmi_dhba(ha);
1655 if (rval)
1656 return rval;
1657
1658 rval = qla2x00_fdmi_rhba(ha);
1659 if (rval)
1660 return rval;
1661 }
1662 rval = qla2x00_fdmi_rpa(ha);
1663
1664 return rval;
1665}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a6d2559217cd..c619583e646b 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)
88 ha->mbx_flags = 0; 88 ha->mbx_flags = 0;
89 ha->isp_abort_cnt = 0; 89 ha->isp_abort_cnt = 0;
90 ha->beacon_blink_led = 0; 90 ha->beacon_blink_led = 0;
91 set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
91 92
92 qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); 93 qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
93 rval = ha->isp_ops.pci_config(ha); 94 rval = ha->isp_ops.pci_config(ha);
@@ -1563,7 +1564,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1563 ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0); 1564 ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0);
1564 ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); 1565 ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);
1565 ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); 1566 ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);
1566 ha->flags.enable_led_scheme = ((nv->efi_parameters & BIT_3) ? 1 : 0); 1567 ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0;
1567 1568
1568 ha->operating_mode = 1569 ha->operating_mode =
1569 (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; 1570 (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;
@@ -1697,6 +1698,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags)
1697 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; 1698 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
1698 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1699 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1699 fcport->flags = FCF_RLC_SUPPORT; 1700 fcport->flags = FCF_RLC_SUPPORT;
1701 fcport->supported_classes = FC_COS_UNSPECIFIED;
1700 1702
1701 return (fcport); 1703 return (fcport);
1702} 1704}
@@ -1898,7 +1900,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
1898 continue; 1900 continue;
1899 1901
1900 /* Bypass if not same domain and area of adapter. */ 1902 /* Bypass if not same domain and area of adapter. */
1901 if (area != ha->d_id.b.area || domain != ha->d_id.b.domain) 1903 if (area && domain &&
1904 (area != ha->d_id.b.area || domain != ha->d_id.b.domain))
1902 continue; 1905 continue;
1903 1906
1904 /* Bypass invalid local loop ID. */ 1907 /* Bypass invalid local loop ID. */
@@ -2075,6 +2078,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2075 return; 2078 return;
2076 } 2079 }
2077 rport->dd_data = fcport; 2080 rport->dd_data = fcport;
2081 rport->supported_classes = fcport->supported_classes;
2078 2082
2079 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2083 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
2080 if (fcport->port_type == FCT_INITIATOR) 2084 if (fcport->port_type == FCT_INITIATOR)
@@ -2130,6 +2134,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2130 return (QLA_SUCCESS); 2134 return (QLA_SUCCESS);
2131 } 2135 }
2132 do { 2136 do {
2137 /* FDMI support. */
2138 if (ql2xfdmienable &&
2139 test_and_clear_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags))
2140 qla2x00_fdmi_register(ha);
2141
2133 /* Ensure we are logged into the SNS. */ 2142 /* Ensure we are logged into the SNS. */
2134 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 2143 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
2135 loop_id = NPH_SNS; 2144 loop_id = NPH_SNS;
@@ -2392,6 +2401,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2392 if (new_fcport->d_id.b24 == ha->d_id.b24) 2401 if (new_fcport->d_id.b24 == ha->d_id.b24)
2393 continue; 2402 continue;
2394 2403
2404 /* Bypass if same domain and area of adapter. */
2405 if (((new_fcport->d_id.b24 & 0xffff00) ==
2406 (ha->d_id.b24 & 0xffff00)) && ha->current_topology ==
2407 ISP_CFG_FL)
2408 continue;
2409
2395 /* Bypass reserved domain fields. */ 2410 /* Bypass reserved domain fields. */
2396 if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0) 2411 if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0)
2397 continue; 2412 continue;
@@ -2794,6 +2809,11 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2794 } 2809 }
2795 } 2810 }
2796 2811
2812 if (mb[10] & BIT_0)
2813 fcport->supported_classes |= FC_COS_CLASS2;
2814 if (mb[10] & BIT_1)
2815 fcport->supported_classes |= FC_COS_CLASS3;
2816
2797 rval = QLA_SUCCESS; 2817 rval = QLA_SUCCESS;
2798 break; 2818 break;
2799 } else if (mb[0] == MBS_LOOP_ID_USED) { 2819 } else if (mb[0] == MBS_LOOP_ID_USED) {
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ebdc3c54d155..37f82e2cd7fb 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)
810 ha->req_q_cnt = ha->request_q_length - 810 ha->req_q_cnt = ha->request_q_length -
811 (ha->req_ring_index - cnt); 811 (ha->req_ring_index - cnt);
812 } 812 }
813 if (ha->req_q_cnt < (req_cnt + 2)) { 813 if (ha->req_q_cnt < (req_cnt + 2))
814 if (cmd->use_sg)
815 pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
816 cmd->sc_data_direction);
817 goto queuing_error; 814 goto queuing_error;
818 }
819 815
820 /* Build command packet. */ 816 /* Build command packet. */
821 ha->current_outstanding_cmd = handle; 817 ha->current_outstanding_cmd = handle;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f910de6dd437..c255bb0268a9 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)
451 451
452 ha->flags.management_server_logged_in = 0; 452 ha->flags.management_server_logged_in = 0;
453 ha->link_data_rate = 0; 453 ha->link_data_rate = 0;
454 if (ql2xfdmienable)
455 set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
454 456
455 /* Update AEN queue. */ 457 /* Update AEN queue. */
456 qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL); 458 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 409ea0ac4032..13e1c9047079 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -19,6 +19,7 @@
19#include "qla_def.h" 19#include "qla_def.h"
20 20
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <scsi/scsi_transport_fc.h>
22 23
23static void 24static void
24qla2x00_mbx_sem_timeout(unsigned long data) 25qla2x00_mbx_sem_timeout(unsigned long data)
@@ -251,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
251 mb0 = RD_REG_WORD(&reg->isp24.mailbox0); 252 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
252 ictrl = RD_REG_DWORD(&reg->isp24.ictrl); 253 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
253 } else { 254 } else {
254 mb0 = RD_MAILBOX_REG(ha, reg->isp, 0); 255 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
255 ictrl = RD_REG_WORD(&reg->isp.ictrl); 256 ictrl = RD_REG_WORD(&reg->isp.ictrl);
256 } 257 }
257 printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n", 258 printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n",
@@ -983,58 +984,6 @@ qla2x00_abort_target(fc_port_t *fcport)
983#endif 984#endif
984 985
985/* 986/*
986 * qla2x00_target_reset
987 * Issue target reset mailbox command.
988 *
989 * Input:
990 * ha = adapter block pointer.
991 * TARGET_QUEUE_LOCK must be released.
992 * ADAPTER_STATE_LOCK must be released.
993 *
994 * Returns:
995 * qla2x00 local function return status code.
996 *
997 * Context:
998 * Kernel context.
999 */
1000int
1001qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport)
1002{
1003 int rval;
1004 mbx_cmd_t mc;
1005 mbx_cmd_t *mcp = &mc;
1006
1007 DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);)
1008
1009 if (atomic_read(&fcport->state) != FCS_ONLINE)
1010 return 0;
1011
1012 mcp->mb[0] = MBC_TARGET_RESET;
1013 if (HAS_EXTENDED_IDS(ha))
1014 mcp->mb[1] = fcport->loop_id;
1015 else
1016 mcp->mb[1] = fcport->loop_id << 8;
1017 mcp->mb[2] = ha->loop_reset_delay;
1018 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1019 mcp->in_mb = MBX_0;
1020 mcp->tov = 30;
1021 mcp->flags = 0;
1022 rval = qla2x00_mailbox_command(ha, mcp);
1023
1024 if (rval != QLA_SUCCESS) {
1025 /*EMPTY*/
1026 DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n",
1027 ha->host_no, rval);)
1028 } else {
1029 /*EMPTY*/
1030 DEBUG11(printk("qla2x00_target_reset(%ld): done.\n",
1031 ha->host_no);)
1032 }
1033
1034 return rval;
1035}
1036
1037/*
1038 * qla2x00_get_adapter_id 987 * qla2x00_get_adapter_id
1039 * Get adapter ID and topology. 988 * Get adapter ID and topology.
1040 * 989 *
@@ -1326,6 +1275,10 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
1326 fcport->port_type = FCT_INITIATOR; 1275 fcport->port_type = FCT_INITIATOR;
1327 else 1276 else
1328 fcport->port_type = FCT_TARGET; 1277 fcport->port_type = FCT_TARGET;
1278
1279 /* Passback COS information. */
1280 fcport->supported_classes = (pd->options & BIT_4) ?
1281 FC_COS_CLASS2: FC_COS_CLASS3;
1329 } 1282 }
1330 1283
1331gpd_error_out: 1284gpd_error_out:
@@ -1661,6 +1614,13 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1661 mb[1] |= BIT_1; 1614 mb[1] |= BIT_1;
1662 } else 1615 } else
1663 mb[1] = BIT_0; 1616 mb[1] = BIT_0;
1617
1618 /* Passback COS information. */
1619 mb[10] = 0;
1620 if (lg->io_parameter[7] || lg->io_parameter[8])
1621 mb[10] |= BIT_0; /* Class 2. */
1622 if (lg->io_parameter[9] || lg->io_parameter[10])
1623 mb[10] |= BIT_1; /* Class 3. */
1664 } 1624 }
1665 1625
1666 dma_pool_free(ha->s_dma_pool, lg, lg_dma); 1626 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
@@ -1723,6 +1683,8 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1723 mb[2] = mcp->mb[2]; 1683 mb[2] = mcp->mb[2];
1724 mb[6] = mcp->mb[6]; 1684 mb[6] = mcp->mb[6];
1725 mb[7] = mcp->mb[7]; 1685 mb[7] = mcp->mb[7];
1686 /* COS retrieved from Get-Port-Database mailbox command. */
1687 mb[10] = 0;
1726 } 1688 }
1727 1689
1728 if (rval != QLA_SUCCESS) { 1690 if (rval != QLA_SUCCESS) {
@@ -2465,3 +2427,32 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
2465 2427
2466 return rval; 2428 return rval;
2467} 2429}
2430
2431int
2432qla2x00_stop_firmware(scsi_qla_host_t *ha)
2433{
2434 int rval;
2435 mbx_cmd_t mc;
2436 mbx_cmd_t *mcp = &mc;
2437
2438 if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
2439 return QLA_FUNCTION_FAILED;
2440
2441 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
2442
2443 mcp->mb[0] = MBC_STOP_FIRMWARE;
2444 mcp->out_mb = MBX_0;
2445 mcp->in_mb = MBX_0;
2446 mcp->tov = 5;
2447 mcp->flags = 0;
2448 rval = qla2x00_mailbox_command(ha, mcp);
2449
2450 if (rval != QLA_SUCCESS) {
2451 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
2452 ha->host_no, rval));
2453 } else {
2454 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
2455 }
2456
2457 return rval;
2458}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9000659bfbcf..8982978c42fd 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);
79MODULE_PARM_DESC(ql2xloginretrycount, 79MODULE_PARM_DESC(ql2xloginretrycount,
80 "Specify an alternate value for the NVRAM login retry count."); 80 "Specify an alternate value for the NVRAM login retry count.");
81 81
82int ql2xfwloadbin; 82int ql2xfwloadbin=1;
83module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR); 83module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
84MODULE_PARM_DESC(ql2xfwloadbin, 84MODULE_PARM_DESC(ql2xfwloadbin,
85 "Load ISP2xxx firmware image via hotplug."); 85 "Load ISP2xxx firmware image via hotplug.");
@@ -88,6 +88,12 @@ static void qla2x00_free_device(scsi_qla_host_t *);
88 88
89static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); 89static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
90 90
91int ql2xfdmienable;
92module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
93MODULE_PARM_DESC(ql2xfdmienable,
94 "Enables FDMI registratons "
95 "Default is 0 - no FDMI. 1 - perfom FDMI.");
96
91/* 97/*
92 * SCSI host template entry points 98 * SCSI host template entry points
93 */ 99 */
@@ -105,6 +111,9 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
105static int qla2x00_loop_reset(scsi_qla_host_t *ha); 111static int qla2x00_loop_reset(scsi_qla_host_t *ha);
106static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); 112static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
107 113
114static int qla2x00_change_queue_depth(struct scsi_device *, int);
115static int qla2x00_change_queue_type(struct scsi_device *, int);
116
108static struct scsi_host_template qla2x00_driver_template = { 117static struct scsi_host_template qla2x00_driver_template = {
109 .module = THIS_MODULE, 118 .module = THIS_MODULE,
110 .name = "qla2xxx", 119 .name = "qla2xxx",
@@ -119,6 +128,8 @@ static struct scsi_host_template qla2x00_driver_template = {
119 128
120 .slave_alloc = qla2xxx_slave_alloc, 129 .slave_alloc = qla2xxx_slave_alloc,
121 .slave_destroy = qla2xxx_slave_destroy, 130 .slave_destroy = qla2xxx_slave_destroy,
131 .change_queue_depth = qla2x00_change_queue_depth,
132 .change_queue_type = qla2x00_change_queue_type,
122 .this_id = -1, 133 .this_id = -1,
123 .cmd_per_lun = 3, 134 .cmd_per_lun = 3,
124 .use_clustering = ENABLE_CLUSTERING, 135 .use_clustering = ENABLE_CLUSTERING,
@@ -129,6 +140,7 @@ static struct scsi_host_template qla2x00_driver_template = {
129 * which equates to 0x800000 sectors. 140 * which equates to 0x800000 sectors.
130 */ 141 */
131 .max_sectors = 0xFFFF, 142 .max_sectors = 0xFFFF,
143 .shost_attrs = qla2x00_host_attrs,
132}; 144};
133 145
134static struct scsi_host_template qla24xx_driver_template = { 146static struct scsi_host_template qla24xx_driver_template = {
@@ -145,12 +157,15 @@ static struct scsi_host_template qla24xx_driver_template = {
145 157
146 .slave_alloc = qla2xxx_slave_alloc, 158 .slave_alloc = qla2xxx_slave_alloc,
147 .slave_destroy = qla2xxx_slave_destroy, 159 .slave_destroy = qla2xxx_slave_destroy,
160 .change_queue_depth = qla2x00_change_queue_depth,
161 .change_queue_type = qla2x00_change_queue_type,
148 .this_id = -1, 162 .this_id = -1,
149 .cmd_per_lun = 3, 163 .cmd_per_lun = 3,
150 .use_clustering = ENABLE_CLUSTERING, 164 .use_clustering = ENABLE_CLUSTERING,
151 .sg_tablesize = SG_ALL, 165 .sg_tablesize = SG_ALL,
152 166
153 .max_sectors = 0xFFFF, 167 .max_sectors = 0xFFFF,
168 .shost_attrs = qla2x00_host_attrs,
154}; 169};
155 170
156static struct scsi_transport_template *qla2xxx_transport_template = NULL; 171static struct scsi_transport_template *qla2xxx_transport_template = NULL;
@@ -487,14 +502,13 @@ qc24_fail_command:
487static int 502static int
488qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) 503qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd)
489{ 504{
490#define ABORT_POLLING_PERIOD HZ 505#define ABORT_POLLING_PERIOD 1000
491#define ABORT_WAIT_ITER ((10 * HZ) / (ABORT_POLLING_PERIOD)) 506#define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD))
492 unsigned long wait_iter = ABORT_WAIT_ITER; 507 unsigned long wait_iter = ABORT_WAIT_ITER;
493 int ret = QLA_SUCCESS; 508 int ret = QLA_SUCCESS;
494 509
495 while (CMD_SP(cmd)) { 510 while (CMD_SP(cmd)) {
496 set_current_state(TASK_UNINTERRUPTIBLE); 511 msleep(ABORT_POLLING_PERIOD);
497 schedule_timeout(ABORT_POLLING_PERIOD);
498 512
499 if (--wait_iter) 513 if (--wait_iter)
500 break; 514 break;
@@ -1016,7 +1030,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
1016 if (fcport->port_type != FCT_TARGET) 1030 if (fcport->port_type != FCT_TARGET)
1017 continue; 1031 continue;
1018 1032
1019 status = qla2x00_target_reset(ha, fcport); 1033 status = qla2x00_device_reset(ha, fcport);
1020 if (status != QLA_SUCCESS) 1034 if (status != QLA_SUCCESS)
1021 break; 1035 break;
1022 } 1036 }
@@ -1103,6 +1117,28 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
1103 sdev->hostdata = NULL; 1117 sdev->hostdata = NULL;
1104} 1118}
1105 1119
1120static int
1121qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
1122{
1123 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
1124 return sdev->queue_depth;
1125}
1126
1127static int
1128qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
1129{
1130 if (sdev->tagged_supported) {
1131 scsi_set_tag_type(sdev, tag_type);
1132 if (tag_type)
1133 scsi_activate_tcq(sdev, sdev->queue_depth);
1134 else
1135 scsi_deactivate_tcq(sdev, sdev->queue_depth);
1136 } else
1137 tag_type = 0;
1138
1139 return tag_type;
1140}
1141
1106/** 1142/**
1107 * qla2x00_config_dma_addressing() - Configure OS DMA addressing method. 1143 * qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
1108 * @ha: HA context 1144 * @ha: HA context
@@ -1113,36 +1149,23 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
1113static void 1149static void
1114qla2x00_config_dma_addressing(scsi_qla_host_t *ha) 1150qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
1115{ 1151{
1116 /* Assume 32bit DMA address */ 1152 /* Assume a 32bit DMA mask. */
1117 ha->flags.enable_64bit_addressing = 0; 1153 ha->flags.enable_64bit_addressing = 0;
1118 1154
1119 /* 1155 if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) {
1120 * Given the two variants pci_set_dma_mask(), allow the compiler to 1156 /* Any upper-dword bits set? */
1121 * assist in setting the proper dma mask. 1157 if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
1122 */ 1158 !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
1123 if (sizeof(dma_addr_t) > 4) { 1159 /* Ok, a 64bit DMA mask is applicable. */
1124 if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {
1125 ha->flags.enable_64bit_addressing = 1; 1160 ha->flags.enable_64bit_addressing = 1;
1126 ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64; 1161 ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64;
1127 ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64; 1162 ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64;
1128 1163 return;
1129 if (pci_set_consistent_dma_mask(ha->pdev,
1130 DMA_64BIT_MASK)) {
1131 qla_printk(KERN_DEBUG, ha,
1132 "Failed to set 64 bit PCI consistent mask; "
1133 "using 32 bit.\n");
1134 pci_set_consistent_dma_mask(ha->pdev,
1135 DMA_32BIT_MASK);
1136 }
1137 } else {
1138 qla_printk(KERN_DEBUG, ha,
1139 "Failed to set 64 bit PCI DMA mask, falling back "
1140 "to 32 bit MASK.\n");
1141 pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
1142 } 1164 }
1143 } else {
1144 pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
1145 } 1165 }
1166
1167 dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK);
1168 pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
1146} 1169}
1147 1170
1148static int 1171static int
@@ -1316,6 +1339,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1316 ha->prev_topology = 0; 1339 ha->prev_topology = 0;
1317 ha->ports = MAX_BUSES; 1340 ha->ports = MAX_BUSES;
1318 ha->init_cb_size = sizeof(init_cb_t); 1341 ha->init_cb_size = sizeof(init_cb_t);
1342 ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
1319 1343
1320 /* Assign ISP specific operations. */ 1344 /* Assign ISP specific operations. */
1321 ha->isp_ops.pci_config = qla2100_pci_config; 1345 ha->isp_ops.pci_config = qla2100_pci_config;
@@ -1338,6 +1362,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1338 ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_32; 1362 ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_32;
1339 ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_32; 1363 ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_32;
1340 ha->isp_ops.prep_ms_iocb = qla2x00_prep_ms_iocb; 1364 ha->isp_ops.prep_ms_iocb = qla2x00_prep_ms_iocb;
1365 ha->isp_ops.prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb;
1341 ha->isp_ops.read_nvram = qla2x00_read_nvram_data; 1366 ha->isp_ops.read_nvram = qla2x00_read_nvram_data;
1342 ha->isp_ops.write_nvram = qla2x00_write_nvram_data; 1367 ha->isp_ops.write_nvram = qla2x00_write_nvram_data;
1343 ha->isp_ops.fw_dump = qla2100_fw_dump; 1368 ha->isp_ops.fw_dump = qla2100_fw_dump;
@@ -1375,6 +1400,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1375 ha->response_q_length = RESPONSE_ENTRY_CNT_2300; 1400 ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
1376 ha->last_loop_id = SNS_LAST_LOOP_ID_2300; 1401 ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
1377 ha->init_cb_size = sizeof(struct init_cb_24xx); 1402 ha->init_cb_size = sizeof(struct init_cb_24xx);
1403 ha->mgmt_svr_loop_id = 10;
1378 ha->isp_ops.pci_config = qla24xx_pci_config; 1404 ha->isp_ops.pci_config = qla24xx_pci_config;
1379 ha->isp_ops.reset_chip = qla24xx_reset_chip; 1405 ha->isp_ops.reset_chip = qla24xx_reset_chip;
1380 ha->isp_ops.chip_diag = qla24xx_chip_diag; 1406 ha->isp_ops.chip_diag = qla24xx_chip_diag;
@@ -1395,6 +1421,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1395 ha->isp_ops.fabric_login = qla24xx_login_fabric; 1421 ha->isp_ops.fabric_login = qla24xx_login_fabric;
1396 ha->isp_ops.fabric_logout = qla24xx_fabric_logout; 1422 ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
1397 ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb; 1423 ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
1424 ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb;
1398 ha->isp_ops.read_nvram = qla24xx_read_nvram_data; 1425 ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
1399 ha->isp_ops.write_nvram = qla24xx_write_nvram_data; 1426 ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
1400 ha->isp_ops.fw_dump = qla24xx_fw_dump; 1427 ha->isp_ops.fw_dump = qla24xx_fw_dump;
@@ -1558,8 +1585,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1558 return 0; 1585 return 0;
1559 1586
1560probe_failed: 1587probe_failed:
1561 fc_remove_host(ha->host);
1562
1563 qla2x00_free_device(ha); 1588 qla2x00_free_device(ha);
1564 1589
1565 scsi_host_put(host); 1590 scsi_host_put(host);
@@ -1601,10 +1626,6 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1601 if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) 1626 if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
1602 qla2x00_cancel_io_descriptors(ha); 1627 qla2x00_cancel_io_descriptors(ha);
1603 1628
1604 /* turn-off interrupts on the card */
1605 if (ha->interrupts_on)
1606 ha->isp_ops.disable_intrs(ha);
1607
1608 /* Disable timer */ 1629 /* Disable timer */
1609 if (ha->timer_active) 1630 if (ha->timer_active)
1610 qla2x00_stop_timer(ha); 1631 qla2x00_stop_timer(ha);
@@ -1624,8 +1645,14 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1624 } 1645 }
1625 } 1646 }
1626 1647
1627 qla2x00_mem_free(ha); 1648 /* Stop currently executing firmware. */
1649 qla2x00_stop_firmware(ha);
1650
1651 /* turn-off interrupts on the card */
1652 if (ha->interrupts_on)
1653 ha->isp_ops.disable_intrs(ha);
1628 1654
1655 qla2x00_mem_free(ha);
1629 1656
1630 ha->flags.online = 0; 1657 ha->flags.online = 0;
1631 1658
@@ -1934,7 +1961,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
1934{ 1961{
1935 struct list_head *fcpl, *fcptemp; 1962 struct list_head *fcpl, *fcptemp;
1936 fc_port_t *fcport; 1963 fc_port_t *fcport;
1937 unsigned long wtime;/* max wait time if mbx cmd is busy. */ 1964 unsigned int wtime;/* max wait time if mbx cmd is busy. */
1938 1965
1939 if (ha == NULL) { 1966 if (ha == NULL) {
1940 /* error */ 1967 /* error */
@@ -1943,11 +1970,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
1943 } 1970 }
1944 1971
1945 /* Make sure all other threads are stopped. */ 1972 /* Make sure all other threads are stopped. */
1946 wtime = 60 * HZ; 1973 wtime = 60 * 1000;
1947 while (ha->dpc_wait && wtime) { 1974 while (ha->dpc_wait && wtime)
1948 set_current_state(TASK_INTERRUPTIBLE); 1975 wtime = msleep_interruptible(wtime);
1949 wtime = schedule_timeout(wtime);
1950 }
1951 1976
1952 /* free ioctl memory */ 1977 /* free ioctl memory */
1953 qla2x00_free_ioctl_mem(ha); 1978 qla2x00_free_ioctl_mem(ha);
@@ -2478,15 +2503,15 @@ qla2x00_timer(scsi_qla_host_t *ha)
2478int 2503int
2479qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) 2504qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
2480{ 2505{
2481 const unsigned int step = HZ/10; 2506 const unsigned int step = 100; /* msecs */
2507 unsigned int iterations = jiffies_to_msecs(timeout)/100;
2482 2508
2483 do { 2509 do {
2484 if (!down_trylock(sema)) 2510 if (!down_trylock(sema))
2485 return 0; 2511 return 0;
2486 set_current_state(TASK_INTERRUPTIBLE); 2512 if (msleep_interruptible(step))
2487 if (schedule_timeout(step))
2488 break; 2513 break;
2489 } while ((timeout -= step) > 0); 2514 } while (--iterations >= 0);
2490 2515
2491 return -ETIMEDOUT; 2516 return -ETIMEDOUT;
2492} 2517}
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index d7f5c608009c..c14abf743b7c 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,
468 uint32_t dwords) 468 uint32_t dwords)
469{ 469{
470 uint32_t i; 470 uint32_t i;
471 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
472
473 /* Pause RISC. */
474 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
475 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
476 471
477 /* Dword reads to flash. */ 472 /* Dword reads to flash. */
478 for (i = 0; i < dwords; i++, faddr++) 473 for (i = 0; i < dwords; i++, faddr++)
479 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, 474 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
480 flash_data_to_access_addr(faddr))); 475 flash_data_to_access_addr(faddr)));
481 476
482 /* Release RISC pause. */
483 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
484 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
485
486 return dwptr; 477 return dwptr;
487} 478}
488 479
@@ -532,10 +523,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
532 523
533 ret = QLA_SUCCESS; 524 ret = QLA_SUCCESS;
534 525
535 /* Pause RISC. */
536 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
537 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
538
539 qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); 526 qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
540 DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, 527 DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__,
541 ha->host_no, man_id, flash_id)); 528 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,
599 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE); 586 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
600 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */ 587 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
601 588
602 /* Release RISC pause. */
603 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
604 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
605
606 return ret; 589 return ret;
607} 590}
608 591
@@ -630,11 +613,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
630{ 613{
631 uint32_t i; 614 uint32_t i;
632 uint32_t *dwptr; 615 uint32_t *dwptr;
633 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
634
635 /* Pause RISC. */
636 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
637 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
638 616
639 /* Dword reads to flash. */ 617 /* Dword reads to flash. */
640 dwptr = (uint32_t *)buf; 618 dwptr = (uint32_t *)buf;
@@ -642,10 +620,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
642 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, 620 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
643 nvram_data_to_access_addr(naddr))); 621 nvram_data_to_access_addr(naddr)));
644 622
645 /* Release RISC pause. */
646 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
647 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
648
649 return buf; 623 return buf;
650} 624}
651 625
@@ -690,10 +664,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
690 664
691 ret = QLA_SUCCESS; 665 ret = QLA_SUCCESS;
692 666
693 /* Pause RISC. */
694 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
695 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
696
697 /* Enable flash write. */ 667 /* Enable flash write. */
698 WRT_REG_DWORD(&reg->ctrl_status, 668 WRT_REG_DWORD(&reg->ctrl_status,
699 RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE); 669 RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
@@ -728,9 +698,5 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
728 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE); 698 RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
729 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */ 699 RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
730 700
731 /* Release RISC pause. */
732 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
733 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
734
735 return ret; 701 return ret;
736} 702}
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index e3cd3618bc54..eae7d6edd531 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -19,9 +19,9 @@
19/* 19/*
20 * Driver version 20 * Driver version
21 */ 21 */
22#define QLA2XXX_VERSION "8.01.00b5-k" 22#define QLA2XXX_VERSION "8.01.00-k"
23 23
24#define QLA_DRIVER_MAJOR_VER 8 24#define QLA_DRIVER_MAJOR_VER 8
25#define QLA_DRIVER_MINOR_VER 1 25#define QLA_DRIVER_MINOR_VER 1
26#define QLA_DRIVER_PATCH_VER 0 26#define QLA_DRIVER_PATCH_VER 0
27#define QLA_DRIVER_BETA_VER 5 27#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
new file mode 100644
index 000000000000..f1ea5027865f
--- /dev/null
+++ b/drivers/scsi/raid_class.c
@@ -0,0 +1,250 @@
1/*
2 * RAID Attributes
3 */
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/list.h>
7#include <linux/raid_class.h>
8#include <scsi/scsi_device.h>
9#include <scsi/scsi_host.h>
10
11#define RAID_NUM_ATTRS 3
12
13struct raid_internal {
14 struct raid_template r;
15 struct raid_function_template *f;
16 /* The actual attributes */
17 struct class_device_attribute private_attrs[RAID_NUM_ATTRS];
18 /* The array of null terminated pointers to attributes
19 * needed by scsi_sysfs.c */
20 struct class_device_attribute *attrs[RAID_NUM_ATTRS + 1];
21};
22
23struct raid_component {
24 struct list_head node;
25 struct device *dev;
26 int num;
27};
28
29#define to_raid_internal(tmpl) container_of(tmpl, struct raid_internal, r)
30
31#define tc_to_raid_internal(tcont) ({ \
32 struct raid_template *r = \
33 container_of(tcont, struct raid_template, raid_attrs); \
34 to_raid_internal(r); \
35})
36
37#define ac_to_raid_internal(acont) ({ \
38 struct transport_container *tc = \
39 container_of(acont, struct transport_container, ac); \
40 tc_to_raid_internal(tc); \
41})
42
43#define class_device_to_raid_internal(cdev) ({ \
44 struct attribute_container *ac = \
45 attribute_container_classdev_to_container(cdev); \
46 ac_to_raid_internal(ac); \
47})
48
49
50static int raid_match(struct attribute_container *cont, struct device *dev)
51{
52 /* We have to look for every subsystem that could house
53 * emulated RAID devices, so start with SCSI */
54 struct raid_internal *i = ac_to_raid_internal(cont);
55
56 if (scsi_is_sdev_device(dev)) {
57 struct scsi_device *sdev = to_scsi_device(dev);
58
59 if (i->f->cookie != sdev->host->hostt)
60 return 0;
61
62 return i->f->is_raid(dev);
63 }
64 /* FIXME: look at other subsystems too */
65 return 0;
66}
67
68static int raid_setup(struct transport_container *tc, struct device *dev,
69 struct class_device *cdev)
70{
71 struct raid_data *rd;
72
73 BUG_ON(class_get_devdata(cdev));
74
75 rd = kmalloc(sizeof(*rd), GFP_KERNEL);
76 if (!rd)
77 return -ENOMEM;
78
79 memset(rd, 0, sizeof(*rd));
80 INIT_LIST_HEAD(&rd->component_list);
81 class_set_devdata(cdev, rd);
82
83 return 0;
84}
85
86static int raid_remove(struct transport_container *tc, struct device *dev,
87 struct class_device *cdev)
88{
89 struct raid_data *rd = class_get_devdata(cdev);
90 struct raid_component *rc, *next;
91 class_set_devdata(cdev, NULL);
92 list_for_each_entry_safe(rc, next, &rd->component_list, node) {
93 char buf[40];
94 snprintf(buf, sizeof(buf), "component-%d", rc->num);
95 list_del(&rc->node);
96 sysfs_remove_link(&cdev->kobj, buf);
97 kfree(rc);
98 }
99 kfree(class_get_devdata(cdev));
100 return 0;
101}
102
103static DECLARE_TRANSPORT_CLASS(raid_class,
104 "raid_devices",
105 raid_setup,
106 raid_remove,
107 NULL);
108
109static struct {
110 enum raid_state value;
111 char *name;
112} raid_states[] = {
113 { RAID_ACTIVE, "active" },
114 { RAID_DEGRADED, "degraded" },
115 { RAID_RESYNCING, "resyncing" },
116 { RAID_OFFLINE, "offline" },
117};
118
119static const char *raid_state_name(enum raid_state state)
120{
121 int i;
122 char *name = NULL;
123
124 for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) {
125 if (raid_states[i].value == state) {
126 name = raid_states[i].name;
127 break;
128 }
129 }
130 return name;
131}
132
133
134#define raid_attr_show_internal(attr, fmt, var, code) \
135static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \
136{ \
137 struct raid_data *rd = class_get_devdata(cdev); \
138 code \
139 return snprintf(buf, 20, #fmt "\n", var); \
140}
141
142#define raid_attr_ro_states(attr, states, code) \
143raid_attr_show_internal(attr, %s, name, \
144 const char *name; \
145 code \
146 name = raid_##states##_name(rd->attr); \
147) \
148static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
149
150
151#define raid_attr_ro_internal(attr, code) \
152raid_attr_show_internal(attr, %d, rd->attr, code) \
153static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
154
155#define ATTR_CODE(attr) \
156 struct raid_internal *i = class_device_to_raid_internal(cdev); \
157 if (i->f->get_##attr) \
158 i->f->get_##attr(cdev->dev);
159
160#define raid_attr_ro(attr) raid_attr_ro_internal(attr, )
161#define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr))
162#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr))
163
164raid_attr_ro(level);
165raid_attr_ro_fn(resync);
166raid_attr_ro_state(state);
167
168void raid_component_add(struct raid_template *r,struct device *raid_dev,
169 struct device *component_dev)
170{
171 struct class_device *cdev =
172 attribute_container_find_class_device(&r->raid_attrs.ac,
173 raid_dev);
174 struct raid_component *rc;
175 struct raid_data *rd = class_get_devdata(cdev);
176 char buf[40];
177
178 rc = kmalloc(sizeof(*rc), GFP_KERNEL);
179 if (!rc)
180 return;
181
182 INIT_LIST_HEAD(&rc->node);
183 rc->dev = component_dev;
184 rc->num = rd->component_count++;
185
186 snprintf(buf, sizeof(buf), "component-%d", rc->num);
187 list_add_tail(&rc->node, &rd->component_list);
188 sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf);
189}
190EXPORT_SYMBOL(raid_component_add);
191
192struct raid_template *
193raid_class_attach(struct raid_function_template *ft)
194{
195 struct raid_internal *i = kmalloc(sizeof(struct raid_internal),
196 GFP_KERNEL);
197 int count = 0;
198
199 if (unlikely(!i))
200 return NULL;
201
202 memset(i, 0, sizeof(*i));
203
204 i->f = ft;
205
206 i->r.raid_attrs.ac.class = &raid_class.class;
207 i->r.raid_attrs.ac.match = raid_match;
208 i->r.raid_attrs.ac.attrs = &i->attrs[0];
209
210 attribute_container_register(&i->r.raid_attrs.ac);
211
212 i->attrs[count++] = &class_device_attr_level;
213 i->attrs[count++] = &class_device_attr_resync;
214 i->attrs[count++] = &class_device_attr_state;
215
216 i->attrs[count] = NULL;
217 BUG_ON(count > RAID_NUM_ATTRS);
218
219 return &i->r;
220}
221EXPORT_SYMBOL(raid_class_attach);
222
223void
224raid_class_release(struct raid_template *r)
225{
226 struct raid_internal *i = to_raid_internal(r);
227
228 attribute_container_unregister(&i->r.raid_attrs.ac);
229
230 kfree(i);
231}
232EXPORT_SYMBOL(raid_class_release);
233
234static __init int raid_init(void)
235{
236 return transport_class_register(&raid_class);
237}
238
239static __exit void raid_exit(void)
240{
241 transport_class_unregister(&raid_class);
242}
243
244MODULE_AUTHOR("James Bottomley");
245MODULE_DESCRIPTION("RAID device class");
246MODULE_LICENSE("GPL");
247
248module_init(raid_init);
249module_exit(raid_exit);
250
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index b444ec2e1c64..07b554affcf2 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -192,6 +192,7 @@ static struct {
192 {"SGI", "RAID5", "*", BLIST_SPARSELUN}, 192 {"SGI", "RAID5", "*", BLIST_SPARSELUN},
193 {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, 193 {"SGI", "TP9100", "*", BLIST_REPORTLUN2},
194 {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, 194 {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
195 {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
195 {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, 196 {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36},
196 {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, 197 {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
197 {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ 198 {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 2686d5672e5e..895c9452be4c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -20,6 +20,7 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/kthread.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/blkdev.h> 25#include <linux/blkdev.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
@@ -115,7 +116,6 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
115 116
116 add_timer(&scmd->eh_timeout); 117 add_timer(&scmd->eh_timeout);
117} 118}
118EXPORT_SYMBOL(scsi_add_timer);
119 119
120/** 120/**
121 * scsi_delete_timer - Delete/cancel timer for a given function. 121 * scsi_delete_timer - Delete/cancel timer for a given function.
@@ -143,7 +143,6 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
143 143
144 return rtn; 144 return rtn;
145} 145}
146EXPORT_SYMBOL(scsi_delete_timer);
147 146
148/** 147/**
149 * scsi_times_out - Timeout function for normal scsi commands. 148 * scsi_times_out - Timeout function for normal scsi commands.
@@ -776,9 +775,11 @@ retry_tur:
776 __FUNCTION__, scmd, rtn)); 775 __FUNCTION__, scmd, rtn));
777 if (rtn == SUCCESS) 776 if (rtn == SUCCESS)
778 return 0; 777 return 0;
779 else if (rtn == NEEDS_RETRY) 778 else if (rtn == NEEDS_RETRY) {
780 if (retry_cnt--) 779 if (retry_cnt--)
781 goto retry_tur; 780 goto retry_tur;
781 return 0;
782 }
782 return 1; 783 return 1;
783} 784}
784 785
@@ -1583,16 +1584,8 @@ int scsi_error_handler(void *data)
1583 int rtn; 1584 int rtn;
1584 DECLARE_MUTEX_LOCKED(sem); 1585 DECLARE_MUTEX_LOCKED(sem);
1585 1586
1586 /*
1587 * Flush resources
1588 */
1589
1590 daemonize("scsi_eh_%d", shost->host_no);
1591
1592 current->flags |= PF_NOFREEZE; 1587 current->flags |= PF_NOFREEZE;
1593
1594 shost->eh_wait = &sem; 1588 shost->eh_wait = &sem;
1595 shost->ehandler = current;
1596 1589
1597 /* 1590 /*
1598 * Wake up the thread that created us. 1591 * Wake up the thread that created us.
@@ -1600,8 +1593,6 @@ int scsi_error_handler(void *data)
1600 SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of" 1593 SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
1601 " scsi_eh_%d\n",shost->host_no)); 1594 " scsi_eh_%d\n",shost->host_no));
1602 1595
1603 complete(shost->eh_notify);
1604
1605 while (1) { 1596 while (1) {
1606 /* 1597 /*
1607 * If we get a signal, it means we are supposed to go 1598 * If we get a signal, it means we are supposed to go
@@ -1622,7 +1613,7 @@ int scsi_error_handler(void *data)
1622 * semaphores isn't unreasonable. 1613 * semaphores isn't unreasonable.
1623 */ 1614 */
1624 down_interruptible(&sem); 1615 down_interruptible(&sem);
1625 if (shost->eh_kill) 1616 if (kthread_should_stop())
1626 break; 1617 break;
1627 1618
1628 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" 1619 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
@@ -1661,22 +1652,6 @@ int scsi_error_handler(void *data)
1661 * Make sure that nobody tries to wake us up again. 1652 * Make sure that nobody tries to wake us up again.
1662 */ 1653 */
1663 shost->eh_wait = NULL; 1654 shost->eh_wait = NULL;
1664
1665 /*
1666 * Knock this down too. From this point on, the host is flying
1667 * without a pilot. If this is because the module is being unloaded,
1668 * that's fine. If the user sent a signal to this thing, we are
1669 * potentially in real danger.
1670 */
1671 shost->eh_active = 0;
1672 shost->ehandler = NULL;
1673
1674 /*
1675 * If anyone is waiting for us to exit (i.e. someone trying to unload
1676 * a driver), then wake up that process to let them know we are on
1677 * the way out the door.
1678 */
1679 complete_and_exit(shost->eh_notify, 0);
1680 return 0; 1655 return 0;
1681} 1656}
1682 1657
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 179a767d221d..b7fddac81347 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -30,20 +30,20 @@
30 30
31#define MAX_BUF PAGE_SIZE 31#define MAX_BUF PAGE_SIZE
32 32
33/* 33/**
34 * If we are told to probe a host, we will return 0 if the host is not 34 * ioctl_probe -- return host identification
35 * present, 1 if the host is present, and will return an identifying 35 * @host: host to identify
36 * string at *arg, if arg is non null, filling to the length stored at 36 * @buffer: userspace buffer for identification
37 * (int *) arg 37 *
38 * Return an identifying string at @buffer, if @buffer is non-NULL, filling
39 * to the length stored at * (int *) @buffer.
38 */ 40 */
39
40static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) 41static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
41{ 42{
42 unsigned int len, slen; 43 unsigned int len, slen;
43 const char *string; 44 const char *string;
44 int temp = host->hostt->present;
45 45
46 if (temp && buffer) { 46 if (buffer) {
47 if (get_user(len, (unsigned int __user *) buffer)) 47 if (get_user(len, (unsigned int __user *) buffer))
48 return -EFAULT; 48 return -EFAULT;
49 49
@@ -59,7 +59,7 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
59 return -EFAULT; 59 return -EFAULT;
60 } 60 }
61 } 61 }
62 return temp; 62 return 1;
63} 63}
64 64
65/* 65/*
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index d30d7f4e63ec..ee6de1768e53 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -63,6 +63,9 @@ extern int __init scsi_init_devinfo(void);
63extern void scsi_exit_devinfo(void); 63extern void scsi_exit_devinfo(void);
64 64
65/* scsi_error.c */ 65/* scsi_error.c */
66extern void scsi_add_timer(struct scsi_cmnd *, int,
67 void (*)(struct scsi_cmnd *));
68extern int scsi_delete_timer(struct scsi_cmnd *);
66extern void scsi_times_out(struct scsi_cmnd *cmd); 69extern void scsi_times_out(struct scsi_cmnd *cmd);
67extern int scsi_error_handler(void *host); 70extern int scsi_error_handler(void *host);
68extern int scsi_decide_disposition(struct scsi_cmnd *cmd); 71extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 611ccde84778..de564b386052 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -972,7 +972,7 @@ static void
972sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) 972sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
973{ 973{
974 unsigned char cmd[10]; 974 unsigned char cmd[10];
975 unsigned long spintime_value = 0; 975 unsigned long spintime_expire = 0;
976 int retries, spintime; 976 int retries, spintime;
977 unsigned int the_result; 977 unsigned int the_result;
978 struct scsi_sense_hdr sshdr; 978 struct scsi_sense_hdr sshdr;
@@ -1049,12 +1049,27 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
1049 scsi_execute_req(sdkp->device, cmd, DMA_NONE, 1049 scsi_execute_req(sdkp->device, cmd, DMA_NONE,
1050 NULL, 0, &sshdr, 1050 NULL, 0, &sshdr,
1051 SD_TIMEOUT, SD_MAX_RETRIES); 1051 SD_TIMEOUT, SD_MAX_RETRIES);
1052 spintime_value = jiffies; 1052 spintime_expire = jiffies + 100 * HZ;
1053 spintime = 1;
1053 } 1054 }
1054 spintime = 1;
1055 /* Wait 1 second for next try */ 1055 /* Wait 1 second for next try */
1056 msleep(1000); 1056 msleep(1000);
1057 printk("."); 1057 printk(".");
1058
1059 /*
1060 * Wait for USB flash devices with slow firmware.
1061 * Yes, this sense key/ASC combination shouldn't
1062 * occur here. It's characteristic of these devices.
1063 */
1064 } else if (sense_valid &&
1065 sshdr.sense_key == UNIT_ATTENTION &&
1066 sshdr.asc == 0x28) {
1067 if (!spintime) {
1068 spintime_expire = jiffies + 5 * HZ;
1069 spintime = 1;
1070 }
1071 /* Wait 1 second for next try */
1072 msleep(1000);
1058 } else { 1073 } else {
1059 /* we don't understand the sense code, so it's 1074 /* we don't understand the sense code, so it's
1060 * probably pointless to loop */ 1075 * probably pointless to loop */
@@ -1066,8 +1081,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
1066 break; 1081 break;
1067 } 1082 }
1068 1083
1069 } while (spintime && 1084 } while (spintime && time_before_eq(jiffies, spintime_expire));
1070 time_after(spintime_value + 100 * HZ, jiffies));
1071 1085
1072 if (spintime) { 1086 if (spintime) {
1073 if (scsi_status_is_good(the_result)) 1087 if (scsi_status_is_good(the_result))
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 052d55c167d4..b1b69d738d08 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 */
61 61
62#ifdef CONFIG_SCSI_PROC_FS 62#ifdef CONFIG_SCSI_PROC_FS
63#include <linux/proc_fs.h> 63#include <linux/proc_fs.h>
64static char *sg_version_date = "20050328"; 64static char *sg_version_date = "20050901";
65 65
66static int sg_proc_init(void); 66static int sg_proc_init(void);
67static void sg_proc_cleanup(void); 67static void sg_proc_cleanup(void);
@@ -1794,12 +1794,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
1794 unsigned long uaddr, size_t count, int rw, 1794 unsigned long uaddr, size_t count, int rw,
1795 unsigned long max_pfn) 1795 unsigned long max_pfn)
1796{ 1796{
1797 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
1798 unsigned long start = uaddr >> PAGE_SHIFT;
1799 const int nr_pages = end - start;
1797 int res, i, j; 1800 int res, i, j;
1798 unsigned int nr_pages;
1799 struct page **pages; 1801 struct page **pages;
1800 1802
1801 nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
1802
1803 /* User attempted Overflow! */ 1803 /* User attempted Overflow! */
1804 if ((uaddr + count) < uaddr) 1804 if ((uaddr + count) < uaddr)
1805 return -EINVAL; 1805 return -EINVAL;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9aadf2fcad6a..a93308ae9736 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support 17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */ 18 */
19 19
20static char *verstr = "20050802"; 20static char *verstr = "20050830";
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23 23
@@ -4440,12 +4440,12 @@ static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pag
4440static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 4440static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
4441 unsigned long uaddr, size_t count, int rw) 4441 unsigned long uaddr, size_t count, int rw)
4442{ 4442{
4443 unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
4444 unsigned long start = uaddr >> PAGE_SHIFT;
4445 const int nr_pages = end - start;
4443 int res, i, j; 4446 int res, i, j;
4444 unsigned int nr_pages;
4445 struct page **pages; 4447 struct page **pages;
4446 4448
4447 nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
4448
4449 /* User attempted Overflow! */ 4449 /* User attempted Overflow! */
4450 if ((uaddr + count) < uaddr) 4450 if ((uaddr + count) < uaddr)
4451 return -EINVAL; 4451 return -EINVAL;
diff --git a/include/linux/attribute_container.h b/include/linux/attribute_container.h
index ee83fe64a102..93bfb0beb62a 100644
--- a/include/linux/attribute_container.h
+++ b/include/linux/attribute_container.h
@@ -11,12 +11,12 @@
11 11
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/klist.h>
14#include <linux/spinlock.h> 15#include <linux/spinlock.h>
15 16
16struct attribute_container { 17struct attribute_container {
17 struct list_head node; 18 struct list_head node;
18 struct list_head containers; 19 struct klist containers;
19 spinlock_t containers_lock;
20 struct class *class; 20 struct class *class;
21 struct class_device_attribute **attrs; 21 struct class_device_attribute **attrs;
22 int (*match)(struct attribute_container *, struct device *); 22 int (*match)(struct attribute_container *, struct device *);
diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h
new file mode 100644
index 000000000000..a71123c28272
--- /dev/null
+++ b/include/linux/raid_class.h
@@ -0,0 +1,59 @@
1/*
2 */
3#include <linux/transport_class.h>
4
5struct raid_template {
6 struct transport_container raid_attrs;
7};
8
9struct raid_function_template {
10 void *cookie;
11 int (*is_raid)(struct device *);
12 void (*get_resync)(struct device *);
13 void (*get_state)(struct device *);
14};
15
16enum raid_state {
17 RAID_ACTIVE = 1,
18 RAID_DEGRADED,
19 RAID_RESYNCING,
20 RAID_OFFLINE,
21};
22
23struct raid_data {
24 struct list_head component_list;
25 int component_count;
26 int level;
27 enum raid_state state;
28 int resync;
29};
30
31#define DEFINE_RAID_ATTRIBUTE(type, attr) \
32static inline void \
33raid_set_##attr(struct raid_template *r, struct device *dev, type value) { \
34 struct class_device *cdev = \
35 attribute_container_find_class_device(&r->raid_attrs.ac, dev);\
36 struct raid_data *rd; \
37 BUG_ON(!cdev); \
38 rd = class_get_devdata(cdev); \
39 rd->attr = value; \
40} \
41static inline type \
42raid_get_##attr(struct raid_template *r, struct device *dev) { \
43 struct class_device *cdev = \
44 attribute_container_find_class_device(&r->raid_attrs.ac, dev);\
45 struct raid_data *rd; \
46 BUG_ON(!cdev); \
47 rd = class_get_devdata(cdev); \
48 return rd->attr; \
49}
50
51DEFINE_RAID_ATTRIBUTE(int, level)
52DEFINE_RAID_ATTRIBUTE(int, resync)
53DEFINE_RAID_ATTRIBUTE(enum raid_state, state)
54
55struct raid_template *raid_class_attach(struct raid_function_template *);
56void raid_class_release(struct raid_template *);
57
58void raid_component_add(struct raid_template *, struct device *,
59 struct device *);
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index b24d224281bd..fabd879c2f2e 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -35,9 +35,6 @@ static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr)
35} 35}
36 36
37 37
38extern void scsi_add_timer(struct scsi_cmnd *, int,
39 void (*)(struct scsi_cmnd *));
40extern int scsi_delete_timer(struct scsi_cmnd *);
41extern void scsi_report_bus_reset(struct Scsi_Host *, int); 38extern void scsi_report_bus_reset(struct Scsi_Host *, int);
42extern void scsi_report_device_reset(struct Scsi_Host *, int, int); 39extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
43extern int scsi_block_when_processing_errors(struct scsi_device *); 40extern int scsi_block_when_processing_errors(struct scsi_device *);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index ac1b6125e3ae..916144be208b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -467,12 +467,10 @@ struct Scsi_Host {
467 struct task_struct * ehandler; /* Error recovery thread. */ 467 struct task_struct * ehandler; /* Error recovery thread. */
468 struct semaphore * eh_wait; /* The error recovery thread waits 468 struct semaphore * eh_wait; /* The error recovery thread waits
469 on this. */ 469 on this. */
470 struct completion * eh_notify; /* wait for eh to begin or end */
471 struct semaphore * eh_action; /* Wait for specific actions on the 470 struct semaphore * eh_action; /* Wait for specific actions on the
472 host. */ 471 host. */
473 unsigned int eh_active:1; /* Indicates the eh thread is awake and active if 472 unsigned int eh_active:1; /* Indicates the eh thread is awake and active if
474 this is true. */ 473 this is true. */
475 unsigned int eh_kill:1; /* set when killing the eh thread */
476 wait_queue_head_t host_wait; 474 wait_queue_head_t host_wait;
477 struct scsi_host_template *hostt; 475 struct scsi_host_template *hostt;
478 struct scsi_transport_template *transportt; 476 struct scsi_transport_template *transportt;