aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 16:30:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 16:30:43 -0400
commitd54b3538b0bfb31351d02d1669d4a978d2abfc5f (patch)
tree5ce539ecba525b30bbfb1c46c55487099264947e /drivers/scsi
parent5d80f8e5a9dc9c9a94d4aeaa567e219a808b8a4a (diff)
parentaf50bb993dfa673cf21ab812efe620d7e0c36319 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (119 commits) [SCSI] scsi_dh_rdac: Retry for NOT_READY check condition [SCSI] mpt2sas: make global symbols unique [SCSI] sd: Make revalidate less chatty [SCSI] sd: Try READ CAPACITY 16 first for SBC-2 devices [SCSI] sd: Refactor sd_read_capacity() [SCSI] mpt2sas v00.100.11.15 [SCSI] mpt2sas: add MPT2SAS_MINOR(221) to miscdevice.h [SCSI] ch: Add scsi type modalias [SCSI] 3w-9xxx: add power management support [SCSI] bsg: add linux/types.h include to bsg.h [SCSI] cxgb3i: fix function descriptions [SCSI] libiscsi: fix possbile null ptr session command cleanup [SCSI] iscsi class: remove host no argument from session creation callout [SCSI] libiscsi: pass session failure a session struct [SCSI] iscsi lib: remove qdepth param from iscsi host allocation [SCSI] iscsi lib: have lib create work queue for transmitting IO [SCSI] iscsi class: fix lock dep warning on logout [SCSI] libiscsi: don't cap queue depth in iscsi modules [SCSI] iscsi_tcp: replace scsi_debug/tcp_debug logging with iscsi conn logging [SCSI] libiscsi_tcp: replace tcp_debug/scsi_debug logging with session/conn logging ...
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/3w-9xxx.c101
-rw-r--r--drivers/scsi/3w-9xxx.h2
-rw-r--r--drivers/scsi/Kconfig18
-rw-r--r--drivers/scsi/Makefile3
-rw-r--r--drivers/scsi/ch.c1
-rw-r--r--drivers/scsi/constants.c13
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c5
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h8
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c27
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c3
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h1
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c14
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c49
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c67
-rw-r--r--drivers/scsi/fcoe/libfcoe.c16
-rw-r--r--drivers/scsi/hosts.c3
-rw-r--r--drivers/scsi/hptiop.c3
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c62
-rw-r--r--drivers/scsi/ipr.c13
-rw-r--r--drivers/scsi/ipr.h4
-rw-r--r--drivers/scsi/ips.c3
-rw-r--r--drivers/scsi/iscsi_tcp.c73
-rw-r--r--drivers/scsi/libfc/fc_exch.c6
-rw-r--r--drivers/scsi/libfc/fc_fcp.c75
-rw-r--r--drivers/scsi/libfc/fc_lport.c5
-rw-r--r--drivers/scsi/libfc/fc_rport.c2
-rw-r--r--drivers/scsi/libiscsi.c236
-rw-r--r--drivers/scsi/libiscsi_tcp.c122
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c6
-rw-r--r--drivers/scsi/mpt2sas/Kconfig66
-rw-r--r--drivers/scsi/mpt2sas/Makefile7
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h1067
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h2151
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h420
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h1295
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h295
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_sas.h282
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h249
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_type.h61
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c3435
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h779
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c1873
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c2516
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h416
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h181
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c5687
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c1211
-rw-r--r--drivers/scsi/osd/Kbuild45
-rw-r--r--drivers/scsi/osd/Kconfig53
-rwxr-xr-xdrivers/scsi/osd/Makefile37
-rw-r--r--drivers/scsi/osd/osd_debug.h30
-rw-r--r--drivers/scsi/osd/osd_initiator.c1657
-rw-r--r--drivers/scsi/osd/osd_uld.c487
-rw-r--r--drivers/scsi/osst.c96
-rw-r--r--drivers/scsi/osst.h2
-rw-r--r--drivers/scsi/scsi.c104
-rw-r--r--drivers/scsi/scsi_debug.c443
-rw-r--r--drivers/scsi/scsi_error.c34
-rw-r--r--drivers/scsi/scsi_lib.c203
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_sysfs.c1
-rw-r--r--drivers/scsi/scsi_transport_fc.c2
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c45
-rw-r--r--drivers/scsi/sd.c349
-rw-r--r--drivers/scsi/sd.h1
-rw-r--r--drivers/scsi/ses.c33
-rw-r--r--drivers/scsi/sg.c495
-rw-r--r--drivers/scsi/st.c6
-rw-r--r--drivers/scsi/stex.c107
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c137
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c64
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h4
74 files changed, 26279 insertions, 1107 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 5311317c2e4c..a12783ebb42d 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -4,7 +4,7 @@
4 Written By: Adam Radford <linuxraid@amcc.com> 4 Written By: Adam Radford <linuxraid@amcc.com>
5 Modifications By: Tom Couch <linuxraid@amcc.com> 5 Modifications By: Tom Couch <linuxraid@amcc.com>
6 6
7 Copyright (C) 2004-2008 Applied Micro Circuits Corporation. 7 Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
@@ -75,6 +75,7 @@
75 Add MSI support and "use_msi" module parameter. 75 Add MSI support and "use_msi" module parameter.
76 Fix bug in twa_get_param() on 4GB+. 76 Fix bug in twa_get_param() on 4GB+.
77 Use pci_resource_len() for ioremap(). 77 Use pci_resource_len() for ioremap().
78 2.26.02.012 - Add power management support.
78*/ 79*/
79 80
80#include <linux/module.h> 81#include <linux/module.h>
@@ -99,7 +100,7 @@
99#include "3w-9xxx.h" 100#include "3w-9xxx.h"
100 101
101/* Globals */ 102/* Globals */
102#define TW_DRIVER_VERSION "2.26.02.011" 103#define TW_DRIVER_VERSION "2.26.02.012"
103static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; 104static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
104static unsigned int twa_device_extension_count; 105static unsigned int twa_device_extension_count;
105static int twa_major = -1; 106static int twa_major = -1;
@@ -2182,6 +2183,98 @@ static void twa_remove(struct pci_dev *pdev)
2182 twa_device_extension_count--; 2183 twa_device_extension_count--;
2183} /* End twa_remove() */ 2184} /* End twa_remove() */
2184 2185
2186#ifdef CONFIG_PM
2187/* This function is called on PCI suspend */
2188static int twa_suspend(struct pci_dev *pdev, pm_message_t state)
2189{
2190 struct Scsi_Host *host = pci_get_drvdata(pdev);
2191 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2192
2193 printk(KERN_WARNING "3w-9xxx: Suspending host %d.\n", tw_dev->host->host_no);
2194
2195 TW_DISABLE_INTERRUPTS(tw_dev);
2196 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2197
2198 if (test_bit(TW_USING_MSI, &tw_dev->flags))
2199 pci_disable_msi(pdev);
2200
2201 /* Tell the card we are shutting down */
2202 if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
2203 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x38, "Connection shutdown failed during suspend");
2204 } else {
2205 printk(KERN_WARNING "3w-9xxx: Suspend complete.\n");
2206 }
2207 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2208
2209 pci_save_state(pdev);
2210 pci_disable_device(pdev);
2211 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2212
2213 return 0;
2214} /* End twa_suspend() */
2215
2216/* This function is called on PCI resume */
2217static int twa_resume(struct pci_dev *pdev)
2218{
2219 int retval = 0;
2220 struct Scsi_Host *host = pci_get_drvdata(pdev);
2221 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2222
2223 printk(KERN_WARNING "3w-9xxx: Resuming host %d.\n", tw_dev->host->host_no);
2224 pci_set_power_state(pdev, PCI_D0);
2225 pci_enable_wake(pdev, PCI_D0, 0);
2226 pci_restore_state(pdev);
2227
2228 retval = pci_enable_device(pdev);
2229 if (retval) {
2230 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x39, "Enable device failed during resume");
2231 return retval;
2232 }
2233
2234 pci_set_master(pdev);
2235 pci_try_set_mwi(pdev);
2236
2237 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
2238 || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
2239 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
2240 || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
2241 TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume");
2242 retval = -ENODEV;
2243 goto out_disable_device;
2244 }
2245
2246 /* Initialize the card */
2247 if (twa_reset_sequence(tw_dev, 0)) {
2248 retval = -ENODEV;
2249 goto out_disable_device;
2250 }
2251
2252 /* Now setup the interrupt handler */
2253 retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev);
2254 if (retval) {
2255 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x42, "Error requesting IRQ during resume");
2256 retval = -ENODEV;
2257 goto out_disable_device;
2258 }
2259
2260 /* Now enable MSI if enabled */
2261 if (test_bit(TW_USING_MSI, &tw_dev->flags))
2262 pci_enable_msi(pdev);
2263
2264 /* Re-enable interrupts on the card */
2265 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2266
2267 printk(KERN_WARNING "3w-9xxx: Resume complete.\n");
2268 return 0;
2269
2270out_disable_device:
2271 scsi_remove_host(host);
2272 pci_disable_device(pdev);
2273
2274 return retval;
2275} /* End twa_resume() */
2276#endif
2277
2185/* PCI Devices supported by this driver */ 2278/* PCI Devices supported by this driver */
2186static struct pci_device_id twa_pci_tbl[] __devinitdata = { 2279static struct pci_device_id twa_pci_tbl[] __devinitdata = {
2187 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000, 2280 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
@@ -2202,6 +2295,10 @@ static struct pci_driver twa_driver = {
2202 .id_table = twa_pci_tbl, 2295 .id_table = twa_pci_tbl,
2203 .probe = twa_probe, 2296 .probe = twa_probe,
2204 .remove = twa_remove, 2297 .remove = twa_remove,
2298#ifdef CONFIG_PM
2299 .suspend = twa_suspend,
2300 .resume = twa_resume,
2301#endif
2205 .shutdown = twa_shutdown 2302 .shutdown = twa_shutdown
2206}; 2303};
2207 2304
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
index 1729a8785fea..2893eec78ed2 100644
--- a/drivers/scsi/3w-9xxx.h
+++ b/drivers/scsi/3w-9xxx.h
@@ -4,7 +4,7 @@
4 Written By: Adam Radford <linuxraid@amcc.com> 4 Written By: Adam Radford <linuxraid@amcc.com>
5 Modifications By: Tom Couch <linuxraid@amcc.com> 5 Modifications By: Tom Couch <linuxraid@amcc.com>
6 6
7 Copyright (C) 2004-2008 Applied Micro Circuits Corporation. 7 Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 256c7bec7bd7..e2f44e6c0bcb 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -224,14 +224,15 @@ config SCSI_LOGGING
224 can enable logging by saying Y to "/proc file system support" and 224 can enable logging by saying Y to "/proc file system support" and
225 "Sysctl support" below and executing the command 225 "Sysctl support" below and executing the command
226 226
227 echo "scsi log token [level]" > /proc/scsi/scsi 227 echo <bitmask> > /proc/sys/dev/scsi/logging_level
228 228
229 at boot time after the /proc file system has been mounted. 229 where <bitmask> is a four byte value representing the logging type
230 and logging level for each type of logging selected.
230 231
231 There are a number of things that can be used for 'token' (you can 232 There are a number of logging types and you can find them in the
232 find them in the source: <file:drivers/scsi/scsi.c>), and this 233 source at <file:drivers/scsi/scsi_logging.h>. The logging levels
233 allows you to select the types of information you want, and the 234 are also described in that file and they determine the verbosity of
234 level allows you to select the level of verbosity. 235 the logging for each logging type.
235 236
236 If you say N here, it may be harder to track down some types of SCSI 237 If you say N here, it may be harder to track down some types of SCSI
237 problems. If you say Y here your kernel will be somewhat larger, but 238 problems. If you say Y here your kernel will be somewhat larger, but
@@ -570,6 +571,7 @@ config SCSI_ARCMSR_AER
570 To enable this function, choose Y here. 571 To enable this function, choose Y here.
571 572
572source "drivers/scsi/megaraid/Kconfig.megaraid" 573source "drivers/scsi/megaraid/Kconfig.megaraid"
574source "drivers/scsi/mpt2sas/Kconfig"
573 575
574config SCSI_HPTIOP 576config SCSI_HPTIOP
575 tristate "HighPoint RocketRAID 3xxx/4xxx Controller support" 577 tristate "HighPoint RocketRAID 3xxx/4xxx Controller support"
@@ -608,6 +610,7 @@ config SCSI_FLASHPOINT
608config LIBFC 610config LIBFC
609 tristate "LibFC module" 611 tristate "LibFC module"
610 select SCSI_FC_ATTRS 612 select SCSI_FC_ATTRS
613 select CRC32
611 ---help--- 614 ---help---
612 Fibre Channel library module 615 Fibre Channel library module
613 616
@@ -1535,6 +1538,7 @@ config SCSI_NSP32
1535config SCSI_DEBUG 1538config SCSI_DEBUG
1536 tristate "SCSI debugging host simulator" 1539 tristate "SCSI debugging host simulator"
1537 depends on SCSI 1540 depends on SCSI
1541 select CRC_T10DIF
1538 help 1542 help
1539 This is a host adapter simulator that can simulate multiple hosts 1543 This is a host adapter simulator that can simulate multiple hosts
1540 each with multiple dummy SCSI devices (disks). It defaults to one 1544 each with multiple dummy SCSI devices (disks). It defaults to one
@@ -1803,4 +1807,6 @@ source "drivers/scsi/pcmcia/Kconfig"
1803 1807
1804source "drivers/scsi/device_handler/Kconfig" 1808source "drivers/scsi/device_handler/Kconfig"
1805 1809
1810source "drivers/scsi/osd/Kconfig"
1811
1806endmenu 1812endmenu
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 7461eb09a031..cf7929634668 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
99obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o 99obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
100obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ 100obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
101obj-$(CONFIG_MEGARAID_SAS) += megaraid/ 101obj-$(CONFIG_MEGARAID_SAS) += megaraid/
102obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/
102obj-$(CONFIG_SCSI_ACARD) += atp870u.o 103obj-$(CONFIG_SCSI_ACARD) += atp870u.o
103obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o 104obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
104obj-$(CONFIG_SCSI_GDTH) += gdth.o 105obj-$(CONFIG_SCSI_GDTH) += gdth.o
@@ -137,6 +138,8 @@ obj-$(CONFIG_CHR_DEV_SG) += sg.o
137obj-$(CONFIG_CHR_DEV_SCH) += ch.o 138obj-$(CONFIG_CHR_DEV_SCH) += ch.o
138obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o 139obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o
139 140
141obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/
142
140# This goes last, so that "real" scsi devices probe earlier 143# This goes last, so that "real" scsi devices probe earlier
141obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o 144obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
142 145
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index af9725409f43..7b1633a8c15a 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -41,6 +41,7 @@ MODULE_DESCRIPTION("device driver for scsi media changer devices");
41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>"); 41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR); 43MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR);
44MODULE_ALIAS_SCSI_DEVICE(TYPE_MEDIUM_CHANGER);
44 45
45static int init = 1; 46static int init = 1;
46module_param(init, int, 0444); 47module_param(init, int, 0444);
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 4003deefb7d8..e79e18101f87 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1373,21 +1373,14 @@ static const char * const driverbyte_table[]={
1373"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; 1373"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
1374#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) 1374#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
1375 1375
1376static const char * const driversuggest_table[]={"SUGGEST_OK",
1377"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
1378"SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
1379#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table)
1380
1381void scsi_show_result(int result) 1376void scsi_show_result(int result)
1382{ 1377{
1383 int hb = host_byte(result); 1378 int hb = host_byte(result);
1384 int db = (driver_byte(result) & DRIVER_MASK); 1379 int db = driver_byte(result);
1385 int su = ((driver_byte(result) & SUGGEST_MASK) >> 4);
1386 1380
1387 printk("Result: hostbyte=%s driverbyte=%s,%s\n", 1381 printk("Result: hostbyte=%s driverbyte=%s\n",
1388 (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"), 1382 (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"),
1389 (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"), 1383 (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"));
1390 (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
1391} 1384}
1392 1385
1393#else 1386#else
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index a83d36e4926f..4eb6f5593b3e 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -196,7 +196,7 @@ static inline int ddp_alloc_gl_skb(struct cxgb3i_ddp_info *ddp, int idx,
196} 196}
197 197
198/** 198/**
199 * cxgb3i_ddp_find_page_index - return ddp page index for a given page size. 199 * cxgb3i_ddp_find_page_index - return ddp page index for a given page size
200 * @pgsz: page size 200 * @pgsz: page size
201 * return the ddp page index, if no match is found return DDP_PGIDX_MAX. 201 * return the ddp page index, if no match is found return DDP_PGIDX_MAX.
202 */ 202 */
@@ -355,8 +355,7 @@ EXPORT_SYMBOL_GPL(cxgb3i_ddp_release_gl);
355 * @tdev: t3cdev adapter 355 * @tdev: t3cdev adapter
356 * @tid: connection id 356 * @tid: connection id
357 * @tformat: tag format 357 * @tformat: tag format
358 * @tagp: the s/w tag, if ddp setup is successful, it will be updated with 358 * @tagp: contains s/w tag initially, will be updated with ddp/hw tag
359 * ddp/hw tag
360 * @gl: the page momory list 359 * @gl: the page momory list
361 * @gfp: allocation mode 360 * @gfp: allocation mode
362 * 361 *
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 3faae7831c83..75a63a81e873 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -185,12 +185,11 @@ static inline int cxgb3i_is_ddp_tag(struct cxgb3i_tag_format *tformat, u32 tag)
185} 185}
186 186
187/** 187/**
188 * cxgb3i_sw_tag_usable - check if a given s/w tag has enough bits left for 188 * cxgb3i_sw_tag_usable - check if s/w tag has enough bits left for hw bits
189 * the reserved/hw bits
190 * @tformat: tag format information 189 * @tformat: tag format information
191 * @sw_tag: s/w tag to be checked 190 * @sw_tag: s/w tag to be checked
192 * 191 *
193 * return true if the tag is a ddp tag, false otherwise. 192 * return true if the tag can be used for hw ddp tag, false otherwise.
194 */ 193 */
195static inline int cxgb3i_sw_tag_usable(struct cxgb3i_tag_format *tformat, 194static inline int cxgb3i_sw_tag_usable(struct cxgb3i_tag_format *tformat,
196 u32 sw_tag) 195 u32 sw_tag)
@@ -222,8 +221,7 @@ static inline u32 cxgb3i_set_non_ddp_tag(struct cxgb3i_tag_format *tformat,
222} 221}
223 222
224/** 223/**
225 * cxgb3i_ddp_tag_base - shift the s/w tag bits so that reserved bits are not 224 * cxgb3i_ddp_tag_base - shift s/w tag bits so that reserved bits are not used
226 * used.
227 * @tformat: tag format information 225 * @tformat: tag format information
228 * @sw_tag: s/w tag to be checked 226 * @sw_tag: s/w tag to be checked
229 */ 227 */
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index fa2a44f37b36..e185dedc4c1f 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -101,8 +101,7 @@ free_snic:
101} 101}
102 102
103/** 103/**
104 * cxgb3i_adapter_remove - release all the resources held and cleanup any 104 * cxgb3i_adapter_remove - release the resources held and cleanup h/w settings
105 * h/w settings
106 * @t3dev: t3cdev adapter 105 * @t3dev: t3cdev adapter
107 */ 106 */
108void cxgb3i_adapter_remove(struct t3cdev *t3dev) 107void cxgb3i_adapter_remove(struct t3cdev *t3dev)
@@ -135,8 +134,7 @@ void cxgb3i_adapter_remove(struct t3cdev *t3dev)
135} 134}
136 135
137/** 136/**
138 * cxgb3i_hba_find_by_netdev - find the cxgb3i_hba structure with a given 137 * cxgb3i_hba_find_by_netdev - find the cxgb3i_hba structure via net_device
139 * net_device
140 * @t3dev: t3cdev adapter 138 * @t3dev: t3cdev adapter
141 */ 139 */
142struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev) 140struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev)
@@ -170,8 +168,7 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
170 int err; 168 int err;
171 169
172 shost = iscsi_host_alloc(&cxgb3i_host_template, 170 shost = iscsi_host_alloc(&cxgb3i_host_template,
173 sizeof(struct cxgb3i_hba), 171 sizeof(struct cxgb3i_hba), 1);
174 CXGB3I_SCSI_QDEPTH_DFLT);
175 if (!shost) { 172 if (!shost) {
176 cxgb3i_log_info("iscsi_host_alloc failed.\n"); 173 cxgb3i_log_info("iscsi_host_alloc failed.\n");
177 return NULL; 174 return NULL;
@@ -335,13 +332,12 @@ static void cxgb3i_ep_disconnect(struct iscsi_endpoint *ep)
335 * @cmds_max: max # of commands 332 * @cmds_max: max # of commands
336 * @qdepth: scsi queue depth 333 * @qdepth: scsi queue depth
337 * @initial_cmdsn: initial iscsi CMDSN for this session 334 * @initial_cmdsn: initial iscsi CMDSN for this session
338 * @host_no: pointer to return host no
339 * 335 *
340 * Creates a new iSCSI session 336 * Creates a new iSCSI session
341 */ 337 */
342static struct iscsi_cls_session * 338static struct iscsi_cls_session *
343cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth, 339cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
344 u32 initial_cmdsn, u32 *host_no) 340 u32 initial_cmdsn)
345{ 341{
346 struct cxgb3i_endpoint *cep; 342 struct cxgb3i_endpoint *cep;
347 struct cxgb3i_hba *hba; 343 struct cxgb3i_hba *hba;
@@ -360,8 +356,6 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
360 cxgb3i_api_debug("ep 0x%p, cep 0x%p, hba 0x%p.\n", ep, cep, hba); 356 cxgb3i_api_debug("ep 0x%p, cep 0x%p, hba 0x%p.\n", ep, cep, hba);
361 BUG_ON(hba != iscsi_host_priv(shost)); 357 BUG_ON(hba != iscsi_host_priv(shost));
362 358
363 *host_no = shost->host_no;
364
365 cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, 359 cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
366 cmds_max, 360 cmds_max,
367 sizeof(struct iscsi_tcp_task) + 361 sizeof(struct iscsi_tcp_task) +
@@ -394,9 +388,9 @@ static void cxgb3i_session_destroy(struct iscsi_cls_session *cls_session)
394} 388}
395 389
396/** 390/**
397 * cxgb3i_conn_max_xmit_dlength -- check the max. xmit pdu segment size, 391 * cxgb3i_conn_max_xmit_dlength -- calc the max. xmit pdu segment size
398 * reduce it to be within the hardware limit if needed
399 * @conn: iscsi connection 392 * @conn: iscsi connection
393 * check the max. xmit pdu payload, reduce it if needed
400 */ 394 */
401static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn) 395static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn)
402 396
@@ -417,8 +411,7 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn)
417} 411}
418 412
419/** 413/**
420 * cxgb3i_conn_max_recv_dlength -- check the max. recv pdu segment size against 414 * cxgb3i_conn_max_recv_dlength -- check the max. recv pdu segment size
421 * the hardware limit
422 * @conn: iscsi connection 415 * @conn: iscsi connection
423 * return 0 if the value is valid, < 0 otherwise. 416 * return 0 if the value is valid, < 0 otherwise.
424 */ 417 */
@@ -759,9 +752,9 @@ static void cxgb3i_parse_itt(struct iscsi_conn *conn, itt_t itt,
759 752
760/** 753/**
761 * cxgb3i_reserve_itt - generate tag for a give task 754 * cxgb3i_reserve_itt - generate tag for a give task
762 * Try to set up ddp for a scsi read task.
763 * @task: iscsi task 755 * @task: iscsi task
764 * @hdr_itt: tag, filled in by this function 756 * @hdr_itt: tag, filled in by this function
757 * Set up ddp for scsi read tasks if possible.
765 */ 758 */
766int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt) 759int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt)
767{ 760{
@@ -809,9 +802,9 @@ int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt)
809 802
810/** 803/**
811 * cxgb3i_release_itt - release the tag for a given task 804 * cxgb3i_release_itt - release the tag for a given task
812 * if the tag is a ddp tag, release the ddp setup
813 * @task: iscsi task 805 * @task: iscsi task
814 * @hdr_itt: tag 806 * @hdr_itt: tag
807 * If the tag is a ddp tag, release the ddp setup
815 */ 808 */
816void cxgb3i_release_itt(struct iscsi_task *task, itt_t hdr_itt) 809void cxgb3i_release_itt(struct iscsi_task *task, itt_t hdr_itt)
817{ 810{
@@ -843,7 +836,7 @@ static struct scsi_host_template cxgb3i_host_template = {
843 .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, 836 .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1,
844 .sg_tablesize = SG_ALL, 837 .sg_tablesize = SG_ALL,
845 .max_sectors = 0xFFFF, 838 .max_sectors = 0xFFFF,
846 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, 839 .cmd_per_lun = CXGB3I_SCSI_QDEPTH_DFLT,
847 .eh_abort_handler = iscsi_eh_abort, 840 .eh_abort_handler = iscsi_eh_abort,
848 .eh_device_reset_handler = iscsi_eh_device_reset, 841 .eh_device_reset_handler = iscsi_eh_device_reset,
849 .eh_target_reset_handler = iscsi_eh_target_reset, 842 .eh_target_reset_handler = iscsi_eh_target_reset,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index de3b3b614cca..c2e434e54e28 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -1417,8 +1417,7 @@ static void c3cn_active_close(struct s3_conn *c3cn)
1417} 1417}
1418 1418
1419/** 1419/**
1420 * cxgb3i_c3cn_release - close and release an iscsi tcp connection and any 1420 * cxgb3i_c3cn_release - close and release an iscsi tcp connection
1421 * resource held
1422 * @c3cn: the iscsi tcp connection 1421 * @c3cn: the iscsi tcp connection
1423 */ 1422 */
1424void cxgb3i_c3cn_release(struct s3_conn *c3cn) 1423void cxgb3i_c3cn_release(struct s3_conn *c3cn)
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index 6344b9eb2589..275f23f16eb7 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -139,6 +139,7 @@ enum c3cn_flags {
139 139
140/** 140/**
141 * cxgb3i_sdev_data - Per adapter data. 141 * cxgb3i_sdev_data - Per adapter data.
142 *
142 * Linked off of each Ethernet device port on the adapter. 143 * Linked off of each Ethernet device port on the adapter.
143 * Also available via the t3cdev structure since we have pointers to our port 144 * Also available via the t3cdev structure since we have pointers to our port
144 * net_device's there ... 145 * net_device's there ...
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
index 17115c230d65..7eebc9a7cb35 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
@@ -479,7 +479,7 @@ void cxgb3i_conn_tx_open(struct s3_conn *c3cn)
479 cxgb3i_tx_debug("cn 0x%p.\n", c3cn); 479 cxgb3i_tx_debug("cn 0x%p.\n", c3cn);
480 if (conn) { 480 if (conn) {
481 cxgb3i_tx_debug("cn 0x%p, cid %d.\n", c3cn, conn->id); 481 cxgb3i_tx_debug("cn 0x%p, cid %d.\n", c3cn, conn->id);
482 scsi_queue_work(conn->session->host, &conn->xmitwork); 482 iscsi_conn_queue_work(conn);
483 } 483 }
484} 484}
485 485
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index e356b43753ff..dba154c8ff64 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -247,8 +247,8 @@ static unsigned submit_stpg(struct scsi_device *sdev, struct alua_dh_data *h)
247 /* Prepare the data buffer */ 247 /* Prepare the data buffer */
248 memset(h->buff, 0, stpg_len); 248 memset(h->buff, 0, stpg_len);
249 h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; 249 h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f;
250 h->buff[6] = (h->group_id >> 8) & 0x0f; 250 h->buff[6] = (h->group_id >> 8) & 0xff;
251 h->buff[7] = h->group_id & 0x0f; 251 h->buff[7] = h->group_id & 0xff;
252 252
253 rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); 253 rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
254 if (!rq) 254 if (!rq)
@@ -461,6 +461,15 @@ static int alua_check_sense(struct scsi_device *sdev,
461 */ 461 */
462 return ADD_TO_MLQUEUE; 462 return ADD_TO_MLQUEUE;
463 } 463 }
464 if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) {
465 /*
466 * REPORTED_LUNS_DATA_HAS_CHANGED is reported
467 * when switching controllers on targets like
468 * Intel Multi-Flex. We can just retry.
469 */
470 return ADD_TO_MLQUEUE;
471 }
472
464 break; 473 break;
465 } 474 }
466 475
@@ -691,6 +700,7 @@ static const struct scsi_dh_devlist alua_dev_list[] = {
691 {"IBM", "2107900" }, 700 {"IBM", "2107900" },
692 {"IBM", "2145" }, 701 {"IBM", "2145" },
693 {"Pillar", "Axiom" }, 702 {"Pillar", "Axiom" },
703 {"Intel", "Multi-Flex"},
694 {NULL, NULL} 704 {NULL, NULL}
695}; 705};
696 706
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 53664765570a..43b8c51e98d0 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -449,28 +449,40 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
449 unsigned char *sensebuf) 449 unsigned char *sensebuf)
450{ 450{
451 struct scsi_sense_hdr sense_hdr; 451 struct scsi_sense_hdr sense_hdr;
452 int sense, err = SCSI_DH_IO, ret; 452 int err = SCSI_DH_IO, ret;
453 453
454 ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr); 454 ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
455 if (!ret) 455 if (!ret)
456 goto done; 456 goto done;
457 457
458 err = SCSI_DH_OK; 458 err = SCSI_DH_OK;
459 sense = (sense_hdr.sense_key << 16) | (sense_hdr.asc << 8) | 459
460 sense_hdr.ascq; 460 switch (sense_hdr.sense_key) {
461 /* If it is retryable failure, submit the c9 inquiry again */ 461 case NO_SENSE:
462 if (sense == 0x59136 || sense == 0x68b02 || sense == 0xb8b02 || 462 case ABORTED_COMMAND:
463 sense == 0x62900) { 463 case UNIT_ATTENTION:
464 /* 0x59136 - Command lock contention
465 * 0x[6b]8b02 - Quiesense in progress or achieved
466 * 0x62900 - Power On, Reset, or Bus Device Reset
467 */
468 err = SCSI_DH_RETRY; 464 err = SCSI_DH_RETRY;
465 break;
466 case NOT_READY:
467 if (sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x01)
468 /* LUN Not Ready and is in the Process of Becoming
469 * Ready
470 */
471 err = SCSI_DH_RETRY;
472 break;
473 case ILLEGAL_REQUEST:
474 if (sense_hdr.asc == 0x91 && sense_hdr.ascq == 0x36)
475 /*
476 * Command Lock contention
477 */
478 err = SCSI_DH_RETRY;
479 break;
480 default:
481 sdev_printk(KERN_INFO, sdev,
482 "MODE_SELECT failed with sense %02x/%02x/%02x.\n",
483 sense_hdr.sense_key, sense_hdr.asc, sense_hdr.ascq);
469 } 484 }
470 485
471 if (sense)
472 sdev_printk(KERN_INFO, sdev,
473 "MODE_SELECT failed with sense 0x%x.\n", sense);
474done: 486done:
475 return err; 487 return err;
476} 488}
@@ -562,6 +574,12 @@ static int rdac_check_sense(struct scsi_device *sdev,
562 * Just retry and wait. 574 * Just retry and wait.
563 */ 575 */
564 return ADD_TO_MLQUEUE; 576 return ADD_TO_MLQUEUE;
577 if (sense_hdr->asc == 0xA1 && sense_hdr->ascq == 0x02)
578 /* LUN Not Ready - Quiescense in progress
579 * or has been achieved
580 * Just retry.
581 */
582 return ADD_TO_MLQUEUE;
565 break; 583 break;
566 case ILLEGAL_REQUEST: 584 case ILLEGAL_REQUEST:
567 if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) { 585 if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) {
@@ -579,6 +597,11 @@ static int rdac_check_sense(struct scsi_device *sdev,
579 * Power On, Reset, or Bus Device Reset, just retry. 597 * Power On, Reset, or Bus Device Reset, just retry.
580 */ 598 */
581 return ADD_TO_MLQUEUE; 599 return ADD_TO_MLQUEUE;
600 if (sense_hdr->asc == 0x8b && sense_hdr->ascq == 0x02)
601 /*
602 * Quiescence in progress , just retry.
603 */
604 return ADD_TO_MLQUEUE;
582 break; 605 break;
583 } 606 }
584 /* success just means we do not care what scsi-ml does */ 607 /* success just means we do not care what scsi-ml does */
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
index da210eba1941..2bbbe3c0cc7b 100644
--- a/drivers/scsi/fcoe/fcoe_sw.c
+++ b/drivers/scsi/fcoe/fcoe_sw.c
@@ -133,6 +133,13 @@ static int fcoe_sw_lport_config(struct fc_lport *lp)
133 /* lport fc_lport related configuration */ 133 /* lport fc_lport related configuration */
134 fc_lport_config(lp); 134 fc_lport_config(lp);
135 135
136 /* offload related configuration */
137 lp->crc_offload = 0;
138 lp->seq_offload = 0;
139 lp->lro_enabled = 0;
140 lp->lro_xid = 0;
141 lp->lso_max = 0;
142
136 return 0; 143 return 0;
137} 144}
138 145
@@ -186,7 +193,27 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
186 if (fc->real_dev->features & NETIF_F_SG) 193 if (fc->real_dev->features & NETIF_F_SG)
187 lp->sg_supp = 1; 194 lp->sg_supp = 1;
188 195
189 196#ifdef NETIF_F_FCOE_CRC
197 if (netdev->features & NETIF_F_FCOE_CRC) {
198 lp->crc_offload = 1;
199 printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
200 netdev->name);
201 }
202#endif
203#ifdef NETIF_F_FSO
204 if (netdev->features & NETIF_F_FSO) {
205 lp->seq_offload = 1;
206 lp->lso_max = netdev->gso_max_size;
207 printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
208 netdev->name, lp->lso_max);
209 }
210#endif
211 if (netdev->fcoe_ddp_xid) {
212 lp->lro_enabled = 1;
213 lp->lro_xid = netdev->fcoe_ddp_xid;
214 printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
215 netdev->name, lp->lro_xid);
216 }
190 skb_queue_head_init(&fc->fcoe_pending_queue); 217 skb_queue_head_init(&fc->fcoe_pending_queue);
191 fc->fcoe_pending_queue_active = 0; 218 fc->fcoe_pending_queue_active = 0;
192 219
@@ -346,8 +373,46 @@ static int fcoe_sw_destroy(struct net_device *netdev)
346 return 0; 373 return 0;
347} 374}
348 375
376/*
377 * fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device
378 * @lp: the corresponding fc_lport
379 * @xid: the exchange id for this ddp transfer
380 * @sgl: the scatterlist describing this transfer
381 * @sgc: number of sg items
382 *
383 * Returns : 0 no ddp
384 */
385static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid,
386 struct scatterlist *sgl, unsigned int sgc)
387{
388 struct net_device *n = fcoe_netdev(lp);
389
390 if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
391 return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
392
393 return 0;
394}
395
396/*
397 * fcoe_sw_ddp_done - calls LLD's ddp_done through net_device
398 * @lp: the corresponding fc_lport
399 * @xid: the exchange id for this ddp transfer
400 *
401 * Returns : the length of data that have been completed by ddp
402 */
403static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid)
404{
405 struct net_device *n = fcoe_netdev(lp);
406
407 if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
408 return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
409 return 0;
410}
411
349static struct libfc_function_template fcoe_sw_libfc_fcn_templ = { 412static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
350 .frame_send = fcoe_xmit, 413 .frame_send = fcoe_xmit,
414 .ddp_setup = fcoe_sw_ddp_setup,
415 .ddp_done = fcoe_sw_ddp_done,
351}; 416};
352 417
353/** 418/**
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 5548bf3bb58b..0d6f5beb7f9e 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -423,7 +423,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
423 423
424 /* crc offload */ 424 /* crc offload */
425 if (likely(lp->crc_offload)) { 425 if (likely(lp->crc_offload)) {
426 skb->ip_summed = CHECKSUM_COMPLETE; 426 skb->ip_summed = CHECKSUM_PARTIAL;
427 skb->csum_start = skb_headroom(skb); 427 skb->csum_start = skb_headroom(skb);
428 skb->csum_offset = skb->len; 428 skb->csum_offset = skb->len;
429 crc = 0; 429 crc = 0;
@@ -460,7 +460,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
460 skb_reset_mac_header(skb); 460 skb_reset_mac_header(skb);
461 skb_reset_network_header(skb); 461 skb_reset_network_header(skb);
462 skb->mac_len = elen; 462 skb->mac_len = elen;
463 skb->protocol = htons(ETH_P_802_3); 463 skb->protocol = htons(ETH_P_FCOE);
464 skb->dev = fc->real_dev; 464 skb->dev = fc->real_dev;
465 465
466 /* fill up mac and fcoe headers */ 466 /* fill up mac and fcoe headers */
@@ -483,6 +483,16 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
483 FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER); 483 FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
484 hp->fcoe_sof = sof; 484 hp->fcoe_sof = sof;
485 485
486#ifdef NETIF_F_FSO
487 /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
488 if (lp->seq_offload && fr_max_payload(fp)) {
489 skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
490 skb_shinfo(skb)->gso_size = fr_max_payload(fp);
491 } else {
492 skb_shinfo(skb)->gso_type = 0;
493 skb_shinfo(skb)->gso_size = 0;
494 }
495#endif
486 /* update tx stats: regardless if LLD fails */ 496 /* update tx stats: regardless if LLD fails */
487 stats = lp->dev_stats[smp_processor_id()]; 497 stats = lp->dev_stats[smp_processor_id()];
488 if (stats) { 498 if (stats) {
@@ -623,7 +633,7 @@ int fcoe_percpu_receive_thread(void *arg)
623 * it's solicited data, in which case, the FCP layer would 633 * it's solicited data, in which case, the FCP layer would
624 * check it during the copy. 634 * check it during the copy.
625 */ 635 */
626 if (lp->crc_offload) 636 if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
627 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; 637 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
628 else 638 else
629 fr_flags(fp) |= FCPHF_CRC_UNCHECKED; 639 fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index aa670a1d1513..89d41a424b33 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -176,7 +176,6 @@ void scsi_remove_host(struct Scsi_Host *shost)
176 transport_unregister_device(&shost->shost_gendev); 176 transport_unregister_device(&shost->shost_gendev);
177 device_unregister(&shost->shost_dev); 177 device_unregister(&shost->shost_dev);
178 device_del(&shost->shost_gendev); 178 device_del(&shost->shost_gendev);
179 scsi_proc_hostdir_rm(shost->hostt);
180} 179}
181EXPORT_SYMBOL(scsi_remove_host); 180EXPORT_SYMBOL(scsi_remove_host);
182 181
@@ -270,6 +269,8 @@ static void scsi_host_dev_release(struct device *dev)
270 struct Scsi_Host *shost = dev_to_shost(dev); 269 struct Scsi_Host *shost = dev_to_shost(dev);
271 struct device *parent = dev->parent; 270 struct device *parent = dev->parent;
272 271
272 scsi_proc_hostdir_rm(shost->hostt);
273
273 if (shost->ehandler) 274 if (shost->ehandler)
274 kthread_stop(shost->ehandler); 275 kthread_stop(shost->ehandler);
275 if (shost->work_q) 276 if (shost->work_q)
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 34be88d7afa5..af1f0af0c5ac 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -580,8 +580,7 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
580 break; 580 break;
581 581
582 default: 582 default:
583 scp->result = ((DRIVER_INVALID|SUGGEST_ABORT)<<24) | 583 scp->result = DRIVER_INVALID << 24 | DID_ABORT << 16;
584 (DID_ABORT<<16);
585 break; 584 break;
586 } 585 }
587 586
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index ed1e728763a2..93d1fbe4ee5d 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2767,6 +2767,40 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt,
2767 ibmvfc_init_tgt(tgt, job_step); 2767 ibmvfc_init_tgt(tgt, job_step);
2768} 2768}
2769 2769
2770/* Defined in FC-LS */
2771static const struct {
2772 int code;
2773 int retry;
2774 int logged_in;
2775} prli_rsp [] = {
2776 { 0, 1, 0 },
2777 { 1, 0, 1 },
2778 { 2, 1, 0 },
2779 { 3, 1, 0 },
2780 { 4, 0, 0 },
2781 { 5, 0, 0 },
2782 { 6, 0, 1 },
2783 { 7, 0, 0 },
2784 { 8, 1, 0 },
2785};
2786
2787/**
2788 * ibmvfc_get_prli_rsp - Find PRLI response index
2789 * @flags: PRLI response flags
2790 *
2791 **/
2792static int ibmvfc_get_prli_rsp(u16 flags)
2793{
2794 int i;
2795 int code = (flags & 0x0f00) >> 8;
2796
2797 for (i = 0; i < ARRAY_SIZE(prli_rsp); i++)
2798 if (prli_rsp[i].code == code)
2799 return i;
2800
2801 return 0;
2802}
2803
2770/** 2804/**
2771 * ibmvfc_tgt_prli_done - Completion handler for Process Login 2805 * ibmvfc_tgt_prli_done - Completion handler for Process Login
2772 * @evt: ibmvfc event struct 2806 * @evt: ibmvfc event struct
@@ -2777,15 +2811,36 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
2777 struct ibmvfc_target *tgt = evt->tgt; 2811 struct ibmvfc_target *tgt = evt->tgt;
2778 struct ibmvfc_host *vhost = evt->vhost; 2812 struct ibmvfc_host *vhost = evt->vhost;
2779 struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli; 2813 struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli;
2814 struct ibmvfc_prli_svc_parms *parms = &rsp->parms;
2780 u32 status = rsp->common.status; 2815 u32 status = rsp->common.status;
2816 int index;
2781 2817
2782 vhost->discovery_threads--; 2818 vhost->discovery_threads--;
2783 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); 2819 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
2784 switch (status) { 2820 switch (status) {
2785 case IBMVFC_MAD_SUCCESS: 2821 case IBMVFC_MAD_SUCCESS:
2786 tgt_dbg(tgt, "Process Login succeeded\n"); 2822 tgt_dbg(tgt, "Process Login succeeded: %X %02X %04X\n",
2787 tgt->need_login = 0; 2823 parms->type, parms->flags, parms->service_parms);
2788 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT); 2824
2825 if (parms->type == IBMVFC_SCSI_FCP_TYPE) {
2826 index = ibmvfc_get_prli_rsp(parms->flags);
2827 if (prli_rsp[index].logged_in) {
2828 if (parms->flags & IBMVFC_PRLI_EST_IMG_PAIR) {
2829 tgt->need_login = 0;
2830 tgt->ids.roles = 0;
2831 if (parms->service_parms & IBMVFC_PRLI_TARGET_FUNC)
2832 tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET;
2833 if (parms->service_parms & IBMVFC_PRLI_INITIATOR_FUNC)
2834 tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
2835 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT);
2836 } else
2837 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2838 } else if (prli_rsp[index].retry)
2839 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
2840 else
2841 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2842 } else
2843 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2789 break; 2844 break;
2790 case IBMVFC_MAD_DRIVER_FAILED: 2845 case IBMVFC_MAD_DRIVER_FAILED:
2791 break; 2846 break;
@@ -2874,7 +2929,6 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
2874 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); 2929 tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
2875 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); 2930 tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
2876 tgt->ids.port_id = tgt->scsi_id; 2931 tgt->ids.port_id = tgt->scsi_id;
2877 tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET;
2878 memcpy(&tgt->service_parms, &rsp->service_parms, 2932 memcpy(&tgt->service_parms, &rsp->service_parms,
2879 sizeof(tgt->service_parms)); 2933 sizeof(tgt->service_parms));
2880 memcpy(&tgt->service_parms_change, &rsp->service_parms_change, 2934 memcpy(&tgt->service_parms_change, &rsp->service_parms_change,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 07829009a8be..def473f0a98f 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -152,13 +152,13 @@ module_param_named(log_level, ipr_log_level, uint, 0);
152MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver"); 152MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver");
153module_param_named(testmode, ipr_testmode, int, 0); 153module_param_named(testmode, ipr_testmode, int, 0);
154MODULE_PARM_DESC(testmode, "DANGEROUS!!! Allows unsupported configurations"); 154MODULE_PARM_DESC(testmode, "DANGEROUS!!! Allows unsupported configurations");
155module_param_named(fastfail, ipr_fastfail, int, 0); 155module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR);
156MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); 156MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
157module_param_named(transop_timeout, ipr_transop_timeout, int, 0); 157module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
158MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); 158MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
159module_param_named(enable_cache, ipr_enable_cache, int, 0); 159module_param_named(enable_cache, ipr_enable_cache, int, 0);
160MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); 160MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
161module_param_named(debug, ipr_debug, int, 0); 161module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR);
162MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); 162MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
163module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); 163module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0);
164MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); 164MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)");
@@ -354,6 +354,8 @@ struct ipr_error_table_t ipr_error_table[] = {
354 "9076: Configuration error, missing remote IOA"}, 354 "9076: Configuration error, missing remote IOA"},
355 {0x06679100, 0, IPR_DEFAULT_LOG_LEVEL, 355 {0x06679100, 0, IPR_DEFAULT_LOG_LEVEL,
356 "4050: Enclosure does not support a required multipath function"}, 356 "4050: Enclosure does not support a required multipath function"},
357 {0x06690000, 0, IPR_DEFAULT_LOG_LEVEL,
358 "4070: Logically bad block written on device"},
357 {0x06690200, 0, IPR_DEFAULT_LOG_LEVEL, 359 {0x06690200, 0, IPR_DEFAULT_LOG_LEVEL,
358 "9041: Array protection temporarily suspended"}, 360 "9041: Array protection temporarily suspended"},
359 {0x06698200, 0, IPR_DEFAULT_LOG_LEVEL, 361 {0x06698200, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -7147,6 +7149,7 @@ static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg)
7147 7149
7148 ENTER; 7150 ENTER;
7149 free_irq(pdev->irq, ioa_cfg); 7151 free_irq(pdev->irq, ioa_cfg);
7152 pci_disable_msi(pdev);
7150 iounmap(ioa_cfg->hdw_dma_regs); 7153 iounmap(ioa_cfg->hdw_dma_regs);
7151 pci_release_regions(pdev); 7154 pci_release_regions(pdev);
7152 ipr_free_mem(ioa_cfg); 7155 ipr_free_mem(ioa_cfg);
@@ -7432,6 +7435,11 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
7432 goto out; 7435 goto out;
7433 } 7436 }
7434 7437
7438 if (!(rc = pci_enable_msi(pdev)))
7439 dev_info(&pdev->dev, "MSI enabled\n");
7440 else if (ipr_debug)
7441 dev_info(&pdev->dev, "Cannot enable MSI\n");
7442
7435 dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq); 7443 dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq);
7436 7444
7437 host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg)); 7445 host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg));
@@ -7574,6 +7582,7 @@ out_release_regions:
7574out_scsi_host_put: 7582out_scsi_host_put:
7575 scsi_host_put(host); 7583 scsi_host_put(host);
7576out_disable: 7584out_disable:
7585 pci_disable_msi(pdev);
7577 pci_disable_device(pdev); 7586 pci_disable_device(pdev);
7578 goto out; 7587 goto out;
7579} 7588}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 8f872f816fe4..79a3ae4fb2c7 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -37,8 +37,8 @@
37/* 37/*
38 * Literals 38 * Literals
39 */ 39 */
40#define IPR_DRIVER_VERSION "2.4.1" 40#define IPR_DRIVER_VERSION "2.4.2"
41#define IPR_DRIVER_DATE "(April 24, 2007)" 41#define IPR_DRIVER_DATE "(January 21, 2009)"
42 42
43/* 43/*
44 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding 44 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index ef683f0d2b5a..457d76a4cfe5 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1004,8 +1004,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC)
1004 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num); 1004 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1005 1005
1006 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { 1006 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1007 scb->scsi_cmd->result = 1007 scb->scsi_cmd->result = DID_RESET << 16;
1008 (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1009 scb->scsi_cmd->scsi_done(scb->scsi_cmd); 1008 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1010 ips_freescb(ha, scb); 1009 ips_freescb(ha, scb);
1011 } 1010 }
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 23808dfe22ba..b3e5e08e44ab 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -48,13 +48,6 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
48 "Alex Aizman <itn780@yahoo.com>"); 48 "Alex Aizman <itn780@yahoo.com>");
49MODULE_DESCRIPTION("iSCSI/TCP data-path"); 49MODULE_DESCRIPTION("iSCSI/TCP data-path");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51#undef DEBUG_TCP
52
53#ifdef DEBUG_TCP
54#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt)
55#else
56#define debug_tcp(fmt...)
57#endif
58 51
59static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport; 52static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport;
60static struct scsi_host_template iscsi_sw_tcp_sht; 53static struct scsi_host_template iscsi_sw_tcp_sht;
@@ -63,6 +56,21 @@ static struct iscsi_transport iscsi_sw_tcp_transport;
63static unsigned int iscsi_max_lun = 512; 56static unsigned int iscsi_max_lun = 512;
64module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); 57module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
65 58
59static int iscsi_sw_tcp_dbg;
60module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,
61 S_IRUGO | S_IWUSR);
62MODULE_PARM_DESC(debug_iscsi_tcp, "Turn on debugging for iscsi_tcp module "
63 "Set to 1 to turn on, and zero to turn off. Default is off.");
64
65#define ISCSI_SW_TCP_DBG(_conn, dbg_fmt, arg...) \
66 do { \
67 if (iscsi_sw_tcp_dbg) \
68 iscsi_conn_printk(KERN_INFO, _conn, \
69 "%s " dbg_fmt, \
70 __func__, ##arg); \
71 } while (0);
72
73
66/** 74/**
67 * iscsi_sw_tcp_recv - TCP receive in sendfile fashion 75 * iscsi_sw_tcp_recv - TCP receive in sendfile fashion
68 * @rd_desc: read descriptor 76 * @rd_desc: read descriptor
@@ -77,7 +85,7 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
77 unsigned int consumed, total_consumed = 0; 85 unsigned int consumed, total_consumed = 0;
78 int status; 86 int status;
79 87
80 debug_tcp("in %d bytes\n", skb->len - offset); 88 ISCSI_SW_TCP_DBG(conn, "in %d bytes\n", skb->len - offset);
81 89
82 do { 90 do {
83 status = 0; 91 status = 0;
@@ -86,7 +94,8 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
86 total_consumed += consumed; 94 total_consumed += consumed;
87 } while (consumed != 0 && status != ISCSI_TCP_SKB_DONE); 95 } while (consumed != 0 && status != ISCSI_TCP_SKB_DONE);
88 96
89 debug_tcp("read %d bytes status %d\n", skb->len - offset, status); 97 ISCSI_SW_TCP_DBG(conn, "read %d bytes status %d\n",
98 skb->len - offset, status);
90 return total_consumed; 99 return total_consumed;
91} 100}
92 101
@@ -131,7 +140,8 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
131 if ((sk->sk_state == TCP_CLOSE_WAIT || 140 if ((sk->sk_state == TCP_CLOSE_WAIT ||
132 sk->sk_state == TCP_CLOSE) && 141 sk->sk_state == TCP_CLOSE) &&
133 !atomic_read(&sk->sk_rmem_alloc)) { 142 !atomic_read(&sk->sk_rmem_alloc)) {
134 debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n"); 143 ISCSI_SW_TCP_DBG(conn, "iscsi_tcp_state_change: "
144 "TCP_CLOSE|TCP_CLOSE_WAIT\n");
135 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 145 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
136 } 146 }
137 147
@@ -155,8 +165,8 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)
155 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 165 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
156 166
157 tcp_sw_conn->old_write_space(sk); 167 tcp_sw_conn->old_write_space(sk);
158 debug_tcp("iscsi_write_space: cid %d\n", conn->id); 168 ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n");
159 scsi_queue_work(conn->session->host, &conn->xmitwork); 169 iscsi_conn_queue_work(conn);
160} 170}
161 171
162static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn) 172static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
@@ -283,7 +293,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
283 } 293 }
284 } 294 }
285 295
286 debug_tcp("xmit %d bytes\n", consumed); 296 ISCSI_SW_TCP_DBG(conn, "xmit %d bytes\n", consumed);
287 297
288 conn->txdata_octets += consumed; 298 conn->txdata_octets += consumed;
289 return consumed; 299 return consumed;
@@ -291,7 +301,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
291error: 301error:
292 /* Transmit error. We could initiate error recovery 302 /* Transmit error. We could initiate error recovery
293 * here. */ 303 * here. */
294 debug_tcp("Error sending PDU, errno=%d\n", rc); 304 ISCSI_SW_TCP_DBG(conn, "Error sending PDU, errno=%d\n", rc);
295 iscsi_conn_failure(conn, rc); 305 iscsi_conn_failure(conn, rc);
296 return -EIO; 306 return -EIO;
297} 307}
@@ -334,9 +344,10 @@ static int iscsi_sw_tcp_send_hdr_done(struct iscsi_tcp_conn *tcp_conn,
334 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 344 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
335 345
336 tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment; 346 tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment;
337 debug_tcp("Header done. Next segment size %u total_size %u\n", 347 ISCSI_SW_TCP_DBG(tcp_conn->iscsi_conn,
338 tcp_sw_conn->out.segment.size, 348 "Header done. Next segment size %u total_size %u\n",
339 tcp_sw_conn->out.segment.total_size); 349 tcp_sw_conn->out.segment.size,
350 tcp_sw_conn->out.segment.total_size);
340 return 0; 351 return 0;
341} 352}
342 353
@@ -346,8 +357,8 @@ static void iscsi_sw_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr,
346 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 357 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
347 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 358 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
348 359
349 debug_tcp("%s(%p%s)\n", __func__, tcp_conn, 360 ISCSI_SW_TCP_DBG(conn, "%s\n", conn->hdrdgst_en ?
350 conn->hdrdgst_en? ", digest enabled" : ""); 361 "digest enabled" : "digest disabled");
351 362
352 /* Clear the data segment - needs to be filled in by the 363 /* Clear the data segment - needs to be filled in by the
353 * caller using iscsi_tcp_send_data_prep() */ 364 * caller using iscsi_tcp_send_data_prep() */
@@ -389,9 +400,9 @@ iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg,
389 struct hash_desc *tx_hash = NULL; 400 struct hash_desc *tx_hash = NULL;
390 unsigned int hdr_spec_len; 401 unsigned int hdr_spec_len;
391 402
392 debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__, 403 ISCSI_SW_TCP_DBG(conn, "offset=%d, datalen=%d %s\n", offset, len,
393 tcp_conn, offset, len, 404 conn->datadgst_en ?
394 conn->datadgst_en? ", digest enabled" : ""); 405 "digest enabled" : "digest disabled");
395 406
396 /* Make sure the datalen matches what the caller 407 /* Make sure the datalen matches what the caller
397 said he would send. */ 408 said he would send. */
@@ -415,8 +426,8 @@ iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data,
415 struct hash_desc *tx_hash = NULL; 426 struct hash_desc *tx_hash = NULL;
416 unsigned int hdr_spec_len; 427 unsigned int hdr_spec_len;
417 428
418 debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len, 429 ISCSI_SW_TCP_DBG(conn, "datalen=%zd %s\n", len, conn->datadgst_en ?
419 conn->datadgst_en? ", digest enabled" : ""); 430 "digest enabled" : "digest disabled");
420 431
421 /* Make sure the datalen matches what the caller 432 /* Make sure the datalen matches what the caller
422 said he would send. */ 433 said he would send. */
@@ -754,8 +765,7 @@ iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
754 765
755static struct iscsi_cls_session * 766static struct iscsi_cls_session *
756iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, 767iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
757 uint16_t qdepth, uint32_t initial_cmdsn, 768 uint16_t qdepth, uint32_t initial_cmdsn)
758 uint32_t *hostno)
759{ 769{
760 struct iscsi_cls_session *cls_session; 770 struct iscsi_cls_session *cls_session;
761 struct iscsi_session *session; 771 struct iscsi_session *session;
@@ -766,10 +776,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
766 return NULL; 776 return NULL;
767 } 777 }
768 778
769 shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, qdepth); 779 shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, 1);
770 if (!shost) 780 if (!shost)
771 return NULL; 781 return NULL;
772 shost->transportt = iscsi_sw_tcp_scsi_transport; 782 shost->transportt = iscsi_sw_tcp_scsi_transport;
783 shost->cmd_per_lun = qdepth;
773 shost->max_lun = iscsi_max_lun; 784 shost->max_lun = iscsi_max_lun;
774 shost->max_id = 0; 785 shost->max_id = 0;
775 shost->max_channel = 0; 786 shost->max_channel = 0;
@@ -777,7 +788,6 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
777 788
778 if (iscsi_host_add(shost, NULL)) 789 if (iscsi_host_add(shost, NULL))
779 goto free_host; 790 goto free_host;
780 *hostno = shost->host_no;
781 791
782 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost, 792 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost,
783 cmds_max, 793 cmds_max,
@@ -813,6 +823,12 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
813 iscsi_host_free(shost); 823 iscsi_host_free(shost);
814} 824}
815 825
826static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
827{
828 set_bit(QUEUE_FLAG_BIDI, &sdev->request_queue->queue_flags);
829 return 0;
830}
831
816static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) 832static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
817{ 833{
818 blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); 834 blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY);
@@ -833,6 +849,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
833 .eh_device_reset_handler= iscsi_eh_device_reset, 849 .eh_device_reset_handler= iscsi_eh_device_reset,
834 .eh_target_reset_handler= iscsi_eh_target_reset, 850 .eh_target_reset_handler= iscsi_eh_target_reset,
835 .use_clustering = DISABLE_CLUSTERING, 851 .use_clustering = DISABLE_CLUSTERING,
852 .slave_alloc = iscsi_sw_tcp_slave_alloc,
836 .slave_configure = iscsi_sw_tcp_slave_configure, 853 .slave_configure = iscsi_sw_tcp_slave_configure,
837 .proc_name = "iscsi_tcp", 854 .proc_name = "iscsi_tcp",
838 .this_id = -1, 855 .this_id = -1,
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 505825b6124d..992af05aacf1 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -281,7 +281,7 @@ static void fc_exch_release(struct fc_exch *ep)
281 ep->destructor(&ep->seq, ep->arg); 281 ep->destructor(&ep->seq, ep->arg);
282 if (ep->lp->tt.exch_put) 282 if (ep->lp->tt.exch_put)
283 ep->lp->tt.exch_put(ep->lp, mp, ep->xid); 283 ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
284 WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE); 284 WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
285 mempool_free(ep, mp->ep_pool); 285 mempool_free(ep, mp->ep_pool);
286 } 286 }
287} 287}
@@ -489,7 +489,7 @@ static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp)
489 struct fc_exch *ep = NULL; 489 struct fc_exch *ep = NULL;
490 490
491 if (mp->max_read) { 491 if (mp->max_read) {
492 if (fc_frame_is_read(fp)) { 492 if (fc_fcp_is_read(fr_fsp(fp))) {
493 min = mp->min_xid; 493 min = mp->min_xid;
494 max = mp->max_read; 494 max = mp->max_read;
495 plast = &mp->last_read; 495 plast = &mp->last_read;
@@ -1841,6 +1841,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
1841 fc_exch_setup_hdr(ep, fp, ep->f_ctl); 1841 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
1842 sp->cnt++; 1842 sp->cnt++;
1843 1843
1844 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
1845
1844 if (unlikely(lp->tt.frame_send(lp, fp))) 1846 if (unlikely(lp->tt.frame_send(lp, fp)))
1845 goto err; 1847 goto err;
1846 1848
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 2a631d7dbcec..a5725f3b7ce1 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -259,12 +259,62 @@ static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp)
259 } 259 }
260 260
261 fsp->state &= ~FC_SRB_ABORT_PENDING; 261 fsp->state &= ~FC_SRB_ABORT_PENDING;
262 fsp->io_status = SUGGEST_RETRY << 24; 262 fsp->io_status = 0;
263 fsp->status_code = FC_ERROR; 263 fsp->status_code = FC_ERROR;
264 fc_fcp_complete_locked(fsp); 264 fc_fcp_complete_locked(fsp);
265} 265}
266 266
267/* 267/*
268 * fc_fcp_ddp_setup - calls to LLD's ddp_setup to set up DDP
269 * transfer for a read I/O indicated by the fc_fcp_pkt.
270 * @fsp: ptr to the fc_fcp_pkt
271 *
272 * This is called in exch_seq_send() when we have a newly allocated
273 * exchange with a valid exchange id to setup ddp.
274 *
275 * returns: none
276 */
277void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid)
278{
279 struct fc_lport *lp;
280
281 if (!fsp)
282 return;
283
284 lp = fsp->lp;
285 if ((fsp->req_flags & FC_SRB_READ) &&
286 (lp->lro_enabled) && (lp->tt.ddp_setup)) {
287 if (lp->tt.ddp_setup(lp, xid, scsi_sglist(fsp->cmd),
288 scsi_sg_count(fsp->cmd)))
289 fsp->xfer_ddp = xid;
290 }
291}
292EXPORT_SYMBOL(fc_fcp_ddp_setup);
293
294/*
295 * fc_fcp_ddp_done - calls to LLD's ddp_done to release any
296 * DDP related resources for this I/O if it is initialized
297 * as a ddp transfer
298 * @fsp: ptr to the fc_fcp_pkt
299 *
300 * returns: none
301 */
302static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
303{
304 struct fc_lport *lp;
305
306 if (!fsp)
307 return;
308
309 lp = fsp->lp;
310 if (fsp->xfer_ddp && lp->tt.ddp_done) {
311 fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
312 fsp->xfer_ddp = 0;
313 }
314}
315
316
317/*
268 * Receive SCSI data from target. 318 * Receive SCSI data from target.
269 * Called after receiving solicited data. 319 * Called after receiving solicited data.
270 */ 320 */
@@ -289,6 +339,9 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
289 len = fr_len(fp) - sizeof(*fh); 339 len = fr_len(fp) - sizeof(*fh);
290 buf = fc_frame_payload_get(fp, 0); 340 buf = fc_frame_payload_get(fp, 0);
291 341
342 /* if this I/O is ddped, update xfer len */
343 fc_fcp_ddp_done(fsp);
344
292 if (offset + len > fsp->data_len) { 345 if (offset + len > fsp->data_len) {
293 /* this should never happen */ 346 /* this should never happen */
294 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && 347 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
@@ -435,7 +488,13 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
435 * burst length (t_blen) to seq_blen, otherwise set t_blen 488 * burst length (t_blen) to seq_blen, otherwise set t_blen
436 * to max FC frame payload previously set in fsp->max_payload. 489 * to max FC frame payload previously set in fsp->max_payload.
437 */ 490 */
438 t_blen = lp->seq_offload ? seq_blen : fsp->max_payload; 491 t_blen = fsp->max_payload;
492 if (lp->seq_offload) {
493 t_blen = min(seq_blen, (size_t)lp->lso_max);
494 FC_DEBUG_FCP("fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n",
495 fsp, seq_blen, lp->lso_max, t_blen);
496 }
497
439 WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD); 498 WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
440 if (t_blen > 512) 499 if (t_blen > 512)
441 t_blen &= ~(512 - 1); /* round down to block size */ 500 t_blen &= ~(512 - 1); /* round down to block size */
@@ -744,6 +803,9 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
744 fsp->scsi_comp_flags = flags; 803 fsp->scsi_comp_flags = flags;
745 expected_len = fsp->data_len; 804 expected_len = fsp->data_len;
746 805
806 /* if ddp, update xfer len */
807 fc_fcp_ddp_done(fsp);
808
747 if (unlikely((flags & ~FCP_CONF_REQ) || fc_rp->fr_status)) { 809 if (unlikely((flags & ~FCP_CONF_REQ) || fc_rp->fr_status)) {
748 rp_ex = (void *)(fc_rp + 1); 810 rp_ex = (void *)(fc_rp + 1);
749 if (flags & (FCP_RSP_LEN_VAL | FCP_SNS_LEN_VAL)) { 811 if (flags & (FCP_RSP_LEN_VAL | FCP_SNS_LEN_VAL)) {
@@ -859,7 +921,7 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
859 (!(fsp->scsi_comp_flags & FCP_RESID_UNDER) || 921 (!(fsp->scsi_comp_flags & FCP_RESID_UNDER) ||
860 fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) { 922 fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) {
861 fsp->status_code = FC_DATA_UNDRUN; 923 fsp->status_code = FC_DATA_UNDRUN;
862 fsp->io_status = SUGGEST_RETRY << 24; 924 fsp->io_status = 0;
863 } 925 }
864 } 926 }
865 927
@@ -1006,7 +1068,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
1006 } 1068 }
1007 1069
1008 memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len); 1070 memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len);
1009 fr_cmd(fp) = fsp->cmd; 1071 fr_fsp(fp) = fsp;
1010 rport = fsp->rport; 1072 rport = fsp->rport;
1011 fsp->max_payload = rport->maxframe_size; 1073 fsp->max_payload = rport->maxframe_size;
1012 rp = rport->dd_data; 1074 rp = rport->dd_data;
@@ -1267,7 +1329,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1267 rp = rport->dd_data; 1329 rp = rport->dd_data;
1268 if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) { 1330 if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) {
1269 fsp->status_code = FC_HRD_ERROR; 1331 fsp->status_code = FC_HRD_ERROR;
1270 fsp->io_status = SUGGEST_RETRY << 24; 1332 fsp->io_status = 0;
1271 fc_fcp_complete_locked(fsp); 1333 fc_fcp_complete_locked(fsp);
1272 return; 1334 return;
1273 } 1335 }
@@ -1740,6 +1802,9 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1740 struct fc_lport *lp; 1802 struct fc_lport *lp;
1741 unsigned long flags; 1803 unsigned long flags;
1742 1804
1805 /* release outstanding ddp context */
1806 fc_fcp_ddp_done(fsp);
1807
1743 fsp->state |= FC_SRB_COMPL; 1808 fsp->state |= FC_SRB_COMPL;
1744 if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) { 1809 if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) {
1745 spin_unlock_bh(&fsp->scsi_pkt_lock); 1810 spin_unlock_bh(&fsp->scsi_pkt_lock);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 2ae50a1188e6..7ef44501ecc6 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -762,10 +762,11 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
762 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); 762 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
763 if (remote_wwpn == lport->wwpn) { 763 if (remote_wwpn == lport->wwpn) {
764 FC_DBG("FLOGI from port with same WWPN %llx " 764 FC_DBG("FLOGI from port with same WWPN %llx "
765 "possible configuration error\n", remote_wwpn); 765 "possible configuration error\n",
766 (unsigned long long)remote_wwpn);
766 goto out; 767 goto out;
767 } 768 }
768 FC_DBG("FLOGI from port WWPN %llx\n", remote_wwpn); 769 FC_DBG("FLOGI from port WWPN %llx\n", (unsigned long long)remote_wwpn);
769 770
770 /* 771 /*
771 * XXX what is the right thing to do for FIDs? 772 * XXX what is the right thing to do for FIDs?
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index dae65133a833..0472bb73221e 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -988,7 +988,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
988 switch (rdata->rp_state) { 988 switch (rdata->rp_state) {
989 case RPORT_ST_INIT: 989 case RPORT_ST_INIT:
990 FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT " 990 FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT "
991 "- reject\n", sid, wwpn); 991 "- reject\n", sid, (unsigned long long)wwpn);
992 reject = ELS_RJT_UNSUP; 992 reject = ELS_RJT_UNSUP;
993 break; 993 break;
994 case RPORT_ST_PLOGI: 994 case RPORT_ST_PLOGI:
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 809d32d95c76..dfaa8adf099e 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -38,6 +38,28 @@
38#include <scsi/scsi_transport_iscsi.h> 38#include <scsi/scsi_transport_iscsi.h>
39#include <scsi/libiscsi.h> 39#include <scsi/libiscsi.h>
40 40
41static int iscsi_dbg_lib;
42module_param_named(debug_libiscsi, iscsi_dbg_lib, int, S_IRUGO | S_IWUSR);
43MODULE_PARM_DESC(debug_libiscsi, "Turn on debugging for libiscsi module. "
44 "Set to 1 to turn on, and zero to turn off. Default "
45 "is off.");
46
47#define ISCSI_DBG_CONN(_conn, dbg_fmt, arg...) \
48 do { \
49 if (iscsi_dbg_lib) \
50 iscsi_conn_printk(KERN_INFO, _conn, \
51 "%s " dbg_fmt, \
52 __func__, ##arg); \
53 } while (0);
54
55#define ISCSI_DBG_SESSION(_session, dbg_fmt, arg...) \
56 do { \
57 if (iscsi_dbg_lib) \
58 iscsi_session_printk(KERN_INFO, _session, \
59 "%s " dbg_fmt, \
60 __func__, ##arg); \
61 } while (0);
62
41/* Serial Number Arithmetic, 32 bits, less than, RFC1982 */ 63/* Serial Number Arithmetic, 32 bits, less than, RFC1982 */
42#define SNA32_CHECK 2147483648UL 64#define SNA32_CHECK 2147483648UL
43 65
@@ -54,6 +76,15 @@ static int iscsi_sna_lte(u32 n1, u32 n2)
54 (n1 > n2 && (n2 - n1 < SNA32_CHECK))); 76 (n1 > n2 && (n2 - n1 < SNA32_CHECK)));
55} 77}
56 78
79inline void iscsi_conn_queue_work(struct iscsi_conn *conn)
80{
81 struct Scsi_Host *shost = conn->session->host;
82 struct iscsi_host *ihost = shost_priv(shost);
83
84 queue_work(ihost->workq, &conn->xmitwork);
85}
86EXPORT_SYMBOL_GPL(iscsi_conn_queue_work);
87
57void 88void
58iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) 89iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
59{ 90{
@@ -81,8 +112,7 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
81 if (!list_empty(&session->leadconn->xmitqueue) || 112 if (!list_empty(&session->leadconn->xmitqueue) ||
82 !list_empty(&session->leadconn->mgmtqueue)) { 113 !list_empty(&session->leadconn->mgmtqueue)) {
83 if (!(session->tt->caps & CAP_DATA_PATH_OFFLOAD)) 114 if (!(session->tt->caps & CAP_DATA_PATH_OFFLOAD))
84 scsi_queue_work(session->host, 115 iscsi_conn_queue_work(session->leadconn);
85 &session->leadconn->xmitwork);
86 } 116 }
87 } 117 }
88} 118}
@@ -176,10 +206,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
176 ecdb_ahdr->reserved = 0; 206 ecdb_ahdr->reserved = 0;
177 memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen); 207 memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen);
178 208
179 debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d " 209 ISCSI_DBG_SESSION(task->conn->session,
180 "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n", 210 "iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
181 cmd->cmd_len, rlen, pad_len, ahslength, task->hdr_len); 211 "rlen %d pad_len %d ahs_length %d iscsi_headers_size "
182 212 "%u\n", cmd->cmd_len, rlen, pad_len, ahslength,
213 task->hdr_len);
183 return 0; 214 return 0;
184} 215}
185 216
@@ -201,10 +232,11 @@ static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
201 rlen_ahdr->reserved = 0; 232 rlen_ahdr->reserved = 0;
202 rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length); 233 rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
203 234
204 debug_scsi("bidi-in rlen_ahdr->read_length(%d) " 235 ISCSI_DBG_SESSION(task->conn->session,
205 "rlen_ahdr->ahslength(%d)\n", 236 "bidi-in rlen_ahdr->read_length(%d) "
206 be32_to_cpu(rlen_ahdr->read_length), 237 "rlen_ahdr->ahslength(%d)\n",
207 be16_to_cpu(rlen_ahdr->ahslength)); 238 be32_to_cpu(rlen_ahdr->read_length),
239 be16_to_cpu(rlen_ahdr->ahslength));
208 return 0; 240 return 0;
209} 241}
210 242
@@ -335,13 +367,15 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
335 list_move_tail(&task->running, &conn->run_list); 367 list_move_tail(&task->running, &conn->run_list);
336 368
337 conn->scsicmd_pdus_cnt++; 369 conn->scsicmd_pdus_cnt++;
338 debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " 370 ISCSI_DBG_SESSION(session, "iscsi prep [%s cid %d sc %p cdb 0x%x "
339 "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ? 371 "itt 0x%x len %d bidi_len %d cmdsn %d win %d]\n",
340 "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ? 372 scsi_bidi_cmnd(sc) ? "bidirectional" :
341 "write" : "read", conn->id, sc, sc->cmnd[0], task->itt, 373 sc->sc_data_direction == DMA_TO_DEVICE ?
342 scsi_bufflen(sc), 374 "write" : "read", conn->id, sc, sc->cmnd[0],
343 scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, 375 task->itt, scsi_bufflen(sc),
344 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); 376 scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
377 session->cmdsn,
378 session->max_cmdsn - session->exp_cmdsn + 1);
345 return 0; 379 return 0;
346} 380}
347 381
@@ -483,9 +517,9 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
483 517
484 task->state = ISCSI_TASK_RUNNING; 518 task->state = ISCSI_TASK_RUNNING;
485 list_move_tail(&task->running, &conn->mgmt_run_list); 519 list_move_tail(&task->running, &conn->mgmt_run_list);
486 debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", 520 ISCSI_DBG_SESSION(session, "mgmtpdu [op 0x%x hdr->itt 0x%x "
487 hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, 521 "datalen %d]\n", hdr->opcode & ISCSI_OPCODE_MASK,
488 task->data_count); 522 hdr->itt, task->data_count);
489 return 0; 523 return 0;
490} 524}
491 525
@@ -560,7 +594,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
560 goto free_task; 594 goto free_task;
561 595
562 } else 596 } else
563 scsi_queue_work(conn->session->host, &conn->xmitwork); 597 iscsi_conn_queue_work(conn);
564 598
565 return task; 599 return task;
566 600
@@ -637,8 +671,9 @@ invalid_datalen:
637 671
638 memcpy(sc->sense_buffer, data + 2, 672 memcpy(sc->sense_buffer, data + 2,
639 min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); 673 min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
640 debug_scsi("copied %d bytes of sense\n", 674 ISCSI_DBG_SESSION(session, "copied %d bytes of sense\n",
641 min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); 675 min_t(uint16_t, senselen,
676 SCSI_SENSE_BUFFERSIZE));
642 } 677 }
643 678
644 if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | 679 if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
@@ -666,8 +701,8 @@ invalid_datalen:
666 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; 701 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
667 } 702 }
668out: 703out:
669 debug_scsi("done [sc %lx res %d itt 0x%x]\n", 704 ISCSI_DBG_SESSION(session, "done [sc %p res %d itt 0x%x]\n",
670 (long)sc, sc->result, task->itt); 705 sc, sc->result, task->itt);
671 conn->scsirsp_pdus_cnt++; 706 conn->scsirsp_pdus_cnt++;
672 707
673 __iscsi_put_task(task); 708 __iscsi_put_task(task);
@@ -835,8 +870,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
835 else 870 else
836 itt = ~0U; 871 itt = ~0U;
837 872
838 debug_scsi("[op 0x%x cid %d itt 0x%x len %d]\n", 873 ISCSI_DBG_SESSION(session, "[op 0x%x cid %d itt 0x%x len %d]\n",
839 opcode, conn->id, itt, datalen); 874 opcode, conn->id, itt, datalen);
840 875
841 if (itt == ~0U) { 876 if (itt == ~0U) {
842 iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); 877 iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
@@ -1034,10 +1069,9 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
1034} 1069}
1035EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); 1070EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
1036 1071
1037void iscsi_session_failure(struct iscsi_cls_session *cls_session, 1072void iscsi_session_failure(struct iscsi_session *session,
1038 enum iscsi_err err) 1073 enum iscsi_err err)
1039{ 1074{
1040 struct iscsi_session *session = cls_session->dd_data;
1041 struct iscsi_conn *conn; 1075 struct iscsi_conn *conn;
1042 struct device *dev; 1076 struct device *dev;
1043 unsigned long flags; 1077 unsigned long flags;
@@ -1095,10 +1129,10 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
1095 * Check for iSCSI window and take care of CmdSN wrap-around 1129 * Check for iSCSI window and take care of CmdSN wrap-around
1096 */ 1130 */
1097 if (!iscsi_sna_lte(session->queued_cmdsn, session->max_cmdsn)) { 1131 if (!iscsi_sna_lte(session->queued_cmdsn, session->max_cmdsn)) {
1098 debug_scsi("iSCSI CmdSN closed. ExpCmdSn %u MaxCmdSN %u " 1132 ISCSI_DBG_SESSION(session, "iSCSI CmdSN closed. ExpCmdSn "
1099 "CmdSN %u/%u\n", session->exp_cmdsn, 1133 "%u MaxCmdSN %u CmdSN %u/%u\n",
1100 session->max_cmdsn, session->cmdsn, 1134 session->exp_cmdsn, session->max_cmdsn,
1101 session->queued_cmdsn); 1135 session->cmdsn, session->queued_cmdsn);
1102 return -ENOSPC; 1136 return -ENOSPC;
1103 } 1137 }
1104 return 0; 1138 return 0;
@@ -1133,7 +1167,7 @@ void iscsi_requeue_task(struct iscsi_task *task)
1133 struct iscsi_conn *conn = task->conn; 1167 struct iscsi_conn *conn = task->conn;
1134 1168
1135 list_move_tail(&task->running, &conn->requeue); 1169 list_move_tail(&task->running, &conn->requeue);
1136 scsi_queue_work(conn->session->host, &conn->xmitwork); 1170 iscsi_conn_queue_work(conn);
1137} 1171}
1138EXPORT_SYMBOL_GPL(iscsi_requeue_task); 1172EXPORT_SYMBOL_GPL(iscsi_requeue_task);
1139 1173
@@ -1152,7 +1186,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
1152 1186
1153 spin_lock_bh(&conn->session->lock); 1187 spin_lock_bh(&conn->session->lock);
1154 if (unlikely(conn->suspend_tx)) { 1188 if (unlikely(conn->suspend_tx)) {
1155 debug_scsi("conn %d Tx suspended!\n", conn->id); 1189 ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
1156 spin_unlock_bh(&conn->session->lock); 1190 spin_unlock_bh(&conn->session->lock);
1157 return -ENODATA; 1191 return -ENODATA;
1158 } 1192 }
@@ -1386,7 +1420,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
1386 goto prepd_reject; 1420 goto prepd_reject;
1387 } 1421 }
1388 } else 1422 } else
1389 scsi_queue_work(session->host, &conn->xmitwork); 1423 iscsi_conn_queue_work(conn);
1390 1424
1391 session->queued_cmdsn++; 1425 session->queued_cmdsn++;
1392 spin_unlock(&session->lock); 1426 spin_unlock(&session->lock);
@@ -1398,7 +1432,8 @@ prepd_reject:
1398 iscsi_complete_command(task); 1432 iscsi_complete_command(task);
1399reject: 1433reject:
1400 spin_unlock(&session->lock); 1434 spin_unlock(&session->lock);
1401 debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); 1435 ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
1436 sc->cmnd[0], reason);
1402 spin_lock(host->host_lock); 1437 spin_lock(host->host_lock);
1403 return SCSI_MLQUEUE_TARGET_BUSY; 1438 return SCSI_MLQUEUE_TARGET_BUSY;
1404 1439
@@ -1407,7 +1442,8 @@ prepd_fault:
1407 iscsi_complete_command(task); 1442 iscsi_complete_command(task);
1408fault: 1443fault:
1409 spin_unlock(&session->lock); 1444 spin_unlock(&session->lock);
1410 debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); 1445 ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
1446 sc->cmnd[0], reason);
1411 if (!scsi_bidi_cmnd(sc)) 1447 if (!scsi_bidi_cmnd(sc))
1412 scsi_set_resid(sc, scsi_bufflen(sc)); 1448 scsi_set_resid(sc, scsi_bufflen(sc));
1413 else { 1449 else {
@@ -1422,8 +1458,6 @@ EXPORT_SYMBOL_GPL(iscsi_queuecommand);
1422 1458
1423int iscsi_change_queue_depth(struct scsi_device *sdev, int depth) 1459int iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
1424{ 1460{
1425 if (depth > ISCSI_MAX_CMD_PER_LUN)
1426 depth = ISCSI_MAX_CMD_PER_LUN;
1427 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); 1461 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
1428 return sdev->queue_depth; 1462 return sdev->queue_depth;
1429} 1463}
@@ -1457,8 +1491,10 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc)
1457 spin_lock_bh(&session->lock); 1491 spin_lock_bh(&session->lock);
1458 if (session->state == ISCSI_STATE_TERMINATE) { 1492 if (session->state == ISCSI_STATE_TERMINATE) {
1459failed: 1493failed:
1460 debug_scsi("failing target reset: session terminated " 1494 iscsi_session_printk(KERN_INFO, session,
1461 "[CID %d age %d]\n", conn->id, session->age); 1495 "failing target reset: Could not log "
1496 "back into target [age %d]\n",
1497 session->age);
1462 spin_unlock_bh(&session->lock); 1498 spin_unlock_bh(&session->lock);
1463 mutex_unlock(&session->eh_mutex); 1499 mutex_unlock(&session->eh_mutex);
1464 return FAILED; 1500 return FAILED;
@@ -1472,7 +1508,7 @@ failed:
1472 */ 1508 */
1473 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1509 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1474 1510
1475 debug_scsi("iscsi_eh_target_reset wait for relogin\n"); 1511 ISCSI_DBG_SESSION(session, "wait for relogin\n");
1476 wait_event_interruptible(conn->ehwait, 1512 wait_event_interruptible(conn->ehwait,
1477 session->state == ISCSI_STATE_TERMINATE || 1513 session->state == ISCSI_STATE_TERMINATE ||
1478 session->state == ISCSI_STATE_LOGGED_IN || 1514 session->state == ISCSI_STATE_LOGGED_IN ||
@@ -1501,7 +1537,7 @@ static void iscsi_tmf_timedout(unsigned long data)
1501 spin_lock(&session->lock); 1537 spin_lock(&session->lock);
1502 if (conn->tmf_state == TMF_QUEUED) { 1538 if (conn->tmf_state == TMF_QUEUED) {
1503 conn->tmf_state = TMF_TIMEDOUT; 1539 conn->tmf_state = TMF_TIMEDOUT;
1504 debug_scsi("tmf timedout\n"); 1540 ISCSI_DBG_SESSION(session, "tmf timedout\n");
1505 /* unblock eh_abort() */ 1541 /* unblock eh_abort() */
1506 wake_up(&conn->ehwait); 1542 wake_up(&conn->ehwait);
1507 } 1543 }
@@ -1521,7 +1557,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
1521 spin_unlock_bh(&session->lock); 1557 spin_unlock_bh(&session->lock);
1522 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1558 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1523 spin_lock_bh(&session->lock); 1559 spin_lock_bh(&session->lock);
1524 debug_scsi("tmf exec failure\n"); 1560 ISCSI_DBG_SESSION(session, "tmf exec failure\n");
1525 return -EPERM; 1561 return -EPERM;
1526 } 1562 }
1527 conn->tmfcmd_pdus_cnt++; 1563 conn->tmfcmd_pdus_cnt++;
@@ -1529,7 +1565,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
1529 conn->tmf_timer.function = iscsi_tmf_timedout; 1565 conn->tmf_timer.function = iscsi_tmf_timedout;
1530 conn->tmf_timer.data = (unsigned long)conn; 1566 conn->tmf_timer.data = (unsigned long)conn;
1531 add_timer(&conn->tmf_timer); 1567 add_timer(&conn->tmf_timer);
1532 debug_scsi("tmf set timeout\n"); 1568 ISCSI_DBG_SESSION(session, "tmf set timeout\n");
1533 1569
1534 spin_unlock_bh(&session->lock); 1570 spin_unlock_bh(&session->lock);
1535 mutex_unlock(&session->eh_mutex); 1571 mutex_unlock(&session->eh_mutex);
@@ -1567,22 +1603,27 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
1567{ 1603{
1568 struct iscsi_task *task, *tmp; 1604 struct iscsi_task *task, *tmp;
1569 1605
1570 if (conn->task && (conn->task->sc->device->lun == lun || lun == -1)) 1606 if (conn->task) {
1571 conn->task = NULL; 1607 if (lun == -1 ||
1608 (conn->task->sc && conn->task->sc->device->lun == lun))
1609 conn->task = NULL;
1610 }
1572 1611
1573 /* flush pending */ 1612 /* flush pending */
1574 list_for_each_entry_safe(task, tmp, &conn->xmitqueue, running) { 1613 list_for_each_entry_safe(task, tmp, &conn->xmitqueue, running) {
1575 if (lun == task->sc->device->lun || lun == -1) { 1614 if (lun == task->sc->device->lun || lun == -1) {
1576 debug_scsi("failing pending sc %p itt 0x%x\n", 1615 ISCSI_DBG_SESSION(conn->session,
1577 task->sc, task->itt); 1616 "failing pending sc %p itt 0x%x\n",
1617 task->sc, task->itt);
1578 fail_command(conn, task, error << 16); 1618 fail_command(conn, task, error << 16);
1579 } 1619 }
1580 } 1620 }
1581 1621
1582 list_for_each_entry_safe(task, tmp, &conn->requeue, running) { 1622 list_for_each_entry_safe(task, tmp, &conn->requeue, running) {
1583 if (lun == task->sc->device->lun || lun == -1) { 1623 if (lun == task->sc->device->lun || lun == -1) {
1584 debug_scsi("failing requeued sc %p itt 0x%x\n", 1624 ISCSI_DBG_SESSION(conn->session,
1585 task->sc, task->itt); 1625 "failing requeued sc %p itt 0x%x\n",
1626 task->sc, task->itt);
1586 fail_command(conn, task, error << 16); 1627 fail_command(conn, task, error << 16);
1587 } 1628 }
1588 } 1629 }
@@ -1590,8 +1631,9 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
1590 /* fail all other running */ 1631 /* fail all other running */
1591 list_for_each_entry_safe(task, tmp, &conn->run_list, running) { 1632 list_for_each_entry_safe(task, tmp, &conn->run_list, running) {
1592 if (lun == task->sc->device->lun || lun == -1) { 1633 if (lun == task->sc->device->lun || lun == -1) {
1593 debug_scsi("failing in progress sc %p itt 0x%x\n", 1634 ISCSI_DBG_SESSION(conn->session,
1594 task->sc, task->itt); 1635 "failing in progress sc %p itt 0x%x\n",
1636 task->sc, task->itt);
1595 fail_command(conn, task, error << 16); 1637 fail_command(conn, task, error << 16);
1596 } 1638 }
1597 } 1639 }
@@ -1599,9 +1641,12 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
1599 1641
1600void iscsi_suspend_tx(struct iscsi_conn *conn) 1642void iscsi_suspend_tx(struct iscsi_conn *conn)
1601{ 1643{
1644 struct Scsi_Host *shost = conn->session->host;
1645 struct iscsi_host *ihost = shost_priv(shost);
1646
1602 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1647 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1603 if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD)) 1648 if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
1604 scsi_flush_work(conn->session->host); 1649 flush_workqueue(ihost->workq);
1605} 1650}
1606EXPORT_SYMBOL_GPL(iscsi_suspend_tx); 1651EXPORT_SYMBOL_GPL(iscsi_suspend_tx);
1607 1652
@@ -1609,7 +1654,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
1609{ 1654{
1610 clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1655 clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1611 if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD)) 1656 if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD))
1612 scsi_queue_work(conn->session->host, &conn->xmitwork); 1657 iscsi_conn_queue_work(conn);
1613} 1658}
1614 1659
1615static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) 1660static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
@@ -1622,7 +1667,7 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1622 cls_session = starget_to_session(scsi_target(scmd->device)); 1667 cls_session = starget_to_session(scsi_target(scmd->device));
1623 session = cls_session->dd_data; 1668 session = cls_session->dd_data;
1624 1669
1625 debug_scsi("scsi cmd %p timedout\n", scmd); 1670 ISCSI_DBG_SESSION(session, "scsi cmd %p timedout\n", scmd);
1626 1671
1627 spin_lock(&session->lock); 1672 spin_lock(&session->lock);
1628 if (session->state != ISCSI_STATE_LOGGED_IN) { 1673 if (session->state != ISCSI_STATE_LOGGED_IN) {
@@ -1662,8 +1707,8 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
1662 rc = BLK_EH_RESET_TIMER; 1707 rc = BLK_EH_RESET_TIMER;
1663done: 1708done:
1664 spin_unlock(&session->lock); 1709 spin_unlock(&session->lock);
1665 debug_scsi("return %s\n", rc == BLK_EH_RESET_TIMER ? 1710 ISCSI_DBG_SESSION(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
1666 "timer reset" : "nh"); 1711 "timer reset" : "nh");
1667 return rc; 1712 return rc;
1668} 1713}
1669 1714
@@ -1697,13 +1742,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
1697 1742
1698 if (time_before_eq(last_recv + recv_timeout, jiffies)) { 1743 if (time_before_eq(last_recv + recv_timeout, jiffies)) {
1699 /* send a ping to try to provoke some traffic */ 1744 /* send a ping to try to provoke some traffic */
1700 debug_scsi("Sending nopout as ping on conn %p\n", conn); 1745 ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
1701 iscsi_send_nopout(conn, NULL); 1746 iscsi_send_nopout(conn, NULL);
1702 next_timeout = conn->last_ping + (conn->ping_timeout * HZ); 1747 next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
1703 } else 1748 } else
1704 next_timeout = last_recv + recv_timeout; 1749 next_timeout = last_recv + recv_timeout;
1705 1750
1706 debug_scsi("Setting next tmo %lu\n", next_timeout); 1751 ISCSI_DBG_CONN(conn, "Setting next tmo %lu\n", next_timeout);
1707 mod_timer(&conn->transport_timer, next_timeout); 1752 mod_timer(&conn->transport_timer, next_timeout);
1708done: 1753done:
1709 spin_unlock(&session->lock); 1754 spin_unlock(&session->lock);
@@ -1740,7 +1785,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1740 * got the command. 1785 * got the command.
1741 */ 1786 */
1742 if (!sc->SCp.ptr) { 1787 if (!sc->SCp.ptr) {
1743 debug_scsi("sc never reached iscsi layer or it completed.\n"); 1788 ISCSI_DBG_SESSION(session, "sc never reached iscsi layer or "
1789 "it completed.\n");
1744 spin_unlock_bh(&session->lock); 1790 spin_unlock_bh(&session->lock);
1745 mutex_unlock(&session->eh_mutex); 1791 mutex_unlock(&session->eh_mutex);
1746 return SUCCESS; 1792 return SUCCESS;
@@ -1762,11 +1808,13 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1762 age = session->age; 1808 age = session->age;
1763 1809
1764 task = (struct iscsi_task *)sc->SCp.ptr; 1810 task = (struct iscsi_task *)sc->SCp.ptr;
1765 debug_scsi("aborting [sc %p itt 0x%x]\n", sc, task->itt); 1811 ISCSI_DBG_SESSION(session, "aborting [sc %p itt 0x%x]\n",
1812 sc, task->itt);
1766 1813
1767 /* task completed before time out */ 1814 /* task completed before time out */
1768 if (!task->sc) { 1815 if (!task->sc) {
1769 debug_scsi("sc completed while abort in progress\n"); 1816 ISCSI_DBG_SESSION(session, "sc completed while abort in "
1817 "progress\n");
1770 goto success; 1818 goto success;
1771 } 1819 }
1772 1820
@@ -1815,7 +1863,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1815 if (!sc->SCp.ptr) { 1863 if (!sc->SCp.ptr) {
1816 conn->tmf_state = TMF_INITIAL; 1864 conn->tmf_state = TMF_INITIAL;
1817 /* task completed before tmf abort response */ 1865 /* task completed before tmf abort response */
1818 debug_scsi("sc completed while abort in progress\n"); 1866 ISCSI_DBG_SESSION(session, "sc completed while abort "
1867 "in progress\n");
1819 goto success; 1868 goto success;
1820 } 1869 }
1821 /* fall through */ 1870 /* fall through */
@@ -1827,15 +1876,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1827success: 1876success:
1828 spin_unlock_bh(&session->lock); 1877 spin_unlock_bh(&session->lock);
1829success_unlocked: 1878success_unlocked:
1830 debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, task->itt); 1879 ISCSI_DBG_SESSION(session, "abort success [sc %p itt 0x%x]\n",
1880 sc, task->itt);
1831 mutex_unlock(&session->eh_mutex); 1881 mutex_unlock(&session->eh_mutex);
1832 return SUCCESS; 1882 return SUCCESS;
1833 1883
1834failed: 1884failed:
1835 spin_unlock_bh(&session->lock); 1885 spin_unlock_bh(&session->lock);
1836failed_unlocked: 1886failed_unlocked:
1837 debug_scsi("abort failed [sc %p itt 0x%x]\n", sc, 1887 ISCSI_DBG_SESSION(session, "abort failed [sc %p itt 0x%x]\n", sc,
1838 task ? task->itt : 0); 1888 task ? task->itt : 0);
1839 mutex_unlock(&session->eh_mutex); 1889 mutex_unlock(&session->eh_mutex);
1840 return FAILED; 1890 return FAILED;
1841} 1891}
@@ -1862,7 +1912,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
1862 cls_session = starget_to_session(scsi_target(sc->device)); 1912 cls_session = starget_to_session(scsi_target(sc->device));
1863 session = cls_session->dd_data; 1913 session = cls_session->dd_data;
1864 1914
1865 debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun); 1915 ISCSI_DBG_SESSION(session, "LU Reset [sc %p lun %u]\n",
1916 sc, sc->device->lun);
1866 1917
1867 mutex_lock(&session->eh_mutex); 1918 mutex_lock(&session->eh_mutex);
1868 spin_lock_bh(&session->lock); 1919 spin_lock_bh(&session->lock);
@@ -1916,8 +1967,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
1916unlock: 1967unlock:
1917 spin_unlock_bh(&session->lock); 1968 spin_unlock_bh(&session->lock);
1918done: 1969done:
1919 debug_scsi("iscsi_eh_device_reset %s\n", 1970 ISCSI_DBG_SESSION(session, "dev reset result = %s\n",
1920 rc == SUCCESS ? "SUCCESS" : "FAILED"); 1971 rc == SUCCESS ? "SUCCESS" : "FAILED");
1921 mutex_unlock(&session->eh_mutex); 1972 mutex_unlock(&session->eh_mutex);
1922 return rc; 1973 return rc;
1923} 1974}
@@ -1944,7 +1995,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
1944 num_arrays++; 1995 num_arrays++;
1945 q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); 1996 q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL);
1946 if (q->pool == NULL) 1997 if (q->pool == NULL)
1947 goto enomem; 1998 return -ENOMEM;
1948 1999
1949 q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), 2000 q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
1950 GFP_KERNEL, NULL); 2001 GFP_KERNEL, NULL);
@@ -1979,8 +2030,7 @@ void iscsi_pool_free(struct iscsi_pool *q)
1979 2030
1980 for (i = 0; i < q->max; i++) 2031 for (i = 0; i < q->max; i++)
1981 kfree(q->pool[i]); 2032 kfree(q->pool[i]);
1982 if (q->pool) 2033 kfree(q->pool);
1983 kfree(q->pool);
1984 kfree(q->queue); 2034 kfree(q->queue);
1985} 2035}
1986EXPORT_SYMBOL_GPL(iscsi_pool_free); 2036EXPORT_SYMBOL_GPL(iscsi_pool_free);
@@ -1998,6 +2048,9 @@ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
1998 if (!shost->can_queue) 2048 if (!shost->can_queue)
1999 shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX; 2049 shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
2000 2050
2051 if (!shost->cmd_per_lun)
2052 shost->cmd_per_lun = ISCSI_DEF_CMD_PER_LUN;
2053
2001 if (!shost->transportt->eh_timed_out) 2054 if (!shost->transportt->eh_timed_out)
2002 shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; 2055 shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
2003 return scsi_add_host(shost, pdev); 2056 return scsi_add_host(shost, pdev);
@@ -2008,13 +2061,13 @@ EXPORT_SYMBOL_GPL(iscsi_host_add);
2008 * iscsi_host_alloc - allocate a host and driver data 2061 * iscsi_host_alloc - allocate a host and driver data
2009 * @sht: scsi host template 2062 * @sht: scsi host template
2010 * @dd_data_size: driver host data size 2063 * @dd_data_size: driver host data size
2011 * @qdepth: default device queue depth 2064 * @xmit_can_sleep: bool indicating if LLD will queue IO from a work queue
2012 * 2065 *
2013 * This should be called by partial offload and software iscsi drivers. 2066 * This should be called by partial offload and software iscsi drivers.
2014 * To access the driver specific memory use the iscsi_host_priv() macro. 2067 * To access the driver specific memory use the iscsi_host_priv() macro.
2015 */ 2068 */
2016struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, 2069struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
2017 int dd_data_size, uint16_t qdepth) 2070 int dd_data_size, bool xmit_can_sleep)
2018{ 2071{
2019 struct Scsi_Host *shost; 2072 struct Scsi_Host *shost;
2020 struct iscsi_host *ihost; 2073 struct iscsi_host *ihost;
@@ -2022,28 +2075,31 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
2022 shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); 2075 shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
2023 if (!shost) 2076 if (!shost)
2024 return NULL; 2077 return NULL;
2078 ihost = shost_priv(shost);
2025 2079
2026 if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { 2080 if (xmit_can_sleep) {
2027 if (qdepth != 0) 2081 snprintf(ihost->workq_name, sizeof(ihost->workq_name),
2028 printk(KERN_ERR "iscsi: invalid queue depth of %d. " 2082 "iscsi_q_%d", shost->host_no);
2029 "Queue depth must be between 1 and %d.\n", 2083 ihost->workq = create_singlethread_workqueue(ihost->workq_name);
2030 qdepth, ISCSI_MAX_CMD_PER_LUN); 2084 if (!ihost->workq)
2031 qdepth = ISCSI_DEF_CMD_PER_LUN; 2085 goto free_host;
2032 } 2086 }
2033 shost->cmd_per_lun = qdepth;
2034 2087
2035 ihost = shost_priv(shost);
2036 spin_lock_init(&ihost->lock); 2088 spin_lock_init(&ihost->lock);
2037 ihost->state = ISCSI_HOST_SETUP; 2089 ihost->state = ISCSI_HOST_SETUP;
2038 ihost->num_sessions = 0; 2090 ihost->num_sessions = 0;
2039 init_waitqueue_head(&ihost->session_removal_wq); 2091 init_waitqueue_head(&ihost->session_removal_wq);
2040 return shost; 2092 return shost;
2093
2094free_host:
2095 scsi_host_put(shost);
2096 return NULL;
2041} 2097}
2042EXPORT_SYMBOL_GPL(iscsi_host_alloc); 2098EXPORT_SYMBOL_GPL(iscsi_host_alloc);
2043 2099
2044static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session) 2100static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)
2045{ 2101{
2046 iscsi_session_failure(cls_session, ISCSI_ERR_INVALID_HOST); 2102 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_INVALID_HOST);
2047} 2103}
2048 2104
2049/** 2105/**
@@ -2069,6 +2125,8 @@ void iscsi_host_remove(struct Scsi_Host *shost)
2069 flush_signals(current); 2125 flush_signals(current);
2070 2126
2071 scsi_remove_host(shost); 2127 scsi_remove_host(shost);
2128 if (ihost->workq)
2129 destroy_workqueue(ihost->workq);
2072} 2130}
2073EXPORT_SYMBOL_GPL(iscsi_host_remove); 2131EXPORT_SYMBOL_GPL(iscsi_host_remove);
2074 2132
@@ -2467,14 +2525,16 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
2467 2525
2468 /* handle pending */ 2526 /* handle pending */
2469 list_for_each_entry_safe(task, tmp, &conn->mgmtqueue, running) { 2527 list_for_each_entry_safe(task, tmp, &conn->mgmtqueue, running) {
2470 debug_scsi("flushing pending mgmt task itt 0x%x\n", task->itt); 2528 ISCSI_DBG_SESSION(session, "flushing pending mgmt task "
2529 "itt 0x%x\n", task->itt);
2471 /* release ref from prep task */ 2530 /* release ref from prep task */
2472 __iscsi_put_task(task); 2531 __iscsi_put_task(task);
2473 } 2532 }
2474 2533
2475 /* handle running */ 2534 /* handle running */
2476 list_for_each_entry_safe(task, tmp, &conn->mgmt_run_list, running) { 2535 list_for_each_entry_safe(task, tmp, &conn->mgmt_run_list, running) {
2477 debug_scsi("flushing running mgmt task itt 0x%x\n", task->itt); 2536 ISCSI_DBG_SESSION(session, "flushing running mgmt task "
2537 "itt 0x%x\n", task->itt);
2478 /* release ref from prep task */ 2538 /* release ref from prep task */
2479 __iscsi_put_task(task); 2539 __iscsi_put_task(task);
2480 } 2540 }
@@ -2524,7 +2584,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
2524 conn->datadgst_en = 0; 2584 conn->datadgst_en = 0;
2525 if (session->state == ISCSI_STATE_IN_RECOVERY && 2585 if (session->state == ISCSI_STATE_IN_RECOVERY &&
2526 old_stop_stage != STOP_CONN_RECOVER) { 2586 old_stop_stage != STOP_CONN_RECOVER) {
2527 debug_scsi("blocking session\n"); 2587 ISCSI_DBG_SESSION(session, "blocking session\n");
2528 iscsi_block_session(session->cls_session); 2588 iscsi_block_session(session->cls_session);
2529 } 2589 }
2530 } 2590 }
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index e7705d3532c9..91f8ce4d8d08 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -49,13 +49,21 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
49 "Alex Aizman <itn780@yahoo.com>"); 49 "Alex Aizman <itn780@yahoo.com>");
50MODULE_DESCRIPTION("iSCSI/TCP data-path"); 50MODULE_DESCRIPTION("iSCSI/TCP data-path");
51MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
52#undef DEBUG_TCP
53 52
54#ifdef DEBUG_TCP 53static int iscsi_dbg_libtcp;
55#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt) 54module_param_named(debug_libiscsi_tcp, iscsi_dbg_libtcp, int,
56#else 55 S_IRUGO | S_IWUSR);
57#define debug_tcp(fmt...) 56MODULE_PARM_DESC(debug_libiscsi_tcp, "Turn on debugging for libiscsi_tcp "
58#endif 57 "module. Set to 1 to turn on, and zero to turn off. Default "
58 "is off.");
59
60#define ISCSI_DBG_TCP(_conn, dbg_fmt, arg...) \
61 do { \
62 if (iscsi_dbg_libtcp) \
63 iscsi_conn_printk(KERN_INFO, _conn, \
64 "%s " dbg_fmt, \
65 __func__, ##arg); \
66 } while (0);
59 67
60static int iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn, 68static int iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn,
61 struct iscsi_segment *segment); 69 struct iscsi_segment *segment);
@@ -123,18 +131,13 @@ static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv)
123 if (page_count(sg_page(sg)) >= 1 && !recv) 131 if (page_count(sg_page(sg)) >= 1 && !recv)
124 return; 132 return;
125 133
126 debug_tcp("iscsi_tcp_segment_map %s %p\n", recv ? "recv" : "xmit",
127 segment);
128 segment->sg_mapped = kmap_atomic(sg_page(sg), KM_SOFTIRQ0); 134 segment->sg_mapped = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
129 segment->data = segment->sg_mapped + sg->offset + segment->sg_offset; 135 segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
130} 136}
131 137
132void iscsi_tcp_segment_unmap(struct iscsi_segment *segment) 138void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
133{ 139{
134 debug_tcp("iscsi_tcp_segment_unmap %p\n", segment);
135
136 if (segment->sg_mapped) { 140 if (segment->sg_mapped) {
137 debug_tcp("iscsi_tcp_segment_unmap valid\n");
138 kunmap_atomic(segment->sg_mapped, KM_SOFTIRQ0); 141 kunmap_atomic(segment->sg_mapped, KM_SOFTIRQ0);
139 segment->sg_mapped = NULL; 142 segment->sg_mapped = NULL;
140 segment->data = NULL; 143 segment->data = NULL;
@@ -180,8 +183,9 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
180 struct scatterlist sg; 183 struct scatterlist sg;
181 unsigned int pad; 184 unsigned int pad;
182 185
183 debug_tcp("copied %u %u size %u %s\n", segment->copied, copied, 186 ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copied %u %u size %u %s\n",
184 segment->size, recv ? "recv" : "xmit"); 187 segment->copied, copied, segment->size,
188 recv ? "recv" : "xmit");
185 if (segment->hash && copied) { 189 if (segment->hash && copied) {
186 /* 190 /*
187 * If a segment is kmapd we must unmap it before sending 191 * If a segment is kmapd we must unmap it before sending
@@ -214,8 +218,8 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
214 iscsi_tcp_segment_unmap(segment); 218 iscsi_tcp_segment_unmap(segment);
215 219
216 /* Do we have more scatterlist entries? */ 220 /* Do we have more scatterlist entries? */
217 debug_tcp("total copied %u total size %u\n", segment->total_copied, 221 ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "total copied %u total size %u\n",
218 segment->total_size); 222 segment->total_copied, segment->total_size);
219 if (segment->total_copied < segment->total_size) { 223 if (segment->total_copied < segment->total_size) {
220 /* Proceed to the next entry in the scatterlist. */ 224 /* Proceed to the next entry in the scatterlist. */
221 iscsi_tcp_segment_init_sg(segment, sg_next(segment->sg), 225 iscsi_tcp_segment_init_sg(segment, sg_next(segment->sg),
@@ -229,7 +233,8 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
229 if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) { 233 if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) {
230 pad = iscsi_padding(segment->total_copied); 234 pad = iscsi_padding(segment->total_copied);
231 if (pad != 0) { 235 if (pad != 0) {
232 debug_tcp("consume %d pad bytes\n", pad); 236 ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
237 "consume %d pad bytes\n", pad);
233 segment->total_size += pad; 238 segment->total_size += pad;
234 segment->size = pad; 239 segment->size = pad;
235 segment->data = segment->padbuf; 240 segment->data = segment->padbuf;
@@ -278,13 +283,13 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn,
278 283
279 while (!iscsi_tcp_segment_done(tcp_conn, segment, 1, copy)) { 284 while (!iscsi_tcp_segment_done(tcp_conn, segment, 1, copy)) {
280 if (copied == len) { 285 if (copied == len) {
281 debug_tcp("iscsi_tcp_segment_recv copied %d bytes\n", 286 ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
282 len); 287 "copied %d bytes\n", len);
283 break; 288 break;
284 } 289 }
285 290
286 copy = min(len - copied, segment->size - segment->copied); 291 copy = min(len - copied, segment->size - segment->copied);
287 debug_tcp("iscsi_tcp_segment_recv copying %d\n", copy); 292 ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copying %d\n", copy);
288 memcpy(segment->data + segment->copied, ptr + copied, copy); 293 memcpy(segment->data + segment->copied, ptr + copied, copy);
289 copied += copy; 294 copied += copy;
290 } 295 }
@@ -311,7 +316,7 @@ iscsi_tcp_dgst_verify(struct iscsi_tcp_conn *tcp_conn,
311 316
312 if (memcmp(segment->recv_digest, segment->digest, 317 if (memcmp(segment->recv_digest, segment->digest,
313 segment->digest_len)) { 318 segment->digest_len)) {
314 debug_scsi("digest mismatch\n"); 319 ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "digest mismatch\n");
315 return 0; 320 return 0;
316 } 321 }
317 322
@@ -355,12 +360,8 @@ iscsi_segment_seek_sg(struct iscsi_segment *segment,
355 struct scatterlist *sg; 360 struct scatterlist *sg;
356 unsigned int i; 361 unsigned int i;
357 362
358 debug_scsi("iscsi_segment_seek_sg offset %u size %llu\n",
359 offset, size);
360 __iscsi_segment_init(segment, size, done, hash); 363 __iscsi_segment_init(segment, size, done, hash);
361 for_each_sg(sg_list, sg, sg_count, i) { 364 for_each_sg(sg_list, sg, sg_count, i) {
362 debug_scsi("sg %d, len %u offset %u\n", i, sg->length,
363 sg->offset);
364 if (offset < sg->length) { 365 if (offset < sg->length) {
365 iscsi_tcp_segment_init_sg(segment, sg, offset); 366 iscsi_tcp_segment_init_sg(segment, sg, offset);
366 return 0; 367 return 0;
@@ -382,8 +383,9 @@ EXPORT_SYMBOL_GPL(iscsi_segment_seek_sg);
382 */ 383 */
383void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn) 384void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn)
384{ 385{
385 debug_tcp("iscsi_tcp_hdr_recv_prep(%p%s)\n", tcp_conn, 386 ISCSI_DBG_TCP(tcp_conn->iscsi_conn,
386 tcp_conn->iscsi_conn->hdrdgst_en ? ", digest enabled" : ""); 387 "(%s)\n", tcp_conn->iscsi_conn->hdrdgst_en ?
388 "digest enabled" : "digest disabled");
387 iscsi_segment_init_linear(&tcp_conn->in.segment, 389 iscsi_segment_init_linear(&tcp_conn->in.segment,
388 tcp_conn->in.hdr_buf, sizeof(struct iscsi_hdr), 390 tcp_conn->in.hdr_buf, sizeof(struct iscsi_hdr),
389 iscsi_tcp_hdr_recv_done, NULL); 391 iscsi_tcp_hdr_recv_done, NULL);
@@ -446,7 +448,7 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task)
446 while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { 448 while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
447 __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, 449 __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
448 sizeof(void*)); 450 sizeof(void*));
449 debug_scsi("iscsi_tcp_cleanup_task pending r2t dropped\n"); 451 ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
450 } 452 }
451 453
452 r2t = tcp_task->r2t; 454 r2t = tcp_task->r2t;
@@ -476,8 +478,8 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
476 return 0; 478 return 0;
477 479
478 if (tcp_task->exp_datasn != datasn) { 480 if (tcp_task->exp_datasn != datasn) {
479 debug_tcp("%s: task->exp_datasn(%d) != rhdr->datasn(%d)\n", 481 ISCSI_DBG_TCP(conn, "task->exp_datasn(%d) != rhdr->datasn(%d)"
480 __func__, tcp_task->exp_datasn, datasn); 482 "\n", tcp_task->exp_datasn, datasn);
481 return ISCSI_ERR_DATASN; 483 return ISCSI_ERR_DATASN;
482 } 484 }
483 485
@@ -485,9 +487,9 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
485 487
486 tcp_task->data_offset = be32_to_cpu(rhdr->offset); 488 tcp_task->data_offset = be32_to_cpu(rhdr->offset);
487 if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) { 489 if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) {
488 debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", 490 ISCSI_DBG_TCP(conn, "data_offset(%d) + data_len(%d) > "
489 __func__, tcp_task->data_offset, 491 "total_length_in(%d)\n", tcp_task->data_offset,
490 tcp_conn->in.datalen, total_in_length); 492 tcp_conn->in.datalen, total_in_length);
491 return ISCSI_ERR_DATA_OFFSET; 493 return ISCSI_ERR_DATA_OFFSET;
492 } 494 }
493 495
@@ -518,8 +520,8 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
518 } 520 }
519 521
520 if (tcp_task->exp_datasn != r2tsn){ 522 if (tcp_task->exp_datasn != r2tsn){
521 debug_tcp("%s: task->exp_datasn(%d) != rhdr->r2tsn(%d)\n", 523 ISCSI_DBG_TCP(conn, "task->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
522 __func__, tcp_task->exp_datasn, r2tsn); 524 tcp_task->exp_datasn, r2tsn);
523 return ISCSI_ERR_R2TSN; 525 return ISCSI_ERR_R2TSN;
524 } 526 }
525 527
@@ -552,9 +554,9 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
552 } 554 }
553 555
554 if (r2t->data_length > session->max_burst) 556 if (r2t->data_length > session->max_burst)
555 debug_scsi("invalid R2T with data len %u and max burst %u." 557 ISCSI_DBG_TCP(conn, "invalid R2T with data len %u and max "
556 "Attempting to execute request.\n", 558 "burst %u. Attempting to execute request.\n",
557 r2t->data_length, session->max_burst); 559 r2t->data_length, session->max_burst);
558 560
559 r2t->data_offset = be32_to_cpu(rhdr->data_offset); 561 r2t->data_offset = be32_to_cpu(rhdr->data_offset);
560 if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) { 562 if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) {
@@ -641,8 +643,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
641 if (rc) 643 if (rc)
642 return rc; 644 return rc;
643 645
644 debug_tcp("opcode 0x%x ahslen %d datalen %d\n", 646 ISCSI_DBG_TCP(conn, "opcode 0x%x ahslen %d datalen %d\n",
645 opcode, ahslen, tcp_conn->in.datalen); 647 opcode, ahslen, tcp_conn->in.datalen);
646 648
647 switch(opcode) { 649 switch(opcode) {
648 case ISCSI_OP_SCSI_DATA_IN: 650 case ISCSI_OP_SCSI_DATA_IN:
@@ -674,10 +676,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
674 !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) 676 !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
675 rx_hash = tcp_conn->rx_hash; 677 rx_hash = tcp_conn->rx_hash;
676 678
677 debug_tcp("iscsi_tcp_begin_data_in(%p, offset=%d, " 679 ISCSI_DBG_TCP(conn, "iscsi_tcp_begin_data_in( "
678 "datalen=%d)\n", tcp_conn, 680 "offset=%d, datalen=%d)\n",
679 tcp_task->data_offset, 681 tcp_task->data_offset,
680 tcp_conn->in.datalen); 682 tcp_conn->in.datalen);
681 rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, 683 rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
682 sdb->table.sgl, 684 sdb->table.sgl,
683 sdb->table.nents, 685 sdb->table.nents,
@@ -854,10 +856,10 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
854 unsigned int consumed = 0; 856 unsigned int consumed = 0;
855 int rc = 0; 857 int rc = 0;
856 858
857 debug_tcp("in %d bytes\n", skb->len - offset); 859 ISCSI_DBG_TCP(conn, "in %d bytes\n", skb->len - offset);
858 860
859 if (unlikely(conn->suspend_rx)) { 861 if (unlikely(conn->suspend_rx)) {
860 debug_tcp("conn %d Rx suspended!\n", conn->id); 862 ISCSI_DBG_TCP(conn, "Rx suspended!\n");
861 *status = ISCSI_TCP_SUSPENDED; 863 *status = ISCSI_TCP_SUSPENDED;
862 return 0; 864 return 0;
863 } 865 }
@@ -874,15 +876,16 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
874 876
875 avail = skb_seq_read(consumed, &ptr, &seq); 877 avail = skb_seq_read(consumed, &ptr, &seq);
876 if (avail == 0) { 878 if (avail == 0) {
877 debug_tcp("no more data avail. Consumed %d\n", 879 ISCSI_DBG_TCP(conn, "no more data avail. Consumed %d\n",
878 consumed); 880 consumed);
879 *status = ISCSI_TCP_SKB_DONE; 881 *status = ISCSI_TCP_SKB_DONE;
880 skb_abort_seq_read(&seq); 882 skb_abort_seq_read(&seq);
881 goto skb_done; 883 goto skb_done;
882 } 884 }
883 BUG_ON(segment->copied >= segment->size); 885 BUG_ON(segment->copied >= segment->size);
884 886
885 debug_tcp("skb %p ptr=%p avail=%u\n", skb, ptr, avail); 887 ISCSI_DBG_TCP(conn, "skb %p ptr=%p avail=%u\n", skb, ptr,
888 avail);
886 rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail); 889 rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail);
887 BUG_ON(rc == 0); 890 BUG_ON(rc == 0);
888 consumed += rc; 891 consumed += rc;
@@ -895,11 +898,11 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
895 898
896segment_done: 899segment_done:
897 *status = ISCSI_TCP_SEGMENT_DONE; 900 *status = ISCSI_TCP_SEGMENT_DONE;
898 debug_tcp("segment done\n"); 901 ISCSI_DBG_TCP(conn, "segment done\n");
899 rc = segment->done(tcp_conn, segment); 902 rc = segment->done(tcp_conn, segment);
900 if (rc != 0) { 903 if (rc != 0) {
901 *status = ISCSI_TCP_CONN_ERR; 904 *status = ISCSI_TCP_CONN_ERR;
902 debug_tcp("Error receiving PDU, errno=%d\n", rc); 905 ISCSI_DBG_TCP(conn, "Error receiving PDU, errno=%d\n", rc);
903 iscsi_conn_failure(conn, rc); 906 iscsi_conn_failure(conn, rc);
904 return 0; 907 return 0;
905 } 908 }
@@ -929,8 +932,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task)
929 * mgmt tasks do not have a scatterlist since they come 932 * mgmt tasks do not have a scatterlist since they come
930 * in from the iscsi interface. 933 * in from the iscsi interface.
931 */ 934 */
932 debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, 935 ISCSI_DBG_TCP(conn, "mtask deq [itt 0x%x]\n", task->itt);
933 task->itt);
934 936
935 return conn->session->tt->init_pdu(task, 0, task->data_count); 937 return conn->session->tt->init_pdu(task, 0, task->data_count);
936 } 938 }
@@ -939,9 +941,8 @@ int iscsi_tcp_task_init(struct iscsi_task *task)
939 tcp_task->exp_datasn = 0; 941 tcp_task->exp_datasn = 0;
940 942
941 /* Prepare PDU, optionally w/ immediate data */ 943 /* Prepare PDU, optionally w/ immediate data */
942 debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n", 944 ISCSI_DBG_TCP(conn, "task deq [itt 0x%x imm %d unsol %d]\n",
943 conn->id, task->itt, task->imm_count, 945 task->itt, task->imm_count, task->unsol_r2t.data_length);
944 task->unsol_r2t.data_length);
945 946
946 err = conn->session->tt->init_pdu(task, 0, task->imm_count); 947 err = conn->session->tt->init_pdu(task, 0, task->imm_count);
947 if (err) 948 if (err)
@@ -965,7 +966,8 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
965 r2t = tcp_task->r2t; 966 r2t = tcp_task->r2t;
966 /* Continue with this R2T? */ 967 /* Continue with this R2T? */
967 if (r2t->data_length <= r2t->sent) { 968 if (r2t->data_length <= r2t->sent) {
968 debug_scsi(" done with r2t %p\n", r2t); 969 ISCSI_DBG_TCP(task->conn,
970 " done with r2t %p\n", r2t);
969 __kfifo_put(tcp_task->r2tpool.queue, 971 __kfifo_put(tcp_task->r2tpool.queue,
970 (void *)&tcp_task->r2t, 972 (void *)&tcp_task->r2t,
971 sizeof(void *)); 973 sizeof(void *));
@@ -1019,7 +1021,7 @@ flush:
1019 r2t = iscsi_tcp_get_curr_r2t(task); 1021 r2t = iscsi_tcp_get_curr_r2t(task);
1020 if (r2t == NULL) { 1022 if (r2t == NULL) {
1021 /* Waiting for more R2Ts to arrive. */ 1023 /* Waiting for more R2Ts to arrive. */
1022 debug_tcp("no R2Ts yet\n"); 1024 ISCSI_DBG_TCP(conn, "no R2Ts yet\n");
1023 return 0; 1025 return 0;
1024 } 1026 }
1025 1027
@@ -1028,9 +1030,9 @@ flush:
1028 return rc; 1030 return rc;
1029 iscsi_prep_data_out_pdu(task, r2t, (struct iscsi_data *) task->hdr); 1031 iscsi_prep_data_out_pdu(task, r2t, (struct iscsi_data *) task->hdr);
1030 1032
1031 debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n", 1033 ISCSI_DBG_TCP(conn, "sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n",
1032 r2t, r2t->datasn - 1, task->hdr->itt, 1034 r2t, r2t->datasn - 1, task->hdr->itt,
1033 r2t->data_offset + r2t->sent, r2t->data_count); 1035 r2t->data_offset + r2t->sent, r2t->data_count);
1034 1036
1035 rc = conn->session->tt->init_pdu(task, r2t->data_offset + r2t->sent, 1037 rc = conn->session->tt->init_pdu(task, r2t->data_offset + r2t->sent,
1036 r2t->data_count); 1038 r2t->data_count);
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index b615eda361d5..81cdcf46c471 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1132,7 +1132,7 @@ lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
1132} 1132}
1133 1133
1134#undef lpfc_debugfs_op_disc_trc 1134#undef lpfc_debugfs_op_disc_trc
1135static struct file_operations lpfc_debugfs_op_disc_trc = { 1135static const struct file_operations lpfc_debugfs_op_disc_trc = {
1136 .owner = THIS_MODULE, 1136 .owner = THIS_MODULE,
1137 .open = lpfc_debugfs_disc_trc_open, 1137 .open = lpfc_debugfs_disc_trc_open,
1138 .llseek = lpfc_debugfs_lseek, 1138 .llseek = lpfc_debugfs_lseek,
@@ -1141,7 +1141,7 @@ static struct file_operations lpfc_debugfs_op_disc_trc = {
1141}; 1141};
1142 1142
1143#undef lpfc_debugfs_op_nodelist 1143#undef lpfc_debugfs_op_nodelist
1144static struct file_operations lpfc_debugfs_op_nodelist = { 1144static const struct file_operations lpfc_debugfs_op_nodelist = {
1145 .owner = THIS_MODULE, 1145 .owner = THIS_MODULE,
1146 .open = lpfc_debugfs_nodelist_open, 1146 .open = lpfc_debugfs_nodelist_open,
1147 .llseek = lpfc_debugfs_lseek, 1147 .llseek = lpfc_debugfs_lseek,
@@ -1150,7 +1150,7 @@ static struct file_operations lpfc_debugfs_op_nodelist = {
1150}; 1150};
1151 1151
1152#undef lpfc_debugfs_op_hbqinfo 1152#undef lpfc_debugfs_op_hbqinfo
1153static struct file_operations lpfc_debugfs_op_hbqinfo = { 1153static const struct file_operations lpfc_debugfs_op_hbqinfo = {
1154 .owner = THIS_MODULE, 1154 .owner = THIS_MODULE,
1155 .open = lpfc_debugfs_hbqinfo_open, 1155 .open = lpfc_debugfs_hbqinfo_open,
1156 .llseek = lpfc_debugfs_lseek, 1156 .llseek = lpfc_debugfs_lseek,
@@ -1159,7 +1159,7 @@ static struct file_operations lpfc_debugfs_op_hbqinfo = {
1159}; 1159};
1160 1160
1161#undef lpfc_debugfs_op_dumpHBASlim 1161#undef lpfc_debugfs_op_dumpHBASlim
1162static struct file_operations lpfc_debugfs_op_dumpHBASlim = { 1162static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
1163 .owner = THIS_MODULE, 1163 .owner = THIS_MODULE,
1164 .open = lpfc_debugfs_dumpHBASlim_open, 1164 .open = lpfc_debugfs_dumpHBASlim_open,
1165 .llseek = lpfc_debugfs_lseek, 1165 .llseek = lpfc_debugfs_lseek,
@@ -1168,7 +1168,7 @@ static struct file_operations lpfc_debugfs_op_dumpHBASlim = {
1168}; 1168};
1169 1169
1170#undef lpfc_debugfs_op_dumpHostSlim 1170#undef lpfc_debugfs_op_dumpHostSlim
1171static struct file_operations lpfc_debugfs_op_dumpHostSlim = { 1171static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
1172 .owner = THIS_MODULE, 1172 .owner = THIS_MODULE,
1173 .open = lpfc_debugfs_dumpHostSlim_open, 1173 .open = lpfc_debugfs_dumpHostSlim_open,
1174 .llseek = lpfc_debugfs_lseek, 1174 .llseek = lpfc_debugfs_lseek,
@@ -1177,7 +1177,7 @@ static struct file_operations lpfc_debugfs_op_dumpHostSlim = {
1177}; 1177};
1178 1178
1179#undef lpfc_debugfs_op_dumpData 1179#undef lpfc_debugfs_op_dumpData
1180static struct file_operations lpfc_debugfs_op_dumpData = { 1180static const struct file_operations lpfc_debugfs_op_dumpData = {
1181 .owner = THIS_MODULE, 1181 .owner = THIS_MODULE,
1182 .open = lpfc_debugfs_dumpData_open, 1182 .open = lpfc_debugfs_dumpData_open,
1183 .llseek = lpfc_debugfs_lseek, 1183 .llseek = lpfc_debugfs_lseek,
@@ -1187,7 +1187,7 @@ static struct file_operations lpfc_debugfs_op_dumpData = {
1187}; 1187};
1188 1188
1189#undef lpfc_debugfs_op_dumpDif 1189#undef lpfc_debugfs_op_dumpDif
1190static struct file_operations lpfc_debugfs_op_dumpDif = { 1190static const struct file_operations lpfc_debugfs_op_dumpDif = {
1191 .owner = THIS_MODULE, 1191 .owner = THIS_MODULE,
1192 .open = lpfc_debugfs_dumpDif_open, 1192 .open = lpfc_debugfs_dumpDif_open,
1193 .llseek = lpfc_debugfs_lseek, 1193 .llseek = lpfc_debugfs_lseek,
@@ -1197,7 +1197,7 @@ static struct file_operations lpfc_debugfs_op_dumpDif = {
1197}; 1197};
1198 1198
1199#undef lpfc_debugfs_op_slow_ring_trc 1199#undef lpfc_debugfs_op_slow_ring_trc
1200static struct file_operations lpfc_debugfs_op_slow_ring_trc = { 1200static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
1201 .owner = THIS_MODULE, 1201 .owner = THIS_MODULE,
1202 .open = lpfc_debugfs_slow_ring_trc_open, 1202 .open = lpfc_debugfs_slow_ring_trc_open,
1203 .llseek = lpfc_debugfs_lseek, 1203 .llseek = lpfc_debugfs_lseek,
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index b103b6ed4970..b1bd3fc7bae8 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1357,7 +1357,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
1357 1357
1358 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, 1358 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
1359 0x10, 0x1); 1359 0x10, 0x1);
1360 cmd->result = (DRIVER_SENSE|SUGGEST_DIE) << 24 1360 cmd->result = DRIVER_SENSE << 24
1361 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); 1361 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
1362 phba->bg_guard_err_cnt++; 1362 phba->bg_guard_err_cnt++;
1363 printk(KERN_ERR "BLKGRD: guard_tag error\n"); 1363 printk(KERN_ERR "BLKGRD: guard_tag error\n");
@@ -1368,7 +1368,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
1368 1368
1369 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, 1369 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
1370 0x10, 0x3); 1370 0x10, 0x3);
1371 cmd->result = (DRIVER_SENSE|SUGGEST_DIE) << 24 1371 cmd->result = DRIVER_SENSE << 24
1372 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); 1372 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
1373 1373
1374 phba->bg_reftag_err_cnt++; 1374 phba->bg_reftag_err_cnt++;
@@ -1380,7 +1380,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
1380 1380
1381 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, 1381 scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
1382 0x10, 0x2); 1382 0x10, 0x2);
1383 cmd->result = (DRIVER_SENSE|SUGGEST_DIE) << 24 1383 cmd->result = DRIVER_SENSE << 24
1384 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); 1384 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION);
1385 1385
1386 phba->bg_apptag_err_cnt++; 1386 phba->bg_apptag_err_cnt++;
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
new file mode 100644
index 000000000000..4a86855c23b3
--- /dev/null
+++ b/drivers/scsi/mpt2sas/Kconfig
@@ -0,0 +1,66 @@
1#
2# Kernel configuration file for the MPT2SAS
3#
4# This code is based on drivers/scsi/mpt2sas/Kconfig
5# Copyright (C) 2007-2008 LSI Corporation
6# (mailto:DL-MPTFusionLinux@lsi.com)
7
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License
10# as published by the Free Software Foundation; either version 2
11# of the License, or (at your option) any later version.
12
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17
18# NO WARRANTY
19# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23# solely responsible for determining the appropriateness of using and
24# distributing the Program and assumes all risks associated with its
25# exercise of rights under this Agreement, including but not limited to
26# the risks and costs of program errors, damage to or loss of data,
27# programs or equipment, and unavailability or interruption of operations.
28
29# DISCLAIMER OF LIABILITY
30# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38# You should have received a copy of the GNU General Public License
39# along with this program; if not, write to the Free Software
40# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41# USA.
42
43config SCSI_MPT2SAS
44 tristate "LSI MPT Fusion SAS 2.0 Device Driver"
45 depends on PCI && SCSI
46 select SCSI_SAS_ATTRS
47 ---help---
48 This driver supports PCI-Express SAS 6Gb/s Host Adapters.
49
50config SCSI_MPT2SAS_MAX_SGE
51 int "LSI MPT Fusion Max number of SG Entries (16 - 128)"
52 depends on PCI && SCSI && SCSI_MPT2SAS
53 default "128"
54 range 16 128
55 ---help---
56 This option allows you to specify the maximum number of scatter-
57 gather entries per I/O. The driver default is 128, which matches
58 SAFE_PHYS_SEGMENTS. However, it may decreased down to 16.
59 Decreasing this parameter will reduce memory requirements
60 on a per controller instance.
61
62config SCSI_MPT2SAS_LOGGING
63 bool "LSI MPT Fusion logging facility"
64 depends on PCI && SCSI && SCSI_MPT2SAS
65 ---help---
66 This turns on a logging facility.
diff --git a/drivers/scsi/mpt2sas/Makefile b/drivers/scsi/mpt2sas/Makefile
new file mode 100644
index 000000000000..728f0475711d
--- /dev/null
+++ b/drivers/scsi/mpt2sas/Makefile
@@ -0,0 +1,7 @@
1# mpt2sas makefile
2obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o
3mpt2sas-y += mpt2sas_base.o \
4 mpt2sas_config.o \
5 mpt2sas_scsih.o \
6 mpt2sas_transport.o \
7 mpt2sas_ctl.o
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
new file mode 100644
index 000000000000..7bb2ece8b2e4
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -0,0 +1,1067 @@
1/*
2 * Copyright (c) 2000-2009 LSI Corporation.
3 *
4 *
5 * Name: mpi2.h
6 * Title: MPI Message independent structures and definitions
7 * including System Interface Register Set and
8 * scatter/gather formats.
9 * Creation Date: June 21, 2006
10 *
11 * mpi2.h Version: 02.00.11
12 *
13 * Version History
14 * ---------------
15 *
16 * Date Version Description
17 * -------- -------- ------------------------------------------------------
18 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
19 * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT.
20 * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT.
21 * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT.
22 * Moved ReplyPostHostIndex register to offset 0x6C of the
23 * MPI2_SYSTEM_INTERFACE_REGS and modified the define for
24 * MPI2_REPLY_POST_HOST_INDEX_OFFSET.
25 * Added union of request descriptors.
26 * Added union of reply descriptors.
27 * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT.
28 * Added define for MPI2_VERSION_02_00.
29 * Fixed the size of the FunctionDependent5 field in the
30 * MPI2_DEFAULT_REPLY structure.
31 * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT.
32 * Removed the MPI-defined Fault Codes and extended the
33 * product specific codes up to 0xEFFF.
34 * Added a sixth key value for the WriteSequence register
35 * and changed the flush value to 0x0.
36 * Added message function codes for Diagnostic Buffer Post
37 * and Diagnsotic Release.
38 * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED
39 * Moved MPI2_VERSION_UNION from mpi2_ioc.h.
40 * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT.
41 * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT.
42 * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT.
43 * Added #defines for marking a reply descriptor as unused.
44 * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT.
45 * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT.
46 * Moved LUN field defines from mpi2_init.h.
47 * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT.
48 * --------------------------------------------------------------------------
49 */
50
51#ifndef MPI2_H
52#define MPI2_H
53
54
55/*****************************************************************************
56*
57* MPI Version Definitions
58*
59*****************************************************************************/
60
61#define MPI2_VERSION_MAJOR (0x02)
62#define MPI2_VERSION_MINOR (0x00)
63#define MPI2_VERSION_MAJOR_MASK (0xFF00)
64#define MPI2_VERSION_MAJOR_SHIFT (8)
65#define MPI2_VERSION_MINOR_MASK (0x00FF)
66#define MPI2_VERSION_MINOR_SHIFT (0)
67#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
68 MPI2_VERSION_MINOR)
69
70#define MPI2_VERSION_02_00 (0x0200)
71
72/* versioning for this MPI header set */
73#define MPI2_HEADER_VERSION_UNIT (0x0B)
74#define MPI2_HEADER_VERSION_DEV (0x00)
75#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
76#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
77#define MPI2_HEADER_VERSION_DEV_MASK (0x00FF)
78#define MPI2_HEADER_VERSION_DEV_SHIFT (0)
79#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | MPI2_HEADER_VERSION_DEV)
80
81
82/*****************************************************************************
83*
84* IOC State Definitions
85*
86*****************************************************************************/
87
88#define MPI2_IOC_STATE_RESET (0x00000000)
89#define MPI2_IOC_STATE_READY (0x10000000)
90#define MPI2_IOC_STATE_OPERATIONAL (0x20000000)
91#define MPI2_IOC_STATE_FAULT (0x40000000)
92
93#define MPI2_IOC_STATE_MASK (0xF0000000)
94#define MPI2_IOC_STATE_SHIFT (28)
95
96/* Fault state range for prodcut specific codes */
97#define MPI2_FAULT_PRODUCT_SPECIFIC_MIN (0x0000)
98#define MPI2_FAULT_PRODUCT_SPECIFIC_MAX (0xEFFF)
99
100
101/*****************************************************************************
102*
103* System Interface Register Definitions
104*
105*****************************************************************************/
106
107typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
108{
109 U32 Doorbell; /* 0x00 */
110 U32 WriteSequence; /* 0x04 */
111 U32 HostDiagnostic; /* 0x08 */
112 U32 Reserved1; /* 0x0C */
113 U32 DiagRWData; /* 0x10 */
114 U32 DiagRWAddressLow; /* 0x14 */
115 U32 DiagRWAddressHigh; /* 0x18 */
116 U32 Reserved2[5]; /* 0x1C */
117 U32 HostInterruptStatus; /* 0x30 */
118 U32 HostInterruptMask; /* 0x34 */
119 U32 DCRData; /* 0x38 */
120 U32 DCRAddress; /* 0x3C */
121 U32 Reserved3[2]; /* 0x40 */
122 U32 ReplyFreeHostIndex; /* 0x48 */
123 U32 Reserved4[8]; /* 0x4C */
124 U32 ReplyPostHostIndex; /* 0x6C */
125 U32 Reserved5; /* 0x70 */
126 U32 HCBSize; /* 0x74 */
127 U32 HCBAddressLow; /* 0x78 */
128 U32 HCBAddressHigh; /* 0x7C */
129 U32 Reserved6[16]; /* 0x80 */
130 U32 RequestDescriptorPostLow; /* 0xC0 */
131 U32 RequestDescriptorPostHigh; /* 0xC4 */
132 U32 Reserved7[14]; /* 0xC8 */
133} MPI2_SYSTEM_INTERFACE_REGS, MPI2_POINTER PTR_MPI2_SYSTEM_INTERFACE_REGS,
134 Mpi2SystemInterfaceRegs_t, MPI2_POINTER pMpi2SystemInterfaceRegs_t;
135
136/*
137 * Defines for working with the Doorbell register.
138 */
139#define MPI2_DOORBELL_OFFSET (0x00000000)
140
141/* IOC --> System values */
142#define MPI2_DOORBELL_USED (0x08000000)
143#define MPI2_DOORBELL_WHO_INIT_MASK (0x07000000)
144#define MPI2_DOORBELL_WHO_INIT_SHIFT (24)
145#define MPI2_DOORBELL_FAULT_CODE_MASK (0x0000FFFF)
146#define MPI2_DOORBELL_DATA_MASK (0x0000FFFF)
147
148/* System --> IOC values */
149#define MPI2_DOORBELL_FUNCTION_MASK (0xFF000000)
150#define MPI2_DOORBELL_FUNCTION_SHIFT (24)
151#define MPI2_DOORBELL_ADD_DWORDS_MASK (0x00FF0000)
152#define MPI2_DOORBELL_ADD_DWORDS_SHIFT (16)
153
154
155/*
156 * Defines for the WriteSequence register
157 */
158#define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004)
159#define MPI2_WRSEQ_KEY_VALUE_MASK (0x0000000F)
160#define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0)
161#define MPI2_WRSEQ_1ST_KEY_VALUE (0xF)
162#define MPI2_WRSEQ_2ND_KEY_VALUE (0x4)
163#define MPI2_WRSEQ_3RD_KEY_VALUE (0xB)
164#define MPI2_WRSEQ_4TH_KEY_VALUE (0x2)
165#define MPI2_WRSEQ_5TH_KEY_VALUE (0x7)
166#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD)
167
168/*
169 * Defines for the HostDiagnostic register
170 */
171#define MPI2_HOST_DIAGNOSTIC_OFFSET (0x00000008)
172
173#define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK (0x00001800)
174#define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT (0x00000000)
175#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800)
176
177#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400)
178#define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200)
179#define MPI2_DIAG_HCB_MODE (0x00000100)
180#define MPI2_DIAG_DIAG_WRITE_ENABLE (0x00000080)
181#define MPI2_DIAG_FLASH_BAD_SIG (0x00000040)
182#define MPI2_DIAG_RESET_HISTORY (0x00000020)
183#define MPI2_DIAG_DIAG_RW_ENABLE (0x00000010)
184#define MPI2_DIAG_RESET_ADAPTER (0x00000004)
185#define MPI2_DIAG_HOLD_IOC_RESET (0x00000002)
186
187/*
188 * Offsets for DiagRWData and address
189 */
190#define MPI2_DIAG_RW_DATA_OFFSET (0x00000010)
191#define MPI2_DIAG_RW_ADDRESS_LOW_OFFSET (0x00000014)
192#define MPI2_DIAG_RW_ADDRESS_HIGH_OFFSET (0x00000018)
193
194/*
195 * Defines for the HostInterruptStatus register
196 */
197#define MPI2_HOST_INTERRUPT_STATUS_OFFSET (0x00000030)
198#define MPI2_HIS_SYS2IOC_DB_STATUS (0x80000000)
199#define MPI2_HIS_IOP_DOORBELL_STATUS MPI2_HIS_SYS2IOC_DB_STATUS
200#define MPI2_HIS_RESET_IRQ_STATUS (0x40000000)
201#define MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT (0x00000008)
202#define MPI2_HIS_IOC2SYS_DB_STATUS (0x00000001)
203#define MPI2_HIS_DOORBELL_INTERRUPT MPI2_HIS_IOC2SYS_DB_STATUS
204
205/*
206 * Defines for the HostInterruptMask register
207 */
208#define MPI2_HOST_INTERRUPT_MASK_OFFSET (0x00000034)
209#define MPI2_HIM_RESET_IRQ_MASK (0x40000000)
210#define MPI2_HIM_REPLY_INT_MASK (0x00000008)
211#define MPI2_HIM_RIM MPI2_HIM_REPLY_INT_MASK
212#define MPI2_HIM_IOC2SYS_DB_MASK (0x00000001)
213#define MPI2_HIM_DIM MPI2_HIM_IOC2SYS_DB_MASK
214
215/*
216 * Offsets for DCRData and address
217 */
218#define MPI2_DCR_DATA_OFFSET (0x00000038)
219#define MPI2_DCR_ADDRESS_OFFSET (0x0000003C)
220
221/*
222 * Offset for the Reply Free Queue
223 */
224#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048)
225
226/*
227 * Offset for the Reply Descriptor Post Queue
228 */
229#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C)
230
231/*
232 * Defines for the HCBSize and address
233 */
234#define MPI2_HCB_SIZE_OFFSET (0x00000074)
235#define MPI2_HCB_SIZE_SIZE_MASK (0xFFFFF000)
236#define MPI2_HCB_SIZE_HCB_ENABLE (0x00000001)
237
238#define MPI2_HCB_ADDRESS_LOW_OFFSET (0x00000078)
239#define MPI2_HCB_ADDRESS_HIGH_OFFSET (0x0000007C)
240
241/*
242 * Offsets for the Request Queue
243 */
244#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0)
245#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4)
246
247
248/*****************************************************************************
249*
250* Message Descriptors
251*
252*****************************************************************************/
253
254/* Request Descriptors */
255
256/* Default Request Descriptor */
257typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
258{
259 U8 RequestFlags; /* 0x00 */
260 U8 VF_ID; /* 0x01 */
261 U16 SMID; /* 0x02 */
262 U16 LMID; /* 0x04 */
263 U16 DescriptorTypeDependent; /* 0x06 */
264} MPI2_DEFAULT_REQUEST_DESCRIPTOR,
265 MPI2_POINTER PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR,
266 Mpi2DefaultRequestDescriptor_t, MPI2_POINTER pMpi2DefaultRequestDescriptor_t;
267
268/* defines for the RequestFlags field */
269#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x0E)
270#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00)
271#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02)
272#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06)
273#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08)
274
275#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
276
277
278/* High Priority Request Descriptor */
279typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR
280{
281 U8 RequestFlags; /* 0x00 */
282 U8 VF_ID; /* 0x01 */
283 U16 SMID; /* 0x02 */
284 U16 LMID; /* 0x04 */
285 U16 Reserved1; /* 0x06 */
286} MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
287 MPI2_POINTER PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR,
288 Mpi2HighPriorityRequestDescriptor_t,
289 MPI2_POINTER pMpi2HighPriorityRequestDescriptor_t;
290
291
292/* SCSI IO Request Descriptor */
293typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR
294{
295 U8 RequestFlags; /* 0x00 */
296 U8 VF_ID; /* 0x01 */
297 U16 SMID; /* 0x02 */
298 U16 LMID; /* 0x04 */
299 U16 DevHandle; /* 0x06 */
300} MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
301 MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR,
302 Mpi2SCSIIORequestDescriptor_t, MPI2_POINTER pMpi2SCSIIORequestDescriptor_t;
303
304
305/* SCSI Target Request Descriptor */
306typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR
307{
308 U8 RequestFlags; /* 0x00 */
309 U8 VF_ID; /* 0x01 */
310 U16 SMID; /* 0x02 */
311 U16 LMID; /* 0x04 */
312 U16 IoIndex; /* 0x06 */
313} MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
314 MPI2_POINTER PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR,
315 Mpi2SCSITargetRequestDescriptor_t,
316 MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t;
317
318/* union of Request Descriptors */
319typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
320{
321 MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
322 MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority;
323 MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO;
324 MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
325 U64 Words;
326} MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
327 Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t;
328
329
330/* Reply Descriptors */
331
332/* Default Reply Descriptor */
333typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
334{
335 U8 ReplyFlags; /* 0x00 */
336 U8 VF_ID; /* 0x01 */
337 U16 DescriptorTypeDependent1; /* 0x02 */
338 U32 DescriptorTypeDependent2; /* 0x04 */
339} MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR,
340 Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t;
341
342/* defines for the ReplyFlags field */
343#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F)
344#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00)
345#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01)
346#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02)
347#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03)
348#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F)
349
350/* values for marking a reply descriptor as unused */
351#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF)
352#define MPI2_RPY_DESCRIPT_UNUSED_WORD1_MARK (0xFFFFFFFF)
353
354/* Address Reply Descriptor */
355typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR
356{
357 U8 ReplyFlags; /* 0x00 */
358 U8 VF_ID; /* 0x01 */
359 U16 SMID; /* 0x02 */
360 U32 ReplyFrameAddress; /* 0x04 */
361} MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR,
362 Mpi2AddressReplyDescriptor_t, MPI2_POINTER pMpi2AddressReplyDescriptor_t;
363
364#define MPI2_ADDRESS_REPLY_SMID_INVALID (0x00)
365
366
367/* SCSI IO Success Reply Descriptor */
368typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
369{
370 U8 ReplyFlags; /* 0x00 */
371 U8 VF_ID; /* 0x01 */
372 U16 SMID; /* 0x02 */
373 U16 TaskTag; /* 0x04 */
374 U16 DevHandle; /* 0x06 */
375} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
376 MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
377 Mpi2SCSIIOSuccessReplyDescriptor_t,
378 MPI2_POINTER pMpi2SCSIIOSuccessReplyDescriptor_t;
379
380
381/* TargetAssist Success Reply Descriptor */
382typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR
383{
384 U8 ReplyFlags; /* 0x00 */
385 U8 VF_ID; /* 0x01 */
386 U16 SMID; /* 0x02 */
387 U8 SequenceNumber; /* 0x04 */
388 U8 Reserved1; /* 0x05 */
389 U16 IoIndex; /* 0x06 */
390} MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
391 MPI2_POINTER PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR,
392 Mpi2TargetAssistSuccessReplyDescriptor_t,
393 MPI2_POINTER pMpi2TargetAssistSuccessReplyDescriptor_t;
394
395
396/* Target Command Buffer Reply Descriptor */
397typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR
398{
399 U8 ReplyFlags; /* 0x00 */
400 U8 VF_ID; /* 0x01 */
401 U8 VP_ID; /* 0x02 */
402 U8 Flags; /* 0x03 */
403 U16 InitiatorDevHandle; /* 0x04 */
404 U16 IoIndex; /* 0x06 */
405} MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
406 MPI2_POINTER PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR,
407 Mpi2TargetCommandBufferReplyDescriptor_t,
408 MPI2_POINTER pMpi2TargetCommandBufferReplyDescriptor_t;
409
410/* defines for Flags field */
411#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F)
412
413
414/* union of Reply Descriptors */
415typedef union _MPI2_REPLY_DESCRIPTORS_UNION
416{
417 MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
418 MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply;
419 MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess;
420 MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess;
421 MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
422 U64 Words;
423} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION,
424 Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t;
425
426
427
428/*****************************************************************************
429*
430* Message Functions
431* 0x80 -> 0x8F reserved for private message use per product
432*
433*
434*****************************************************************************/
435
436#define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */
437#define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01) /* SCSI Task Management */
438#define MPI2_FUNCTION_IOC_INIT (0x02) /* IOC Init */
439#define MPI2_FUNCTION_IOC_FACTS (0x03) /* IOC Facts */
440#define MPI2_FUNCTION_CONFIG (0x04) /* Configuration */
441#define MPI2_FUNCTION_PORT_FACTS (0x05) /* Port Facts */
442#define MPI2_FUNCTION_PORT_ENABLE (0x06) /* Port Enable */
443#define MPI2_FUNCTION_EVENT_NOTIFICATION (0x07) /* Event Notification */
444#define MPI2_FUNCTION_EVENT_ACK (0x08) /* Event Acknowledge */
445#define MPI2_FUNCTION_FW_DOWNLOAD (0x09) /* FW Download */
446#define MPI2_FUNCTION_TARGET_ASSIST (0x0B) /* Target Assist */
447#define MPI2_FUNCTION_TARGET_STATUS_SEND (0x0C) /* Target Status Send */
448#define MPI2_FUNCTION_TARGET_MODE_ABORT (0x0D) /* Target Mode Abort */
449#define MPI2_FUNCTION_FW_UPLOAD (0x12) /* FW Upload */
450#define MPI2_FUNCTION_RAID_ACTION (0x15) /* RAID Action */
451#define MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16) /* SCSI IO RAID Passthrough */
452#define MPI2_FUNCTION_TOOLBOX (0x17) /* Toolbox */
453#define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18) /* SCSI Enclosure Processor */
454#define MPI2_FUNCTION_SMP_PASSTHROUGH (0x1A) /* SMP Passthrough */
455#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) /* SAS IO Unit Control */
456#define MPI2_FUNCTION_SATA_PASSTHROUGH (0x1C) /* SATA Passthrough */
457#define MPI2_FUNCTION_DIAG_BUFFER_POST (0x1D) /* Diagnostic Buffer Post */
458#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */
459#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */
460#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */
461
462
463
464/* Doorbell functions */
465#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40)
466/* #define MPI2_FUNCTION_IO_UNIT_RESET (0x41) */
467#define MPI2_FUNCTION_HANDSHAKE (0x42)
468
469
470/*****************************************************************************
471*
472* IOC Status Values
473*
474*****************************************************************************/
475
476/* mask for IOCStatus status value */
477#define MPI2_IOCSTATUS_MASK (0x7FFF)
478
479/****************************************************************************
480* Common IOCStatus values for all replies
481****************************************************************************/
482
483#define MPI2_IOCSTATUS_SUCCESS (0x0000)
484#define MPI2_IOCSTATUS_INVALID_FUNCTION (0x0001)
485#define MPI2_IOCSTATUS_BUSY (0x0002)
486#define MPI2_IOCSTATUS_INVALID_SGL (0x0003)
487#define MPI2_IOCSTATUS_INTERNAL_ERROR (0x0004)
488#define MPI2_IOCSTATUS_INVALID_VPID (0x0005)
489#define MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006)
490#define MPI2_IOCSTATUS_INVALID_FIELD (0x0007)
491#define MPI2_IOCSTATUS_INVALID_STATE (0x0008)
492#define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009)
493
494/****************************************************************************
495* Config IOCStatus values
496****************************************************************************/
497
498#define MPI2_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020)
499#define MPI2_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021)
500#define MPI2_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022)
501#define MPI2_IOCSTATUS_CONFIG_INVALID_DATA (0x0023)
502#define MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024)
503#define MPI2_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025)
504
505/****************************************************************************
506* SCSI IO Reply
507****************************************************************************/
508
509#define MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040)
510#define MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE (0x0042)
511#define MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043)
512#define MPI2_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044)
513#define MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045)
514#define MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046)
515#define MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047)
516#define MPI2_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048)
517#define MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049)
518#define MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A)
519#define MPI2_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B)
520#define MPI2_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
521
522/****************************************************************************
523* For use by SCSI Initiator and SCSI Target end-to-end data protection
524****************************************************************************/
525
526#define MPI2_IOCSTATUS_EEDP_GUARD_ERROR (0x004D)
527#define MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E)
528#define MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
529
530/****************************************************************************
531* SCSI Target values
532****************************************************************************/
533
534#define MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062)
535#define MPI2_IOCSTATUS_TARGET_ABORTED (0x0063)
536#define MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064)
537#define MPI2_IOCSTATUS_TARGET_NO_CONNECTION (0x0065)
538#define MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A)
539#define MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D)
540#define MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E)
541#define MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F)
542#define MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070)
543#define MPI2_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071)
544
545/****************************************************************************
546* Serial Attached SCSI values
547****************************************************************************/
548
549#define MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
550#define MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091)
551
552/****************************************************************************
553* Diagnostic Buffer Post / Diagnostic Release values
554****************************************************************************/
555
556#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0)
557
558
559/****************************************************************************
560* IOCStatus flag to indicate that log info is available
561****************************************************************************/
562
563#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000)
564
565/****************************************************************************
566* IOCLogInfo Types
567****************************************************************************/
568
569#define MPI2_IOCLOGINFO_TYPE_MASK (0xF0000000)
570#define MPI2_IOCLOGINFO_TYPE_SHIFT (28)
571#define MPI2_IOCLOGINFO_TYPE_NONE (0x0)
572#define MPI2_IOCLOGINFO_TYPE_SCSI (0x1)
573#define MPI2_IOCLOGINFO_TYPE_FC (0x2)
574#define MPI2_IOCLOGINFO_TYPE_SAS (0x3)
575#define MPI2_IOCLOGINFO_TYPE_ISCSI (0x4)
576#define MPI2_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF)
577
578
579/*****************************************************************************
580*
581* Standard Message Structures
582*
583*****************************************************************************/
584
585/****************************************************************************
586* Request Message Header for all request messages
587****************************************************************************/
588
589typedef struct _MPI2_REQUEST_HEADER
590{
591 U16 FunctionDependent1; /* 0x00 */
592 U8 ChainOffset; /* 0x02 */
593 U8 Function; /* 0x03 */
594 U16 FunctionDependent2; /* 0x04 */
595 U8 FunctionDependent3; /* 0x06 */
596 U8 MsgFlags; /* 0x07 */
597 U8 VP_ID; /* 0x08 */
598 U8 VF_ID; /* 0x09 */
599 U16 Reserved1; /* 0x0A */
600} MPI2_REQUEST_HEADER, MPI2_POINTER PTR_MPI2_REQUEST_HEADER,
601 MPI2RequestHeader_t, MPI2_POINTER pMPI2RequestHeader_t;
602
603
604/****************************************************************************
605* Default Reply
606****************************************************************************/
607
608typedef struct _MPI2_DEFAULT_REPLY
609{
610 U16 FunctionDependent1; /* 0x00 */
611 U8 MsgLength; /* 0x02 */
612 U8 Function; /* 0x03 */
613 U16 FunctionDependent2; /* 0x04 */
614 U8 FunctionDependent3; /* 0x06 */
615 U8 MsgFlags; /* 0x07 */
616 U8 VP_ID; /* 0x08 */
617 U8 VF_ID; /* 0x09 */
618 U16 Reserved1; /* 0x0A */
619 U16 FunctionDependent5; /* 0x0C */
620 U16 IOCStatus; /* 0x0E */
621 U32 IOCLogInfo; /* 0x10 */
622} MPI2_DEFAULT_REPLY, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY,
623 MPI2DefaultReply_t, MPI2_POINTER pMPI2DefaultReply_t;
624
625
626/* common version structure/union used in messages and configuration pages */
627
628typedef struct _MPI2_VERSION_STRUCT
629{
630 U8 Dev; /* 0x00 */
631 U8 Unit; /* 0x01 */
632 U8 Minor; /* 0x02 */
633 U8 Major; /* 0x03 */
634} MPI2_VERSION_STRUCT;
635
636typedef union _MPI2_VERSION_UNION
637{
638 MPI2_VERSION_STRUCT Struct;
639 U32 Word;
640} MPI2_VERSION_UNION;
641
642
643/* LUN field defines, common to many structures */
644#define MPI2_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF)
645#define MPI2_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000)
646#define MPI2_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF)
647#define MPI2_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000)
648#define MPI2_LUN_LEVEL_1_WORD (0xFF00)
649#define MPI2_LUN_LEVEL_1_DWORD (0x0000FF00)
650
651
652/*****************************************************************************
653*
654* Fusion-MPT MPI Scatter Gather Elements
655*
656*****************************************************************************/
657
658/****************************************************************************
659* MPI Simple Element structures
660****************************************************************************/
661
662typedef struct _MPI2_SGE_SIMPLE32
663{
664 U32 FlagsLength;
665 U32 Address;
666} MPI2_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_SGE_SIMPLE32,
667 Mpi2SGESimple32_t, MPI2_POINTER pMpi2SGESimple32_t;
668
669typedef struct _MPI2_SGE_SIMPLE64
670{
671 U32 FlagsLength;
672 U64 Address;
673} MPI2_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_SGE_SIMPLE64,
674 Mpi2SGESimple64_t, MPI2_POINTER pMpi2SGESimple64_t;
675
676typedef struct _MPI2_SGE_SIMPLE_UNION
677{
678 U32 FlagsLength;
679 union
680 {
681 U32 Address32;
682 U64 Address64;
683 } u;
684} MPI2_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_SIMPLE_UNION,
685 Mpi2SGESimpleUnion_t, MPI2_POINTER pMpi2SGESimpleUnion_t;
686
687
688/****************************************************************************
689* MPI Chain Element structures
690****************************************************************************/
691
692typedef struct _MPI2_SGE_CHAIN32
693{
694 U16 Length;
695 U8 NextChainOffset;
696 U8 Flags;
697 U32 Address;
698} MPI2_SGE_CHAIN32, MPI2_POINTER PTR_MPI2_SGE_CHAIN32,
699 Mpi2SGEChain32_t, MPI2_POINTER pMpi2SGEChain32_t;
700
701typedef struct _MPI2_SGE_CHAIN64
702{
703 U16 Length;
704 U8 NextChainOffset;
705 U8 Flags;
706 U64 Address;
707} MPI2_SGE_CHAIN64, MPI2_POINTER PTR_MPI2_SGE_CHAIN64,
708 Mpi2SGEChain64_t, MPI2_POINTER pMpi2SGEChain64_t;
709
710typedef struct _MPI2_SGE_CHAIN_UNION
711{
712 U16 Length;
713 U8 NextChainOffset;
714 U8 Flags;
715 union
716 {
717 U32 Address32;
718 U64 Address64;
719 } u;
720} MPI2_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_SGE_CHAIN_UNION,
721 Mpi2SGEChainUnion_t, MPI2_POINTER pMpi2SGEChainUnion_t;
722
723
724/****************************************************************************
725* MPI Transaction Context Element structures
726****************************************************************************/
727
728typedef struct _MPI2_SGE_TRANSACTION32
729{
730 U8 Reserved;
731 U8 ContextSize;
732 U8 DetailsLength;
733 U8 Flags;
734 U32 TransactionContext[1];
735 U32 TransactionDetails[1];
736} MPI2_SGE_TRANSACTION32, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION32,
737 Mpi2SGETransaction32_t, MPI2_POINTER pMpi2SGETransaction32_t;
738
739typedef struct _MPI2_SGE_TRANSACTION64
740{
741 U8 Reserved;
742 U8 ContextSize;
743 U8 DetailsLength;
744 U8 Flags;
745 U32 TransactionContext[2];
746 U32 TransactionDetails[1];
747} MPI2_SGE_TRANSACTION64, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION64,
748 Mpi2SGETransaction64_t, MPI2_POINTER pMpi2SGETransaction64_t;
749
750typedef struct _MPI2_SGE_TRANSACTION96
751{
752 U8 Reserved;
753 U8 ContextSize;
754 U8 DetailsLength;
755 U8 Flags;
756 U32 TransactionContext[3];
757 U32 TransactionDetails[1];
758} MPI2_SGE_TRANSACTION96, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION96,
759 Mpi2SGETransaction96_t, MPI2_POINTER pMpi2SGETransaction96_t;
760
761typedef struct _MPI2_SGE_TRANSACTION128
762{
763 U8 Reserved;
764 U8 ContextSize;
765 U8 DetailsLength;
766 U8 Flags;
767 U32 TransactionContext[4];
768 U32 TransactionDetails[1];
769} MPI2_SGE_TRANSACTION128, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION128,
770 Mpi2SGETransaction_t128, MPI2_POINTER pMpi2SGETransaction_t128;
771
772typedef struct _MPI2_SGE_TRANSACTION_UNION
773{
774 U8 Reserved;
775 U8 ContextSize;
776 U8 DetailsLength;
777 U8 Flags;
778 union
779 {
780 U32 TransactionContext32[1];
781 U32 TransactionContext64[2];
782 U32 TransactionContext96[3];
783 U32 TransactionContext128[4];
784 } u;
785 U32 TransactionDetails[1];
786} MPI2_SGE_TRANSACTION_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION_UNION,
787 Mpi2SGETransactionUnion_t, MPI2_POINTER pMpi2SGETransactionUnion_t;
788
789
790/****************************************************************************
791* MPI SGE union for IO SGL's
792****************************************************************************/
793
794typedef struct _MPI2_MPI_SGE_IO_UNION
795{
796 union
797 {
798 MPI2_SGE_SIMPLE_UNION Simple;
799 MPI2_SGE_CHAIN_UNION Chain;
800 } u;
801} MPI2_MPI_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_IO_UNION,
802 Mpi2MpiSGEIOUnion_t, MPI2_POINTER pMpi2MpiSGEIOUnion_t;
803
804
805/****************************************************************************
806* MPI SGE union for SGL's with Simple and Transaction elements
807****************************************************************************/
808
809typedef struct _MPI2_SGE_TRANS_SIMPLE_UNION
810{
811 union
812 {
813 MPI2_SGE_SIMPLE_UNION Simple;
814 MPI2_SGE_TRANSACTION_UNION Transaction;
815 } u;
816} MPI2_SGE_TRANS_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANS_SIMPLE_UNION,
817 Mpi2SGETransSimpleUnion_t, MPI2_POINTER pMpi2SGETransSimpleUnion_t;
818
819
820/****************************************************************************
821* All MPI SGE types union
822****************************************************************************/
823
824typedef struct _MPI2_MPI_SGE_UNION
825{
826 union
827 {
828 MPI2_SGE_SIMPLE_UNION Simple;
829 MPI2_SGE_CHAIN_UNION Chain;
830 MPI2_SGE_TRANSACTION_UNION Transaction;
831 } u;
832} MPI2_MPI_SGE_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_UNION,
833 Mpi2MpiSgeUnion_t, MPI2_POINTER pMpi2MpiSgeUnion_t;
834
835
836/****************************************************************************
837* MPI SGE field definition and masks
838****************************************************************************/
839
840/* Flags field bit definitions */
841
842#define MPI2_SGE_FLAGS_LAST_ELEMENT (0x80)
843#define MPI2_SGE_FLAGS_END_OF_BUFFER (0x40)
844#define MPI2_SGE_FLAGS_ELEMENT_TYPE_MASK (0x30)
845#define MPI2_SGE_FLAGS_LOCAL_ADDRESS (0x08)
846#define MPI2_SGE_FLAGS_DIRECTION (0x04)
847#define MPI2_SGE_FLAGS_ADDRESS_SIZE (0x02)
848#define MPI2_SGE_FLAGS_END_OF_LIST (0x01)
849
850#define MPI2_SGE_FLAGS_SHIFT (24)
851
852#define MPI2_SGE_LENGTH_MASK (0x00FFFFFF)
853#define MPI2_SGE_CHAIN_LENGTH_MASK (0x0000FFFF)
854
855/* Element Type */
856
857#define MPI2_SGE_FLAGS_TRANSACTION_ELEMENT (0x00)
858#define MPI2_SGE_FLAGS_SIMPLE_ELEMENT (0x10)
859#define MPI2_SGE_FLAGS_CHAIN_ELEMENT (0x30)
860#define MPI2_SGE_FLAGS_ELEMENT_MASK (0x30)
861
862/* Address location */
863
864#define MPI2_SGE_FLAGS_SYSTEM_ADDRESS (0x00)
865
866/* Direction */
867
868#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00)
869#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04)
870
871/* Address Size */
872
873#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00)
874#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02)
875
876/* Context Size */
877
878#define MPI2_SGE_FLAGS_32_BIT_CONTEXT (0x00)
879#define MPI2_SGE_FLAGS_64_BIT_CONTEXT (0x02)
880#define MPI2_SGE_FLAGS_96_BIT_CONTEXT (0x04)
881#define MPI2_SGE_FLAGS_128_BIT_CONTEXT (0x06)
882
883#define MPI2_SGE_CHAIN_OFFSET_MASK (0x00FF0000)
884#define MPI2_SGE_CHAIN_OFFSET_SHIFT (16)
885
886/****************************************************************************
887* MPI SGE operation Macros
888****************************************************************************/
889
890/* SIMPLE FlagsLength manipulations... */
891#define MPI2_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_SGE_FLAGS_SHIFT)
892#define MPI2_SGE_GET_FLAGS(f) (((f) & ~MPI2_SGE_LENGTH_MASK) >> MPI2_SGE_FLAGS_SHIFT)
893#define MPI2_SGE_LENGTH(f) ((f) & MPI2_SGE_LENGTH_MASK)
894#define MPI2_SGE_CHAIN_LENGTH(f) ((f) & MPI2_SGE_CHAIN_LENGTH_MASK)
895
896#define MPI2_SGE_SET_FLAGS_LENGTH(f,l) (MPI2_SGE_SET_FLAGS(f) | MPI2_SGE_LENGTH(l))
897
898#define MPI2_pSGE_GET_FLAGS(psg) MPI2_SGE_GET_FLAGS((psg)->FlagsLength)
899#define MPI2_pSGE_GET_LENGTH(psg) MPI2_SGE_LENGTH((psg)->FlagsLength)
900#define MPI2_pSGE_SET_FLAGS_LENGTH(psg,f,l) (psg)->FlagsLength = MPI2_SGE_SET_FLAGS_LENGTH(f,l)
901
902/* CAUTION - The following are READ-MODIFY-WRITE! */
903#define MPI2_pSGE_SET_FLAGS(psg,f) (psg)->FlagsLength |= MPI2_SGE_SET_FLAGS(f)
904#define MPI2_pSGE_SET_LENGTH(psg,l) (psg)->FlagsLength |= MPI2_SGE_LENGTH(l)
905
906#define MPI2_GET_CHAIN_OFFSET(x) ((x & MPI2_SGE_CHAIN_OFFSET_MASK) >> MPI2_SGE_CHAIN_OFFSET_SHIFT)
907
908
909/*****************************************************************************
910*
911* Fusion-MPT IEEE Scatter Gather Elements
912*
913*****************************************************************************/
914
915/****************************************************************************
916* IEEE Simple Element structures
917****************************************************************************/
918
919typedef struct _MPI2_IEEE_SGE_SIMPLE32
920{
921 U32 Address;
922 U32 FlagsLength;
923} MPI2_IEEE_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE32,
924 Mpi2IeeeSgeSimple32_t, MPI2_POINTER pMpi2IeeeSgeSimple32_t;
925
926typedef struct _MPI2_IEEE_SGE_SIMPLE64
927{
928 U64 Address;
929 U32 Length;
930 U16 Reserved1;
931 U8 Reserved2;
932 U8 Flags;
933} MPI2_IEEE_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE64,
934 Mpi2IeeeSgeSimple64_t, MPI2_POINTER pMpi2IeeeSgeSimple64_t;
935
936typedef union _MPI2_IEEE_SGE_SIMPLE_UNION
937{
938 MPI2_IEEE_SGE_SIMPLE32 Simple32;
939 MPI2_IEEE_SGE_SIMPLE64 Simple64;
940} MPI2_IEEE_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE_UNION,
941 Mpi2IeeeSgeSimpleUnion_t, MPI2_POINTER pMpi2IeeeSgeSimpleUnion_t;
942
943
944/****************************************************************************
945* IEEE Chain Element structures
946****************************************************************************/
947
948typedef MPI2_IEEE_SGE_SIMPLE32 MPI2_IEEE_SGE_CHAIN32;
949
950typedef MPI2_IEEE_SGE_SIMPLE64 MPI2_IEEE_SGE_CHAIN64;
951
952typedef union _MPI2_IEEE_SGE_CHAIN_UNION
953{
954 MPI2_IEEE_SGE_CHAIN32 Chain32;
955 MPI2_IEEE_SGE_CHAIN64 Chain64;
956} MPI2_IEEE_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_CHAIN_UNION,
957 Mpi2IeeeSgeChainUnion_t, MPI2_POINTER pMpi2IeeeSgeChainUnion_t;
958
959
960/****************************************************************************
961* All IEEE SGE types union
962****************************************************************************/
963
964typedef struct _MPI2_IEEE_SGE_UNION
965{
966 union
967 {
968 MPI2_IEEE_SGE_SIMPLE_UNION Simple;
969 MPI2_IEEE_SGE_CHAIN_UNION Chain;
970 } u;
971} MPI2_IEEE_SGE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_UNION,
972 Mpi2IeeeSgeUnion_t, MPI2_POINTER pMpi2IeeeSgeUnion_t;
973
974
975/****************************************************************************
976* IEEE SGE field definitions and masks
977****************************************************************************/
978
979/* Flags field bit definitions */
980
981#define MPI2_IEEE_SGE_FLAGS_ELEMENT_TYPE_MASK (0x80)
982
983#define MPI2_IEEE32_SGE_FLAGS_SHIFT (24)
984
985#define MPI2_IEEE32_SGE_LENGTH_MASK (0x00FFFFFF)
986
987/* Element Type */
988
989#define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT (0x00)
990#define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80)
991
992/* Data Location Address Space */
993
994#define MPI2_IEEE_SGE_FLAGS_ADDR_MASK (0x03)
995#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00)
996#define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01)
997#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02)
998#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
999
1000
1001/****************************************************************************
1002* IEEE SGE operation Macros
1003****************************************************************************/
1004
1005/* SIMPLE FlagsLength manipulations... */
1006#define MPI2_IEEE32_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_IEEE32_SGE_FLAGS_SHIFT)
1007#define MPI2_IEEE32_SGE_GET_FLAGS(f) (((f) & ~MPI2_IEEE32_SGE_LENGTH_MASK) >> MPI2_IEEE32_SGE_FLAGS_SHIFT)
1008#define MPI2_IEEE32_SGE_LENGTH(f) ((f) & MPI2_IEEE32_SGE_LENGTH_MASK)
1009
1010#define MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_IEEE32_SGE_SET_FLAGS(f) | MPI2_IEEE32_SGE_LENGTH(l))
1011
1012#define MPI2_IEEE32_pSGE_GET_FLAGS(psg) MPI2_IEEE32_SGE_GET_FLAGS((psg)->FlagsLength)
1013#define MPI2_IEEE32_pSGE_GET_LENGTH(psg) MPI2_IEEE32_SGE_LENGTH((psg)->FlagsLength)
1014#define MPI2_IEEE32_pSGE_SET_FLAGS_LENGTH(psg,f,l) (psg)->FlagsLength = MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f,l)
1015
1016/* CAUTION - The following are READ-MODIFY-WRITE! */
1017#define MPI2_IEEE32_pSGE_SET_FLAGS(psg,f) (psg)->FlagsLength |= MPI2_IEEE32_SGE_SET_FLAGS(f)
1018#define MPI2_IEEE32_pSGE_SET_LENGTH(psg,l) (psg)->FlagsLength |= MPI2_IEEE32_SGE_LENGTH(l)
1019
1020
1021
1022
1023/*****************************************************************************
1024*
1025* Fusion-MPT MPI/IEEE Scatter Gather Unions
1026*
1027*****************************************************************************/
1028
1029typedef union _MPI2_SIMPLE_SGE_UNION
1030{
1031 MPI2_SGE_SIMPLE_UNION MpiSimple;
1032 MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple;
1033} MPI2_SIMPLE_SGE_UNION, MPI2_POINTER PTR_MPI2_SIMPLE_SGE_UNION,
1034 Mpi2SimpleSgeUntion_t, MPI2_POINTER pMpi2SimpleSgeUntion_t;
1035
1036
1037typedef union _MPI2_SGE_IO_UNION
1038{
1039 MPI2_SGE_SIMPLE_UNION MpiSimple;
1040 MPI2_SGE_CHAIN_UNION MpiChain;
1041 MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple;
1042 MPI2_IEEE_SGE_CHAIN_UNION IeeeChain;
1043} MPI2_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_SGE_IO_UNION,
1044 Mpi2SGEIOUnion_t, MPI2_POINTER pMpi2SGEIOUnion_t;
1045
1046
1047/****************************************************************************
1048*
1049* Values for SGLFlags field, used in many request messages with an SGL
1050*
1051****************************************************************************/
1052
1053/* values for MPI SGL Data Location Address Space subfield */
1054#define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK (0x0C)
1055#define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE (0x00)
1056#define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE (0x04)
1057#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08)
1058#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C)
1059/* values for SGL Type subfield */
1060#define MPI2_SGLFLAGS_SGL_TYPE_MASK (0x03)
1061#define MPI2_SGLFLAGS_SGL_TYPE_MPI (0x00)
1062#define MPI2_SGLFLAGS_SGL_TYPE_IEEE32 (0x01)
1063#define MPI2_SGLFLAGS_SGL_TYPE_IEEE64 (0x02)
1064
1065
1066#endif
1067
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
new file mode 100644
index 000000000000..2f27cf6d6c65
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -0,0 +1,2151 @@
1/*
2 * Copyright (c) 2000-2009 LSI Corporation.
3 *
4 *
5 * Name: mpi2_cnfg.h
6 * Title: MPI Configuration messages and pages
7 * Creation Date: November 10, 2006
8 *
9 * mpi2_cnfg.h Version: 02.00.10
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 06-04-07 02.00.01 Added defines for SAS IO Unit Page 2 PhyFlags.
18 * Added Manufacturing Page 11.
19 * Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE
20 * define.
21 * 06-26-07 02.00.02 Adding generic structure for product-specific
22 * Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS.
23 * Rework of BIOS Page 2 configuration page.
24 * Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the
25 * forms.
26 * Added configuration pages IOC Page 8 and Driver
27 * Persistent Mapping Page 0.
28 * 08-31-07 02.00.03 Modified configuration pages dealing with Integrated
29 * RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1,
30 * RAID Physical Disk Pages 0 and 1, RAID Configuration
31 * Page 0).
32 * Added new value for AccessStatus field of SAS Device
33 * Page 0 (_SATA_NEEDS_INITIALIZATION).
34 * 10-31-07 02.00.04 Added missing SEPDevHandle field to
35 * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
36 * 12-18-07 02.00.05 Modified IO Unit Page 0 to use 32-bit version fields for
37 * NVDATA.
38 * Modified IOC Page 7 to use masks and added field for
39 * SASBroadcastPrimitiveMasks.
40 * Added MPI2_CONFIG_PAGE_BIOS_4.
41 * Added MPI2_CONFIG_PAGE_LOG_0.
42 * 02-29-08 02.00.06 Modified various names to make them 32-character unique.
43 * Added SAS Device IDs.
44 * Updated Integrated RAID configuration pages including
45 * Manufacturing Page 4, IOC Page 6, and RAID Configuration
46 * Page 0.
47 * 05-21-08 02.00.07 Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA.
48 * Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION.
49 * Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING.
50 * Added missing MaxNumRoutedSasAddresses field to
51 * MPI2_CONFIG_PAGE_EXPANDER_0.
52 * Added SAS Port Page 0.
53 * Modified structure layout for
54 * MPI2_CONFIG_PAGE_DRIVER_MAPPING_0.
55 * 06-27-08 02.00.08 Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use
56 * MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array.
57 * 10-02-08 02.00.09 Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF
58 * to 0x000000FF.
59 * Added two new values for the Physical Disk Coercion Size
60 * bits in the Flags field of Manufacturing Page 4.
61 * Added product-specific Manufacturing pages 16 to 31.
62 * Modified Flags bits for controlling write cache on SATA
63 * drives in IO Unit Page 1.
64 * Added new bit to AdditionalControlFlags of SAS IO Unit
65 * Page 1 to control Invalid Topology Correction.
66 * Added additional defines for RAID Volume Page 0
67 * VolumeStatusFlags field.
68 * Modified meaning of RAID Volume Page 0 VolumeSettings
69 * define for auto-configure of hot-swap drives.
70 * Added SupportedPhysDisks field to RAID Volume Page 1 and
71 * added related defines.
72 * Added PhysDiskAttributes field (and related defines) to
73 * RAID Physical Disk Page 0.
74 * Added MPI2_SAS_PHYINFO_PHY_VACANT define.
75 * Added three new DiscoveryStatus bits for SAS IO Unit
76 * Page 0 and SAS Expander Page 0.
77 * Removed multiplexing information from SAS IO Unit pages.
78 * Added BootDeviceWaitTime field to SAS IO Unit Page 4.
79 * Removed Zone Address Resolved bit from PhyInfo and from
80 * Expander Page 0 Flags field.
81 * Added two new AccessStatus values to SAS Device Page 0
82 * for indicating routing problems. Added 3 reserved words
83 * to this page.
84 * 01-19-09 02.00.10 Fixed defines for GPIOVal field of IO Unit Page 3.
85 * Inserted missing reserved field into structure for IOC
86 * Page 6.
87 * Added more pending task bits to RAID Volume Page 0
88 * VolumeStatusFlags defines.
89 * Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define.
90 * Added a new DiscoveryStatus bit for SAS IO Unit Page 0
91 * and SAS Expander Page 0 to flag a downstream initiator
92 * when in simplified routing mode.
93 * Removed SATA Init Failure defines for DiscoveryStatus
94 * fields of SAS IO Unit Page 0 and SAS Expander Page 0.
95 * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define.
96 * Added PortGroups, DmaGroup, and ControlGroup fields to
97 * SAS Device Page 0.
98 * --------------------------------------------------------------------------
99 */
100
101#ifndef MPI2_CNFG_H
102#define MPI2_CNFG_H
103
104/*****************************************************************************
105* Configuration Page Header and defines
106*****************************************************************************/
107
108/* Config Page Header */
109typedef struct _MPI2_CONFIG_PAGE_HEADER
110{
111 U8 PageVersion; /* 0x00 */
112 U8 PageLength; /* 0x01 */
113 U8 PageNumber; /* 0x02 */
114 U8 PageType; /* 0x03 */
115} MPI2_CONFIG_PAGE_HEADER, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_HEADER,
116 Mpi2ConfigPageHeader_t, MPI2_POINTER pMpi2ConfigPageHeader_t;
117
118typedef union _MPI2_CONFIG_PAGE_HEADER_UNION
119{
120 MPI2_CONFIG_PAGE_HEADER Struct;
121 U8 Bytes[4];
122 U16 Word16[2];
123 U32 Word32;
124} MPI2_CONFIG_PAGE_HEADER_UNION, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_HEADER_UNION,
125 Mpi2ConfigPageHeaderUnion, MPI2_POINTER pMpi2ConfigPageHeaderUnion;
126
127/* Extended Config Page Header */
128typedef struct _MPI2_CONFIG_EXTENDED_PAGE_HEADER
129{
130 U8 PageVersion; /* 0x00 */
131 U8 Reserved1; /* 0x01 */
132 U8 PageNumber; /* 0x02 */
133 U8 PageType; /* 0x03 */
134 U16 ExtPageLength; /* 0x04 */
135 U8 ExtPageType; /* 0x06 */
136 U8 Reserved2; /* 0x07 */
137} MPI2_CONFIG_EXTENDED_PAGE_HEADER,
138 MPI2_POINTER PTR_MPI2_CONFIG_EXTENDED_PAGE_HEADER,
139 Mpi2ConfigExtendedPageHeader_t, MPI2_POINTER pMpi2ConfigExtendedPageHeader_t;
140
141typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
142{
143 MPI2_CONFIG_PAGE_HEADER Struct;
144 MPI2_CONFIG_EXTENDED_PAGE_HEADER Ext;
145 U8 Bytes[8];
146 U16 Word16[4];
147 U32 Word32[2];
148} MPI2_CONFIG_EXT_PAGE_HEADER_UNION, MPI2_POINTER PTR_MPI2_CONFIG_EXT_PAGE_HEADER_UNION,
149 Mpi2ConfigPageExtendedHeaderUnion, MPI2_POINTER pMpi2ConfigPageExtendedHeaderUnion;
150
151
152/* PageType field values */
153#define MPI2_CONFIG_PAGEATTR_READ_ONLY (0x00)
154#define MPI2_CONFIG_PAGEATTR_CHANGEABLE (0x10)
155#define MPI2_CONFIG_PAGEATTR_PERSISTENT (0x20)
156#define MPI2_CONFIG_PAGEATTR_MASK (0xF0)
157
158#define MPI2_CONFIG_PAGETYPE_IO_UNIT (0x00)
159#define MPI2_CONFIG_PAGETYPE_IOC (0x01)
160#define MPI2_CONFIG_PAGETYPE_BIOS (0x02)
161#define MPI2_CONFIG_PAGETYPE_RAID_VOLUME (0x08)
162#define MPI2_CONFIG_PAGETYPE_MANUFACTURING (0x09)
163#define MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A)
164#define MPI2_CONFIG_PAGETYPE_EXTENDED (0x0F)
165#define MPI2_CONFIG_PAGETYPE_MASK (0x0F)
166
167#define MPI2_CONFIG_TYPENUM_MASK (0x0FFF)
168
169
170/* ExtPageType field values */
171#define MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT (0x10)
172#define MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER (0x11)
173#define MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE (0x12)
174#define MPI2_CONFIG_EXTPAGETYPE_SAS_PHY (0x13)
175#define MPI2_CONFIG_EXTPAGETYPE_LOG (0x14)
176#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE (0x15)
177#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16)
178#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17)
179#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18)
180
181
182/*****************************************************************************
183* PageAddress defines
184*****************************************************************************/
185
186/* RAID Volume PageAddress format */
187#define MPI2_RAID_VOLUME_PGAD_FORM_MASK (0xF0000000)
188#define MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
189#define MPI2_RAID_VOLUME_PGAD_FORM_HANDLE (0x10000000)
190
191#define MPI2_RAID_VOLUME_PGAD_HANDLE_MASK (0x0000FFFF)
192
193
194/* RAID Physical Disk PageAddress format */
195#define MPI2_PHYSDISK_PGAD_FORM_MASK (0xF0000000)
196#define MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM (0x00000000)
197#define MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM (0x10000000)
198#define MPI2_PHYSDISK_PGAD_FORM_DEVHANDLE (0x20000000)
199
200#define MPI2_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF)
201#define MPI2_PHYSDISK_PGAD_DEVHANDLE_MASK (0x0000FFFF)
202
203
204/* SAS Expander PageAddress format */
205#define MPI2_SAS_EXPAND_PGAD_FORM_MASK (0xF0000000)
206#define MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL (0x00000000)
207#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM (0x10000000)
208#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL (0x20000000)
209
210#define MPI2_SAS_EXPAND_PGAD_HANDLE_MASK (0x0000FFFF)
211#define MPI2_SAS_EXPAND_PGAD_PHYNUM_MASK (0x00FF0000)
212#define MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT (16)
213
214
215/* SAS Device PageAddress format */
216#define MPI2_SAS_DEVICE_PGAD_FORM_MASK (0xF0000000)
217#define MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
218#define MPI2_SAS_DEVICE_PGAD_FORM_HANDLE (0x20000000)
219
220#define MPI2_SAS_DEVICE_PGAD_HANDLE_MASK (0x0000FFFF)
221
222
223/* SAS PHY PageAddress format */
224#define MPI2_SAS_PHY_PGAD_FORM_MASK (0xF0000000)
225#define MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER (0x00000000)
226#define MPI2_SAS_PHY_PGAD_FORM_PHY_TBL_INDEX (0x10000000)
227
228#define MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK (0x000000FF)
229#define MPI2_SAS_PHY_PGAD_PHY_TBL_INDEX_MASK (0x0000FFFF)
230
231
232/* SAS Port PageAddress format */
233#define MPI2_SASPORT_PGAD_FORM_MASK (0xF0000000)
234#define MPI2_SASPORT_PGAD_FORM_GET_NEXT_PORT (0x00000000)
235#define MPI2_SASPORT_PGAD_FORM_PORT_NUM (0x10000000)
236
237#define MPI2_SASPORT_PGAD_PORTNUMBER_MASK (0x00000FFF)
238
239
240/* SAS Enclosure PageAddress format */
241#define MPI2_SAS_ENCLOS_PGAD_FORM_MASK (0xF0000000)
242#define MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
243#define MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE (0x10000000)
244
245#define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK (0x0000FFFF)
246
247
248/* RAID Configuration PageAddress format */
249#define MPI2_RAID_PGAD_FORM_MASK (0xF0000000)
250#define MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM (0x00000000)
251#define MPI2_RAID_PGAD_FORM_CONFIGNUM (0x10000000)
252#define MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG (0x20000000)
253
254#define MPI2_RAID_PGAD_CONFIGNUM_MASK (0x000000FF)
255
256
257/* Driver Persistent Mapping PageAddress format */
258#define MPI2_DPM_PGAD_FORM_MASK (0xF0000000)
259#define MPI2_DPM_PGAD_FORM_ENTRY_RANGE (0x00000000)
260
261#define MPI2_DPM_PGAD_ENTRY_COUNT_MASK (0x0FFF0000)
262#define MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT (16)
263#define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF)
264
265
266/****************************************************************************
267* Configuration messages
268****************************************************************************/
269
270/* Configuration Request Message */
271typedef struct _MPI2_CONFIG_REQUEST
272{
273 U8 Action; /* 0x00 */
274 U8 SGLFlags; /* 0x01 */
275 U8 ChainOffset; /* 0x02 */
276 U8 Function; /* 0x03 */
277 U16 ExtPageLength; /* 0x04 */
278 U8 ExtPageType; /* 0x06 */
279 U8 MsgFlags; /* 0x07 */
280 U8 VP_ID; /* 0x08 */
281 U8 VF_ID; /* 0x09 */
282 U16 Reserved1; /* 0x0A */
283 U32 Reserved2; /* 0x0C */
284 U32 Reserved3; /* 0x10 */
285 MPI2_CONFIG_PAGE_HEADER Header; /* 0x14 */
286 U32 PageAddress; /* 0x18 */
287 MPI2_SGE_IO_UNION PageBufferSGE; /* 0x1C */
288} MPI2_CONFIG_REQUEST, MPI2_POINTER PTR_MPI2_CONFIG_REQUEST,
289 Mpi2ConfigRequest_t, MPI2_POINTER pMpi2ConfigRequest_t;
290
291/* values for the Action field */
292#define MPI2_CONFIG_ACTION_PAGE_HEADER (0x00)
293#define MPI2_CONFIG_ACTION_PAGE_READ_CURRENT (0x01)
294#define MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02)
295#define MPI2_CONFIG_ACTION_PAGE_DEFAULT (0x03)
296#define MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM (0x04)
297#define MPI2_CONFIG_ACTION_PAGE_READ_DEFAULT (0x05)
298#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06)
299#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07)
300
301/* values for SGLFlags field are in the SGL section of mpi2.h */
302
303
304/* Config Reply Message */
305typedef struct _MPI2_CONFIG_REPLY
306{
307 U8 Action; /* 0x00 */
308 U8 SGLFlags; /* 0x01 */
309 U8 MsgLength; /* 0x02 */
310 U8 Function; /* 0x03 */
311 U16 ExtPageLength; /* 0x04 */
312 U8 ExtPageType; /* 0x06 */
313 U8 MsgFlags; /* 0x07 */
314 U8 VP_ID; /* 0x08 */
315 U8 VF_ID; /* 0x09 */
316 U16 Reserved1; /* 0x0A */
317 U16 Reserved2; /* 0x0C */
318 U16 IOCStatus; /* 0x0E */
319 U32 IOCLogInfo; /* 0x10 */
320 MPI2_CONFIG_PAGE_HEADER Header; /* 0x14 */
321} MPI2_CONFIG_REPLY, MPI2_POINTER PTR_MPI2_CONFIG_REPLY,
322 Mpi2ConfigReply_t, MPI2_POINTER pMpi2ConfigReply_t;
323
324
325
326/*****************************************************************************
327*
328* C o n f i g u r a t i o n P a g e s
329*
330*****************************************************************************/
331
332/****************************************************************************
333* Manufacturing Config pages
334****************************************************************************/
335
336#define MPI2_MFGPAGE_VENDORID_LSI (0x1000)
337
338/* SAS */
339#define MPI2_MFGPAGE_DEVID_SAS2004 (0x0070)
340#define MPI2_MFGPAGE_DEVID_SAS2008 (0x0072)
341#define MPI2_MFGPAGE_DEVID_SAS2108_1 (0x0074)
342#define MPI2_MFGPAGE_DEVID_SAS2108_2 (0x0076)
343#define MPI2_MFGPAGE_DEVID_SAS2108_3 (0x0077)
344#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064)
345#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065)
346
347
348/* Manufacturing Page 0 */
349
350typedef struct _MPI2_CONFIG_PAGE_MAN_0
351{
352 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
353 U8 ChipName[16]; /* 0x04 */
354 U8 ChipRevision[8]; /* 0x14 */
355 U8 BoardName[16]; /* 0x1C */
356 U8 BoardAssembly[16]; /* 0x2C */
357 U8 BoardTracerNumber[16]; /* 0x3C */
358} MPI2_CONFIG_PAGE_MAN_0,
359 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_0,
360 Mpi2ManufacturingPage0_t, MPI2_POINTER pMpi2ManufacturingPage0_t;
361
362#define MPI2_MANUFACTURING0_PAGEVERSION (0x00)
363
364
365/* Manufacturing Page 1 */
366
367typedef struct _MPI2_CONFIG_PAGE_MAN_1
368{
369 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
370 U8 VPD[256]; /* 0x04 */
371} MPI2_CONFIG_PAGE_MAN_1,
372 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_1,
373 Mpi2ManufacturingPage1_t, MPI2_POINTER pMpi2ManufacturingPage1_t;
374
375#define MPI2_MANUFACTURING1_PAGEVERSION (0x00)
376
377
378typedef struct _MPI2_CHIP_REVISION_ID
379{
380 U16 DeviceID; /* 0x00 */
381 U8 PCIRevisionID; /* 0x02 */
382 U8 Reserved; /* 0x03 */
383} MPI2_CHIP_REVISION_ID, MPI2_POINTER PTR_MPI2_CHIP_REVISION_ID,
384 Mpi2ChipRevisionId_t, MPI2_POINTER pMpi2ChipRevisionId_t;
385
386
387/* Manufacturing Page 2 */
388
389/*
390 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
391 * one and check Header.PageLength at runtime.
392 */
393#ifndef MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS
394#define MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS (1)
395#endif
396
397typedef struct _MPI2_CONFIG_PAGE_MAN_2
398{
399 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
400 MPI2_CHIP_REVISION_ID ChipId; /* 0x04 */
401 U32 HwSettings[MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS];/* 0x08 */
402} MPI2_CONFIG_PAGE_MAN_2,
403 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_2,
404 Mpi2ManufacturingPage2_t, MPI2_POINTER pMpi2ManufacturingPage2_t;
405
406#define MPI2_MANUFACTURING2_PAGEVERSION (0x00)
407
408
409/* Manufacturing Page 3 */
410
411/*
412 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
413 * one and check Header.PageLength at runtime.
414 */
415#ifndef MPI2_MAN_PAGE_3_INFO_WORDS
416#define MPI2_MAN_PAGE_3_INFO_WORDS (1)
417#endif
418
419typedef struct _MPI2_CONFIG_PAGE_MAN_3
420{
421 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
422 MPI2_CHIP_REVISION_ID ChipId; /* 0x04 */
423 U32 Info[MPI2_MAN_PAGE_3_INFO_WORDS];/* 0x08 */
424} MPI2_CONFIG_PAGE_MAN_3,
425 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_3,
426 Mpi2ManufacturingPage3_t, MPI2_POINTER pMpi2ManufacturingPage3_t;
427
428#define MPI2_MANUFACTURING3_PAGEVERSION (0x00)
429
430
431/* Manufacturing Page 4 */
432
433typedef struct _MPI2_MANPAGE4_PWR_SAVE_SETTINGS
434{
435 U8 PowerSaveFlags; /* 0x00 */
436 U8 InternalOperationsSleepTime; /* 0x01 */
437 U8 InternalOperationsRunTime; /* 0x02 */
438 U8 HostIdleTime; /* 0x03 */
439} MPI2_MANPAGE4_PWR_SAVE_SETTINGS,
440 MPI2_POINTER PTR_MPI2_MANPAGE4_PWR_SAVE_SETTINGS,
441 Mpi2ManPage4PwrSaveSettings_t, MPI2_POINTER pMpi2ManPage4PwrSaveSettings_t;
442
443/* defines for the PowerSaveFlags field */
444#define MPI2_MANPAGE4_MASK_POWERSAVE_MODE (0x03)
445#define MPI2_MANPAGE4_POWERSAVE_MODE_DISABLED (0x00)
446#define MPI2_MANPAGE4_CUSTOM_POWERSAVE_MODE (0x01)
447#define MPI2_MANPAGE4_FULL_POWERSAVE_MODE (0x02)
448
449typedef struct _MPI2_CONFIG_PAGE_MAN_4
450{
451 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
452 U32 Reserved1; /* 0x04 */
453 U32 Flags; /* 0x08 */
454 U8 InquirySize; /* 0x0C */
455 U8 Reserved2; /* 0x0D */
456 U16 Reserved3; /* 0x0E */
457 U8 InquiryData[56]; /* 0x10 */
458 U32 RAID0VolumeSettings; /* 0x48 */
459 U32 RAID1EVolumeSettings; /* 0x4C */
460 U32 RAID1VolumeSettings; /* 0x50 */
461 U32 RAID10VolumeSettings; /* 0x54 */
462 U32 Reserved4; /* 0x58 */
463 U32 Reserved5; /* 0x5C */
464 MPI2_MANPAGE4_PWR_SAVE_SETTINGS PowerSaveSettings; /* 0x60 */
465 U8 MaxOCEDisks; /* 0x64 */
466 U8 ResyncRate; /* 0x65 */
467 U16 DataScrubDuration; /* 0x66 */
468 U8 MaxHotSpares; /* 0x68 */
469 U8 MaxPhysDisksPerVol; /* 0x69 */
470 U8 MaxPhysDisks; /* 0x6A */
471 U8 MaxVolumes; /* 0x6B */
472} MPI2_CONFIG_PAGE_MAN_4,
473 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_4,
474 Mpi2ManufacturingPage4_t, MPI2_POINTER pMpi2ManufacturingPage4_t;
475
476#define MPI2_MANUFACTURING4_PAGEVERSION (0x0A)
477
478/* Manufacturing Page 4 Flags field */
479#define MPI2_MANPAGE4_METADATA_SIZE_MASK (0x00030000)
480#define MPI2_MANPAGE4_METADATA_512MB (0x00000000)
481
482#define MPI2_MANPAGE4_MIX_SSD_SAS_SATA (0x00008000)
483#define MPI2_MANPAGE4_MIX_SSD_AND_NON_SSD (0x00004000)
484#define MPI2_MANPAGE4_HIDE_PHYSDISK_NON_IR (0x00002000)
485
486#define MPI2_MANPAGE4_MASK_PHYSDISK_COERCION (0x00001C00)
487#define MPI2_MANPAGE4_PHYSDISK_COERCION_1GB (0x00000000)
488#define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION (0x00000400)
489#define MPI2_MANPAGE4_PHYSDISK_ADAPTIVE_COERCION (0x00000800)
490#define MPI2_MANPAGE4_PHYSDISK_ZERO_COERCION (0x00000C00)
491
492#define MPI2_MANPAGE4_MASK_BAD_BLOCK_MARKING (0x00000300)
493#define MPI2_MANPAGE4_DEFAULT_BAD_BLOCK_MARKING (0x00000000)
494#define MPI2_MANPAGE4_TABLE_BAD_BLOCK_MARKING (0x00000100)
495#define MPI2_MANPAGE4_WRITE_LONG_BAD_BLOCK_MARKING (0x00000200)
496
497#define MPI2_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x00000080)
498#define MPI2_MANPAGE4_RAID10_DISABLE (0x00000040)
499#define MPI2_MANPAGE4_RAID1E_DISABLE (0x00000020)
500#define MPI2_MANPAGE4_RAID1_DISABLE (0x00000010)
501#define MPI2_MANPAGE4_RAID0_DISABLE (0x00000008)
502#define MPI2_MANPAGE4_IR_MODEPAGE8_DISABLE (0x00000004)
503#define MPI2_MANPAGE4_IM_RESYNC_CACHE_ENABLE (0x00000002)
504#define MPI2_MANPAGE4_IR_NO_MIX_SAS_SATA (0x00000001)
505
506
507/* Manufacturing Page 5 */
508
509/*
510 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
511 * one and check Header.PageLength or NumPhys at runtime.
512 */
513#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES
514#define MPI2_MAN_PAGE_5_PHY_ENTRIES (1)
515#endif
516
517typedef struct _MPI2_MANUFACTURING5_ENTRY
518{
519 U64 WWID; /* 0x00 */
520 U64 DeviceName; /* 0x08 */
521} MPI2_MANUFACTURING5_ENTRY, MPI2_POINTER PTR_MPI2_MANUFACTURING5_ENTRY,
522 Mpi2Manufacturing5Entry_t, MPI2_POINTER pMpi2Manufacturing5Entry_t;
523
524typedef struct _MPI2_CONFIG_PAGE_MAN_5
525{
526 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
527 U8 NumPhys; /* 0x04 */
528 U8 Reserved1; /* 0x05 */
529 U16 Reserved2; /* 0x06 */
530 U32 Reserved3; /* 0x08 */
531 U32 Reserved4; /* 0x0C */
532 MPI2_MANUFACTURING5_ENTRY Phy[MPI2_MAN_PAGE_5_PHY_ENTRIES];/* 0x08 */
533} MPI2_CONFIG_PAGE_MAN_5,
534 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_5,
535 Mpi2ManufacturingPage5_t, MPI2_POINTER pMpi2ManufacturingPage5_t;
536
537#define MPI2_MANUFACTURING5_PAGEVERSION (0x03)
538
539
540/* Manufacturing Page 6 */
541
542typedef struct _MPI2_CONFIG_PAGE_MAN_6
543{
544 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
545 U32 ProductSpecificInfo;/* 0x04 */
546} MPI2_CONFIG_PAGE_MAN_6,
547 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_6,
548 Mpi2ManufacturingPage6_t, MPI2_POINTER pMpi2ManufacturingPage6_t;
549
550#define MPI2_MANUFACTURING6_PAGEVERSION (0x00)
551
552
553/* Manufacturing Page 7 */
554
555typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO
556{
557 U32 Pinout; /* 0x00 */
558 U8 Connector[16]; /* 0x04 */
559 U8 Location; /* 0x14 */
560 U8 Reserved1; /* 0x15 */
561 U16 Slot; /* 0x16 */
562 U32 Reserved2; /* 0x18 */
563} MPI2_MANPAGE7_CONNECTOR_INFO, MPI2_POINTER PTR_MPI2_MANPAGE7_CONNECTOR_INFO,
564 Mpi2ManPage7ConnectorInfo_t, MPI2_POINTER pMpi2ManPage7ConnectorInfo_t;
565
566/* defines for the Pinout field */
567#define MPI2_MANPAGE7_PINOUT_SFF_8484_L4 (0x00080000)
568#define MPI2_MANPAGE7_PINOUT_SFF_8484_L3 (0x00040000)
569#define MPI2_MANPAGE7_PINOUT_SFF_8484_L2 (0x00020000)
570#define MPI2_MANPAGE7_PINOUT_SFF_8484_L1 (0x00010000)
571#define MPI2_MANPAGE7_PINOUT_SFF_8470_L4 (0x00000800)
572#define MPI2_MANPAGE7_PINOUT_SFF_8470_L3 (0x00000400)
573#define MPI2_MANPAGE7_PINOUT_SFF_8470_L2 (0x00000200)
574#define MPI2_MANPAGE7_PINOUT_SFF_8470_L1 (0x00000100)
575#define MPI2_MANPAGE7_PINOUT_SFF_8482 (0x00000002)
576#define MPI2_MANPAGE7_PINOUT_CONNECTION_UNKNOWN (0x00000001)
577
578/* defines for the Location field */
579#define MPI2_MANPAGE7_LOCATION_UNKNOWN (0x01)
580#define MPI2_MANPAGE7_LOCATION_INTERNAL (0x02)
581#define MPI2_MANPAGE7_LOCATION_EXTERNAL (0x04)
582#define MPI2_MANPAGE7_LOCATION_SWITCHABLE (0x08)
583#define MPI2_MANPAGE7_LOCATION_AUTO (0x10)
584#define MPI2_MANPAGE7_LOCATION_NOT_PRESENT (0x20)
585#define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED (0x80)
586
587/*
588 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
589 * one and check NumPhys at runtime.
590 */
591#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX
592#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX (1)
593#endif
594
595typedef struct _MPI2_CONFIG_PAGE_MAN_7
596{
597 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
598 U32 Reserved1; /* 0x04 */
599 U32 Reserved2; /* 0x08 */
600 U32 Flags; /* 0x0C */
601 U8 EnclosureName[16]; /* 0x10 */
602 U8 NumPhys; /* 0x20 */
603 U8 Reserved3; /* 0x21 */
604 U16 Reserved4; /* 0x22 */
605 MPI2_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI2_MANPAGE7_CONNECTOR_INFO_MAX]; /* 0x24 */
606} MPI2_CONFIG_PAGE_MAN_7,
607 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_7,
608 Mpi2ManufacturingPage7_t, MPI2_POINTER pMpi2ManufacturingPage7_t;
609
610#define MPI2_MANUFACTURING7_PAGEVERSION (0x00)
611
612/* defines for the Flags field */
613#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
614
615
616/*
617 * Generic structure to use for product-specific manufacturing pages
618 * (currently Manufacturing Page 8 through Manufacturing Page 31).
619 */
620
621typedef struct _MPI2_CONFIG_PAGE_MAN_PS
622{
623 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
624 U32 ProductSpecificInfo;/* 0x04 */
625} MPI2_CONFIG_PAGE_MAN_PS,
626 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_PS,
627 Mpi2ManufacturingPagePS_t, MPI2_POINTER pMpi2ManufacturingPagePS_t;
628
629#define MPI2_MANUFACTURING8_PAGEVERSION (0x00)
630#define MPI2_MANUFACTURING9_PAGEVERSION (0x00)
631#define MPI2_MANUFACTURING10_PAGEVERSION (0x00)
632#define MPI2_MANUFACTURING11_PAGEVERSION (0x00)
633#define MPI2_MANUFACTURING12_PAGEVERSION (0x00)
634#define MPI2_MANUFACTURING13_PAGEVERSION (0x00)
635#define MPI2_MANUFACTURING14_PAGEVERSION (0x00)
636#define MPI2_MANUFACTURING15_PAGEVERSION (0x00)
637#define MPI2_MANUFACTURING16_PAGEVERSION (0x00)
638#define MPI2_MANUFACTURING17_PAGEVERSION (0x00)
639#define MPI2_MANUFACTURING18_PAGEVERSION (0x00)
640#define MPI2_MANUFACTURING19_PAGEVERSION (0x00)
641#define MPI2_MANUFACTURING20_PAGEVERSION (0x00)
642#define MPI2_MANUFACTURING21_PAGEVERSION (0x00)
643#define MPI2_MANUFACTURING22_PAGEVERSION (0x00)
644#define MPI2_MANUFACTURING23_PAGEVERSION (0x00)
645#define MPI2_MANUFACTURING24_PAGEVERSION (0x00)
646#define MPI2_MANUFACTURING25_PAGEVERSION (0x00)
647#define MPI2_MANUFACTURING26_PAGEVERSION (0x00)
648#define MPI2_MANUFACTURING27_PAGEVERSION (0x00)
649#define MPI2_MANUFACTURING28_PAGEVERSION (0x00)
650#define MPI2_MANUFACTURING29_PAGEVERSION (0x00)
651#define MPI2_MANUFACTURING30_PAGEVERSION (0x00)
652#define MPI2_MANUFACTURING31_PAGEVERSION (0x00)
653
654
655/****************************************************************************
656* IO Unit Config Pages
657****************************************************************************/
658
659/* IO Unit Page 0 */
660
661typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_0
662{
663 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
664 U64 UniqueValue; /* 0x04 */
665 MPI2_VERSION_UNION NvdataVersionDefault; /* 0x08 */
666 MPI2_VERSION_UNION NvdataVersionPersistent; /* 0x0A */
667} MPI2_CONFIG_PAGE_IO_UNIT_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_0,
668 Mpi2IOUnitPage0_t, MPI2_POINTER pMpi2IOUnitPage0_t;
669
670#define MPI2_IOUNITPAGE0_PAGEVERSION (0x02)
671
672
673/* IO Unit Page 1 */
674
675typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
676{
677 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
678 U32 Flags; /* 0x04 */
679} MPI2_CONFIG_PAGE_IO_UNIT_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_1,
680 Mpi2IOUnitPage1_t, MPI2_POINTER pMpi2IOUnitPage1_t;
681
682#define MPI2_IOUNITPAGE1_PAGEVERSION (0x04)
683
684/* IO Unit Page 1 Flags defines */
685#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600)
686#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000)
687#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200)
688#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400)
689#define MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100)
690#define MPI2_IOUNITPAGE1_DISABLE_IR (0x00000040)
691#define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020)
692#define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004)
693#define MPI2_IOUNITPAGE1_MULTI_PATHING (0x00000002)
694#define MPI2_IOUNITPAGE1_SINGLE_PATHING (0x00000000)
695
696
697/* IO Unit Page 3 */
698
699/*
700 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
701 * one and check Header.PageLength at runtime.
702 */
703#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX
704#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1)
705#endif
706
707typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3
708{
709 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
710 U8 GPIOCount; /* 0x04 */
711 U8 Reserved1; /* 0x05 */
712 U16 Reserved2; /* 0x06 */
713 U16 GPIOVal[MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX];/* 0x08 */
714} MPI2_CONFIG_PAGE_IO_UNIT_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_3,
715 Mpi2IOUnitPage3_t, MPI2_POINTER pMpi2IOUnitPage3_t;
716
717#define MPI2_IOUNITPAGE3_PAGEVERSION (0x01)
718
719/* defines for IO Unit Page 3 GPIOVal field */
720#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_MASK (0xFFFC)
721#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_SHIFT (2)
722#define MPI2_IOUNITPAGE3_GPIO_SETTING_OFF (0x0000)
723#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001)
724
725
726/****************************************************************************
727* IOC Config Pages
728****************************************************************************/
729
730/* IOC Page 0 */
731
732typedef struct _MPI2_CONFIG_PAGE_IOC_0
733{
734 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
735 U32 Reserved1; /* 0x04 */
736 U32 Reserved2; /* 0x08 */
737 U16 VendorID; /* 0x0C */
738 U16 DeviceID; /* 0x0E */
739 U8 RevisionID; /* 0x10 */
740 U8 Reserved3; /* 0x11 */
741 U16 Reserved4; /* 0x12 */
742 U32 ClassCode; /* 0x14 */
743 U16 SubsystemVendorID; /* 0x18 */
744 U16 SubsystemID; /* 0x1A */
745} MPI2_CONFIG_PAGE_IOC_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_0,
746 Mpi2IOCPage0_t, MPI2_POINTER pMpi2IOCPage0_t;
747
748#define MPI2_IOCPAGE0_PAGEVERSION (0x02)
749
750
751/* IOC Page 1 */
752
753typedef struct _MPI2_CONFIG_PAGE_IOC_1
754{
755 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
756 U32 Flags; /* 0x04 */
757 U32 CoalescingTimeout; /* 0x08 */
758 U8 CoalescingDepth; /* 0x0C */
759 U8 PCISlotNum; /* 0x0D */
760 U8 PCIBusNum; /* 0x0E */
761 U8 PCIDomainSegment; /* 0x0F */
762 U32 Reserved1; /* 0x10 */
763 U32 Reserved2; /* 0x14 */
764} MPI2_CONFIG_PAGE_IOC_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_1,
765 Mpi2IOCPage1_t, MPI2_POINTER pMpi2IOCPage1_t;
766
767#define MPI2_IOCPAGE1_PAGEVERSION (0x05)
768
769/* defines for IOC Page 1 Flags field */
770#define MPI2_IOCPAGE1_REPLY_COALESCING (0x00000001)
771
772#define MPI2_IOCPAGE1_PCISLOTNUM_UNKNOWN (0xFF)
773#define MPI2_IOCPAGE1_PCIBUSNUM_UNKNOWN (0xFF)
774#define MPI2_IOCPAGE1_PCIDOMAIN_UNKNOWN (0xFF)
775
776/* IOC Page 6 */
777
778typedef struct _MPI2_CONFIG_PAGE_IOC_6
779{
780 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
781 U32 CapabilitiesFlags; /* 0x04 */
782 U8 MaxDrivesRAID0; /* 0x08 */
783 U8 MaxDrivesRAID1; /* 0x09 */
784 U8 MaxDrivesRAID1E; /* 0x0A */
785 U8 MaxDrivesRAID10; /* 0x0B */
786 U8 MinDrivesRAID0; /* 0x0C */
787 U8 MinDrivesRAID1; /* 0x0D */
788 U8 MinDrivesRAID1E; /* 0x0E */
789 U8 MinDrivesRAID10; /* 0x0F */
790 U32 Reserved1; /* 0x10 */
791 U8 MaxGlobalHotSpares; /* 0x14 */
792 U8 MaxPhysDisks; /* 0x15 */
793 U8 MaxVolumes; /* 0x16 */
794 U8 MaxConfigs; /* 0x17 */
795 U8 MaxOCEDisks; /* 0x18 */
796 U8 Reserved2; /* 0x19 */
797 U16 Reserved3; /* 0x1A */
798 U32 SupportedStripeSizeMapRAID0; /* 0x1C */
799 U32 SupportedStripeSizeMapRAID1E; /* 0x20 */
800 U32 SupportedStripeSizeMapRAID10; /* 0x24 */
801 U32 Reserved4; /* 0x28 */
802 U32 Reserved5; /* 0x2C */
803 U16 DefaultMetadataSize; /* 0x30 */
804 U16 Reserved6; /* 0x32 */
805 U16 MaxBadBlockTableEntries; /* 0x34 */
806 U16 Reserved7; /* 0x36 */
807 U32 IRNvsramVersion; /* 0x38 */
808} MPI2_CONFIG_PAGE_IOC_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_6,
809 Mpi2IOCPage6_t, MPI2_POINTER pMpi2IOCPage6_t;
810
811#define MPI2_IOCPAGE6_PAGEVERSION (0x04)
812
813/* defines for IOC Page 6 CapabilitiesFlags */
814#define MPI2_IOCPAGE6_CAP_FLAGS_RAID10_SUPPORT (0x00000010)
815#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1_SUPPORT (0x00000008)
816#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1E_SUPPORT (0x00000004)
817#define MPI2_IOCPAGE6_CAP_FLAGS_RAID0_SUPPORT (0x00000002)
818#define MPI2_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001)
819
820
821/* IOC Page 7 */
822
823#define MPI2_IOCPAGE7_EVENTMASK_WORDS (4)
824
825typedef struct _MPI2_CONFIG_PAGE_IOC_7
826{
827 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
828 U32 Reserved1; /* 0x04 */
829 U32 EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/* 0x08 */
830 U16 SASBroadcastPrimitiveMasks; /* 0x18 */
831 U16 Reserved2; /* 0x1A */
832 U32 Reserved3; /* 0x1C */
833} MPI2_CONFIG_PAGE_IOC_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_7,
834 Mpi2IOCPage7_t, MPI2_POINTER pMpi2IOCPage7_t;
835
836#define MPI2_IOCPAGE7_PAGEVERSION (0x01)
837
838
839/* IOC Page 8 */
840
841typedef struct _MPI2_CONFIG_PAGE_IOC_8
842{
843 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
844 U8 NumDevsPerEnclosure; /* 0x04 */
845 U8 Reserved1; /* 0x05 */
846 U16 Reserved2; /* 0x06 */
847 U16 MaxPersistentEntries; /* 0x08 */
848 U16 MaxNumPhysicalMappedIDs; /* 0x0A */
849 U16 Flags; /* 0x0C */
850 U16 Reserved3; /* 0x0E */
851 U16 IRVolumeMappingFlags; /* 0x10 */
852 U16 Reserved4; /* 0x12 */
853 U32 Reserved5; /* 0x14 */
854} MPI2_CONFIG_PAGE_IOC_8, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_8,
855 Mpi2IOCPage8_t, MPI2_POINTER pMpi2IOCPage8_t;
856
857#define MPI2_IOCPAGE8_PAGEVERSION (0x00)
858
859/* defines for IOC Page 8 Flags field */
860#define MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1 (0x00000020)
861#define MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0 (0x00000010)
862
863#define MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE (0x0000000E)
864#define MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING (0x00000000)
865#define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING (0x00000002)
866
867#define MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING (0x00000001)
868#define MPI2_IOCPAGE8_FLAGS_ENABLE_PERSISTENT_MAPPING (0x00000000)
869
870/* defines for IOC Page 8 IRVolumeMappingFlags */
871#define MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE (0x00000003)
872#define MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING (0x00000000)
873#define MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING (0x00000001)
874
875
876/****************************************************************************
877* BIOS Config Pages
878****************************************************************************/
879
880/* BIOS Page 1 */
881
882typedef struct _MPI2_CONFIG_PAGE_BIOS_1
883{
884 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
885 U32 BiosOptions; /* 0x04 */
886 U32 IOCSettings; /* 0x08 */
887 U32 Reserved1; /* 0x0C */
888 U32 DeviceSettings; /* 0x10 */
889 U16 NumberOfDevices; /* 0x14 */
890 U16 Reserved2; /* 0x16 */
891 U16 IOTimeoutBlockDevicesNonRM; /* 0x18 */
892 U16 IOTimeoutSequential; /* 0x1A */
893 U16 IOTimeoutOther; /* 0x1C */
894 U16 IOTimeoutBlockDevicesRM; /* 0x1E */
895} MPI2_CONFIG_PAGE_BIOS_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_1,
896 Mpi2BiosPage1_t, MPI2_POINTER pMpi2BiosPage1_t;
897
898#define MPI2_BIOSPAGE1_PAGEVERSION (0x04)
899
900/* values for BIOS Page 1 BiosOptions field */
901#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
902
903/* values for BIOS Page 1 IOCSettings field */
904#define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
905#define MPI2_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
906#define MPI2_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
907
908#define MPI2_BIOSPAGE1_IOCSET_MASK_RM_SETTING (0x000000C0)
909#define MPI2_BIOSPAGE1_IOCSET_NONE_RM_SETTING (0x00000000)
910#define MPI2_BIOSPAGE1_IOCSET_BOOT_RM_SETTING (0x00000040)
911#define MPI2_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING (0x00000080)
912
913#define MPI2_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT (0x00000030)
914#define MPI2_BIOSPAGE1_IOCSET_NO_SUPPORT (0x00000000)
915#define MPI2_BIOSPAGE1_IOCSET_BIOS_SUPPORT (0x00000010)
916#define MPI2_BIOSPAGE1_IOCSET_OS_SUPPORT (0x00000020)
917#define MPI2_BIOSPAGE1_IOCSET_ALL_SUPPORT (0x00000030)
918
919#define MPI2_BIOSPAGE1_IOCSET_ALTERNATE_CHS (0x00000008)
920
921/* values for BIOS Page 1 DeviceSettings field */
922#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING (0x00000010)
923#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN (0x00000008)
924#define MPI2_BIOSPAGE1_DEVSET_DISABLE_RM_LUN (0x00000004)
925#define MPI2_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002)
926#define MPI2_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001)
927
928
929/* BIOS Page 2 */
930
931typedef struct _MPI2_BOOT_DEVICE_ADAPTER_ORDER
932{
933 U32 Reserved1; /* 0x00 */
934 U32 Reserved2; /* 0x04 */
935 U32 Reserved3; /* 0x08 */
936 U32 Reserved4; /* 0x0C */
937 U32 Reserved5; /* 0x10 */
938 U32 Reserved6; /* 0x14 */
939} MPI2_BOOT_DEVICE_ADAPTER_ORDER,
940 MPI2_POINTER PTR_MPI2_BOOT_DEVICE_ADAPTER_ORDER,
941 Mpi2BootDeviceAdapterOrder_t, MPI2_POINTER pMpi2BootDeviceAdapterOrder_t;
942
943typedef struct _MPI2_BOOT_DEVICE_SAS_WWID
944{
945 U64 SASAddress; /* 0x00 */
946 U8 LUN[8]; /* 0x08 */
947 U32 Reserved1; /* 0x10 */
948 U32 Reserved2; /* 0x14 */
949} MPI2_BOOT_DEVICE_SAS_WWID, MPI2_POINTER PTR_MPI2_BOOT_DEVICE_SAS_WWID,
950 Mpi2BootDeviceSasWwid_t, MPI2_POINTER pMpi2BootDeviceSasWwid_t;
951
952typedef struct _MPI2_BOOT_DEVICE_ENCLOSURE_SLOT
953{
954 U64 EnclosureLogicalID; /* 0x00 */
955 U32 Reserved1; /* 0x08 */
956 U32 Reserved2; /* 0x0C */
957 U16 SlotNumber; /* 0x10 */
958 U16 Reserved3; /* 0x12 */
959 U32 Reserved4; /* 0x14 */
960} MPI2_BOOT_DEVICE_ENCLOSURE_SLOT,
961 MPI2_POINTER PTR_MPI2_BOOT_DEVICE_ENCLOSURE_SLOT,
962 Mpi2BootDeviceEnclosureSlot_t, MPI2_POINTER pMpi2BootDeviceEnclosureSlot_t;
963
964typedef struct _MPI2_BOOT_DEVICE_DEVICE_NAME
965{
966 U64 DeviceName; /* 0x00 */
967 U8 LUN[8]; /* 0x08 */
968 U32 Reserved1; /* 0x10 */
969 U32 Reserved2; /* 0x14 */
970} MPI2_BOOT_DEVICE_DEVICE_NAME, MPI2_POINTER PTR_MPI2_BOOT_DEVICE_DEVICE_NAME,
971 Mpi2BootDeviceDeviceName_t, MPI2_POINTER pMpi2BootDeviceDeviceName_t;
972
973typedef union _MPI2_MPI2_BIOSPAGE2_BOOT_DEVICE
974{
975 MPI2_BOOT_DEVICE_ADAPTER_ORDER AdapterOrder;
976 MPI2_BOOT_DEVICE_SAS_WWID SasWwid;
977 MPI2_BOOT_DEVICE_ENCLOSURE_SLOT EnclosureSlot;
978 MPI2_BOOT_DEVICE_DEVICE_NAME DeviceName;
979} MPI2_BIOSPAGE2_BOOT_DEVICE, MPI2_POINTER PTR_MPI2_BIOSPAGE2_BOOT_DEVICE,
980 Mpi2BiosPage2BootDevice_t, MPI2_POINTER pMpi2BiosPage2BootDevice_t;
981
982typedef struct _MPI2_CONFIG_PAGE_BIOS_2
983{
984 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
985 U32 Reserved1; /* 0x04 */
986 U32 Reserved2; /* 0x08 */
987 U32 Reserved3; /* 0x0C */
988 U32 Reserved4; /* 0x10 */
989 U32 Reserved5; /* 0x14 */
990 U32 Reserved6; /* 0x18 */
991 U8 ReqBootDeviceForm; /* 0x1C */
992 U8 Reserved7; /* 0x1D */
993 U16 Reserved8; /* 0x1E */
994 MPI2_BIOSPAGE2_BOOT_DEVICE RequestedBootDevice; /* 0x20 */
995 U8 ReqAltBootDeviceForm; /* 0x38 */
996 U8 Reserved9; /* 0x39 */
997 U16 Reserved10; /* 0x3A */
998 MPI2_BIOSPAGE2_BOOT_DEVICE RequestedAltBootDevice; /* 0x3C */
999 U8 CurrentBootDeviceForm; /* 0x58 */
1000 U8 Reserved11; /* 0x59 */
1001 U16 Reserved12; /* 0x5A */
1002 MPI2_BIOSPAGE2_BOOT_DEVICE CurrentBootDevice; /* 0x58 */
1003} MPI2_CONFIG_PAGE_BIOS_2, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_2,
1004 Mpi2BiosPage2_t, MPI2_POINTER pMpi2BiosPage2_t;
1005
1006#define MPI2_BIOSPAGE2_PAGEVERSION (0x04)
1007
1008/* values for BIOS Page 2 BootDeviceForm fields */
1009#define MPI2_BIOSPAGE2_FORM_MASK (0x0F)
1010#define MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED (0x00)
1011#define MPI2_BIOSPAGE2_FORM_SAS_WWID (0x05)
1012#define MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06)
1013#define MPI2_BIOSPAGE2_FORM_DEVICE_NAME (0x07)
1014
1015
1016/* BIOS Page 3 */
1017
1018typedef struct _MPI2_ADAPTER_INFO
1019{
1020 U8 PciBusNumber; /* 0x00 */
1021 U8 PciDeviceAndFunctionNumber; /* 0x01 */
1022 U16 AdapterFlags; /* 0x02 */
1023} MPI2_ADAPTER_INFO, MPI2_POINTER PTR_MPI2_ADAPTER_INFO,
1024 Mpi2AdapterInfo_t, MPI2_POINTER pMpi2AdapterInfo_t;
1025
1026#define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED (0x0001)
1027#define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS (0x0002)
1028
1029typedef struct _MPI2_CONFIG_PAGE_BIOS_3
1030{
1031 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1032 U32 GlobalFlags; /* 0x04 */
1033 U32 BiosVersion; /* 0x08 */
1034 MPI2_ADAPTER_INFO AdapterOrder[4]; /* 0x0C */
1035 U32 Reserved1; /* 0x1C */
1036} MPI2_CONFIG_PAGE_BIOS_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_3,
1037 Mpi2BiosPage3_t, MPI2_POINTER pMpi2BiosPage3_t;
1038
1039#define MPI2_BIOSPAGE3_PAGEVERSION (0x00)
1040
1041/* values for BIOS Page 3 GlobalFlags */
1042#define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR (0x00000002)
1043#define MPI2_BIOSPAGE3_FLAGS_VERBOSE_ENABLE (0x00000004)
1044#define MPI2_BIOSPAGE3_FLAGS_HOOK_INT_40_DISABLE (0x00000010)
1045
1046#define MPI2_BIOSPAGE3_FLAGS_DEV_LIST_DISPLAY_MASK (0x000000E0)
1047#define MPI2_BIOSPAGE3_FLAGS_INSTALLED_DEV_DISPLAY (0x00000000)
1048#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DISPLAY (0x00000020)
1049#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DEV_DISPLAY (0x00000040)
1050
1051
1052/* BIOS Page 4 */
1053
1054/*
1055 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1056 * one and check Header.PageLength or NumPhys at runtime.
1057 */
1058#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES
1059#define MPI2_BIOS_PAGE_4_PHY_ENTRIES (1)
1060#endif
1061
1062typedef struct _MPI2_BIOS4_ENTRY
1063{
1064 U64 ReassignmentWWID; /* 0x00 */
1065 U64 ReassignmentDeviceName; /* 0x08 */
1066} MPI2_BIOS4_ENTRY, MPI2_POINTER PTR_MPI2_BIOS4_ENTRY,
1067 Mpi2MBios4Entry_t, MPI2_POINTER pMpi2Bios4Entry_t;
1068
1069typedef struct _MPI2_CONFIG_PAGE_BIOS_4
1070{
1071 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1072 U8 NumPhys; /* 0x04 */
1073 U8 Reserved1; /* 0x05 */
1074 U16 Reserved2; /* 0x06 */
1075 MPI2_BIOS4_ENTRY Phy[MPI2_BIOS_PAGE_4_PHY_ENTRIES]; /* 0x08 */
1076} MPI2_CONFIG_PAGE_BIOS_4, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_4,
1077 Mpi2BiosPage4_t, MPI2_POINTER pMpi2BiosPage4_t;
1078
1079#define MPI2_BIOSPAGE4_PAGEVERSION (0x01)
1080
1081
1082/****************************************************************************
1083* RAID Volume Config Pages
1084****************************************************************************/
1085
1086/* RAID Volume Page 0 */
1087
1088typedef struct _MPI2_RAIDVOL0_PHYS_DISK
1089{
1090 U8 RAIDSetNum; /* 0x00 */
1091 U8 PhysDiskMap; /* 0x01 */
1092 U8 PhysDiskNum; /* 0x02 */
1093 U8 Reserved; /* 0x03 */
1094} MPI2_RAIDVOL0_PHYS_DISK, MPI2_POINTER PTR_MPI2_RAIDVOL0_PHYS_DISK,
1095 Mpi2RaidVol0PhysDisk_t, MPI2_POINTER pMpi2RaidVol0PhysDisk_t;
1096
1097/* defines for the PhysDiskMap field */
1098#define MPI2_RAIDVOL0_PHYSDISK_PRIMARY (0x01)
1099#define MPI2_RAIDVOL0_PHYSDISK_SECONDARY (0x02)
1100
1101typedef struct _MPI2_RAIDVOL0_SETTINGS
1102{
1103 U16 Settings; /* 0x00 */
1104 U8 HotSparePool; /* 0x01 */
1105 U8 Reserved; /* 0x02 */
1106} MPI2_RAIDVOL0_SETTINGS, MPI2_POINTER PTR_MPI2_RAIDVOL0_SETTINGS,
1107 Mpi2RaidVol0Settings_t, MPI2_POINTER pMpi2RaidVol0Settings_t;
1108
1109/* RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */
1110#define MPI2_RAID_HOT_SPARE_POOL_0 (0x01)
1111#define MPI2_RAID_HOT_SPARE_POOL_1 (0x02)
1112#define MPI2_RAID_HOT_SPARE_POOL_2 (0x04)
1113#define MPI2_RAID_HOT_SPARE_POOL_3 (0x08)
1114#define MPI2_RAID_HOT_SPARE_POOL_4 (0x10)
1115#define MPI2_RAID_HOT_SPARE_POOL_5 (0x20)
1116#define MPI2_RAID_HOT_SPARE_POOL_6 (0x40)
1117#define MPI2_RAID_HOT_SPARE_POOL_7 (0x80)
1118
1119/* RAID Volume Page 0 VolumeSettings defines */
1120#define MPI2_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0008)
1121#define MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE (0x0004)
1122
1123#define MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING (0x0003)
1124#define MPI2_RAIDVOL0_SETTING_UNCHANGED (0x0000)
1125#define MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING (0x0001)
1126#define MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING (0x0002)
1127
1128/*
1129 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1130 * one and check Header.PageLength at runtime.
1131 */
1132#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX
1133#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX (1)
1134#endif
1135
1136typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0
1137{
1138 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1139 U16 DevHandle; /* 0x04 */
1140 U8 VolumeState; /* 0x06 */
1141 U8 VolumeType; /* 0x07 */
1142 U32 VolumeStatusFlags; /* 0x08 */
1143 MPI2_RAIDVOL0_SETTINGS VolumeSettings; /* 0x0C */
1144 U64 MaxLBA; /* 0x10 */
1145 U32 StripeSize; /* 0x18 */
1146 U16 BlockSize; /* 0x1C */
1147 U16 Reserved1; /* 0x1E */
1148 U8 SupportedPhysDisks; /* 0x20 */
1149 U8 ResyncRate; /* 0x21 */
1150 U16 DataScrubDuration; /* 0x22 */
1151 U8 NumPhysDisks; /* 0x24 */
1152 U8 Reserved2; /* 0x25 */
1153 U8 Reserved3; /* 0x26 */
1154 U8 InactiveStatus; /* 0x27 */
1155 MPI2_RAIDVOL0_PHYS_DISK PhysDisk[MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /* 0x28 */
1156} MPI2_CONFIG_PAGE_RAID_VOL_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_VOL_0,
1157 Mpi2RaidVolPage0_t, MPI2_POINTER pMpi2RaidVolPage0_t;
1158
1159#define MPI2_RAIDVOLPAGE0_PAGEVERSION (0x0A)
1160
1161/* values for RAID VolumeState */
1162#define MPI2_RAID_VOL_STATE_MISSING (0x00)
1163#define MPI2_RAID_VOL_STATE_FAILED (0x01)
1164#define MPI2_RAID_VOL_STATE_INITIALIZING (0x02)
1165#define MPI2_RAID_VOL_STATE_ONLINE (0x03)
1166#define MPI2_RAID_VOL_STATE_DEGRADED (0x04)
1167#define MPI2_RAID_VOL_STATE_OPTIMAL (0x05)
1168
1169/* values for RAID VolumeType */
1170#define MPI2_RAID_VOL_TYPE_RAID0 (0x00)
1171#define MPI2_RAID_VOL_TYPE_RAID1E (0x01)
1172#define MPI2_RAID_VOL_TYPE_RAID1 (0x02)
1173#define MPI2_RAID_VOL_TYPE_RAID10 (0x05)
1174#define MPI2_RAID_VOL_TYPE_UNKNOWN (0xFF)
1175
1176/* values for RAID Volume Page 0 VolumeStatusFlags field */
1177#define MPI2_RAIDVOL0_STATUS_FLAG_PENDING_RESYNC (0x02000000)
1178#define MPI2_RAIDVOL0_STATUS_FLAG_BACKG_INIT_PENDING (0x01000000)
1179#define MPI2_RAIDVOL0_STATUS_FLAG_MDC_PENDING (0x00800000)
1180#define MPI2_RAIDVOL0_STATUS_FLAG_USER_CONSIST_PENDING (0x00400000)
1181#define MPI2_RAIDVOL0_STATUS_FLAG_MAKE_DATA_CONSISTENT (0x00200000)
1182#define MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB (0x00100000)
1183#define MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK (0x00080000)
1184#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000)
1185#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000)
1186#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000)
1187#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040)
1188#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020)
1189#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000)
1190#define MPI2_RAIDVOL0_STATUS_FLAG_1E_ADJACENT_MIRROR (0x00000010)
1191#define MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x00000008)
1192#define MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x00000004)
1193#define MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED (0x00000002)
1194#define MPI2_RAIDVOL0_STATUS_FLAG_ENABLED (0x00000001)
1195
1196/* values for RAID Volume Page 0 SupportedPhysDisks field */
1197#define MPI2_RAIDVOL0_SUPPORT_SOLID_STATE_DISKS (0x08)
1198#define MPI2_RAIDVOL0_SUPPORT_HARD_DISKS (0x04)
1199#define MPI2_RAIDVOL0_SUPPORT_SAS_PROTOCOL (0x02)
1200#define MPI2_RAIDVOL0_SUPPORT_SATA_PROTOCOL (0x01)
1201
1202/* values for RAID Volume Page 0 InactiveStatus field */
1203#define MPI2_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
1204#define MPI2_RAIDVOLPAGE0_STALE_METADATA_INACTIVE (0x01)
1205#define MPI2_RAIDVOLPAGE0_FOREIGN_VOLUME_INACTIVE (0x02)
1206#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_RESOURCE_INACTIVE (0x03)
1207#define MPI2_RAIDVOLPAGE0_CLONE_VOLUME_INACTIVE (0x04)
1208#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_METADATA_INACTIVE (0x05)
1209#define MPI2_RAIDVOLPAGE0_PREVIOUSLY_DELETED (0x06)
1210
1211
1212/* RAID Volume Page 1 */
1213
1214typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_1
1215{
1216 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1217 U16 DevHandle; /* 0x04 */
1218 U16 Reserved0; /* 0x06 */
1219 U8 GUID[24]; /* 0x08 */
1220 U8 Name[16]; /* 0x20 */
1221 U64 WWID; /* 0x30 */
1222 U32 Reserved1; /* 0x38 */
1223 U32 Reserved2; /* 0x3C */
1224} MPI2_CONFIG_PAGE_RAID_VOL_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_VOL_1,
1225 Mpi2RaidVolPage1_t, MPI2_POINTER pMpi2RaidVolPage1_t;
1226
1227#define MPI2_RAIDVOLPAGE1_PAGEVERSION (0x03)
1228
1229
1230/****************************************************************************
1231* RAID Physical Disk Config Pages
1232****************************************************************************/
1233
1234/* RAID Physical Disk Page 0 */
1235
1236typedef struct _MPI2_RAIDPHYSDISK0_SETTINGS
1237{
1238 U16 Reserved1; /* 0x00 */
1239 U8 HotSparePool; /* 0x02 */
1240 U8 Reserved2; /* 0x03 */
1241} MPI2_RAIDPHYSDISK0_SETTINGS, MPI2_POINTER PTR_MPI2_RAIDPHYSDISK0_SETTINGS,
1242 Mpi2RaidPhysDisk0Settings_t, MPI2_POINTER pMpi2RaidPhysDisk0Settings_t;
1243
1244/* use MPI2_RAID_HOT_SPARE_POOL_ defines for the HotSparePool field */
1245
1246typedef struct _MPI2_RAIDPHYSDISK0_INQUIRY_DATA
1247{
1248 U8 VendorID[8]; /* 0x00 */
1249 U8 ProductID[16]; /* 0x08 */
1250 U8 ProductRevLevel[4]; /* 0x18 */
1251 U8 SerialNum[32]; /* 0x1C */
1252} MPI2_RAIDPHYSDISK0_INQUIRY_DATA,
1253 MPI2_POINTER PTR_MPI2_RAIDPHYSDISK0_INQUIRY_DATA,
1254 Mpi2RaidPhysDisk0InquiryData_t, MPI2_POINTER pMpi2RaidPhysDisk0InquiryData_t;
1255
1256typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0
1257{
1258 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1259 U16 DevHandle; /* 0x04 */
1260 U8 Reserved1; /* 0x06 */
1261 U8 PhysDiskNum; /* 0x07 */
1262 MPI2_RAIDPHYSDISK0_SETTINGS PhysDiskSettings; /* 0x08 */
1263 U32 Reserved2; /* 0x0C */
1264 MPI2_RAIDPHYSDISK0_INQUIRY_DATA InquiryData; /* 0x10 */
1265 U32 Reserved3; /* 0x4C */
1266 U8 PhysDiskState; /* 0x50 */
1267 U8 OfflineReason; /* 0x51 */
1268 U8 IncompatibleReason; /* 0x52 */
1269 U8 PhysDiskAttributes; /* 0x53 */
1270 U32 PhysDiskStatusFlags; /* 0x54 */
1271 U64 DeviceMaxLBA; /* 0x58 */
1272 U64 HostMaxLBA; /* 0x60 */
1273 U64 CoercedMaxLBA; /* 0x68 */
1274 U16 BlockSize; /* 0x70 */
1275 U16 Reserved5; /* 0x72 */
1276 U32 Reserved6; /* 0x74 */
1277} MPI2_CONFIG_PAGE_RD_PDISK_0,
1278 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RD_PDISK_0,
1279 Mpi2RaidPhysDiskPage0_t, MPI2_POINTER pMpi2RaidPhysDiskPage0_t;
1280
1281#define MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION (0x05)
1282
1283/* PhysDiskState defines */
1284#define MPI2_RAID_PD_STATE_NOT_CONFIGURED (0x00)
1285#define MPI2_RAID_PD_STATE_NOT_COMPATIBLE (0x01)
1286#define MPI2_RAID_PD_STATE_OFFLINE (0x02)
1287#define MPI2_RAID_PD_STATE_ONLINE (0x03)
1288#define MPI2_RAID_PD_STATE_HOT_SPARE (0x04)
1289#define MPI2_RAID_PD_STATE_DEGRADED (0x05)
1290#define MPI2_RAID_PD_STATE_REBUILDING (0x06)
1291#define MPI2_RAID_PD_STATE_OPTIMAL (0x07)
1292
1293/* OfflineReason defines */
1294#define MPI2_PHYSDISK0_ONLINE (0x00)
1295#define MPI2_PHYSDISK0_OFFLINE_MISSING (0x01)
1296#define MPI2_PHYSDISK0_OFFLINE_FAILED (0x03)
1297#define MPI2_PHYSDISK0_OFFLINE_INITIALIZING (0x04)
1298#define MPI2_PHYSDISK0_OFFLINE_REQUESTED (0x05)
1299#define MPI2_PHYSDISK0_OFFLINE_FAILED_REQUESTED (0x06)
1300#define MPI2_PHYSDISK0_OFFLINE_OTHER (0xFF)
1301
1302/* IncompatibleReason defines */
1303#define MPI2_PHYSDISK0_COMPATIBLE (0x00)
1304#define MPI2_PHYSDISK0_INCOMPATIBLE_PROTOCOL (0x01)
1305#define MPI2_PHYSDISK0_INCOMPATIBLE_BLOCKSIZE (0x02)
1306#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03)
1307#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04)
1308#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05)
1309#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF)
1310
1311/* PhysDiskAttributes defines */
1312#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08)
1313#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04)
1314#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02)
1315#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01)
1316
1317/* PhysDiskStatusFlags defines */
1318#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED (0x00000040)
1319#define MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET (0x00000020)
1320#define MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED (0x00000010)
1321#define MPI2_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00000000)
1322#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x00000008)
1323#define MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x00000004)
1324#define MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED (0x00000002)
1325#define MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x00000001)
1326
1327
1328/* RAID Physical Disk Page 1 */
1329
1330/*
1331 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1332 * one and check Header.PageLength or NumPhysDiskPaths at runtime.
1333 */
1334#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX
1335#define MPI2_RAID_PHYS_DISK1_PATH_MAX (1)
1336#endif
1337
1338typedef struct _MPI2_RAIDPHYSDISK1_PATH
1339{
1340 U16 DevHandle; /* 0x00 */
1341 U16 Reserved1; /* 0x02 */
1342 U64 WWID; /* 0x04 */
1343 U64 OwnerWWID; /* 0x0C */
1344 U8 OwnerIdentifier; /* 0x14 */
1345 U8 Reserved2; /* 0x15 */
1346 U16 Flags; /* 0x16 */
1347} MPI2_RAIDPHYSDISK1_PATH, MPI2_POINTER PTR_MPI2_RAIDPHYSDISK1_PATH,
1348 Mpi2RaidPhysDisk1Path_t, MPI2_POINTER pMpi2RaidPhysDisk1Path_t;
1349
1350/* RAID Physical Disk Page 1 Physical Disk Path Flags field defines */
1351#define MPI2_RAID_PHYSDISK1_FLAG_PRIMARY (0x0004)
1352#define MPI2_RAID_PHYSDISK1_FLAG_BROKEN (0x0002)
1353#define MPI2_RAID_PHYSDISK1_FLAG_INVALID (0x0001)
1354
1355typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
1356{
1357 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1358 U8 NumPhysDiskPaths; /* 0x04 */
1359 U8 PhysDiskNum; /* 0x05 */
1360 U16 Reserved1; /* 0x06 */
1361 U32 Reserved2; /* 0x08 */
1362 MPI2_RAIDPHYSDISK1_PATH PhysicalDiskPath[MPI2_RAID_PHYS_DISK1_PATH_MAX];/* 0x0C */
1363} MPI2_CONFIG_PAGE_RD_PDISK_1,
1364 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RD_PDISK_1,
1365 Mpi2RaidPhysDiskPage1_t, MPI2_POINTER pMpi2RaidPhysDiskPage1_t;
1366
1367#define MPI2_RAIDPHYSDISKPAGE1_PAGEVERSION (0x02)
1368
1369
1370/****************************************************************************
1371* values for fields used by several types of SAS Config Pages
1372****************************************************************************/
1373
1374/* values for NegotiatedLinkRates fields */
1375#define MPI2_SAS_NEG_LINK_RATE_MASK_LOGICAL (0xF0)
1376#define MPI2_SAS_NEG_LINK_RATE_SHIFT_LOGICAL (4)
1377#define MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL (0x0F)
1378/* link rates used for Negotiated Physical and Logical Link Rate */
1379#define MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE (0x00)
1380#define MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED (0x01)
1381#define MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED (0x02)
1382#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03)
1383#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04)
1384#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05)
1385#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08)
1386#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09)
1387#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A)
1388
1389
1390/* values for AttachedPhyInfo fields */
1391#define MPI2_SAS_APHYINFO_INSIDE_ZPSDS_PERSISTENT (0x00000040)
1392#define MPI2_SAS_APHYINFO_REQUESTED_INSIDE_ZPSDS (0x00000020)
1393#define MPI2_SAS_APHYINFO_BREAK_REPLY_CAPABLE (0x00000010)
1394
1395#define MPI2_SAS_APHYINFO_REASON_MASK (0x0000000F)
1396#define MPI2_SAS_APHYINFO_REASON_UNKNOWN (0x00000000)
1397#define MPI2_SAS_APHYINFO_REASON_POWER_ON (0x00000001)
1398#define MPI2_SAS_APHYINFO_REASON_HARD_RESET (0x00000002)
1399#define MPI2_SAS_APHYINFO_REASON_SMP_PHY_CONTROL (0x00000003)
1400#define MPI2_SAS_APHYINFO_REASON_LOSS_OF_SYNC (0x00000004)
1401#define MPI2_SAS_APHYINFO_REASON_MULTIPLEXING_SEQ (0x00000005)
1402#define MPI2_SAS_APHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00000006)
1403#define MPI2_SAS_APHYINFO_REASON_BREAK_TIMEOUT (0x00000007)
1404#define MPI2_SAS_APHYINFO_REASON_PHY_TEST_STOPPED (0x00000008)
1405
1406
1407/* values for PhyInfo fields */
1408#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000)
1409#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000)
1410#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000)
1411#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000)
1412#define MPI2_SAS_PHYINFO_ZONE_GROUP_PERSISTENT (0x00400000)
1413#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS (0x00200000)
1414#define MPI2_SAS_PHYINFO_ZONING_ENABLED (0x00100000)
1415
1416#define MPI2_SAS_PHYINFO_REASON_MASK (0x000F0000)
1417#define MPI2_SAS_PHYINFO_REASON_UNKNOWN (0x00000000)
1418#define MPI2_SAS_PHYINFO_REASON_POWER_ON (0x00010000)
1419#define MPI2_SAS_PHYINFO_REASON_HARD_RESET (0x00020000)
1420#define MPI2_SAS_PHYINFO_REASON_SMP_PHY_CONTROL (0x00030000)
1421#define MPI2_SAS_PHYINFO_REASON_LOSS_OF_SYNC (0x00040000)
1422#define MPI2_SAS_PHYINFO_REASON_MULTIPLEXING_SEQ (0x00050000)
1423#define MPI2_SAS_PHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00060000)
1424#define MPI2_SAS_PHYINFO_REASON_BREAK_TIMEOUT (0x00070000)
1425#define MPI2_SAS_PHYINFO_REASON_PHY_TEST_STOPPED (0x00080000)
1426
1427#define MPI2_SAS_PHYINFO_MULTIPLEXING_SUPPORTED (0x00008000)
1428#define MPI2_SAS_PHYINFO_SATA_PORT_ACTIVE (0x00004000)
1429#define MPI2_SAS_PHYINFO_SATA_PORT_SELECTOR_PRESENT (0x00002000)
1430#define MPI2_SAS_PHYINFO_VIRTUAL_PHY (0x00001000)
1431
1432#define MPI2_SAS_PHYINFO_MASK_PARTIAL_PATHWAY_TIME (0x00000F00)
1433#define MPI2_SAS_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME (8)
1434
1435#define MPI2_SAS_PHYINFO_MASK_ROUTING_ATTRIBUTE (0x000000F0)
1436#define MPI2_SAS_PHYINFO_DIRECT_ROUTING (0x00000000)
1437#define MPI2_SAS_PHYINFO_SUBTRACTIVE_ROUTING (0x00000010)
1438#define MPI2_SAS_PHYINFO_TABLE_ROUTING (0x00000020)
1439
1440
1441/* values for SAS ProgrammedLinkRate fields */
1442#define MPI2_SAS_PRATE_MAX_RATE_MASK (0xF0)
1443#define MPI2_SAS_PRATE_MAX_RATE_NOT_PROGRAMMABLE (0x00)
1444#define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80)
1445#define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90)
1446#define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0)
1447#define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F)
1448#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00)
1449#define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08)
1450#define MPI2_SAS_PRATE_MIN_RATE_3_0 (0x09)
1451#define MPI2_SAS_PRATE_MIN_RATE_6_0 (0x0A)
1452
1453
1454/* values for SAS HwLinkRate fields */
1455#define MPI2_SAS_HWRATE_MAX_RATE_MASK (0xF0)
1456#define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80)
1457#define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90)
1458#define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0)
1459#define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F)
1460#define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08)
1461#define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09)
1462#define MPI2_SAS_HWRATE_MIN_RATE_6_0 (0x0A)
1463
1464
1465
1466/****************************************************************************
1467* SAS IO Unit Config Pages
1468****************************************************************************/
1469
1470/* SAS IO Unit Page 0 */
1471
1472typedef struct _MPI2_SAS_IO_UNIT0_PHY_DATA
1473{
1474 U8 Port; /* 0x00 */
1475 U8 PortFlags; /* 0x01 */
1476 U8 PhyFlags; /* 0x02 */
1477 U8 NegotiatedLinkRate; /* 0x03 */
1478 U32 ControllerPhyDeviceInfo;/* 0x04 */
1479 U16 AttachedDevHandle; /* 0x08 */
1480 U16 ControllerDevHandle; /* 0x0A */
1481 U32 DiscoveryStatus; /* 0x0C */
1482 U32 Reserved; /* 0x10 */
1483} MPI2_SAS_IO_UNIT0_PHY_DATA, MPI2_POINTER PTR_MPI2_SAS_IO_UNIT0_PHY_DATA,
1484 Mpi2SasIOUnit0PhyData_t, MPI2_POINTER pMpi2SasIOUnit0PhyData_t;
1485
1486/*
1487 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1488 * one and check Header.ExtPageLength or NumPhys at runtime.
1489 */
1490#ifndef MPI2_SAS_IOUNIT0_PHY_MAX
1491#define MPI2_SAS_IOUNIT0_PHY_MAX (1)
1492#endif
1493
1494typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_0
1495{
1496 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1497 U32 Reserved1; /* 0x08 */
1498 U8 NumPhys; /* 0x0C */
1499 U8 Reserved2; /* 0x0D */
1500 U16 Reserved3; /* 0x0E */
1501 MPI2_SAS_IO_UNIT0_PHY_DATA PhyData[MPI2_SAS_IOUNIT0_PHY_MAX]; /* 0x10 */
1502} MPI2_CONFIG_PAGE_SASIOUNIT_0,
1503 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_0,
1504 Mpi2SasIOUnitPage0_t, MPI2_POINTER pMpi2SasIOUnitPage0_t;
1505
1506#define MPI2_SASIOUNITPAGE0_PAGEVERSION (0x05)
1507
1508/* values for SAS IO Unit Page 0 PortFlags */
1509#define MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS (0x08)
1510#define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG (0x01)
1511
1512/* values for SAS IO Unit Page 0 PhyFlags */
1513#define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED (0x10)
1514#define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED (0x08)
1515
1516/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
1517
1518/* see mpi2_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */
1519
1520/* values for SAS IO Unit Page 0 DiscoveryStatus */
1521#define MPI2_SASIOUNIT0_DS_MAX_ENCLOSURES_EXCEED (0x80000000)
1522#define MPI2_SASIOUNIT0_DS_MAX_EXPANDERS_EXCEED (0x40000000)
1523#define MPI2_SASIOUNIT0_DS_MAX_DEVICES_EXCEED (0x20000000)
1524#define MPI2_SASIOUNIT0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000)
1525#define MPI2_SASIOUNIT0_DS_DOWNSTREAM_INITIATOR (0x08000000)
1526#define MPI2_SASIOUNIT0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000)
1527#define MPI2_SASIOUNIT0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000)
1528#define MPI2_SASIOUNIT0_DS_MULTI_PORT_DOMAIN (0x00002000)
1529#define MPI2_SASIOUNIT0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000)
1530#define MPI2_SASIOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800)
1531#define MPI2_SASIOUNIT0_DS_TABLE_LINK (0x00000400)
1532#define MPI2_SASIOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200)
1533#define MPI2_SASIOUNIT0_DS_SMP_CRC_ERROR (0x00000100)
1534#define MPI2_SASIOUNIT0_DS_SMP_FUNCTION_FAILED (0x00000080)
1535#define MPI2_SASIOUNIT0_DS_INDEX_NOT_EXIST (0x00000040)
1536#define MPI2_SASIOUNIT0_DS_OUT_ROUTE_ENTRIES (0x00000020)
1537#define MPI2_SASIOUNIT0_DS_SMP_TIMEOUT (0x00000010)
1538#define MPI2_SASIOUNIT0_DS_MULTIPLE_PORTS (0x00000004)
1539#define MPI2_SASIOUNIT0_DS_UNADDRESSABLE_DEVICE (0x00000002)
1540#define MPI2_SASIOUNIT0_DS_LOOP_DETECTED (0x00000001)
1541
1542
1543/* SAS IO Unit Page 1 */
1544
1545typedef struct _MPI2_SAS_IO_UNIT1_PHY_DATA
1546{
1547 U8 Port; /* 0x00 */
1548 U8 PortFlags; /* 0x01 */
1549 U8 PhyFlags; /* 0x02 */
1550 U8 MaxMinLinkRate; /* 0x03 */
1551 U32 ControllerPhyDeviceInfo; /* 0x04 */
1552 U16 MaxTargetPortConnectTime; /* 0x08 */
1553 U16 Reserved1; /* 0x0A */
1554} MPI2_SAS_IO_UNIT1_PHY_DATA, MPI2_POINTER PTR_MPI2_SAS_IO_UNIT1_PHY_DATA,
1555 Mpi2SasIOUnit1PhyData_t, MPI2_POINTER pMpi2SasIOUnit1PhyData_t;
1556
1557/*
1558 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1559 * one and check Header.ExtPageLength or NumPhys at runtime.
1560 */
1561#ifndef MPI2_SAS_IOUNIT1_PHY_MAX
1562#define MPI2_SAS_IOUNIT1_PHY_MAX (1)
1563#endif
1564
1565typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
1566{
1567 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1568 U16 ControlFlags; /* 0x08 */
1569 U16 SASNarrowMaxQueueDepth; /* 0x0A */
1570 U16 AdditionalControlFlags; /* 0x0C */
1571 U16 SASWideMaxQueueDepth; /* 0x0E */
1572 U8 NumPhys; /* 0x10 */
1573 U8 SATAMaxQDepth; /* 0x11 */
1574 U8 ReportDeviceMissingDelay; /* 0x12 */
1575 U8 IODeviceMissingDelay; /* 0x13 */
1576 MPI2_SAS_IO_UNIT1_PHY_DATA PhyData[MPI2_SAS_IOUNIT1_PHY_MAX]; /* 0x14 */
1577} MPI2_CONFIG_PAGE_SASIOUNIT_1,
1578 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_1,
1579 Mpi2SasIOUnitPage1_t, MPI2_POINTER pMpi2SasIOUnitPage1_t;
1580
1581#define MPI2_SASIOUNITPAGE1_PAGEVERSION (0x09)
1582
1583/* values for SAS IO Unit Page 1 ControlFlags */
1584#define MPI2_SASIOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
1585#define MPI2_SASIOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
1586#define MPI2_SASIOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
1587#define MPI2_SASIOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
1588
1589#define MPI2_SASIOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600)
1590#define MPI2_SASIOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
1591#define MPI2_SASIOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x0)
1592#define MPI2_SASIOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x1)
1593#define MPI2_SASIOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x2)
1594
1595#define MPI2_SASIOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
1596#define MPI2_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
1597#define MPI2_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
1598#define MPI2_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010)
1599#define MPI2_SASIOUNIT1_CONTROL_TABLE_SUBTRACTIVE_ILLEGAL (0x0008)
1600#define MPI2_SASIOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004)
1601#define MPI2_SASIOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
1602#define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
1603
1604/* values for SAS IO Unit Page 1 AdditionalControlFlags */
1605#define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL (0x0080)
1606#define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040)
1607#define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION (0x0020)
1608#define MPI2_SASIOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010)
1609#define MPI2_SASIOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008)
1610#define MPI2_SASIOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004)
1611#define MPI2_SASIOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002)
1612#define MPI2_SASIOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
1613
1614/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
1615#define MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F)
1616#define MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16 (0x80)
1617
1618/* values for SAS IO Unit Page 1 PortFlags */
1619#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
1620
1621/* values for SAS IO Unit Page 2 PhyFlags */
1622#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10)
1623#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08)
1624
1625/* values for SAS IO Unit Page 0 MaxMinLinkRate */
1626#define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0)
1627#define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80)
1628#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90)
1629#define MPI2_SASIOUNIT1_MAX_RATE_6_0 (0xA0)
1630#define MPI2_SASIOUNIT1_MIN_RATE_MASK (0x0F)
1631#define MPI2_SASIOUNIT1_MIN_RATE_1_5 (0x08)
1632#define MPI2_SASIOUNIT1_MIN_RATE_3_0 (0x09)
1633#define MPI2_SASIOUNIT1_MIN_RATE_6_0 (0x0A)
1634
1635/* see mpi2_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
1636
1637
1638/* SAS IO Unit Page 4 */
1639
1640typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP
1641{
1642 U8 MaxTargetSpinup; /* 0x00 */
1643 U8 SpinupDelay; /* 0x01 */
1644 U16 Reserved1; /* 0x02 */
1645} MPI2_SAS_IOUNIT4_SPINUP_GROUP, MPI2_POINTER PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP,
1646 Mpi2SasIOUnit4SpinupGroup_t, MPI2_POINTER pMpi2SasIOUnit4SpinupGroup_t;
1647
1648/*
1649 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1650 * four and check Header.ExtPageLength or NumPhys at runtime.
1651 */
1652#ifndef MPI2_SAS_IOUNIT4_PHY_MAX
1653#define MPI2_SAS_IOUNIT4_PHY_MAX (4)
1654#endif
1655
1656typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4
1657{
1658 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1659 MPI2_SAS_IOUNIT4_SPINUP_GROUP SpinupGroupParameters[4]; /* 0x08 */
1660 U32 Reserved1; /* 0x18 */
1661 U32 Reserved2; /* 0x1C */
1662 U32 Reserved3; /* 0x20 */
1663 U8 BootDeviceWaitTime; /* 0x24 */
1664 U8 Reserved4; /* 0x25 */
1665 U16 Reserved5; /* 0x26 */
1666 U8 NumPhys; /* 0x28 */
1667 U8 PEInitialSpinupDelay; /* 0x29 */
1668 U8 PEReplyDelay; /* 0x2A */
1669 U8 Flags; /* 0x2B */
1670 U8 PHY[MPI2_SAS_IOUNIT4_PHY_MAX]; /* 0x2C */
1671} MPI2_CONFIG_PAGE_SASIOUNIT_4,
1672 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_4,
1673 Mpi2SasIOUnitPage4_t, MPI2_POINTER pMpi2SasIOUnitPage4_t;
1674
1675#define MPI2_SASIOUNITPAGE4_PAGEVERSION (0x02)
1676
1677/* defines for Flags field */
1678#define MPI2_SASIOUNIT4_FLAGS_AUTO_PORTENABLE (0x01)
1679
1680/* defines for PHY field */
1681#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03)
1682
1683
1684/****************************************************************************
1685* SAS Expander Config Pages
1686****************************************************************************/
1687
1688/* SAS Expander Page 0 */
1689
1690typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0
1691{
1692 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1693 U8 PhysicalPort; /* 0x08 */
1694 U8 ReportGenLength; /* 0x09 */
1695 U16 EnclosureHandle; /* 0x0A */
1696 U64 SASAddress; /* 0x0C */
1697 U32 DiscoveryStatus; /* 0x14 */
1698 U16 DevHandle; /* 0x18 */
1699 U16 ParentDevHandle; /* 0x1A */
1700 U16 ExpanderChangeCount; /* 0x1C */
1701 U16 ExpanderRouteIndexes; /* 0x1E */
1702 U8 NumPhys; /* 0x20 */
1703 U8 SASLevel; /* 0x21 */
1704 U16 Flags; /* 0x22 */
1705 U16 STPBusInactivityTimeLimit; /* 0x24 */
1706 U16 STPMaxConnectTimeLimit; /* 0x26 */
1707 U16 STP_SMP_NexusLossTime; /* 0x28 */
1708 U16 MaxNumRoutedSasAddresses; /* 0x2A */
1709 U64 ActiveZoneManagerSASAddress;/* 0x2C */
1710 U16 ZoneLockInactivityLimit; /* 0x34 */
1711 U16 Reserved1; /* 0x36 */
1712} MPI2_CONFIG_PAGE_EXPANDER_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_0,
1713 Mpi2ExpanderPage0_t, MPI2_POINTER pMpi2ExpanderPage0_t;
1714
1715#define MPI2_SASEXPANDER0_PAGEVERSION (0x05)
1716
1717/* values for SAS Expander Page 0 DiscoveryStatus field */
1718#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000)
1719#define MPI2_SAS_EXPANDER0_DS_MAX_EXPANDERS_EXCEED (0x40000000)
1720#define MPI2_SAS_EXPANDER0_DS_MAX_DEVICES_EXCEED (0x20000000)
1721#define MPI2_SAS_EXPANDER0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000)
1722#define MPI2_SAS_EXPANDER0_DS_DOWNSTREAM_INITIATOR (0x08000000)
1723#define MPI2_SAS_EXPANDER0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000)
1724#define MPI2_SAS_EXPANDER0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000)
1725#define MPI2_SAS_EXPANDER0_DS_MULTI_PORT_DOMAIN (0x00002000)
1726#define MPI2_SAS_EXPANDER0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000)
1727#define MPI2_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE (0x00000800)
1728#define MPI2_SAS_EXPANDER0_DS_TABLE_LINK (0x00000400)
1729#define MPI2_SAS_EXPANDER0_DS_SUBTRACTIVE_LINK (0x00000200)
1730#define MPI2_SAS_EXPANDER0_DS_SMP_CRC_ERROR (0x00000100)
1731#define MPI2_SAS_EXPANDER0_DS_SMP_FUNCTION_FAILED (0x00000080)
1732#define MPI2_SAS_EXPANDER0_DS_INDEX_NOT_EXIST (0x00000040)
1733#define MPI2_SAS_EXPANDER0_DS_OUT_ROUTE_ENTRIES (0x00000020)
1734#define MPI2_SAS_EXPANDER0_DS_SMP_TIMEOUT (0x00000010)
1735#define MPI2_SAS_EXPANDER0_DS_MULTIPLE_PORTS (0x00000004)
1736#define MPI2_SAS_EXPANDER0_DS_UNADDRESSABLE_DEVICE (0x00000002)
1737#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001)
1738
1739/* values for SAS Expander Page 0 Flags field */
1740#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000)
1741#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800)
1742#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400)
1743#define MPI2_SAS_EXPANDER0_FLAGS_ZONING_SUPPORT (0x0200)
1744#define MPI2_SAS_EXPANDER0_FLAGS_ENABLED_ZONING (0x0100)
1745#define MPI2_SAS_EXPANDER0_FLAGS_TABLE_TO_TABLE_SUPPORT (0x0080)
1746#define MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE (0x0010)
1747#define MPI2_SAS_EXPANDER0_FLAGS_OTHERS_CONFIG (0x0004)
1748#define MPI2_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS (0x0002)
1749#define MPI2_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG (0x0001)
1750
1751
1752/* SAS Expander Page 1 */
1753
1754typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1
1755{
1756 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1757 U8 PhysicalPort; /* 0x08 */
1758 U8 Reserved1; /* 0x09 */
1759 U16 Reserved2; /* 0x0A */
1760 U8 NumPhys; /* 0x0C */
1761 U8 Phy; /* 0x0D */
1762 U16 NumTableEntriesProgrammed; /* 0x0E */
1763 U8 ProgrammedLinkRate; /* 0x10 */
1764 U8 HwLinkRate; /* 0x11 */
1765 U16 AttachedDevHandle; /* 0x12 */
1766 U32 PhyInfo; /* 0x14 */
1767 U32 AttachedDeviceInfo; /* 0x18 */
1768 U16 ExpanderDevHandle; /* 0x1C */
1769 U8 ChangeCount; /* 0x1E */
1770 U8 NegotiatedLinkRate; /* 0x1F */
1771 U8 PhyIdentifier; /* 0x20 */
1772 U8 AttachedPhyIdentifier; /* 0x21 */
1773 U8 Reserved3; /* 0x22 */
1774 U8 DiscoveryInfo; /* 0x23 */
1775 U32 AttachedPhyInfo; /* 0x24 */
1776 U8 ZoneGroup; /* 0x28 */
1777 U8 SelfConfigStatus; /* 0x29 */
1778 U16 Reserved4; /* 0x2A */
1779} MPI2_CONFIG_PAGE_EXPANDER_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_1,
1780 Mpi2ExpanderPage1_t, MPI2_POINTER pMpi2ExpanderPage1_t;
1781
1782#define MPI2_SASEXPANDER1_PAGEVERSION (0x02)
1783
1784/* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */
1785
1786/* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */
1787
1788/* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
1789
1790/* see mpi2_sas.h for the MPI2_SAS_DEVICE_INFO_ defines used for the AttachedDeviceInfo field */
1791
1792/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
1793
1794/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
1795
1796/* values for SAS Expander Page 1 DiscoveryInfo field */
1797#define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED (0x04)
1798#define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE (0x02)
1799#define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES (0x01)
1800
1801
1802/****************************************************************************
1803* SAS Device Config Pages
1804****************************************************************************/
1805
1806/* SAS Device Page 0 */
1807
1808typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
1809{
1810 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1811 U16 Slot; /* 0x08 */
1812 U16 EnclosureHandle; /* 0x0A */
1813 U64 SASAddress; /* 0x0C */
1814 U16 ParentDevHandle; /* 0x14 */
1815 U8 PhyNum; /* 0x16 */
1816 U8 AccessStatus; /* 0x17 */
1817 U16 DevHandle; /* 0x18 */
1818 U8 AttachedPhyIdentifier; /* 0x1A */
1819 U8 ZoneGroup; /* 0x1B */
1820 U32 DeviceInfo; /* 0x1C */
1821 U16 Flags; /* 0x20 */
1822 U8 PhysicalPort; /* 0x22 */
1823 U8 MaxPortConnections; /* 0x23 */
1824 U64 DeviceName; /* 0x24 */
1825 U8 PortGroups; /* 0x2C */
1826 U8 DmaGroup; /* 0x2D */
1827 U8 ControlGroup; /* 0x2E */
1828 U8 Reserved1; /* 0x2F */
1829 U32 Reserved2; /* 0x30 */
1830 U32 Reserved3; /* 0x34 */
1831} MPI2_CONFIG_PAGE_SAS_DEV_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_DEV_0,
1832 Mpi2SasDevicePage0_t, MPI2_POINTER pMpi2SasDevicePage0_t;
1833
1834#define MPI2_SASDEVICE0_PAGEVERSION (0x08)
1835
1836/* values for SAS Device Page 0 AccessStatus field */
1837#define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00)
1838#define MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01)
1839#define MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02)
1840#define MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03)
1841#define MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION (0x04)
1842#define MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE (0x05)
1843#define MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE (0x06)
1844#define MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED (0x07)
1845/* specific values for SATA Init failures */
1846#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10)
1847#define MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11)
1848#define MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12)
1849#define MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13)
1850#define MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14)
1851#define MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15)
1852#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16)
1853#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17)
1854#define MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18)
1855#define MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19)
1856#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F)
1857
1858/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
1859
1860/* values for SAS Device Page 0 Flags field */
1861#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400)
1862#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200)
1863#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
1864#define MPI2_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080)
1865#define MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040)
1866#define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020)
1867#define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010)
1868#define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008)
1869#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
1870
1871
1872/* SAS Device Page 1 */
1873
1874typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_1
1875{
1876 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1877 U32 Reserved1; /* 0x08 */
1878 U64 SASAddress; /* 0x0C */
1879 U32 Reserved2; /* 0x14 */
1880 U16 DevHandle; /* 0x18 */
1881 U16 Reserved3; /* 0x1A */
1882 U8 InitialRegDeviceFIS[20];/* 0x1C */
1883} MPI2_CONFIG_PAGE_SAS_DEV_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_DEV_1,
1884 Mpi2SasDevicePage1_t, MPI2_POINTER pMpi2SasDevicePage1_t;
1885
1886#define MPI2_SASDEVICE1_PAGEVERSION (0x01)
1887
1888
1889/****************************************************************************
1890* SAS PHY Config Pages
1891****************************************************************************/
1892
1893/* SAS PHY Page 0 */
1894
1895typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0
1896{
1897 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1898 U16 OwnerDevHandle; /* 0x08 */
1899 U16 Reserved1; /* 0x0A */
1900 U16 AttachedDevHandle; /* 0x0C */
1901 U8 AttachedPhyIdentifier; /* 0x0E */
1902 U8 Reserved2; /* 0x0F */
1903 U32 AttachedPhyInfo; /* 0x10 */
1904 U8 ProgrammedLinkRate; /* 0x14 */
1905 U8 HwLinkRate; /* 0x15 */
1906 U8 ChangeCount; /* 0x16 */
1907 U8 Flags; /* 0x17 */
1908 U32 PhyInfo; /* 0x18 */
1909 U8 NegotiatedLinkRate; /* 0x1C */
1910 U8 Reserved3; /* 0x1D */
1911 U16 Reserved4; /* 0x1E */
1912} MPI2_CONFIG_PAGE_SAS_PHY_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_0,
1913 Mpi2SasPhyPage0_t, MPI2_POINTER pMpi2SasPhyPage0_t;
1914
1915#define MPI2_SASPHY0_PAGEVERSION (0x03)
1916
1917/* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */
1918
1919/* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */
1920
1921/* values for SAS PHY Page 0 Flags field */
1922#define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01)
1923
1924/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
1925
1926/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
1927
1928/* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
1929
1930
1931/* SAS PHY Page 1 */
1932
1933typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_1
1934{
1935 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1936 U32 Reserved1; /* 0x08 */
1937 U32 InvalidDwordCount; /* 0x0C */
1938 U32 RunningDisparityErrorCount; /* 0x10 */
1939 U32 LossDwordSynchCount; /* 0x14 */
1940 U32 PhyResetProblemCount; /* 0x18 */
1941} MPI2_CONFIG_PAGE_SAS_PHY_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_1,
1942 Mpi2SasPhyPage1_t, MPI2_POINTER pMpi2SasPhyPage1_t;
1943
1944#define MPI2_SASPHY1_PAGEVERSION (0x01)
1945
1946
1947/****************************************************************************
1948* SAS Port Config Pages
1949****************************************************************************/
1950
1951/* SAS Port Page 0 */
1952
1953typedef struct _MPI2_CONFIG_PAGE_SAS_PORT_0
1954{
1955 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1956 U8 PortNumber; /* 0x08 */
1957 U8 PhysicalPort; /* 0x09 */
1958 U8 PortWidth; /* 0x0A */
1959 U8 PhysicalPortWidth; /* 0x0B */
1960 U8 ZoneGroup; /* 0x0C */
1961 U8 Reserved1; /* 0x0D */
1962 U16 Reserved2; /* 0x0E */
1963 U64 SASAddress; /* 0x10 */
1964 U32 DeviceInfo; /* 0x18 */
1965 U32 Reserved3; /* 0x1C */
1966 U32 Reserved4; /* 0x20 */
1967} MPI2_CONFIG_PAGE_SAS_PORT_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PORT_0,
1968 Mpi2SasPortPage0_t, MPI2_POINTER pMpi2SasPortPage0_t;
1969
1970#define MPI2_SASPORT0_PAGEVERSION (0x00)
1971
1972/* see mpi2_sas.h for values for SAS Port Page 0 DeviceInfo values */
1973
1974
1975/****************************************************************************
1976* SAS Enclosure Config Pages
1977****************************************************************************/
1978
1979/* SAS Enclosure Page 0 */
1980
1981typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
1982{
1983 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
1984 U32 Reserved1; /* 0x08 */
1985 U64 EnclosureLogicalID; /* 0x0C */
1986 U16 Flags; /* 0x14 */
1987 U16 EnclosureHandle; /* 0x16 */
1988 U16 NumSlots; /* 0x18 */
1989 U16 StartSlot; /* 0x1A */
1990 U16 Reserved2; /* 0x1C */
1991 U16 SEPDevHandle; /* 0x1E */
1992 U32 Reserved3; /* 0x20 */
1993 U32 Reserved4; /* 0x24 */
1994} MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
1995 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
1996 Mpi2SasEnclosurePage0_t, MPI2_POINTER pMpi2SasEnclosurePage0_t;
1997
1998#define MPI2_SASENCLOSURE0_PAGEVERSION (0x03)
1999
2000/* values for SAS Enclosure Page 0 Flags field */
2001#define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK (0x000F)
2002#define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000)
2003#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES (0x0001)
2004#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002)
2005#define MPI2_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003)
2006#define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
2007#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
2008
2009
2010/****************************************************************************
2011* Log Config Page
2012****************************************************************************/
2013
2014/* Log Page 0 */
2015
2016/*
2017 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2018 * one and check Header.ExtPageLength or NumPhys at runtime.
2019 */
2020#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES
2021#define MPI2_LOG_0_NUM_LOG_ENTRIES (1)
2022#endif
2023
2024#define MPI2_LOG_0_LOG_DATA_LENGTH (0x1C)
2025
2026typedef struct _MPI2_LOG_0_ENTRY
2027{
2028 U64 TimeStamp; /* 0x00 */
2029 U32 Reserved1; /* 0x08 */
2030 U16 LogSequence; /* 0x0C */
2031 U16 LogEntryQualifier; /* 0x0E */
2032 U8 VP_ID; /* 0x10 */
2033 U8 VF_ID; /* 0x11 */
2034 U16 Reserved2; /* 0x12 */
2035 U8 LogData[MPI2_LOG_0_LOG_DATA_LENGTH];/* 0x14 */
2036} MPI2_LOG_0_ENTRY, MPI2_POINTER PTR_MPI2_LOG_0_ENTRY,
2037 Mpi2Log0Entry_t, MPI2_POINTER pMpi2Log0Entry_t;
2038
2039/* values for Log Page 0 LogEntry LogEntryQualifier field */
2040#define MPI2_LOG_0_ENTRY_QUAL_ENTRY_UNUSED (0x0000)
2041#define MPI2_LOG_0_ENTRY_QUAL_POWER_ON_RESET (0x0001)
2042#define MPI2_LOG_0_ENTRY_QUAL_TIMESTAMP_UPDATE (0x0002)
2043#define MPI2_LOG_0_ENTRY_QUAL_MIN_IMPLEMENT_SPEC (0x8000)
2044#define MPI2_LOG_0_ENTRY_QUAL_MAX_IMPLEMENT_SPEC (0xFFFF)
2045
2046typedef struct _MPI2_CONFIG_PAGE_LOG_0
2047{
2048 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2049 U32 Reserved1; /* 0x08 */
2050 U32 Reserved2; /* 0x0C */
2051 U16 NumLogEntries; /* 0x10 */
2052 U16 Reserved3; /* 0x12 */
2053 MPI2_LOG_0_ENTRY LogEntry[MPI2_LOG_0_NUM_LOG_ENTRIES]; /* 0x14 */
2054} MPI2_CONFIG_PAGE_LOG_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_LOG_0,
2055 Mpi2LogPage0_t, MPI2_POINTER pMpi2LogPage0_t;
2056
2057#define MPI2_LOG_0_PAGEVERSION (0x02)
2058
2059
2060/****************************************************************************
2061* RAID Config Page
2062****************************************************************************/
2063
2064/* RAID Page 0 */
2065
2066/*
2067 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2068 * one and check Header.ExtPageLength or NumPhys at runtime.
2069 */
2070#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS
2071#define MPI2_RAIDCONFIG0_MAX_ELEMENTS (1)
2072#endif
2073
2074typedef struct _MPI2_RAIDCONFIG0_CONFIG_ELEMENT
2075{
2076 U16 ElementFlags; /* 0x00 */
2077 U16 VolDevHandle; /* 0x02 */
2078 U8 HotSparePool; /* 0x04 */
2079 U8 PhysDiskNum; /* 0x05 */
2080 U16 PhysDiskDevHandle; /* 0x06 */
2081} MPI2_RAIDCONFIG0_CONFIG_ELEMENT,
2082 MPI2_POINTER PTR_MPI2_RAIDCONFIG0_CONFIG_ELEMENT,
2083 Mpi2RaidConfig0ConfigElement_t, MPI2_POINTER pMpi2RaidConfig0ConfigElement_t;
2084
2085/* values for the ElementFlags field */
2086#define MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE (0x000F)
2087#define MPI2_RAIDCONFIG0_EFLAGS_VOLUME_ELEMENT (0x0000)
2088#define MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT (0x0001)
2089#define MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT (0x0002)
2090#define MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT (0x0003)
2091
2092
2093typedef struct _MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0
2094{
2095 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2096 U8 NumHotSpares; /* 0x08 */
2097 U8 NumPhysDisks; /* 0x09 */
2098 U8 NumVolumes; /* 0x0A */
2099 U8 ConfigNum; /* 0x0B */
2100 U32 Flags; /* 0x0C */
2101 U8 ConfigGUID[24]; /* 0x10 */
2102 U32 Reserved1; /* 0x28 */
2103 U8 NumElements; /* 0x2C */
2104 U8 Reserved2; /* 0x2D */
2105 U16 Reserved3; /* 0x2E */
2106 MPI2_RAIDCONFIG0_CONFIG_ELEMENT ConfigElement[MPI2_RAIDCONFIG0_MAX_ELEMENTS]; /* 0x30 */
2107} MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0,
2108 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0,
2109 Mpi2RaidConfigurationPage0_t, MPI2_POINTER pMpi2RaidConfigurationPage0_t;
2110
2111#define MPI2_RAIDCONFIG0_PAGEVERSION (0x00)
2112
2113/* values for RAID Configuration Page 0 Flags field */
2114#define MPI2_RAIDCONFIG0_FLAG_FOREIGN_CONFIG (0x00000001)
2115
2116
2117/****************************************************************************
2118* Driver Persistent Mapping Config Pages
2119****************************************************************************/
2120
2121/* Driver Persistent Mapping Page 0 */
2122
2123typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY
2124{
2125 U64 PhysicalIdentifier; /* 0x00 */
2126 U16 MappingInformation; /* 0x08 */
2127 U16 DeviceIndex; /* 0x0A */
2128 U32 PhysicalBitsMapping; /* 0x0C */
2129 U32 Reserved1; /* 0x10 */
2130} MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY,
2131 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY,
2132 Mpi2DriverMap0Entry_t, MPI2_POINTER pMpi2DriverMap0Entry_t;
2133
2134typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0
2135{
2136 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2137 MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY Entry; /* 0x08 */
2138} MPI2_CONFIG_PAGE_DRIVER_MAPPING_0,
2139 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_DRIVER_MAPPING_0,
2140 Mpi2DriverMappingPage0_t, MPI2_POINTER pMpi2DriverMappingPage0_t;
2141
2142#define MPI2_DRIVERMAPPING0_PAGEVERSION (0x00)
2143
2144/* values for Driver Persistent Mapping Page 0 MappingInformation field */
2145#define MPI2_DRVMAP0_MAPINFO_SLOT_MASK (0x07F0)
2146#define MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT (4)
2147#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F)
2148
2149
2150#endif
2151
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
new file mode 100644
index 000000000000..f1115f0f0eb2
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -0,0 +1,420 @@
1/*
2 * Copyright (c) 2000-2008 LSI Corporation.
3 *
4 *
5 * Name: mpi2_init.h
6 * Title: MPI SCSI initiator mode messages and structures
7 * Creation Date: June 23, 2006
8 *
9 * mpi2_init.h Version: 02.00.06
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t.
18 * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines.
19 * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention.
20 * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY.
21 * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
22 * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
23 * Control field Task Attribute flags.
24 * Moved LUN field defines to mpi2.h becasue they are
25 * common to many structures.
26 * --------------------------------------------------------------------------
27 */
28
29#ifndef MPI2_INIT_H
30#define MPI2_INIT_H
31
32/*****************************************************************************
33*
34* SCSI Initiator Messages
35*
36*****************************************************************************/
37
38/****************************************************************************
39* SCSI IO messages and associated structures
40****************************************************************************/
41
42typedef struct
43{
44 U8 CDB[20]; /* 0x00 */
45 U32 PrimaryReferenceTag; /* 0x14 */
46 U16 PrimaryApplicationTag; /* 0x18 */
47 U16 PrimaryApplicationTagMask; /* 0x1A */
48 U32 TransferLength; /* 0x1C */
49} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32,
50 Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t;
51
52/* TBD: I don't think this is needed for MPI2/Gen2 */
53#if 0
54typedef struct
55{
56 U8 CDB[16]; /* 0x00 */
57 U32 DataLength; /* 0x10 */
58 U32 PrimaryReferenceTag; /* 0x14 */
59 U16 PrimaryApplicationTag; /* 0x18 */
60 U16 PrimaryApplicationTagMask; /* 0x1A */
61 U32 TransferLength; /* 0x1C */
62} MPI2_SCSI_IO32_CDB_EEDP16, MPI2_POINTER PTR_MPI2_SCSI_IO32_CDB_EEDP16,
63 Mpi2ScsiIo32CdbEedp16_t, MPI2_POINTER pMpi2ScsiIo32CdbEedp16_t;
64#endif
65
66typedef union
67{
68 U8 CDB32[32];
69 MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
70 MPI2_SGE_SIMPLE_UNION SGE;
71} MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION,
72 Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t;
73
74/* SCSI IO Request Message */
75typedef struct _MPI2_SCSI_IO_REQUEST
76{
77 U16 DevHandle; /* 0x00 */
78 U8 ChainOffset; /* 0x02 */
79 U8 Function; /* 0x03 */
80 U16 Reserved1; /* 0x04 */
81 U8 Reserved2; /* 0x06 */
82 U8 MsgFlags; /* 0x07 */
83 U8 VP_ID; /* 0x08 */
84 U8 VF_ID; /* 0x09 */
85 U16 Reserved3; /* 0x0A */
86 U32 SenseBufferLowAddress; /* 0x0C */
87 U16 SGLFlags; /* 0x10 */
88 U8 SenseBufferLength; /* 0x12 */
89 U8 Reserved4; /* 0x13 */
90 U8 SGLOffset0; /* 0x14 */
91 U8 SGLOffset1; /* 0x15 */
92 U8 SGLOffset2; /* 0x16 */
93 U8 SGLOffset3; /* 0x17 */
94 U32 SkipCount; /* 0x18 */
95 U32 DataLength; /* 0x1C */
96 U32 BidirectionalDataLength; /* 0x20 */
97 U16 IoFlags; /* 0x24 */
98 U16 EEDPFlags; /* 0x26 */
99 U32 EEDPBlockSize; /* 0x28 */
100 U32 SecondaryReferenceTag; /* 0x2C */
101 U16 SecondaryApplicationTag; /* 0x30 */
102 U16 ApplicationTagTranslationMask; /* 0x32 */
103 U8 LUN[8]; /* 0x34 */
104 U32 Control; /* 0x3C */
105 MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
106 MPI2_SGE_IO_UNION SGL; /* 0x60 */
107} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
108 Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
109
110/* SCSI IO MsgFlags bits */
111
112/* MsgFlags for SenseBufferAddressSpace */
113#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C)
114#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00)
115#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04)
116#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08)
117#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C)
118
119/* SCSI IO SGLFlags bits */
120
121/* base values for Data Location Address Space */
122#define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK (0x0C)
123#define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR (0x00)
124#define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR (0x04)
125#define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR (0x08)
126#define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR (0x0C)
127
128/* base values for Type */
129#define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK (0x03)
130#define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI (0x00)
131#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32 (0x01)
132#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64 (0x02)
133
134/* shift values for each sub-field */
135#define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT (12)
136#define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT (8)
137#define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT (4)
138#define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT (0)
139
140/* SCSI IO IoFlags bits */
141
142/* Large CDB Address Space */
143#define MPI2_SCSIIO_CDB_ADDR_MASK (0x6000)
144#define MPI2_SCSIIO_CDB_ADDR_SYSTEM (0x0000)
145#define MPI2_SCSIIO_CDB_ADDR_IOCDDR (0x2000)
146#define MPI2_SCSIIO_CDB_ADDR_IOCPLB (0x4000)
147#define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA (0x6000)
148
149#define MPI2_SCSIIO_IOFLAGS_LARGE_CDB (0x1000)
150#define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800)
151#define MPI2_SCSIIO_IOFLAGS_MULTICAST (0x0400)
152#define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200)
153#define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF)
154
155/* SCSI IO EEDPFlags bits */
156
157#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
158#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG (0x4000)
159#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG (0x2000)
160#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG (0x1000)
161
162#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400)
163#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200)
164#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100)
165
166#define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG (0x0008)
167
168#define MPI2_SCSIIO_EEDPFLAGS_MASK_OP (0x0007)
169#define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP (0x0000)
170#define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP (0x0001)
171#define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP (0x0002)
172#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003)
173#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004)
174#define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP (0x0006)
175#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP (0x0007)
176
177/* SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */
178
179/* SCSI IO Control bits */
180#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK (0xFC000000)
181#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26)
182
183#define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000)
184#define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000)
185#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000)
186#define MPI2_SCSIIO_CONTROL_READ (0x02000000)
187#define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL (0x03000000)
188
189#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800)
190#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11)
191
192#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
193#define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000)
194#define MPI2_SCSIIO_CONTROL_HEADOFQ (0x00000100)
195#define MPI2_SCSIIO_CONTROL_ORDEREDQ (0x00000200)
196#define MPI2_SCSIIO_CONTROL_ACAQ (0x00000400)
197
198#define MPI2_SCSIIO_CONTROL_TLR_MASK (0x000000C0)
199#define MPI2_SCSIIO_CONTROL_NO_TLR (0x00000000)
200#define MPI2_SCSIIO_CONTROL_TLR_ON (0x00000040)
201#define MPI2_SCSIIO_CONTROL_TLR_OFF (0x00000080)
202
203
204/* SCSI IO Error Reply Message */
205typedef struct _MPI2_SCSI_IO_REPLY
206{
207 U16 DevHandle; /* 0x00 */
208 U8 MsgLength; /* 0x02 */
209 U8 Function; /* 0x03 */
210 U16 Reserved1; /* 0x04 */
211 U8 Reserved2; /* 0x06 */
212 U8 MsgFlags; /* 0x07 */
213 U8 VP_ID; /* 0x08 */
214 U8 VF_ID; /* 0x09 */
215 U16 Reserved3; /* 0x0A */
216 U8 SCSIStatus; /* 0x0C */
217 U8 SCSIState; /* 0x0D */
218 U16 IOCStatus; /* 0x0E */
219 U32 IOCLogInfo; /* 0x10 */
220 U32 TransferCount; /* 0x14 */
221 U32 SenseCount; /* 0x18 */
222 U32 ResponseInfo; /* 0x1C */
223 U16 TaskTag; /* 0x20 */
224 U16 Reserved4; /* 0x22 */
225 U32 BidirectionalTransferCount; /* 0x24 */
226 U32 Reserved5; /* 0x28 */
227 U32 Reserved6; /* 0x2C */
228} MPI2_SCSI_IO_REPLY, MPI2_POINTER PTR_MPI2_SCSI_IO_REPLY,
229 Mpi2SCSIIOReply_t, MPI2_POINTER pMpi2SCSIIOReply_t;
230
231/* SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
232
233#define MPI2_SCSI_STATUS_GOOD (0x00)
234#define MPI2_SCSI_STATUS_CHECK_CONDITION (0x02)
235#define MPI2_SCSI_STATUS_CONDITION_MET (0x04)
236#define MPI2_SCSI_STATUS_BUSY (0x08)
237#define MPI2_SCSI_STATUS_INTERMEDIATE (0x10)
238#define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET (0x14)
239#define MPI2_SCSI_STATUS_RESERVATION_CONFLICT (0x18)
240#define MPI2_SCSI_STATUS_COMMAND_TERMINATED (0x22) /* obsolete */
241#define MPI2_SCSI_STATUS_TASK_SET_FULL (0x28)
242#define MPI2_SCSI_STATUS_ACA_ACTIVE (0x30)
243#define MPI2_SCSI_STATUS_TASK_ABORTED (0x40)
244
245/* SCSI IO Reply SCSIState flags */
246
247#define MPI2_SCSI_STATE_RESPONSE_INFO_VALID (0x10)
248#define MPI2_SCSI_STATE_TERMINATED (0x08)
249#define MPI2_SCSI_STATE_NO_SCSI_STATUS (0x04)
250#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02)
251#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01)
252
253#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF)
254
255
256/****************************************************************************
257* SCSI Task Management messages
258****************************************************************************/
259
260/* SCSI Task Management Request Message */
261typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
262{
263 U16 DevHandle; /* 0x00 */
264 U8 ChainOffset; /* 0x02 */
265 U8 Function; /* 0x03 */
266 U8 Reserved1; /* 0x04 */
267 U8 TaskType; /* 0x05 */
268 U8 Reserved2; /* 0x06 */
269 U8 MsgFlags; /* 0x07 */
270 U8 VP_ID; /* 0x08 */
271 U8 VF_ID; /* 0x09 */
272 U16 Reserved3; /* 0x0A */
273 U8 LUN[8]; /* 0x0C */
274 U32 Reserved4[7]; /* 0x14 */
275 U16 TaskMID; /* 0x30 */
276 U16 Reserved5; /* 0x32 */
277} MPI2_SCSI_TASK_MANAGE_REQUEST,
278 MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REQUEST,
279 Mpi2SCSITaskManagementRequest_t,
280 MPI2_POINTER pMpi2SCSITaskManagementRequest_t;
281
282/* TaskType values */
283
284#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01)
285#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02)
286#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
287#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
288#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
289#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
290#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
291#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09)
292#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION (0x0A)
293
294/* MsgFlags bits */
295
296#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18)
297#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00)
298#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08)
299#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10)
300
301#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01)
302
303
304
305/* SCSI Task Management Reply Message */
306typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
307{
308 U16 DevHandle; /* 0x00 */
309 U8 MsgLength; /* 0x02 */
310 U8 Function; /* 0x03 */
311 U8 ResponseCode; /* 0x04 */
312 U8 TaskType; /* 0x05 */
313 U8 Reserved1; /* 0x06 */
314 U8 MsgFlags; /* 0x07 */
315 U8 VP_ID; /* 0x08 */
316 U8 VF_ID; /* 0x09 */
317 U16 Reserved2; /* 0x0A */
318 U16 Reserved3; /* 0x0C */
319 U16 IOCStatus; /* 0x0E */
320 U32 IOCLogInfo; /* 0x10 */
321 U32 TerminationCount; /* 0x14 */
322} MPI2_SCSI_TASK_MANAGE_REPLY,
323 MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY,
324 Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t;
325
326/* ResponseCode values */
327
328#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00)
329#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02)
330#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04)
331#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05)
332#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08)
333#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09)
334#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80)
335
336
337/****************************************************************************
338* SCSI Enclosure Processor messages
339****************************************************************************/
340
341/* SCSI Enclosure Processor Request Message */
342typedef struct _MPI2_SEP_REQUEST
343{
344 U16 DevHandle; /* 0x00 */
345 U8 ChainOffset; /* 0x02 */
346 U8 Function; /* 0x03 */
347 U8 Action; /* 0x04 */
348 U8 Flags; /* 0x05 */
349 U8 Reserved1; /* 0x06 */
350 U8 MsgFlags; /* 0x07 */
351 U8 VP_ID; /* 0x08 */
352 U8 VF_ID; /* 0x09 */
353 U16 Reserved2; /* 0x0A */
354 U32 SlotStatus; /* 0x0C */
355 U32 Reserved3; /* 0x10 */
356 U32 Reserved4; /* 0x14 */
357 U32 Reserved5; /* 0x18 */
358 U16 Slot; /* 0x1C */
359 U16 EnclosureHandle; /* 0x1E */
360} MPI2_SEP_REQUEST, MPI2_POINTER PTR_MPI2_SEP_REQUEST,
361 Mpi2SepRequest_t, MPI2_POINTER pMpi2SepRequest_t;
362
363/* Action defines */
364#define MPI2_SEP_REQ_ACTION_WRITE_STATUS (0x00)
365#define MPI2_SEP_REQ_ACTION_READ_STATUS (0x01)
366
367/* Flags defines */
368#define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS (0x00)
369#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01)
370
371/* SlotStatus defines */
372#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
373#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
374#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
375#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
376#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
377#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
378#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004)
379#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
380#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
381
382
383/* SCSI Enclosure Processor Reply Message */
384typedef struct _MPI2_SEP_REPLY
385{
386 U16 DevHandle; /* 0x00 */
387 U8 MsgLength; /* 0x02 */
388 U8 Function; /* 0x03 */
389 U8 Action; /* 0x04 */
390 U8 Flags; /* 0x05 */
391 U8 Reserved1; /* 0x06 */
392 U8 MsgFlags; /* 0x07 */
393 U8 VP_ID; /* 0x08 */
394 U8 VF_ID; /* 0x09 */
395 U16 Reserved2; /* 0x0A */
396 U16 Reserved3; /* 0x0C */
397 U16 IOCStatus; /* 0x0E */
398 U32 IOCLogInfo; /* 0x10 */
399 U32 SlotStatus; /* 0x14 */
400 U32 Reserved4; /* 0x18 */
401 U16 Slot; /* 0x1C */
402 U16 EnclosureHandle; /* 0x1E */
403} MPI2_SEP_REPLY, MPI2_POINTER PTR_MPI2_SEP_REPLY,
404 Mpi2SepReply_t, MPI2_POINTER pMpi2SepReply_t;
405
406/* SlotStatus defines */
407#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
408#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
409#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
410#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
411#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
412#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
413#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004)
414#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002)
415#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001)
416
417
418#endif
419
420
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
new file mode 100644
index 000000000000..8c5d81870c03
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -0,0 +1,1295 @@
1/*
2 * Copyright (c) 2000-2009 LSI Corporation.
3 *
4 *
5 * Name: mpi2_ioc.h
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: October 11, 2006
8 *
9 * mpi2_ioc.h Version: 02.00.10
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 06-04-07 02.00.01 In IOCFacts Reply structure, renamed MaxDevices to
18 * MaxTargets.
19 * Added TotalImageSize field to FWDownload Request.
20 * Added reserved words to FWUpload Request.
21 * 06-26-07 02.00.02 Added IR Configuration Change List Event.
22 * 08-31-07 02.00.03 Removed SystemReplyQueueDepth field from the IOCInit
23 * request and replaced it with
24 * ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth.
25 * Replaced the MinReplyQueueDepth field of the IOCFacts
26 * reply with MaxReplyDescriptorPostQueueDepth.
27 * Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum
28 * depth for the Reply Descriptor Post Queue.
29 * Added SASAddress field to Initiator Device Table
30 * Overflow Event data.
31 * 10-31-07 02.00.04 Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING
32 * for SAS Initiator Device Status Change Event data.
33 * Modified Reason Code defines for SAS Topology Change
34 * List Event data, including adding a bit for PHY Vacant
35 * status, and adding a mask for the Reason Code.
36 * Added define for
37 * MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING.
38 * Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID.
39 * 12-18-07 02.00.05 Added Boot Status defines for the IOCExceptions field of
40 * the IOCFacts Reply.
41 * Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
42 * Moved MPI2_VERSION_UNION to mpi2.h.
43 * Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks
44 * instead of enables, and added SASBroadcastPrimitiveMasks
45 * field.
46 * Added Log Entry Added Event and related structure.
47 * 02-29-08 02.00.06 Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID.
48 * Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET.
49 * Added MaxVolumes and MaxPersistentEntries fields to
50 * IOCFacts reply.
51 * Added ProtocalFlags and IOCCapabilities fields to
52 * MPI2_FW_IMAGE_HEADER.
53 * Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT.
54 * 03-03-08 02.00.07 Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to
55 * a U16 (from a U32).
56 * Removed extra 's' from EventMasks name.
57 * 06-27-08 02.00.08 Fixed an offset in a comment.
58 * 10-02-08 02.00.09 Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST.
59 * Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and
60 * renamed MinReplyFrameSize to ReplyFrameSize.
61 * Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX.
62 * Added two new RAIDOperation values for Integrated RAID
63 * Operations Status Event data.
64 * Added four new IR Configuration Change List Event data
65 * ReasonCode values.
66 * Added two new ReasonCode defines for SAS Device Status
67 * Change Event data.
68 * Added three new DiscoveryStatus bits for the SAS
69 * Discovery event data.
70 * Added Multiplexing Status Change bit to the PhyStatus
71 * field of the SAS Topology Change List event data.
72 * Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY.
73 * BootFlags are now product-specific.
74 * Added defines for the indivdual signature bytes
75 * for MPI2_INIT_IMAGE_FOOTER.
76 * 01-19-09 02.00.10 Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define.
77 * Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR
78 * define.
79 * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE
80 * define.
81 * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define.
82 * --------------------------------------------------------------------------
83 */
84
85#ifndef MPI2_IOC_H
86#define MPI2_IOC_H
87
88/*****************************************************************************
89*
90* IOC Messages
91*
92*****************************************************************************/
93
94/****************************************************************************
95* IOCInit message
96****************************************************************************/
97
98/* IOCInit Request message */
99typedef struct _MPI2_IOC_INIT_REQUEST
100{
101 U8 WhoInit; /* 0x00 */
102 U8 Reserved1; /* 0x01 */
103 U8 ChainOffset; /* 0x02 */
104 U8 Function; /* 0x03 */
105 U16 Reserved2; /* 0x04 */
106 U8 Reserved3; /* 0x06 */
107 U8 MsgFlags; /* 0x07 */
108 U8 VP_ID; /* 0x08 */
109 U8 VF_ID; /* 0x09 */
110 U16 Reserved4; /* 0x0A */
111 U16 MsgVersion; /* 0x0C */
112 U16 HeaderVersion; /* 0x0E */
113 U32 Reserved5; /* 0x10 */
114 U32 Reserved6; /* 0x14 */
115 U16 Reserved7; /* 0x18 */
116 U16 SystemRequestFrameSize; /* 0x1A */
117 U16 ReplyDescriptorPostQueueDepth; /* 0x1C */
118 U16 ReplyFreeQueueDepth; /* 0x1E */
119 U32 SenseBufferAddressHigh; /* 0x20 */
120 U32 SystemReplyAddressHigh; /* 0x24 */
121 U64 SystemRequestFrameBaseAddress; /* 0x28 */
122 U64 ReplyDescriptorPostQueueAddress;/* 0x30 */
123 U64 ReplyFreeQueueAddress; /* 0x38 */
124 U64 TimeStamp; /* 0x40 */
125} MPI2_IOC_INIT_REQUEST, MPI2_POINTER PTR_MPI2_IOC_INIT_REQUEST,
126 Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest_t;
127
128/* WhoInit values */
129#define MPI2_WHOINIT_NOT_INITIALIZED (0x00)
130#define MPI2_WHOINIT_SYSTEM_BIOS (0x01)
131#define MPI2_WHOINIT_ROM_BIOS (0x02)
132#define MPI2_WHOINIT_PCI_PEER (0x03)
133#define MPI2_WHOINIT_HOST_DRIVER (0x04)
134#define MPI2_WHOINIT_MANUFACTURER (0x05)
135
136/* MsgVersion */
137#define MPI2_IOCINIT_MSGVERSION_MAJOR_MASK (0xFF00)
138#define MPI2_IOCINIT_MSGVERSION_MAJOR_SHIFT (8)
139#define MPI2_IOCINIT_MSGVERSION_MINOR_MASK (0x00FF)
140#define MPI2_IOCINIT_MSGVERSION_MINOR_SHIFT (0)
141
142/* HeaderVersion */
143#define MPI2_IOCINIT_HDRVERSION_UNIT_MASK (0xFF00)
144#define MPI2_IOCINIT_HDRVERSION_UNIT_SHIFT (8)
145#define MPI2_IOCINIT_HDRVERSION_DEV_MASK (0x00FF)
146#define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT (0)
147
148/* minimum depth for the Reply Descriptor Post Queue */
149#define MPI2_RDPQ_DEPTH_MIN (16)
150
151
152/* IOCInit Reply message */
153typedef struct _MPI2_IOC_INIT_REPLY
154{
155 U8 WhoInit; /* 0x00 */
156 U8 Reserved1; /* 0x01 */
157 U8 MsgLength; /* 0x02 */
158 U8 Function; /* 0x03 */
159 U16 Reserved2; /* 0x04 */
160 U8 Reserved3; /* 0x06 */
161 U8 MsgFlags; /* 0x07 */
162 U8 VP_ID; /* 0x08 */
163 U8 VF_ID; /* 0x09 */
164 U16 Reserved4; /* 0x0A */
165 U16 Reserved5; /* 0x0C */
166 U16 IOCStatus; /* 0x0E */
167 U32 IOCLogInfo; /* 0x10 */
168} MPI2_IOC_INIT_REPLY, MPI2_POINTER PTR_MPI2_IOC_INIT_REPLY,
169 Mpi2IOCInitReply_t, MPI2_POINTER pMpi2IOCInitReply_t;
170
171
172/****************************************************************************
173* IOCFacts message
174****************************************************************************/
175
176/* IOCFacts Request message */
177typedef struct _MPI2_IOC_FACTS_REQUEST
178{
179 U16 Reserved1; /* 0x00 */
180 U8 ChainOffset; /* 0x02 */
181 U8 Function; /* 0x03 */
182 U16 Reserved2; /* 0x04 */
183 U8 Reserved3; /* 0x06 */
184 U8 MsgFlags; /* 0x07 */
185 U8 VP_ID; /* 0x08 */
186 U8 VF_ID; /* 0x09 */
187 U16 Reserved4; /* 0x0A */
188} MPI2_IOC_FACTS_REQUEST, MPI2_POINTER PTR_MPI2_IOC_FACTS_REQUEST,
189 Mpi2IOCFactsRequest_t, MPI2_POINTER pMpi2IOCFactsRequest_t;
190
191
192/* IOCFacts Reply message */
193typedef struct _MPI2_IOC_FACTS_REPLY
194{
195 U16 MsgVersion; /* 0x00 */
196 U8 MsgLength; /* 0x02 */
197 U8 Function; /* 0x03 */
198 U16 HeaderVersion; /* 0x04 */
199 U8 IOCNumber; /* 0x06 */
200 U8 MsgFlags; /* 0x07 */
201 U8 VP_ID; /* 0x08 */
202 U8 VF_ID; /* 0x09 */
203 U16 Reserved1; /* 0x0A */
204 U16 IOCExceptions; /* 0x0C */
205 U16 IOCStatus; /* 0x0E */
206 U32 IOCLogInfo; /* 0x10 */
207 U8 MaxChainDepth; /* 0x14 */
208 U8 WhoInit; /* 0x15 */
209 U8 NumberOfPorts; /* 0x16 */
210 U8 Reserved2; /* 0x17 */
211 U16 RequestCredit; /* 0x18 */
212 U16 ProductID; /* 0x1A */
213 U32 IOCCapabilities; /* 0x1C */
214 MPI2_VERSION_UNION FWVersion; /* 0x20 */
215 U16 IOCRequestFrameSize; /* 0x24 */
216 U16 Reserved3; /* 0x26 */
217 U16 MaxInitiators; /* 0x28 */
218 U16 MaxTargets; /* 0x2A */
219 U16 MaxSasExpanders; /* 0x2C */
220 U16 MaxEnclosures; /* 0x2E */
221 U16 ProtocolFlags; /* 0x30 */
222 U16 HighPriorityCredit; /* 0x32 */
223 U16 MaxReplyDescriptorPostQueueDepth; /* 0x34 */
224 U8 ReplyFrameSize; /* 0x36 */
225 U8 MaxVolumes; /* 0x37 */
226 U16 MaxDevHandle; /* 0x38 */
227 U16 MaxPersistentEntries; /* 0x3A */
228 U32 Reserved4; /* 0x3C */
229} MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY,
230 Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t;
231
232/* MsgVersion */
233#define MPI2_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00)
234#define MPI2_IOCFACTS_MSGVERSION_MAJOR_SHIFT (8)
235#define MPI2_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF)
236#define MPI2_IOCFACTS_MSGVERSION_MINOR_SHIFT (0)
237
238/* HeaderVersion */
239#define MPI2_IOCFACTS_HDRVERSION_UNIT_MASK (0xFF00)
240#define MPI2_IOCFACTS_HDRVERSION_UNIT_SHIFT (8)
241#define MPI2_IOCFACTS_HDRVERSION_DEV_MASK (0x00FF)
242#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0)
243
244/* IOCExceptions */
245#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100)
246
247#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0)
248#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_GOOD (0x0000)
249#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_BACKUP (0x0020)
250#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_RESTORED (0x0040)
251#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_CORRUPT_BACKUP (0x0060)
252
253#define MPI2_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010)
254#define MPI2_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL (0x0008)
255#define MPI2_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
256#define MPI2_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
257#define MPI2_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001)
258
259/* defines for WhoInit field are after the IOCInit Request */
260
261/* ProductID field uses MPI2_FW_HEADER_PID_ */
262
263/* IOCCapabilities */
264#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000)
265#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000)
266#define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800)
267#define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
268#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080)
269#define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040)
270#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
271#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
272#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
273
274/* ProtocolFlags */
275#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001)
276#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR (0x0002)
277
278
279/****************************************************************************
280* PortFacts message
281****************************************************************************/
282
283/* PortFacts Request message */
284typedef struct _MPI2_PORT_FACTS_REQUEST
285{
286 U16 Reserved1; /* 0x00 */
287 U8 ChainOffset; /* 0x02 */
288 U8 Function; /* 0x03 */
289 U16 Reserved2; /* 0x04 */
290 U8 PortNumber; /* 0x06 */
291 U8 MsgFlags; /* 0x07 */
292 U8 VP_ID; /* 0x08 */
293 U8 VF_ID; /* 0x09 */
294 U16 Reserved3; /* 0x0A */
295} MPI2_PORT_FACTS_REQUEST, MPI2_POINTER PTR_MPI2_PORT_FACTS_REQUEST,
296 Mpi2PortFactsRequest_t, MPI2_POINTER pMpi2PortFactsRequest_t;
297
298/* PortFacts Reply message */
299typedef struct _MPI2_PORT_FACTS_REPLY
300{
301 U16 Reserved1; /* 0x00 */
302 U8 MsgLength; /* 0x02 */
303 U8 Function; /* 0x03 */
304 U16 Reserved2; /* 0x04 */
305 U8 PortNumber; /* 0x06 */
306 U8 MsgFlags; /* 0x07 */
307 U8 VP_ID; /* 0x08 */
308 U8 VF_ID; /* 0x09 */
309 U16 Reserved3; /* 0x0A */
310 U16 Reserved4; /* 0x0C */
311 U16 IOCStatus; /* 0x0E */
312 U32 IOCLogInfo; /* 0x10 */
313 U8 Reserved5; /* 0x14 */
314 U8 PortType; /* 0x15 */
315 U16 Reserved6; /* 0x16 */
316 U16 MaxPostedCmdBuffers; /* 0x18 */
317 U16 Reserved7; /* 0x1A */
318} MPI2_PORT_FACTS_REPLY, MPI2_POINTER PTR_MPI2_PORT_FACTS_REPLY,
319 Mpi2PortFactsReply_t, MPI2_POINTER pMpi2PortFactsReply_t;
320
321/* PortType values */
322#define MPI2_PORTFACTS_PORTTYPE_INACTIVE (0x00)
323#define MPI2_PORTFACTS_PORTTYPE_FC (0x10)
324#define MPI2_PORTFACTS_PORTTYPE_ISCSI (0x20)
325#define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30)
326#define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31)
327
328
329/****************************************************************************
330* PortEnable message
331****************************************************************************/
332
333/* PortEnable Request message */
334typedef struct _MPI2_PORT_ENABLE_REQUEST
335{
336 U16 Reserved1; /* 0x00 */
337 U8 ChainOffset; /* 0x02 */
338 U8 Function; /* 0x03 */
339 U8 Reserved2; /* 0x04 */
340 U8 PortFlags; /* 0x05 */
341 U8 Reserved3; /* 0x06 */
342 U8 MsgFlags; /* 0x07 */
343 U8 VP_ID; /* 0x08 */
344 U8 VF_ID; /* 0x09 */
345 U16 Reserved4; /* 0x0A */
346} MPI2_PORT_ENABLE_REQUEST, MPI2_POINTER PTR_MPI2_PORT_ENABLE_REQUEST,
347 Mpi2PortEnableRequest_t, MPI2_POINTER pMpi2PortEnableRequest_t;
348
349
350/* PortEnable Reply message */
351typedef struct _MPI2_PORT_ENABLE_REPLY
352{
353 U16 Reserved1; /* 0x00 */
354 U8 MsgLength; /* 0x02 */
355 U8 Function; /* 0x03 */
356 U8 Reserved2; /* 0x04 */
357 U8 PortFlags; /* 0x05 */
358 U8 Reserved3; /* 0x06 */
359 U8 MsgFlags; /* 0x07 */
360 U8 VP_ID; /* 0x08 */
361 U8 VF_ID; /* 0x09 */
362 U16 Reserved4; /* 0x0A */
363 U16 Reserved5; /* 0x0C */
364 U16 IOCStatus; /* 0x0E */
365 U32 IOCLogInfo; /* 0x10 */
366} MPI2_PORT_ENABLE_REPLY, MPI2_POINTER PTR_MPI2_PORT_ENABLE_REPLY,
367 Mpi2PortEnableReply_t, MPI2_POINTER pMpi2PortEnableReply_t;
368
369
370/****************************************************************************
371* EventNotification message
372****************************************************************************/
373
374/* EventNotification Request message */
375#define MPI2_EVENT_NOTIFY_EVENTMASK_WORDS (4)
376
377typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST
378{
379 U16 Reserved1; /* 0x00 */
380 U8 ChainOffset; /* 0x02 */
381 U8 Function; /* 0x03 */
382 U16 Reserved2; /* 0x04 */
383 U8 Reserved3; /* 0x06 */
384 U8 MsgFlags; /* 0x07 */
385 U8 VP_ID; /* 0x08 */
386 U8 VF_ID; /* 0x09 */
387 U16 Reserved4; /* 0x0A */
388 U32 Reserved5; /* 0x0C */
389 U32 Reserved6; /* 0x10 */
390 U32 EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];/* 0x14 */
391 U16 SASBroadcastPrimitiveMasks; /* 0x24 */
392 U16 Reserved7; /* 0x26 */
393 U32 Reserved8; /* 0x28 */
394} MPI2_EVENT_NOTIFICATION_REQUEST,
395 MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REQUEST,
396 Mpi2EventNotificationRequest_t, MPI2_POINTER pMpi2EventNotificationRequest_t;
397
398
399/* EventNotification Reply message */
400typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
401{
402 U16 EventDataLength; /* 0x00 */
403 U8 MsgLength; /* 0x02 */
404 U8 Function; /* 0x03 */
405 U16 Reserved1; /* 0x04 */
406 U8 AckRequired; /* 0x06 */
407 U8 MsgFlags; /* 0x07 */
408 U8 VP_ID; /* 0x08 */
409 U8 VF_ID; /* 0x09 */
410 U16 Reserved2; /* 0x0A */
411 U16 Reserved3; /* 0x0C */
412 U16 IOCStatus; /* 0x0E */
413 U32 IOCLogInfo; /* 0x10 */
414 U16 Event; /* 0x14 */
415 U16 Reserved4; /* 0x16 */
416 U32 EventContext; /* 0x18 */
417 U32 EventData[1]; /* 0x1C */
418} MPI2_EVENT_NOTIFICATION_REPLY, MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REPLY,
419 Mpi2EventNotificationReply_t, MPI2_POINTER pMpi2EventNotificationReply_t;
420
421/* AckRequired */
422#define MPI2_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00)
423#define MPI2_EVENT_NOTIFICATION_ACK_REQUIRED (0x01)
424
425/* Event */
426#define MPI2_EVENT_LOG_DATA (0x0001)
427#define MPI2_EVENT_STATE_CHANGE (0x0002)
428#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005)
429#define MPI2_EVENT_EVENT_CHANGE (0x000A)
430#define MPI2_EVENT_TASK_SET_FULL (0x000E)
431#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F)
432#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014)
433#define MPI2_EVENT_SAS_DISCOVERY (0x0016)
434#define MPI2_EVENT_SAS_BROADCAST_PRIMITIVE (0x0017)
435#define MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x0018)
436#define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW (0x0019)
437#define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST (0x001C)
438#define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE (0x001D)
439#define MPI2_EVENT_IR_VOLUME (0x001E)
440#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F)
441#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020)
442#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021)
443
444
445/* Log Entry Added Event data */
446
447/* the following structure matches MPI2_LOG_0_ENTRY in mpi2_cnfg.h */
448#define MPI2_EVENT_DATA_LOG_DATA_LENGTH (0x1C)
449
450typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED
451{
452 U64 TimeStamp; /* 0x00 */
453 U32 Reserved1; /* 0x08 */
454 U16 LogSequence; /* 0x0C */
455 U16 LogEntryQualifier; /* 0x0E */
456 U8 VP_ID; /* 0x10 */
457 U8 VF_ID; /* 0x11 */
458 U16 Reserved2; /* 0x12 */
459 U8 LogData[MPI2_EVENT_DATA_LOG_DATA_LENGTH];/* 0x14 */
460} MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
461 MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED,
462 Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t;
463
464/* Hard Reset Received Event data */
465
466typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
467{
468 U8 Reserved1; /* 0x00 */
469 U8 Port; /* 0x01 */
470 U16 Reserved2; /* 0x02 */
471} MPI2_EVENT_DATA_HARD_RESET_RECEIVED,
472 MPI2_POINTER PTR_MPI2_EVENT_DATA_HARD_RESET_RECEIVED,
473 Mpi2EventDataHardResetReceived_t,
474 MPI2_POINTER pMpi2EventDataHardResetReceived_t;
475
476/* Task Set Full Event data */
477
478typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL
479{
480 U16 DevHandle; /* 0x00 */
481 U16 CurrentDepth; /* 0x02 */
482} MPI2_EVENT_DATA_TASK_SET_FULL, MPI2_POINTER PTR_MPI2_EVENT_DATA_TASK_SET_FULL,
483 Mpi2EventDataTaskSetFull_t, MPI2_POINTER pMpi2EventDataTaskSetFull_t;
484
485
486/* SAS Device Status Change Event data */
487
488typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
489{
490 U16 TaskTag; /* 0x00 */
491 U8 ReasonCode; /* 0x02 */
492 U8 Reserved1; /* 0x03 */
493 U8 ASC; /* 0x04 */
494 U8 ASCQ; /* 0x05 */
495 U16 DevHandle; /* 0x06 */
496 U32 Reserved2; /* 0x08 */
497 U64 SASAddress; /* 0x0C */
498 U8 LUN[8]; /* 0x14 */
499} MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
500 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
501 Mpi2EventDataSasDeviceStatusChange_t,
502 MPI2_POINTER pMpi2EventDataSasDeviceStatusChange_t;
503
504/* SAS Device Status Change Event data ReasonCode values */
505#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
506#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
507#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
508#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09)
509#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
510#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
511#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
512#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
513#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E)
514#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F)
515#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10)
516
517
518/* Integrated RAID Operation Status Event data */
519
520typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS
521{
522 U16 VolDevHandle; /* 0x00 */
523 U16 Reserved1; /* 0x02 */
524 U8 RAIDOperation; /* 0x04 */
525 U8 PercentComplete; /* 0x05 */
526 U16 Reserved2; /* 0x06 */
527 U32 Resereved3; /* 0x08 */
528} MPI2_EVENT_DATA_IR_OPERATION_STATUS,
529 MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS,
530 Mpi2EventDataIrOperationStatus_t,
531 MPI2_POINTER pMpi2EventDataIrOperationStatus_t;
532
533/* Integrated RAID Operation Status Event data RAIDOperation values */
534#define MPI2_EVENT_IR_RAIDOP_RESYNC (0x00)
535#define MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION (0x01)
536#define MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK (0x02)
537#define MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT (0x03)
538#define MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT (0x04)
539
540
541/* Integrated RAID Volume Event data */
542
543typedef struct _MPI2_EVENT_DATA_IR_VOLUME
544{
545 U16 VolDevHandle; /* 0x00 */
546 U8 ReasonCode; /* 0x02 */
547 U8 Reserved1; /* 0x03 */
548 U32 NewValue; /* 0x04 */
549 U32 PreviousValue; /* 0x08 */
550} MPI2_EVENT_DATA_IR_VOLUME, MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_VOLUME,
551 Mpi2EventDataIrVolume_t, MPI2_POINTER pMpi2EventDataIrVolume_t;
552
553/* Integrated RAID Volume Event data ReasonCode values */
554#define MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED (0x01)
555#define MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED (0x02)
556#define MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED (0x03)
557
558
559/* Integrated RAID Physical Disk Event data */
560
561typedef struct _MPI2_EVENT_DATA_IR_PHYSICAL_DISK
562{
563 U16 Reserved1; /* 0x00 */
564 U8 ReasonCode; /* 0x02 */
565 U8 PhysDiskNum; /* 0x03 */
566 U16 PhysDiskDevHandle; /* 0x04 */
567 U16 Reserved2; /* 0x06 */
568 U16 Slot; /* 0x08 */
569 U16 EnclosureHandle; /* 0x0A */
570 U32 NewValue; /* 0x0C */
571 U32 PreviousValue; /* 0x10 */
572} MPI2_EVENT_DATA_IR_PHYSICAL_DISK,
573 MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_PHYSICAL_DISK,
574 Mpi2EventDataIrPhysicalDisk_t, MPI2_POINTER pMpi2EventDataIrPhysicalDisk_t;
575
576/* Integrated RAID Physical Disk Event data ReasonCode values */
577#define MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED (0x01)
578#define MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED (0x02)
579#define MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED (0x03)
580
581
582/* Integrated RAID Configuration Change List Event data */
583
584/*
585 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
586 * one and check NumElements at runtime.
587 */
588#ifndef MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT
589#define MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT (1)
590#endif
591
592typedef struct _MPI2_EVENT_IR_CONFIG_ELEMENT
593{
594 U16 ElementFlags; /* 0x00 */
595 U16 VolDevHandle; /* 0x02 */
596 U8 ReasonCode; /* 0x04 */
597 U8 PhysDiskNum; /* 0x05 */
598 U16 PhysDiskDevHandle; /* 0x06 */
599} MPI2_EVENT_IR_CONFIG_ELEMENT, MPI2_POINTER PTR_MPI2_EVENT_IR_CONFIG_ELEMENT,
600 Mpi2EventIrConfigElement_t, MPI2_POINTER pMpi2EventIrConfigElement_t;
601
602/* IR Configuration Change List Event data ElementFlags values */
603#define MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK (0x000F)
604#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT (0x0000)
605#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT (0x0001)
606#define MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT (0x0002)
607
608/* IR Configuration Change List Event data ReasonCode values */
609#define MPI2_EVENT_IR_CHANGE_RC_ADDED (0x01)
610#define MPI2_EVENT_IR_CHANGE_RC_REMOVED (0x02)
611#define MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE (0x03)
612#define MPI2_EVENT_IR_CHANGE_RC_HIDE (0x04)
613#define MPI2_EVENT_IR_CHANGE_RC_UNHIDE (0x05)
614#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED (0x06)
615#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED (0x07)
616#define MPI2_EVENT_IR_CHANGE_RC_PD_CREATED (0x08)
617#define MPI2_EVENT_IR_CHANGE_RC_PD_DELETED (0x09)
618
619typedef struct _MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST
620{
621 U8 NumElements; /* 0x00 */
622 U8 Reserved1; /* 0x01 */
623 U8 Reserved2; /* 0x02 */
624 U8 ConfigNum; /* 0x03 */
625 U32 Flags; /* 0x04 */
626 MPI2_EVENT_IR_CONFIG_ELEMENT ConfigElement[MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT]; /* 0x08 */
627} MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST,
628 MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST,
629 Mpi2EventDataIrConfigChangeList_t,
630 MPI2_POINTER pMpi2EventDataIrConfigChangeList_t;
631
632/* IR Configuration Change List Event data Flags values */
633#define MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG (0x00000001)
634
635
636/* SAS Discovery Event data */
637
638typedef struct _MPI2_EVENT_DATA_SAS_DISCOVERY
639{
640 U8 Flags; /* 0x00 */
641 U8 ReasonCode; /* 0x01 */
642 U8 PhysicalPort; /* 0x02 */
643 U8 Reserved1; /* 0x03 */
644 U32 DiscoveryStatus; /* 0x04 */
645} MPI2_EVENT_DATA_SAS_DISCOVERY,
646 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_DISCOVERY,
647 Mpi2EventDataSasDiscovery_t, MPI2_POINTER pMpi2EventDataSasDiscovery_t;
648
649/* SAS Discovery Event data Flags values */
650#define MPI2_EVENT_SAS_DISC_DEVICE_CHANGE (0x02)
651#define MPI2_EVENT_SAS_DISC_IN_PROGRESS (0x01)
652
653/* SAS Discovery Event data ReasonCode values */
654#define MPI2_EVENT_SAS_DISC_RC_STARTED (0x01)
655#define MPI2_EVENT_SAS_DISC_RC_COMPLETED (0x02)
656
657/* SAS Discovery Event data DiscoveryStatus values */
658#define MPI2_EVENT_SAS_DISC_DS_MAX_ENCLOSURES_EXCEED (0x80000000)
659#define MPI2_EVENT_SAS_DISC_DS_MAX_EXPANDERS_EXCEED (0x40000000)
660#define MPI2_EVENT_SAS_DISC_DS_MAX_DEVICES_EXCEED (0x20000000)
661#define MPI2_EVENT_SAS_DISC_DS_MAX_TOPO_PHYS_EXCEED (0x10000000)
662#define MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR (0x08000000)
663#define MPI2_EVENT_SAS_DISC_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000)
664#define MPI2_EVENT_SAS_DISC_DS_EXP_MULTI_SUBTRACTIVE (0x00004000)
665#define MPI2_EVENT_SAS_DISC_DS_MULTI_PORT_DOMAIN (0x00002000)
666#define MPI2_EVENT_SAS_DISC_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000)
667#define MPI2_EVENT_SAS_DISC_DS_UNSUPPORTED_DEVICE (0x00000800)
668#define MPI2_EVENT_SAS_DISC_DS_TABLE_LINK (0x00000400)
669#define MPI2_EVENT_SAS_DISC_DS_SUBTRACTIVE_LINK (0x00000200)
670#define MPI2_EVENT_SAS_DISC_DS_SMP_CRC_ERROR (0x00000100)
671#define MPI2_EVENT_SAS_DISC_DS_SMP_FUNCTION_FAILED (0x00000080)
672#define MPI2_EVENT_SAS_DISC_DS_INDEX_NOT_EXIST (0x00000040)
673#define MPI2_EVENT_SAS_DISC_DS_OUT_ROUTE_ENTRIES (0x00000020)
674#define MPI2_EVENT_SAS_DISC_DS_SMP_TIMEOUT (0x00000010)
675#define MPI2_EVENT_SAS_DISC_DS_MULTIPLE_PORTS (0x00000004)
676#define MPI2_EVENT_SAS_DISC_DS_UNADDRESSABLE_DEVICE (0x00000002)
677#define MPI2_EVENT_SAS_DISC_DS_LOOP_DETECTED (0x00000001)
678
679
680/* SAS Broadcast Primitive Event data */
681
682typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE
683{
684 U8 PhyNum; /* 0x00 */
685 U8 Port; /* 0x01 */
686 U8 PortWidth; /* 0x02 */
687 U8 Primitive; /* 0x03 */
688} MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
689 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
690 Mpi2EventDataSasBroadcastPrimitive_t,
691 MPI2_POINTER pMpi2EventDataSasBroadcastPrimitive_t;
692
693/* defines for the Primitive field */
694#define MPI2_EVENT_PRIMITIVE_CHANGE (0x01)
695#define MPI2_EVENT_PRIMITIVE_SES (0x02)
696#define MPI2_EVENT_PRIMITIVE_EXPANDER (0x03)
697#define MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT (0x04)
698#define MPI2_EVENT_PRIMITIVE_RESERVED3 (0x05)
699#define MPI2_EVENT_PRIMITIVE_RESERVED4 (0x06)
700#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07)
701#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08)
702
703
704/* SAS Initiator Device Status Change Event data */
705
706typedef struct _MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
707{
708 U8 ReasonCode; /* 0x00 */
709 U8 PhysicalPort; /* 0x01 */
710 U16 DevHandle; /* 0x02 */
711 U64 SASAddress; /* 0x04 */
712} MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
713 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
714 Mpi2EventDataSasInitDevStatusChange_t,
715 MPI2_POINTER pMpi2EventDataSasInitDevStatusChange_t;
716
717/* SAS Initiator Device Status Change event ReasonCode values */
718#define MPI2_EVENT_SAS_INIT_RC_ADDED (0x01)
719#define MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING (0x02)
720
721
722/* SAS Initiator Device Table Overflow Event data */
723
724typedef struct _MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
725{
726 U16 MaxInit; /* 0x00 */
727 U16 CurrentInit; /* 0x02 */
728 U64 SASAddress; /* 0x04 */
729} MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
730 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
731 Mpi2EventDataSasInitTableOverflow_t,
732 MPI2_POINTER pMpi2EventDataSasInitTableOverflow_t;
733
734
735/* SAS Topology Change List Event data */
736
737/*
738 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
739 * one and check NumEntries at runtime.
740 */
741#ifndef MPI2_EVENT_SAS_TOPO_PHY_COUNT
742#define MPI2_EVENT_SAS_TOPO_PHY_COUNT (1)
743#endif
744
745typedef struct _MPI2_EVENT_SAS_TOPO_PHY_ENTRY
746{
747 U16 AttachedDevHandle; /* 0x00 */
748 U8 LinkRate; /* 0x02 */
749 U8 PhyStatus; /* 0x03 */
750} MPI2_EVENT_SAS_TOPO_PHY_ENTRY, MPI2_POINTER PTR_MPI2_EVENT_SAS_TOPO_PHY_ENTRY,
751 Mpi2EventSasTopoPhyEntry_t, MPI2_POINTER pMpi2EventSasTopoPhyEntry_t;
752
753typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
754{
755 U16 EnclosureHandle; /* 0x00 */
756 U16 ExpanderDevHandle; /* 0x02 */
757 U8 NumPhys; /* 0x04 */
758 U8 Reserved1; /* 0x05 */
759 U16 Reserved2; /* 0x06 */
760 U8 NumEntries; /* 0x08 */
761 U8 StartPhyNum; /* 0x09 */
762 U8 ExpStatus; /* 0x0A */
763 U8 PhysicalPort; /* 0x0B */
764 MPI2_EVENT_SAS_TOPO_PHY_ENTRY PHY[MPI2_EVENT_SAS_TOPO_PHY_COUNT]; /* 0x0C*/
765} MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST,
766 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST,
767 Mpi2EventDataSasTopologyChangeList_t,
768 MPI2_POINTER pMpi2EventDataSasTopologyChangeList_t;
769
770/* values for the ExpStatus field */
771#define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01)
772#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02)
773#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03)
774#define MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING (0x04)
775
776/* defines for the LinkRate field */
777#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK (0xF0)
778#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT (4)
779#define MPI2_EVENT_SAS_TOPO_LR_PREV_MASK (0x0F)
780#define MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT (0)
781
782#define MPI2_EVENT_SAS_TOPO_LR_UNKNOWN_LINK_RATE (0x00)
783#define MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED (0x01)
784#define MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED (0x02)
785#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03)
786#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04)
787#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05)
788#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08)
789#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09)
790#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A)
791
792/* values for the PhyStatus field */
793#define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT (0x80)
794#define MPI2_EVENT_SAS_TOPO_PS_MULTIPLEX_CHANGE (0x10)
795/* values for the PhyStatus ReasonCode sub-field */
796#define MPI2_EVENT_SAS_TOPO_RC_MASK (0x0F)
797#define MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED (0x01)
798#define MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING (0x02)
799#define MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED (0x03)
800#define MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE (0x04)
801#define MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING (0x05)
802
803
804/* SAS Enclosure Device Status Change Event data */
805
806typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE
807{
808 U16 EnclosureHandle; /* 0x00 */
809 U8 ReasonCode; /* 0x02 */
810 U8 PhysicalPort; /* 0x03 */
811 U64 EnclosureLogicalID; /* 0x04 */
812 U16 NumSlots; /* 0x0C */
813 U16 StartSlot; /* 0x0E */
814 U32 PhyBits; /* 0x10 */
815} MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
816 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
817 Mpi2EventDataSasEnclDevStatusChange_t,
818 MPI2_POINTER pMpi2EventDataSasEnclDevStatusChange_t;
819
820/* SAS Enclosure Device Status Change event ReasonCode values */
821#define MPI2_EVENT_SAS_ENCL_RC_ADDED (0x01)
822#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02)
823
824
825/****************************************************************************
826* EventAck message
827****************************************************************************/
828
829/* EventAck Request message */
830typedef struct _MPI2_EVENT_ACK_REQUEST
831{
832 U16 Reserved1; /* 0x00 */
833 U8 ChainOffset; /* 0x02 */
834 U8 Function; /* 0x03 */
835 U16 Reserved2; /* 0x04 */
836 U8 Reserved3; /* 0x06 */
837 U8 MsgFlags; /* 0x07 */
838 U8 VP_ID; /* 0x08 */
839 U8 VF_ID; /* 0x09 */
840 U16 Reserved4; /* 0x0A */
841 U16 Event; /* 0x0C */
842 U16 Reserved5; /* 0x0E */
843 U32 EventContext; /* 0x10 */
844} MPI2_EVENT_ACK_REQUEST, MPI2_POINTER PTR_MPI2_EVENT_ACK_REQUEST,
845 Mpi2EventAckRequest_t, MPI2_POINTER pMpi2EventAckRequest_t;
846
847
848/* EventAck Reply message */
849typedef struct _MPI2_EVENT_ACK_REPLY
850{
851 U16 Reserved1; /* 0x00 */
852 U8 MsgLength; /* 0x02 */
853 U8 Function; /* 0x03 */
854 U16 Reserved2; /* 0x04 */
855 U8 Reserved3; /* 0x06 */
856 U8 MsgFlags; /* 0x07 */
857 U8 VP_ID; /* 0x08 */
858 U8 VF_ID; /* 0x09 */
859 U16 Reserved4; /* 0x0A */
860 U16 Reserved5; /* 0x0C */
861 U16 IOCStatus; /* 0x0E */
862 U32 IOCLogInfo; /* 0x10 */
863} MPI2_EVENT_ACK_REPLY, MPI2_POINTER PTR_MPI2_EVENT_ACK_REPLY,
864 Mpi2EventAckReply_t, MPI2_POINTER pMpi2EventAckReply_t;
865
866
867/****************************************************************************
868* FWDownload message
869****************************************************************************/
870
871/* FWDownload Request message */
872typedef struct _MPI2_FW_DOWNLOAD_REQUEST
873{
874 U8 ImageType; /* 0x00 */
875 U8 Reserved1; /* 0x01 */
876 U8 ChainOffset; /* 0x02 */
877 U8 Function; /* 0x03 */
878 U16 Reserved2; /* 0x04 */
879 U8 Reserved3; /* 0x06 */
880 U8 MsgFlags; /* 0x07 */
881 U8 VP_ID; /* 0x08 */
882 U8 VF_ID; /* 0x09 */
883 U16 Reserved4; /* 0x0A */
884 U32 TotalImageSize; /* 0x0C */
885 U32 Reserved5; /* 0x10 */
886 MPI2_MPI_SGE_UNION SGL; /* 0x14 */
887} MPI2_FW_DOWNLOAD_REQUEST, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_REQUEST,
888 Mpi2FWDownloadRequest, MPI2_POINTER pMpi2FWDownloadRequest;
889
890#define MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT (0x01)
891
892#define MPI2_FW_DOWNLOAD_ITYPE_FW (0x01)
893#define MPI2_FW_DOWNLOAD_ITYPE_BIOS (0x02)
894#define MPI2_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06)
895#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07)
896#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08)
897#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09)
898#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
899
900/* FWDownload TransactionContext Element */
901typedef struct _MPI2_FW_DOWNLOAD_TCSGE
902{
903 U8 Reserved1; /* 0x00 */
904 U8 ContextSize; /* 0x01 */
905 U8 DetailsLength; /* 0x02 */
906 U8 Flags; /* 0x03 */
907 U32 Reserved2; /* 0x04 */
908 U32 ImageOffset; /* 0x08 */
909 U32 ImageSize; /* 0x0C */
910} MPI2_FW_DOWNLOAD_TCSGE, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_TCSGE,
911 Mpi2FWDownloadTCSGE_t, MPI2_POINTER pMpi2FWDownloadTCSGE_t;
912
913/* FWDownload Reply message */
914typedef struct _MPI2_FW_DOWNLOAD_REPLY
915{
916 U8 ImageType; /* 0x00 */
917 U8 Reserved1; /* 0x01 */
918 U8 MsgLength; /* 0x02 */
919 U8 Function; /* 0x03 */
920 U16 Reserved2; /* 0x04 */
921 U8 Reserved3; /* 0x06 */
922 U8 MsgFlags; /* 0x07 */
923 U8 VP_ID; /* 0x08 */
924 U8 VF_ID; /* 0x09 */
925 U16 Reserved4; /* 0x0A */
926 U16 Reserved5; /* 0x0C */
927 U16 IOCStatus; /* 0x0E */
928 U32 IOCLogInfo; /* 0x10 */
929} MPI2_FW_DOWNLOAD_REPLY, MPI2_POINTER PTR_MPI2_FW_DOWNLOAD_REPLY,
930 Mpi2FWDownloadReply_t, MPI2_POINTER pMpi2FWDownloadReply_t;
931
932
933/****************************************************************************
934* FWUpload message
935****************************************************************************/
936
937/* FWUpload Request message */
938typedef struct _MPI2_FW_UPLOAD_REQUEST
939{
940 U8 ImageType; /* 0x00 */
941 U8 Reserved1; /* 0x01 */
942 U8 ChainOffset; /* 0x02 */
943 U8 Function; /* 0x03 */
944 U16 Reserved2; /* 0x04 */
945 U8 Reserved3; /* 0x06 */
946 U8 MsgFlags; /* 0x07 */
947 U8 VP_ID; /* 0x08 */
948 U8 VF_ID; /* 0x09 */
949 U16 Reserved4; /* 0x0A */
950 U32 Reserved5; /* 0x0C */
951 U32 Reserved6; /* 0x10 */
952 MPI2_MPI_SGE_UNION SGL; /* 0x14 */
953} MPI2_FW_UPLOAD_REQUEST, MPI2_POINTER PTR_MPI2_FW_UPLOAD_REQUEST,
954 Mpi2FWUploadRequest_t, MPI2_POINTER pMpi2FWUploadRequest_t;
955
956#define MPI2_FW_UPLOAD_ITYPE_FW_CURRENT (0x00)
957#define MPI2_FW_UPLOAD_ITYPE_FW_FLASH (0x01)
958#define MPI2_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02)
959#define MPI2_FW_UPLOAD_ITYPE_FW_BACKUP (0x05)
960#define MPI2_FW_UPLOAD_ITYPE_MANUFACTURING (0x06)
961#define MPI2_FW_UPLOAD_ITYPE_CONFIG_1 (0x07)
962#define MPI2_FW_UPLOAD_ITYPE_CONFIG_2 (0x08)
963#define MPI2_FW_UPLOAD_ITYPE_MEGARAID (0x09)
964#define MPI2_FW_UPLOAD_ITYPE_COMPLETE (0x0A)
965#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
966
967typedef struct _MPI2_FW_UPLOAD_TCSGE
968{
969 U8 Reserved1; /* 0x00 */
970 U8 ContextSize; /* 0x01 */
971 U8 DetailsLength; /* 0x02 */
972 U8 Flags; /* 0x03 */
973 U32 Reserved2; /* 0x04 */
974 U32 ImageOffset; /* 0x08 */
975 U32 ImageSize; /* 0x0C */
976} MPI2_FW_UPLOAD_TCSGE, MPI2_POINTER PTR_MPI2_FW_UPLOAD_TCSGE,
977 Mpi2FWUploadTCSGE_t, MPI2_POINTER pMpi2FWUploadTCSGE_t;
978
979/* FWUpload Reply message */
980typedef struct _MPI2_FW_UPLOAD_REPLY
981{
982 U8 ImageType; /* 0x00 */
983 U8 Reserved1; /* 0x01 */
984 U8 MsgLength; /* 0x02 */
985 U8 Function; /* 0x03 */
986 U16 Reserved2; /* 0x04 */
987 U8 Reserved3; /* 0x06 */
988 U8 MsgFlags; /* 0x07 */
989 U8 VP_ID; /* 0x08 */
990 U8 VF_ID; /* 0x09 */
991 U16 Reserved4; /* 0x0A */
992 U16 Reserved5; /* 0x0C */
993 U16 IOCStatus; /* 0x0E */
994 U32 IOCLogInfo; /* 0x10 */
995 U32 ActualImageSize; /* 0x14 */
996} MPI2_FW_UPLOAD_REPLY, MPI2_POINTER PTR_MPI2_FW_UPLOAD_REPLY,
997 Mpi2FWUploadReply_t, MPI2_POINTER pMPi2FWUploadReply_t;
998
999
1000/* FW Image Header */
1001typedef struct _MPI2_FW_IMAGE_HEADER
1002{
1003 U32 Signature; /* 0x00 */
1004 U32 Signature0; /* 0x04 */
1005 U32 Signature1; /* 0x08 */
1006 U32 Signature2; /* 0x0C */
1007 MPI2_VERSION_UNION MPIVersion; /* 0x10 */
1008 MPI2_VERSION_UNION FWVersion; /* 0x14 */
1009 MPI2_VERSION_UNION NVDATAVersion; /* 0x18 */
1010 MPI2_VERSION_UNION PackageVersion; /* 0x1C */
1011 U16 VendorID; /* 0x20 */
1012 U16 ProductID; /* 0x22 */
1013 U16 ProtocolFlags; /* 0x24 */
1014 U16 Reserved26; /* 0x26 */
1015 U32 IOCCapabilities; /* 0x28 */
1016 U32 ImageSize; /* 0x2C */
1017 U32 NextImageHeaderOffset; /* 0x30 */
1018 U32 Checksum; /* 0x34 */
1019 U32 Reserved38; /* 0x38 */
1020 U32 Reserved3C; /* 0x3C */
1021 U32 Reserved40; /* 0x40 */
1022 U32 Reserved44; /* 0x44 */
1023 U32 Reserved48; /* 0x48 */
1024 U32 Reserved4C; /* 0x4C */
1025 U32 Reserved50; /* 0x50 */
1026 U32 Reserved54; /* 0x54 */
1027 U32 Reserved58; /* 0x58 */
1028 U32 Reserved5C; /* 0x5C */
1029 U32 Reserved60; /* 0x60 */
1030 U32 FirmwareVersionNameWhat; /* 0x64 */
1031 U8 FirmwareVersionName[32]; /* 0x68 */
1032 U32 VendorNameWhat; /* 0x88 */
1033 U8 VendorName[32]; /* 0x8C */
1034 U32 PackageNameWhat; /* 0x88 */
1035 U8 PackageName[32]; /* 0x8C */
1036 U32 ReservedD0; /* 0xD0 */
1037 U32 ReservedD4; /* 0xD4 */
1038 U32 ReservedD8; /* 0xD8 */
1039 U32 ReservedDC; /* 0xDC */
1040 U32 ReservedE0; /* 0xE0 */
1041 U32 ReservedE4; /* 0xE4 */
1042 U32 ReservedE8; /* 0xE8 */
1043 U32 ReservedEC; /* 0xEC */
1044 U32 ReservedF0; /* 0xF0 */
1045 U32 ReservedF4; /* 0xF4 */
1046 U32 ReservedF8; /* 0xF8 */
1047 U32 ReservedFC; /* 0xFC */
1048} MPI2_FW_IMAGE_HEADER, MPI2_POINTER PTR_MPI2_FW_IMAGE_HEADER,
1049 Mpi2FWImageHeader_t, MPI2_POINTER pMpi2FWImageHeader_t;
1050
1051/* Signature field */
1052#define MPI2_FW_HEADER_SIGNATURE_OFFSET (0x00)
1053#define MPI2_FW_HEADER_SIGNATURE_MASK (0xFF000000)
1054#define MPI2_FW_HEADER_SIGNATURE (0xEA000000)
1055
1056/* Signature0 field */
1057#define MPI2_FW_HEADER_SIGNATURE0_OFFSET (0x04)
1058#define MPI2_FW_HEADER_SIGNATURE0 (0x5AFAA55A)
1059
1060/* Signature1 field */
1061#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08)
1062#define MPI2_FW_HEADER_SIGNATURE1 (0xA55AFAA5)
1063
1064/* Signature2 field */
1065#define MPI2_FW_HEADER_SIGNATURE2_OFFSET (0x0C)
1066#define MPI2_FW_HEADER_SIGNATURE2 (0x5AA55AFA)
1067
1068
1069/* defines for using the ProductID field */
1070#define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000)
1071#define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000)
1072
1073#define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00)
1074#define MPI2_FW_HEADER_PID_PROD_A (0x0000)
1075
1076#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF)
1077/* SAS */
1078#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010)
1079
1080/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
1081
1082/* use MPI2_IOCFACTS_CAPABILITY_ defines for IOCCapabilities field */
1083
1084
1085#define MPI2_FW_HEADER_IMAGESIZE_OFFSET (0x2C)
1086#define MPI2_FW_HEADER_NEXTIMAGE_OFFSET (0x30)
1087#define MPI2_FW_HEADER_VERNMHWAT_OFFSET (0x64)
1088
1089#define MPI2_FW_HEADER_WHAT_SIGNATURE (0x29232840)
1090
1091#define MPI2_FW_HEADER_SIZE (0x100)
1092
1093
1094/* Extended Image Header */
1095typedef struct _MPI2_EXT_IMAGE_HEADER
1096
1097{
1098 U8 ImageType; /* 0x00 */
1099 U8 Reserved1; /* 0x01 */
1100 U16 Reserved2; /* 0x02 */
1101 U32 Checksum; /* 0x04 */
1102 U32 ImageSize; /* 0x08 */
1103 U32 NextImageHeaderOffset; /* 0x0C */
1104 U32 PackageVersion; /* 0x10 */
1105 U32 Reserved3; /* 0x14 */
1106 U32 Reserved4; /* 0x18 */
1107 U32 Reserved5; /* 0x1C */
1108 U8 IdentifyString[32]; /* 0x20 */
1109} MPI2_EXT_IMAGE_HEADER, MPI2_POINTER PTR_MPI2_EXT_IMAGE_HEADER,
1110 Mpi2ExtImageHeader_t, MPI2_POINTER pMpi2ExtImageHeader_t;
1111
1112/* useful offsets */
1113#define MPI2_EXT_IMAGE_IMAGETYPE_OFFSET (0x00)
1114#define MPI2_EXT_IMAGE_IMAGESIZE_OFFSET (0x08)
1115#define MPI2_EXT_IMAGE_NEXTIMAGE_OFFSET (0x0C)
1116
1117#define MPI2_EXT_IMAGE_HEADER_SIZE (0x40)
1118
1119/* defines for the ImageType field */
1120#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00)
1121#define MPI2_EXT_IMAGE_TYPE_FW (0x01)
1122#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03)
1123#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04)
1124#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05)
1125#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06)
1126#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07)
1127#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08)
1128
1129#define MPI2_EXT_IMAGE_TYPE_MAX (MPI2_EXT_IMAGE_TYPE_MEGARAID)
1130
1131
1132
1133/* FLASH Layout Extended Image Data */
1134
1135/*
1136 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1137 * one and check RegionsPerLayout at runtime.
1138 */
1139#ifndef MPI2_FLASH_NUMBER_OF_REGIONS
1140#define MPI2_FLASH_NUMBER_OF_REGIONS (1)
1141#endif
1142
1143/*
1144 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1145 * one and check NumberOfLayouts at runtime.
1146 */
1147#ifndef MPI2_FLASH_NUMBER_OF_LAYOUTS
1148#define MPI2_FLASH_NUMBER_OF_LAYOUTS (1)
1149#endif
1150
1151typedef struct _MPI2_FLASH_REGION
1152{
1153 U8 RegionType; /* 0x00 */
1154 U8 Reserved1; /* 0x01 */
1155 U16 Reserved2; /* 0x02 */
1156 U32 RegionOffset; /* 0x04 */
1157 U32 RegionSize; /* 0x08 */
1158 U32 Reserved3; /* 0x0C */
1159} MPI2_FLASH_REGION, MPI2_POINTER PTR_MPI2_FLASH_REGION,
1160 Mpi2FlashRegion_t, MPI2_POINTER pMpi2FlashRegion_t;
1161
1162typedef struct _MPI2_FLASH_LAYOUT
1163{
1164 U32 FlashSize; /* 0x00 */
1165 U32 Reserved1; /* 0x04 */
1166 U32 Reserved2; /* 0x08 */
1167 U32 Reserved3; /* 0x0C */
1168 MPI2_FLASH_REGION Region[MPI2_FLASH_NUMBER_OF_REGIONS];/* 0x10 */
1169} MPI2_FLASH_LAYOUT, MPI2_POINTER PTR_MPI2_FLASH_LAYOUT,
1170 Mpi2FlashLayout_t, MPI2_POINTER pMpi2FlashLayout_t;
1171
1172typedef struct _MPI2_FLASH_LAYOUT_DATA
1173{
1174 U8 ImageRevision; /* 0x00 */
1175 U8 Reserved1; /* 0x01 */
1176 U8 SizeOfRegion; /* 0x02 */
1177 U8 Reserved2; /* 0x03 */
1178 U16 NumberOfLayouts; /* 0x04 */
1179 U16 RegionsPerLayout; /* 0x06 */
1180 U16 MinimumSectorAlignment; /* 0x08 */
1181 U16 Reserved3; /* 0x0A */
1182 U32 Reserved4; /* 0x0C */
1183 MPI2_FLASH_LAYOUT Layout[MPI2_FLASH_NUMBER_OF_LAYOUTS];/* 0x10 */
1184} MPI2_FLASH_LAYOUT_DATA, MPI2_POINTER PTR_MPI2_FLASH_LAYOUT_DATA,
1185 Mpi2FlashLayoutData_t, MPI2_POINTER pMpi2FlashLayoutData_t;
1186
1187/* defines for the RegionType field */
1188#define MPI2_FLASH_REGION_UNUSED (0x00)
1189#define MPI2_FLASH_REGION_FIRMWARE (0x01)
1190#define MPI2_FLASH_REGION_BIOS (0x02)
1191#define MPI2_FLASH_REGION_NVDATA (0x03)
1192#define MPI2_FLASH_REGION_FIRMWARE_BACKUP (0x05)
1193#define MPI2_FLASH_REGION_MFG_INFORMATION (0x06)
1194#define MPI2_FLASH_REGION_CONFIG_1 (0x07)
1195#define MPI2_FLASH_REGION_CONFIG_2 (0x08)
1196#define MPI2_FLASH_REGION_MEGARAID (0x09)
1197#define MPI2_FLASH_REGION_INIT (0x0A)
1198
1199/* ImageRevision */
1200#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00)
1201
1202
1203
1204/* Supported Devices Extended Image Data */
1205
1206/*
1207 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1208 * one and check NumberOfDevices at runtime.
1209 */
1210#ifndef MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES
1211#define MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES (1)
1212#endif
1213
1214typedef struct _MPI2_SUPPORTED_DEVICE
1215{
1216 U16 DeviceID; /* 0x00 */
1217 U16 VendorID; /* 0x02 */
1218 U16 DeviceIDMask; /* 0x04 */
1219 U16 Reserved1; /* 0x06 */
1220 U8 LowPCIRev; /* 0x08 */
1221 U8 HighPCIRev; /* 0x09 */
1222 U16 Reserved2; /* 0x0A */
1223 U32 Reserved3; /* 0x0C */
1224} MPI2_SUPPORTED_DEVICE, MPI2_POINTER PTR_MPI2_SUPPORTED_DEVICE,
1225 Mpi2SupportedDevice_t, MPI2_POINTER pMpi2SupportedDevice_t;
1226
1227typedef struct _MPI2_SUPPORTED_DEVICES_DATA
1228{
1229 U8 ImageRevision; /* 0x00 */
1230 U8 Reserved1; /* 0x01 */
1231 U8 NumberOfDevices; /* 0x02 */
1232 U8 Reserved2; /* 0x03 */
1233 U32 Reserved3; /* 0x04 */
1234 MPI2_SUPPORTED_DEVICE SupportedDevice[MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES]; /* 0x08 */
1235} MPI2_SUPPORTED_DEVICES_DATA, MPI2_POINTER PTR_MPI2_SUPPORTED_DEVICES_DATA,
1236 Mpi2SupportedDevicesData_t, MPI2_POINTER pMpi2SupportedDevicesData_t;
1237
1238/* ImageRevision */
1239#define MPI2_SUPPORTED_DEVICES_IMAGE_REVISION (0x00)
1240
1241
1242/* Init Extended Image Data */
1243
1244typedef struct _MPI2_INIT_IMAGE_FOOTER
1245
1246{
1247 U32 BootFlags; /* 0x00 */
1248 U32 ImageSize; /* 0x04 */
1249 U32 Signature0; /* 0x08 */
1250 U32 Signature1; /* 0x0C */
1251 U32 Signature2; /* 0x10 */
1252 U32 ResetVector; /* 0x14 */
1253} MPI2_INIT_IMAGE_FOOTER, MPI2_POINTER PTR_MPI2_INIT_IMAGE_FOOTER,
1254 Mpi2InitImageFooter_t, MPI2_POINTER pMpi2InitImageFooter_t;
1255
1256/* defines for the BootFlags field */
1257#define MPI2_INIT_IMAGE_BOOTFLAGS_OFFSET (0x00)
1258
1259/* defines for the ImageSize field */
1260#define MPI2_INIT_IMAGE_IMAGESIZE_OFFSET (0x04)
1261
1262/* defines for the Signature0 field */
1263#define MPI2_INIT_IMAGE_SIGNATURE0_OFFSET (0x08)
1264#define MPI2_INIT_IMAGE_SIGNATURE0 (0x5AA55AEA)
1265
1266/* defines for the Signature1 field */
1267#define MPI2_INIT_IMAGE_SIGNATURE1_OFFSET (0x0C)
1268#define MPI2_INIT_IMAGE_SIGNATURE1 (0xA55AEAA5)
1269
1270/* defines for the Signature2 field */
1271#define MPI2_INIT_IMAGE_SIGNATURE2_OFFSET (0x10)
1272#define MPI2_INIT_IMAGE_SIGNATURE2 (0x5AEAA55A)
1273
1274/* Signature fields as individual bytes */
1275#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_0 (0xEA)
1276#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_1 (0x5A)
1277#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_2 (0xA5)
1278#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_3 (0x5A)
1279
1280#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_4 (0xA5)
1281#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_5 (0xEA)
1282#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_6 (0x5A)
1283#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_7 (0xA5)
1284
1285#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_8 (0x5A)
1286#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_9 (0xA5)
1287#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_A (0xEA)
1288#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_B (0x5A)
1289
1290/* defines for the ResetVector field */
1291#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14)
1292
1293
1294#endif
1295
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
new file mode 100644
index 000000000000..7134816d9046
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -0,0 +1,295 @@
1/*
2 * Copyright (c) 2000-2008 LSI Corporation.
3 *
4 *
5 * Name: mpi2_raid.h
6 * Title: MPI Integrated RAID messages and structures
7 * Creation Date: April 26, 2007
8 *
9 * mpi2_raid.h Version: 02.00.03
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 08-31-07 02.00.01 Modifications to RAID Action request and reply,
18 * including the Actions and ActionData.
19 * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD.
20 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
21 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
22 * can be sized by the build environment.
23 * --------------------------------------------------------------------------
24 */
25
26#ifndef MPI2_RAID_H
27#define MPI2_RAID_H
28
29/*****************************************************************************
30*
31* Integrated RAID Messages
32*
33*****************************************************************************/
34
35/****************************************************************************
36* RAID Action messages
37****************************************************************************/
38
39/* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */
40#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000)
41#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001)
42
43/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
44
45/* ActionDataWord defines for use with MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */
46#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001)
47
48/* ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */
49typedef struct _MPI2_RAID_ACTION_RATE_DATA
50{
51 U8 RateToChange; /* 0x00 */
52 U8 RateOrMode; /* 0x01 */
53 U16 DataScrubDuration; /* 0x02 */
54} MPI2_RAID_ACTION_RATE_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_RATE_DATA,
55 Mpi2RaidActionRateData_t, MPI2_POINTER pMpi2RaidActionRateData_t;
56
57#define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00)
58#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01)
59#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02)
60
61/* ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */
62typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION
63{
64 U8 RAIDFunction; /* 0x00 */
65 U8 Flags; /* 0x01 */
66 U16 Reserved1; /* 0x02 */
67} MPI2_RAID_ACTION_START_RAID_FUNCTION,
68 MPI2_POINTER PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION,
69 Mpi2RaidActionStartRaidFunction_t,
70 MPI2_POINTER pMpi2RaidActionStartRaidFunction_t;
71
72/* defines for the RAIDFunction field */
73#define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00)
74#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01)
75#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02)
76
77/* defines for the Flags field */
78#define MPI2_RAID_ACTION_START_NEW (0x00)
79#define MPI2_RAID_ACTION_START_RESUME (0x01)
80
81/* ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */
82typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION
83{
84 U8 RAIDFunction; /* 0x00 */
85 U8 Flags; /* 0x01 */
86 U16 Reserved1; /* 0x02 */
87} MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
88 MPI2_POINTER PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
89 Mpi2RaidActionStopRaidFunction_t,
90 MPI2_POINTER pMpi2RaidActionStopRaidFunction_t;
91
92/* defines for the RAIDFunction field */
93#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00)
94#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01)
95#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02)
96
97/* defines for the Flags field */
98#define MPI2_RAID_ACTION_STOP_ABORT (0x00)
99#define MPI2_RAID_ACTION_STOP_PAUSE (0x01)
100
101/* ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */
102typedef struct _MPI2_RAID_ACTION_HOT_SPARE
103{
104 U8 HotSparePool; /* 0x00 */
105 U8 Reserved1; /* 0x01 */
106 U16 DevHandle; /* 0x02 */
107} MPI2_RAID_ACTION_HOT_SPARE, MPI2_POINTER PTR_MPI2_RAID_ACTION_HOT_SPARE,
108 Mpi2RaidActionHotSpare_t, MPI2_POINTER pMpi2RaidActionHotSpare_t;
109
110/* ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */
111typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE
112{
113 U8 Flags; /* 0x00 */
114 U8 DeviceFirmwareUpdateModeTimeout; /* 0x01 */
115 U16 Reserved1; /* 0x02 */
116} MPI2_RAID_ACTION_FW_UPDATE_MODE,
117 MPI2_POINTER PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE,
118 Mpi2RaidActionFwUpdateMode_t, MPI2_POINTER pMpi2RaidActionFwUpdateMode_t;
119
120/* ActionDataWord defines for use with MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */
121#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00)
122#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01)
123
124typedef union _MPI2_RAID_ACTION_DATA
125{
126 U32 Word;
127 MPI2_RAID_ACTION_RATE_DATA Rates;
128 MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction;
129 MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction;
130 MPI2_RAID_ACTION_HOT_SPARE HotSpare;
131 MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode;
132} MPI2_RAID_ACTION_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_DATA,
133 Mpi2RaidActionData_t, MPI2_POINTER pMpi2RaidActionData_t;
134
135
136/* RAID Action Request Message */
137typedef struct _MPI2_RAID_ACTION_REQUEST
138{
139 U8 Action; /* 0x00 */
140 U8 Reserved1; /* 0x01 */
141 U8 ChainOffset; /* 0x02 */
142 U8 Function; /* 0x03 */
143 U16 VolDevHandle; /* 0x04 */
144 U8 PhysDiskNum; /* 0x06 */
145 U8 MsgFlags; /* 0x07 */
146 U8 VP_ID; /* 0x08 */
147 U8 VF_ID; /* 0x09 */
148 U16 Reserved2; /* 0x0A */
149 U32 Reserved3; /* 0x0C */
150 MPI2_RAID_ACTION_DATA ActionDataWord; /* 0x10 */
151 MPI2_SGE_SIMPLE_UNION ActionDataSGE; /* 0x14 */
152} MPI2_RAID_ACTION_REQUEST, MPI2_POINTER PTR_MPI2_RAID_ACTION_REQUEST,
153 Mpi2RaidActionRequest_t, MPI2_POINTER pMpi2RaidActionRequest_t;
154
155/* RAID Action request Action values */
156
157#define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01)
158#define MPI2_RAID_ACTION_CREATE_VOLUME (0x02)
159#define MPI2_RAID_ACTION_DELETE_VOLUME (0x03)
160#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04)
161#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05)
162#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A)
163#define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B)
164#define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F)
165#define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11)
166#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15)
167#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17)
168#define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18)
169#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19)
170#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C)
171#define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D)
172#define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E)
173#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20)
174#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21)
175#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22)
176
177
178/* RAID Volume Creation Structure */
179
180/*
181 * The following define can be customized for the targeted product.
182 */
183#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS
184#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1)
185#endif
186
187typedef struct _MPI2_RAID_VOLUME_PHYSDISK
188{
189 U8 RAIDSetNum; /* 0x00 */
190 U8 PhysDiskMap; /* 0x01 */
191 U16 PhysDiskDevHandle; /* 0x02 */
192} MPI2_RAID_VOLUME_PHYSDISK, MPI2_POINTER PTR_MPI2_RAID_VOLUME_PHYSDISK,
193 Mpi2RaidVolumePhysDisk_t, MPI2_POINTER pMpi2RaidVolumePhysDisk_t;
194
195/* defines for the PhysDiskMap field */
196#define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01)
197#define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02)
198
199typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT
200{
201 U8 NumPhysDisks; /* 0x00 */
202 U8 VolumeType; /* 0x01 */
203 U16 Reserved1; /* 0x02 */
204 U32 VolumeCreationFlags; /* 0x04 */
205 U32 VolumeSettings; /* 0x08 */
206 U8 Reserved2; /* 0x0C */
207 U8 ResyncRate; /* 0x0D */
208 U16 DataScrubDuration; /* 0x0E */
209 U64 VolumeMaxLBA; /* 0x10 */
210 U32 StripeSize; /* 0x18 */
211 U8 Name[16]; /* 0x1C */
212 MPI2_RAID_VOLUME_PHYSDISK PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS];/* 0x2C */
213} MPI2_RAID_VOLUME_CREATION_STRUCT,
214 MPI2_POINTER PTR_MPI2_RAID_VOLUME_CREATION_STRUCT,
215 Mpi2RaidVolumeCreationStruct_t, MPI2_POINTER pMpi2RaidVolumeCreationStruct_t;
216
217/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
218
219/* defines for the VolumeCreationFlags field */
220#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
221#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x04)
222#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x02)
223#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x01)
224
225
226/* RAID Online Capacity Expansion Structure */
227
228typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION
229{
230 U32 Flags; /* 0x00 */
231 U16 DevHandle0; /* 0x04 */
232 U16 Reserved1; /* 0x06 */
233 U16 DevHandle1; /* 0x08 */
234 U16 Reserved2; /* 0x0A */
235} MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
236 MPI2_POINTER PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
237 Mpi2RaidOnlineCapacityExpansion_t,
238 MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t;
239
240
241/* RAID Volume Indicator Structure */
242
243typedef struct _MPI2_RAID_VOL_INDICATOR
244{
245 U64 TotalBlocks; /* 0x00 */
246 U64 BlocksRemaining; /* 0x08 */
247 U32 Flags; /* 0x10 */
248} MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR,
249 Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t;
250
251/* defines for RAID Volume Indicator Flags field */
252#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F)
253#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000)
254#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
255#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002)
256#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003)
257
258
259/* RAID Action Reply ActionData union */
260typedef union _MPI2_RAID_ACTION_REPLY_DATA
261{
262 U32 Word[5];
263 MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator;
264 U16 VolDevHandle;
265 U8 VolumeState;
266 U8 PhysDiskNum;
267} MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA,
268 Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t;
269
270/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
271
272
273/* RAID Action Reply Message */
274typedef struct _MPI2_RAID_ACTION_REPLY
275{
276 U8 Action; /* 0x00 */
277 U8 Reserved1; /* 0x01 */
278 U8 MsgLength; /* 0x02 */
279 U8 Function; /* 0x03 */
280 U16 VolDevHandle; /* 0x04 */
281 U8 PhysDiskNum; /* 0x06 */
282 U8 MsgFlags; /* 0x07 */
283 U8 VP_ID; /* 0x08 */
284 U8 VF_ID; /* 0x09 */
285 U16 Reserved2; /* 0x0A */
286 U16 Reserved3; /* 0x0C */
287 U16 IOCStatus; /* 0x0E */
288 U32 IOCLogInfo; /* 0x10 */
289 MPI2_RAID_ACTION_REPLY_DATA ActionData; /* 0x14 */
290} MPI2_RAID_ACTION_REPLY, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY,
291 Mpi2RaidActionReply_t, MPI2_POINTER pMpi2RaidActionReply_t;
292
293
294#endif
295
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
new file mode 100644
index 000000000000..8a42b136cf53
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h
@@ -0,0 +1,282 @@
1/*
2 * Copyright (c) 2000-2007 LSI Corporation.
3 *
4 *
5 * Name: mpi2_sas.h
6 * Title: MPI Serial Attached SCSI structures and definitions
7 * Creation Date: February 9, 2007
8 *
9 * mpi2.h Version: 02.00.02
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit
18 * Control Request.
19 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control
20 * Request.
21 * --------------------------------------------------------------------------
22 */
23
24#ifndef MPI2_SAS_H
25#define MPI2_SAS_H
26
27/*
28 * Values for SASStatus.
29 */
30#define MPI2_SASSTATUS_SUCCESS (0x00)
31#define MPI2_SASSTATUS_UNKNOWN_ERROR (0x01)
32#define MPI2_SASSTATUS_INVALID_FRAME (0x02)
33#define MPI2_SASSTATUS_UTC_BAD_DEST (0x03)
34#define MPI2_SASSTATUS_UTC_BREAK_RECEIVED (0x04)
35#define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05)
36#define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06)
37#define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07)
38#define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08)
39#define MPI2_SASSTATUS_UTC_WRONG_DESTINATION (0x09)
40#define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A)
41#define MPI2_SASSTATUS_LONG_INFORMATION_UNIT (0x0B)
42#define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C)
43#define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D)
44#define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E)
45#define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F)
46#define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10)
47#define MPI2_SASSTATUS_DATA_OFFSET_ERROR (0x11)
48#define MPI2_SASSTATUS_SDSF_NAK_RECEIVED (0x12)
49#define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED (0x13)
50#define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14)
51
52
53/*
54 * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
55 * data and SAS Configuration pages.
56 */
57#define MPI2_SAS_DEVICE_INFO_SEP (0x00004000)
58#define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
59#define MPI2_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
60#define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
61#define MPI2_SAS_DEVICE_INFO_SSP_TARGET (0x00000400)
62#define MPI2_SAS_DEVICE_INFO_STP_TARGET (0x00000200)
63#define MPI2_SAS_DEVICE_INFO_SMP_TARGET (0x00000100)
64#define MPI2_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080)
65#define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040)
66#define MPI2_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020)
67#define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010)
68#define MPI2_SAS_DEVICE_INFO_SATA_HOST (0x00000008)
69
70#define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007)
71#define MPI2_SAS_DEVICE_INFO_NO_DEVICE (0x00000000)
72#define MPI2_SAS_DEVICE_INFO_END_DEVICE (0x00000001)
73#define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002)
74#define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003)
75
76
77/*****************************************************************************
78*
79* SAS Messages
80*
81*****************************************************************************/
82
83/****************************************************************************
84* SMP Passthrough messages
85****************************************************************************/
86
87/* SMP Passthrough Request Message */
88typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
89{
90 U8 PassthroughFlags; /* 0x00 */
91 U8 PhysicalPort; /* 0x01 */
92 U8 ChainOffset; /* 0x02 */
93 U8 Function; /* 0x03 */
94 U16 RequestDataLength; /* 0x04 */
95 U8 SGLFlags; /* 0x06 */
96 U8 MsgFlags; /* 0x07 */
97 U8 VP_ID; /* 0x08 */
98 U8 VF_ID; /* 0x09 */
99 U16 Reserved1; /* 0x0A */
100 U32 Reserved2; /* 0x0C */
101 U64 SASAddress; /* 0x10 */
102 U32 Reserved3; /* 0x18 */
103 U32 Reserved4; /* 0x1C */
104 MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */
105} MPI2_SMP_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REQUEST,
106 Mpi2SmpPassthroughRequest_t, MPI2_POINTER pMpi2SmpPassthroughRequest_t;
107
108/* values for PassthroughFlags field */
109#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
110
111/* values for SGLFlags field are in the SGL section of mpi2.h */
112
113
114/* SMP Passthrough Reply Message */
115typedef struct _MPI2_SMP_PASSTHROUGH_REPLY
116{
117 U8 PassthroughFlags; /* 0x00 */
118 U8 PhysicalPort; /* 0x01 */
119 U8 MsgLength; /* 0x02 */
120 U8 Function; /* 0x03 */
121 U16 ResponseDataLength; /* 0x04 */
122 U8 SGLFlags; /* 0x06 */
123 U8 MsgFlags; /* 0x07 */
124 U8 VP_ID; /* 0x08 */
125 U8 VF_ID; /* 0x09 */
126 U16 Reserved1; /* 0x0A */
127 U8 Reserved2; /* 0x0C */
128 U8 SASStatus; /* 0x0D */
129 U16 IOCStatus; /* 0x0E */
130 U32 IOCLogInfo; /* 0x10 */
131 U32 Reserved3; /* 0x14 */
132 U8 ResponseData[4]; /* 0x18 */
133} MPI2_SMP_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REPLY,
134 Mpi2SmpPassthroughReply_t, MPI2_POINTER pMpi2SmpPassthroughReply_t;
135
136/* values for PassthroughFlags field */
137#define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80)
138
139/* values for SASStatus field are at the top of this file */
140
141
142/****************************************************************************
143* SATA Passthrough messages
144****************************************************************************/
145
146/* SATA Passthrough Request Message */
147typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
148{
149 U16 DevHandle; /* 0x00 */
150 U8 ChainOffset; /* 0x02 */
151 U8 Function; /* 0x03 */
152 U16 PassthroughFlags; /* 0x04 */
153 U8 SGLFlags; /* 0x06 */
154 U8 MsgFlags; /* 0x07 */
155 U8 VP_ID; /* 0x08 */
156 U8 VF_ID; /* 0x09 */
157 U16 Reserved1; /* 0x0A */
158 U32 Reserved2; /* 0x0C */
159 U32 Reserved3; /* 0x10 */
160 U32 Reserved4; /* 0x14 */
161 U32 DataLength; /* 0x18 */
162 U8 CommandFIS[20]; /* 0x1C */
163 MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */
164} MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST,
165 Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t;
166
167/* values for PassthroughFlags field */
168#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100)
169#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020)
170#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010)
171#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004)
172#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002)
173#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001)
174
175/* values for SGLFlags field are in the SGL section of mpi2.h */
176
177
178/* SATA Passthrough Reply Message */
179typedef struct _MPI2_SATA_PASSTHROUGH_REPLY
180{
181 U16 DevHandle; /* 0x00 */
182 U8 MsgLength; /* 0x02 */
183 U8 Function; /* 0x03 */
184 U16 PassthroughFlags; /* 0x04 */
185 U8 SGLFlags; /* 0x06 */
186 U8 MsgFlags; /* 0x07 */
187 U8 VP_ID; /* 0x08 */
188 U8 VF_ID; /* 0x09 */
189 U16 Reserved1; /* 0x0A */
190 U8 Reserved2; /* 0x0C */
191 U8 SASStatus; /* 0x0D */
192 U16 IOCStatus; /* 0x0E */
193 U32 IOCLogInfo; /* 0x10 */
194 U8 StatusFIS[20]; /* 0x14 */
195 U32 StatusControlRegisters; /* 0x28 */
196 U32 TransferCount; /* 0x2C */
197} MPI2_SATA_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REPLY,
198 Mpi2SataPassthroughReply_t, MPI2_POINTER pMpi2SataPassthroughReply_t;
199
200/* values for SASStatus field are at the top of this file */
201
202
203/****************************************************************************
204* SAS IO Unit Control messages
205****************************************************************************/
206
207/* SAS IO Unit Control Request Message */
208typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST
209{
210 U8 Operation; /* 0x00 */
211 U8 Reserved1; /* 0x01 */
212 U8 ChainOffset; /* 0x02 */
213 U8 Function; /* 0x03 */
214 U16 DevHandle; /* 0x04 */
215 U8 IOCParameter; /* 0x06 */
216 U8 MsgFlags; /* 0x07 */
217 U8 VP_ID; /* 0x08 */
218 U8 VF_ID; /* 0x09 */
219 U16 Reserved3; /* 0x0A */
220 U16 Reserved4; /* 0x0C */
221 U8 PhyNum; /* 0x0E */
222 U8 PrimFlags; /* 0x0F */
223 U32 Primitive; /* 0x10 */
224 U8 LookupMethod; /* 0x14 */
225 U8 Reserved5; /* 0x15 */
226 U16 SlotNumber; /* 0x16 */
227 U64 LookupAddress; /* 0x18 */
228 U32 IOCParameterValue; /* 0x20 */
229 U32 Reserved7; /* 0x24 */
230 U32 Reserved8; /* 0x28 */
231} MPI2_SAS_IOUNIT_CONTROL_REQUEST,
232 MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST,
233 Mpi2SasIoUnitControlRequest_t, MPI2_POINTER pMpi2SasIoUnitControlRequest_t;
234
235/* values for the Operation field */
236#define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
237#define MPI2_SAS_OP_PHY_LINK_RESET (0x06)
238#define MPI2_SAS_OP_PHY_HARD_RESET (0x07)
239#define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
240#define MPI2_SAS_OP_SEND_PRIMITIVE (0x0A)
241#define MPI2_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
242#define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
243#define MPI2_SAS_OP_REMOVE_DEVICE (0x0D)
244#define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E)
245#define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F)
246#define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80)
247
248/* values for the PrimFlags field */
249#define MPI2_SAS_PRIMFLAGS_SINGLE (0x08)
250#define MPI2_SAS_PRIMFLAGS_TRIPLE (0x02)
251#define MPI2_SAS_PRIMFLAGS_REDUNDANT (0x01)
252
253/* values for the LookupMethod field */
254#define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS (0x01)
255#define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT (0x02)
256#define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03)
257
258
259/* SAS IO Unit Control Reply Message */
260typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY
261{
262 U8 Operation; /* 0x00 */
263 U8 Reserved1; /* 0x01 */
264 U8 MsgLength; /* 0x02 */
265 U8 Function; /* 0x03 */
266 U16 DevHandle; /* 0x04 */
267 U8 IOCParameter; /* 0x06 */
268 U8 MsgFlags; /* 0x07 */
269 U8 VP_ID; /* 0x08 */
270 U8 VF_ID; /* 0x09 */
271 U16 Reserved3; /* 0x0A */
272 U16 Reserved4; /* 0x0C */
273 U16 IOCStatus; /* 0x0E */
274 U32 IOCLogInfo; /* 0x10 */
275} MPI2_SAS_IOUNIT_CONTROL_REPLY,
276 MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY,
277 Mpi2SasIoUnitControlReply_t, MPI2_POINTER pMpi2SasIoUnitControlReply_t;
278
279
280#endif
281
282
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
new file mode 100644
index 000000000000..2ff4e936bd39
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -0,0 +1,249 @@
1/*
2 * Copyright (c) 2000-2008 LSI Corporation.
3 *
4 *
5 * Name: mpi2_tool.h
6 * Title: MPI diagnostic tool structures and definitions
7 * Creation Date: March 26, 2007
8 *
9 * mpi2_tool.h Version: 02.00.02
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release
18 * structures and defines.
19 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
20 * --------------------------------------------------------------------------
21 */
22
23#ifndef MPI2_TOOL_H
24#define MPI2_TOOL_H
25
26/*****************************************************************************
27*
28* Toolbox Messages
29*
30*****************************************************************************/
31
32/* defines for the Tools */
33#define MPI2_TOOLBOX_CLEAN_TOOL (0x00)
34#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
35#define MPI2_TOOLBOX_BEACON_TOOL (0x05)
36
37/****************************************************************************
38* Toolbox reply
39****************************************************************************/
40
41typedef struct _MPI2_TOOLBOX_REPLY
42{
43 U8 Tool; /* 0x00 */
44 U8 Reserved1; /* 0x01 */
45 U8 MsgLength; /* 0x02 */
46 U8 Function; /* 0x03 */
47 U16 Reserved2; /* 0x04 */
48 U8 Reserved3; /* 0x06 */
49 U8 MsgFlags; /* 0x07 */
50 U8 VP_ID; /* 0x08 */
51 U8 VF_ID; /* 0x09 */
52 U16 Reserved4; /* 0x0A */
53 U16 Reserved5; /* 0x0C */
54 U16 IOCStatus; /* 0x0E */
55 U32 IOCLogInfo; /* 0x10 */
56} MPI2_TOOLBOX_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_REPLY,
57 Mpi2ToolboxReply_t, MPI2_POINTER pMpi2ToolboxReply_t;
58
59
60/****************************************************************************
61* Toolbox Clean Tool request
62****************************************************************************/
63
64typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
65{
66 U8 Tool; /* 0x00 */
67 U8 Reserved1; /* 0x01 */
68 U8 ChainOffset; /* 0x02 */
69 U8 Function; /* 0x03 */
70 U16 Reserved2; /* 0x04 */
71 U8 Reserved3; /* 0x06 */
72 U8 MsgFlags; /* 0x07 */
73 U8 VP_ID; /* 0x08 */
74 U8 VF_ID; /* 0x09 */
75 U16 Reserved4; /* 0x0A */
76 U32 Flags; /* 0x0C */
77 } MPI2_TOOLBOX_CLEAN_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_CLEAN_REQUEST,
78 Mpi2ToolboxCleanRequest_t, MPI2_POINTER pMpi2ToolboxCleanRequest_t;
79
80/* values for the Flags field */
81#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000)
82#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000)
83#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000)
84#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000)
85#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000)
86#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000)
87#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000)
88#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004)
89#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002)
90#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001)
91
92
93/****************************************************************************
94* Toolbox Memory Move request
95****************************************************************************/
96
97typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
98{
99 U8 Tool; /* 0x00 */
100 U8 Reserved1; /* 0x01 */
101 U8 ChainOffset; /* 0x02 */
102 U8 Function; /* 0x03 */
103 U16 Reserved2; /* 0x04 */
104 U8 Reserved3; /* 0x06 */
105 U8 MsgFlags; /* 0x07 */
106 U8 VP_ID; /* 0x08 */
107 U8 VF_ID; /* 0x09 */
108 U16 Reserved4; /* 0x0A */
109 MPI2_SGE_SIMPLE_UNION SGL; /* 0x0C */
110} MPI2_TOOLBOX_MEM_MOVE_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST,
111 Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t;
112
113
114/****************************************************************************
115* Toolbox Beacon Tool request
116****************************************************************************/
117
118typedef struct _MPI2_TOOLBOX_BEACON_REQUEST
119{
120 U8 Tool; /* 0x00 */
121 U8 Reserved1; /* 0x01 */
122 U8 ChainOffset; /* 0x02 */
123 U8 Function; /* 0x03 */
124 U16 Reserved2; /* 0x04 */
125 U8 Reserved3; /* 0x06 */
126 U8 MsgFlags; /* 0x07 */
127 U8 VP_ID; /* 0x08 */
128 U8 VF_ID; /* 0x09 */
129 U16 Reserved4; /* 0x0A */
130 U8 Reserved5; /* 0x0C */
131 U8 PhysicalPort; /* 0x0D */
132 U8 Reserved6; /* 0x0E */
133 U8 Flags; /* 0x0F */
134} MPI2_TOOLBOX_BEACON_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_BEACON_REQUEST,
135 Mpi2ToolboxBeaconRequest_t, MPI2_POINTER pMpi2ToolboxBeaconRequest_t;
136
137/* values for the Flags field */
138#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00)
139#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01)
140
141
142/*****************************************************************************
143*
144* Diagnostic Buffer Messages
145*
146*****************************************************************************/
147
148
149/****************************************************************************
150* Diagnostic Buffer Post request
151****************************************************************************/
152
153typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
154{
155 U8 Reserved1; /* 0x00 */
156 U8 BufferType; /* 0x01 */
157 U8 ChainOffset; /* 0x02 */
158 U8 Function; /* 0x03 */
159 U16 Reserved2; /* 0x04 */
160 U8 Reserved3; /* 0x06 */
161 U8 MsgFlags; /* 0x07 */
162 U8 VP_ID; /* 0x08 */
163 U8 VF_ID; /* 0x09 */
164 U16 Reserved4; /* 0x0A */
165 U64 BufferAddress; /* 0x0C */
166 U32 BufferLength; /* 0x14 */
167 U32 Reserved5; /* 0x18 */
168 U32 Reserved6; /* 0x1C */
169 U32 Flags; /* 0x20 */
170 U32 ProductSpecific[23]; /* 0x24 */
171} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
172 Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
173
174/* values for the BufferType field */
175#define MPI2_DIAG_BUF_TYPE_TRACE (0x00)
176#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01)
177/* count of the number of buffer types */
178#define MPI2_DIAG_BUF_TYPE_COUNT (0x02)
179
180
181/****************************************************************************
182* Diagnostic Buffer Post reply
183****************************************************************************/
184
185typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
186{
187 U8 Reserved1; /* 0x00 */
188 U8 BufferType; /* 0x01 */
189 U8 MsgLength; /* 0x02 */
190 U8 Function; /* 0x03 */
191 U16 Reserved2; /* 0x04 */
192 U8 Reserved3; /* 0x06 */
193 U8 MsgFlags; /* 0x07 */
194 U8 VP_ID; /* 0x08 */
195 U8 VF_ID; /* 0x09 */
196 U16 Reserved4; /* 0x0A */
197 U16 Reserved5; /* 0x0C */
198 U16 IOCStatus; /* 0x0E */
199 U32 IOCLogInfo; /* 0x10 */
200 U32 TransferLength; /* 0x14 */
201} MPI2_DIAG_BUFFER_POST_REPLY, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REPLY,
202 Mpi2DiagBufferPostReply_t, MPI2_POINTER pMpi2DiagBufferPostReply_t;
203
204
205/****************************************************************************
206* Diagnostic Release request
207****************************************************************************/
208
209typedef struct _MPI2_DIAG_RELEASE_REQUEST
210{
211 U8 Reserved1; /* 0x00 */
212 U8 BufferType; /* 0x01 */
213 U8 ChainOffset; /* 0x02 */
214 U8 Function; /* 0x03 */
215 U16 Reserved2; /* 0x04 */
216 U8 Reserved3; /* 0x06 */
217 U8 MsgFlags; /* 0x07 */
218 U8 VP_ID; /* 0x08 */
219 U8 VF_ID; /* 0x09 */
220 U16 Reserved4; /* 0x0A */
221} MPI2_DIAG_RELEASE_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REQUEST,
222 Mpi2DiagReleaseRequest_t, MPI2_POINTER pMpi2DiagReleaseRequest_t;
223
224
225/****************************************************************************
226* Diagnostic Buffer Post reply
227****************************************************************************/
228
229typedef struct _MPI2_DIAG_RELEASE_REPLY
230{
231 U8 Reserved1; /* 0x00 */
232 U8 BufferType; /* 0x01 */
233 U8 MsgLength; /* 0x02 */
234 U8 Function; /* 0x03 */
235 U16 Reserved2; /* 0x04 */
236 U8 Reserved3; /* 0x06 */
237 U8 MsgFlags; /* 0x07 */
238 U8 VP_ID; /* 0x08 */
239 U8 VF_ID; /* 0x09 */
240 U16 Reserved4; /* 0x0A */
241 U16 Reserved5; /* 0x0C */
242 U16 IOCStatus; /* 0x0E */
243 U32 IOCLogInfo; /* 0x10 */
244} MPI2_DIAG_RELEASE_REPLY, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REPLY,
245 Mpi2DiagReleaseReply_t, MPI2_POINTER pMpi2DiagReleaseReply_t;
246
247
248#endif
249
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_type.h b/drivers/scsi/mpt2sas/mpi/mpi2_type.h
new file mode 100644
index 000000000000..cfde017bf16e
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_type.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2000-2007 LSI Corporation.
3 *
4 *
5 * Name: mpi2_type.h
6 * Title: MPI basic type definitions
7 * Creation Date: August 16, 2006
8 *
9 * mpi2_type.h Version: 02.00.00
10 *
11 * Version History
12 * ---------------
13 *
14 * Date Version Description
15 * -------- -------- ------------------------------------------------------
16 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
17 * --------------------------------------------------------------------------
18 */
19
20#ifndef MPI2_TYPE_H
21#define MPI2_TYPE_H
22
23
24/*******************************************************************************
25 * Define MPI2_POINTER if it hasn't already been defined. By default
26 * MPI2_POINTER is defined to be a near pointer. MPI2_POINTER can be defined as
27 * a far pointer by defining MPI2_POINTER as "far *" before this header file is
28 * included.
29 */
30#ifndef MPI2_POINTER
31#define MPI2_POINTER *
32#endif
33
34/* the basic types may have already been included by mpi_type.h */
35#ifndef MPI_TYPE_H
36/*****************************************************************************
37*
38* Basic Types
39*
40*****************************************************************************/
41
42typedef u8 U8;
43typedef __le16 U16;
44typedef __le32 U32;
45typedef __le64 U64 __attribute__((aligned(4)));
46
47/*****************************************************************************
48*
49* Pointer Types
50*
51*****************************************************************************/
52
53typedef U8 *PU8;
54typedef U16 *PU16;
55typedef U32 *PU32;
56typedef U64 *PU64;
57
58#endif
59
60#endif
61
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
new file mode 100644
index 000000000000..52427a8324f5
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -0,0 +1,3435 @@
1/*
2 * This is the Fusion MPT base driver providing common API layer interface
3 * for access to MPT (Message Passing Technology) firmware.
4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
6 * Copyright (C) 2007-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
45#include <linux/version.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/errno.h>
49#include <linux/init.h>
50#include <linux/slab.h>
51#include <linux/types.h>
52#include <linux/pci.h>
53#include <linux/kdev_t.h>
54#include <linux/blkdev.h>
55#include <linux/delay.h>
56#include <linux/interrupt.h>
57#include <linux/dma-mapping.h>
58#include <linux/sort.h>
59#include <linux/io.h>
60
61#include "mpt2sas_base.h"
62
63static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
64
65#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
66#define MPT2SAS_MAX_REQUEST_QUEUE 500 /* maximum controller queue depth */
67
68static int max_queue_depth = -1;
69module_param(max_queue_depth, int, 0);
70MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
71
72static int max_sgl_entries = -1;
73module_param(max_sgl_entries, int, 0);
74MODULE_PARM_DESC(max_sgl_entries, " max sg entries ");
75
76static int msix_disable = -1;
77module_param(msix_disable, int, 0);
78MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
79
80/**
81 * _base_fault_reset_work - workq handling ioc fault conditions
82 * @work: input argument, used to derive ioc
83 * Context: sleep.
84 *
85 * Return nothing.
86 */
87static void
88_base_fault_reset_work(struct work_struct *work)
89{
90 struct MPT2SAS_ADAPTER *ioc =
91 container_of(work, struct MPT2SAS_ADAPTER, fault_reset_work.work);
92 unsigned long flags;
93 u32 doorbell;
94 int rc;
95
96 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
97 if (ioc->ioc_reset_in_progress)
98 goto rearm_timer;
99 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
100
101 doorbell = mpt2sas_base_get_iocstate(ioc, 0);
102 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
103 rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
104 FORCE_BIG_HAMMER);
105 printk(MPT2SAS_WARN_FMT "%s: hard reset: %s\n", ioc->name,
106 __func__, (rc == 0) ? "success" : "failed");
107 doorbell = mpt2sas_base_get_iocstate(ioc, 0);
108 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
109 mpt2sas_base_fault_info(ioc, doorbell &
110 MPI2_DOORBELL_DATA_MASK);
111 }
112
113 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
114 rearm_timer:
115 if (ioc->fault_reset_work_q)
116 queue_delayed_work(ioc->fault_reset_work_q,
117 &ioc->fault_reset_work,
118 msecs_to_jiffies(FAULT_POLLING_INTERVAL));
119 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
120}
121
122#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
123/**
124 * _base_sas_ioc_info - verbose translation of the ioc status
125 * @ioc: pointer to scsi command object
126 * @mpi_reply: reply mf payload returned from firmware
127 * @request_hdr: request mf
128 *
129 * Return nothing.
130 */
131static void
132_base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
133 MPI2RequestHeader_t *request_hdr)
134{
135 u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
136 MPI2_IOCSTATUS_MASK;
137 char *desc = NULL;
138 u16 frame_sz;
139 char *func_str = NULL;
140
141 /* SCSI_IO, RAID_PASS are handled from _scsih_scsi_ioc_info */
142 if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
143 request_hdr->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
144 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION)
145 return;
146
147 switch (ioc_status) {
148
149/****************************************************************************
150* Common IOCStatus values for all replies
151****************************************************************************/
152
153 case MPI2_IOCSTATUS_INVALID_FUNCTION:
154 desc = "invalid function";
155 break;
156 case MPI2_IOCSTATUS_BUSY:
157 desc = "busy";
158 break;
159 case MPI2_IOCSTATUS_INVALID_SGL:
160 desc = "invalid sgl";
161 break;
162 case MPI2_IOCSTATUS_INTERNAL_ERROR:
163 desc = "internal error";
164 break;
165 case MPI2_IOCSTATUS_INVALID_VPID:
166 desc = "invalid vpid";
167 break;
168 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
169 desc = "insufficient resources";
170 break;
171 case MPI2_IOCSTATUS_INVALID_FIELD:
172 desc = "invalid field";
173 break;
174 case MPI2_IOCSTATUS_INVALID_STATE:
175 desc = "invalid state";
176 break;
177 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
178 desc = "op state not supported";
179 break;
180
181/****************************************************************************
182* Config IOCStatus values
183****************************************************************************/
184
185 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION:
186 desc = "config invalid action";
187 break;
188 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE:
189 desc = "config invalid type";
190 break;
191 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE:
192 desc = "config invalid page";
193 break;
194 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA:
195 desc = "config invalid data";
196 break;
197 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS:
198 desc = "config no defaults";
199 break;
200 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT:
201 desc = "config cant commit";
202 break;
203
204/****************************************************************************
205* SCSI IO Reply
206****************************************************************************/
207
208 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
209 case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
210 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
211 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
212 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
213 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
214 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
215 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
216 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
217 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
218 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
219 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
220 break;
221
222/****************************************************************************
223* For use by SCSI Initiator and SCSI Target end-to-end data protection
224****************************************************************************/
225
226 case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
227 desc = "eedp guard error";
228 break;
229 case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
230 desc = "eedp ref tag error";
231 break;
232 case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
233 desc = "eedp app tag error";
234 break;
235
236/****************************************************************************
237* SCSI Target values
238****************************************************************************/
239
240 case MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX:
241 desc = "target invalid io index";
242 break;
243 case MPI2_IOCSTATUS_TARGET_ABORTED:
244 desc = "target aborted";
245 break;
246 case MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE:
247 desc = "target no conn retryable";
248 break;
249 case MPI2_IOCSTATUS_TARGET_NO_CONNECTION:
250 desc = "target no connection";
251 break;
252 case MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH:
253 desc = "target xfer count mismatch";
254 break;
255 case MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR:
256 desc = "target data offset error";
257 break;
258 case MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA:
259 desc = "target too much write data";
260 break;
261 case MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT:
262 desc = "target iu too short";
263 break;
264 case MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT:
265 desc = "target ack nak timeout";
266 break;
267 case MPI2_IOCSTATUS_TARGET_NAK_RECEIVED:
268 desc = "target nak received";
269 break;
270
271/****************************************************************************
272* Serial Attached SCSI values
273****************************************************************************/
274
275 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
276 desc = "smp request failed";
277 break;
278 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
279 desc = "smp data overrun";
280 break;
281
282/****************************************************************************
283* Diagnostic Buffer Post / Diagnostic Release values
284****************************************************************************/
285
286 case MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED:
287 desc = "diagnostic released";
288 break;
289 default:
290 break;
291 }
292
293 if (!desc)
294 return;
295
296 switch (request_hdr->Function) {
297 case MPI2_FUNCTION_CONFIG:
298 frame_sz = sizeof(Mpi2ConfigRequest_t) + ioc->sge_size;
299 func_str = "config_page";
300 break;
301 case MPI2_FUNCTION_SCSI_TASK_MGMT:
302 frame_sz = sizeof(Mpi2SCSITaskManagementRequest_t);
303 func_str = "task_mgmt";
304 break;
305 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
306 frame_sz = sizeof(Mpi2SasIoUnitControlRequest_t);
307 func_str = "sas_iounit_ctl";
308 break;
309 case MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
310 frame_sz = sizeof(Mpi2SepRequest_t);
311 func_str = "enclosure";
312 break;
313 case MPI2_FUNCTION_IOC_INIT:
314 frame_sz = sizeof(Mpi2IOCInitRequest_t);
315 func_str = "ioc_init";
316 break;
317 case MPI2_FUNCTION_PORT_ENABLE:
318 frame_sz = sizeof(Mpi2PortEnableRequest_t);
319 func_str = "port_enable";
320 break;
321 case MPI2_FUNCTION_SMP_PASSTHROUGH:
322 frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size;
323 func_str = "smp_passthru";
324 break;
325 default:
326 frame_sz = 32;
327 func_str = "unknown";
328 break;
329 }
330
331 printk(MPT2SAS_WARN_FMT "ioc_status: %s(0x%04x), request(0x%p),"
332 " (%s)\n", ioc->name, desc, ioc_status, request_hdr, func_str);
333
334 _debug_dump_mf(request_hdr, frame_sz/4);
335}
336
337/**
338 * _base_display_event_data - verbose translation of firmware asyn events
339 * @ioc: pointer to scsi command object
340 * @mpi_reply: reply mf payload returned from firmware
341 *
342 * Return nothing.
343 */
344static void
345_base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
346 Mpi2EventNotificationReply_t *mpi_reply)
347{
348 char *desc = NULL;
349 u16 event;
350
351 if (!(ioc->logging_level & MPT_DEBUG_EVENTS))
352 return;
353
354 event = le16_to_cpu(mpi_reply->Event);
355
356 switch (event) {
357 case MPI2_EVENT_LOG_DATA:
358 desc = "Log Data";
359 break;
360 case MPI2_EVENT_STATE_CHANGE:
361 desc = "Status Change";
362 break;
363 case MPI2_EVENT_HARD_RESET_RECEIVED:
364 desc = "Hard Reset Received";
365 break;
366 case MPI2_EVENT_EVENT_CHANGE:
367 desc = "Event Change";
368 break;
369 case MPI2_EVENT_TASK_SET_FULL:
370 desc = "Task Set Full";
371 break;
372 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
373 desc = "Device Status Change";
374 break;
375 case MPI2_EVENT_IR_OPERATION_STATUS:
376 desc = "IR Operation Status";
377 break;
378 case MPI2_EVENT_SAS_DISCOVERY:
379 desc = "Discovery";
380 break;
381 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
382 desc = "SAS Broadcast Primitive";
383 break;
384 case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
385 desc = "SAS Init Device Status Change";
386 break;
387 case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW:
388 desc = "SAS Init Table Overflow";
389 break;
390 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
391 desc = "SAS Topology Change List";
392 break;
393 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
394 desc = "SAS Enclosure Device Status Change";
395 break;
396 case MPI2_EVENT_IR_VOLUME:
397 desc = "IR Volume";
398 break;
399 case MPI2_EVENT_IR_PHYSICAL_DISK:
400 desc = "IR Physical Disk";
401 break;
402 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
403 desc = "IR Configuration Change List";
404 break;
405 case MPI2_EVENT_LOG_ENTRY_ADDED:
406 desc = "Log Entry Added";
407 break;
408 }
409
410 if (!desc)
411 return;
412
413 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, desc);
414}
415#endif
416
417/**
418 * _base_sas_log_info - verbose translation of firmware log info
419 * @ioc: pointer to scsi command object
420 * @log_info: log info
421 *
422 * Return nothing.
423 */
424static void
425_base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
426{
427 union loginfo_type {
428 u32 loginfo;
429 struct {
430 u32 subcode:16;
431 u32 code:8;
432 u32 originator:4;
433 u32 bus_type:4;
434 } dw;
435 };
436 union loginfo_type sas_loginfo;
437 char *originator_str = NULL;
438
439 sas_loginfo.loginfo = log_info;
440 if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
441 return;
442
443 /* eat the loginfos associated with task aborts */
444 if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==
445 0x31140000 || log_info == 0x31130000))
446 return;
447
448 switch (sas_loginfo.dw.originator) {
449 case 0:
450 originator_str = "IOP";
451 break;
452 case 1:
453 originator_str = "PL";
454 break;
455 case 2:
456 originator_str = "IR";
457 break;
458 }
459
460 printk(MPT2SAS_WARN_FMT "log_info(0x%08x): originator(%s), "
461 "code(0x%02x), sub_code(0x%04x)\n", ioc->name, log_info,
462 originator_str, sas_loginfo.dw.code,
463 sas_loginfo.dw.subcode);
464}
465
466/**
467 * mpt2sas_base_fault_info - verbose translation of firmware FAULT code
468 * @ioc: pointer to scsi command object
469 * @fault_code: fault code
470 *
471 * Return nothing.
472 */
473void
474mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
475{
476 printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n",
477 ioc->name, fault_code);
478}
479
480/**
481 * _base_display_reply_info -
482 * @ioc: pointer to scsi command object
483 * @smid: system request message index
484 * @VF_ID: virtual function id
485 * @reply: reply message frame(lower 32bit addr)
486 *
487 * Return nothing.
488 */
489static void
490_base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
491 u32 reply)
492{
493 MPI2DefaultReply_t *mpi_reply;
494 u16 ioc_status;
495
496 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
497 ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
498#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
499 if ((ioc_status & MPI2_IOCSTATUS_MASK) &&
500 (ioc->logging_level & MPT_DEBUG_REPLY)) {
501 _base_sas_ioc_info(ioc , mpi_reply,
502 mpt2sas_base_get_msg_frame(ioc, smid));
503 }
504#endif
505 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
506 _base_sas_log_info(ioc, le32_to_cpu(mpi_reply->IOCLogInfo));
507}
508
509/**
510 * mpt2sas_base_done - base internal command completion routine
511 * @ioc: pointer to scsi command object
512 * @smid: system request message index
513 * @VF_ID: virtual function id
514 * @reply: reply message frame(lower 32bit addr)
515 *
516 * Return nothing.
517 */
518void
519mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
520{
521 MPI2DefaultReply_t *mpi_reply;
522
523 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
524 if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
525 return;
526
527 if (ioc->base_cmds.status == MPT2_CMD_NOT_USED)
528 return;
529
530 ioc->base_cmds.status |= MPT2_CMD_COMPLETE;
531 if (mpi_reply) {
532 ioc->base_cmds.status |= MPT2_CMD_REPLY_VALID;
533 memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
534 }
535 ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
536 complete(&ioc->base_cmds.done);
537}
538
539/**
540 * _base_async_event - main callback handler for firmware asyn events
541 * @ioc: pointer to scsi command object
542 * @VF_ID: virtual function id
543 * @reply: reply message frame(lower 32bit addr)
544 *
545 * Return nothing.
546 */
547static void
548_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
549{
550 Mpi2EventNotificationReply_t *mpi_reply;
551 Mpi2EventAckRequest_t *ack_request;
552 u16 smid;
553
554 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
555 if (!mpi_reply)
556 return;
557 if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
558 return;
559#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
560 _base_display_event_data(ioc, mpi_reply);
561#endif
562 if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED))
563 goto out;
564 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
565 if (!smid) {
566 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
567 ioc->name, __func__);
568 goto out;
569 }
570
571 ack_request = mpt2sas_base_get_msg_frame(ioc, smid);
572 memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t));
573 ack_request->Function = MPI2_FUNCTION_EVENT_ACK;
574 ack_request->Event = mpi_reply->Event;
575 ack_request->EventContext = mpi_reply->EventContext;
576 ack_request->VF_ID = VF_ID;
577 mpt2sas_base_put_smid_default(ioc, smid, VF_ID);
578
579 out:
580
581 /* scsih callback handler */
582 mpt2sas_scsih_event_callback(ioc, VF_ID, reply);
583
584 /* ctl callback handler */
585 mpt2sas_ctl_event_callback(ioc, VF_ID, reply);
586}
587
588/**
589 * _base_mask_interrupts - disable interrupts
590 * @ioc: pointer to scsi command object
591 *
592 * Disabling ResetIRQ, Reply and Doorbell Interrupts
593 *
594 * Return nothing.
595 */
596static void
597_base_mask_interrupts(struct MPT2SAS_ADAPTER *ioc)
598{
599 u32 him_register;
600
601 ioc->mask_interrupts = 1;
602 him_register = readl(&ioc->chip->HostInterruptMask);
603 him_register |= MPI2_HIM_DIM + MPI2_HIM_RIM + MPI2_HIM_RESET_IRQ_MASK;
604 writel(him_register, &ioc->chip->HostInterruptMask);
605 readl(&ioc->chip->HostInterruptMask);
606}
607
608/**
609 * _base_unmask_interrupts - enable interrupts
610 * @ioc: pointer to scsi command object
611 *
612 * Enabling only Reply Interrupts
613 *
614 * Return nothing.
615 */
616static void
617_base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc)
618{
619 u32 him_register;
620
621 writel(0, &ioc->chip->HostInterruptStatus);
622 him_register = readl(&ioc->chip->HostInterruptMask);
623 him_register &= ~MPI2_HIM_RIM;
624 writel(him_register, &ioc->chip->HostInterruptMask);
625 ioc->mask_interrupts = 0;
626}
627
628/**
629 * _base_interrupt - MPT adapter (IOC) specific interrupt handler.
630 * @irq: irq number (not used)
631 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
632 * @r: pt_regs pointer (not used)
633 *
634 * Return IRQ_HANDLE if processed, else IRQ_NONE.
635 */
636static irqreturn_t
637_base_interrupt(int irq, void *bus_id)
638{
639 u32 post_index, post_index_next, completed_cmds;
640 u8 request_desript_type;
641 u16 smid;
642 u8 cb_idx;
643 u32 reply;
644 u8 VF_ID;
645 int i;
646 struct MPT2SAS_ADAPTER *ioc = bus_id;
647
648 if (ioc->mask_interrupts)
649 return IRQ_NONE;
650
651 post_index = ioc->reply_post_host_index;
652 request_desript_type = ioc->reply_post_free[post_index].
653 Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
654 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
655 return IRQ_NONE;
656
657 completed_cmds = 0;
658 do {
659 if (ioc->reply_post_free[post_index].Words == ~0ULL)
660 goto out;
661 reply = 0;
662 cb_idx = 0xFF;
663 smid = le16_to_cpu(ioc->reply_post_free[post_index].
664 Default.DescriptorTypeDependent1);
665 VF_ID = ioc->reply_post_free[post_index].
666 Default.VF_ID;
667 if (request_desript_type ==
668 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
669 reply = le32_to_cpu(ioc->reply_post_free[post_index].
670 AddressReply.ReplyFrameAddress);
671 } else if (request_desript_type ==
672 MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
673 goto next;
674 else if (request_desript_type ==
675 MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS)
676 goto next;
677 if (smid)
678 cb_idx = ioc->scsi_lookup[smid - 1].cb_idx;
679 if (smid && cb_idx != 0xFF) {
680 mpt_callbacks[cb_idx](ioc, smid, VF_ID, reply);
681 if (reply)
682 _base_display_reply_info(ioc, smid, VF_ID,
683 reply);
684 mpt2sas_base_free_smid(ioc, smid);
685 }
686 if (!smid)
687 _base_async_event(ioc, VF_ID, reply);
688
689 /* reply free queue handling */
690 if (reply) {
691 ioc->reply_free_host_index =
692 (ioc->reply_free_host_index ==
693 (ioc->reply_free_queue_depth - 1)) ?
694 0 : ioc->reply_free_host_index + 1;
695 ioc->reply_free[ioc->reply_free_host_index] =
696 cpu_to_le32(reply);
697 writel(ioc->reply_free_host_index,
698 &ioc->chip->ReplyFreeHostIndex);
699 wmb();
700 }
701
702 next:
703 post_index_next = (post_index == (ioc->reply_post_queue_depth -
704 1)) ? 0 : post_index + 1;
705 request_desript_type =
706 ioc->reply_post_free[post_index_next].Default.ReplyFlags
707 & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
708 completed_cmds++;
709 if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
710 goto out;
711 post_index = post_index_next;
712 } while (1);
713
714 out:
715
716 if (!completed_cmds)
717 return IRQ_NONE;
718
719 /* reply post descriptor handling */
720 post_index_next = ioc->reply_post_host_index;
721 for (i = 0 ; i < completed_cmds; i++) {
722 post_index = post_index_next;
723 /* poison the reply post descriptor */
724 ioc->reply_post_free[post_index_next].Words = ~0ULL;
725 post_index_next = (post_index ==
726 (ioc->reply_post_queue_depth - 1))
727 ? 0 : post_index + 1;
728 }
729 ioc->reply_post_host_index = post_index_next;
730 writel(post_index_next, &ioc->chip->ReplyPostHostIndex);
731 wmb();
732 return IRQ_HANDLED;
733}
734
735/**
736 * mpt2sas_base_release_callback_handler - clear interupt callback handler
737 * @cb_idx: callback index
738 *
739 * Return nothing.
740 */
741void
742mpt2sas_base_release_callback_handler(u8 cb_idx)
743{
744 mpt_callbacks[cb_idx] = NULL;
745}
746
747/**
748 * mpt2sas_base_register_callback_handler - obtain index for the interrupt callback handler
749 * @cb_func: callback function
750 *
751 * Returns cb_func.
752 */
753u8
754mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func)
755{
756 u8 cb_idx;
757
758 for (cb_idx = MPT_MAX_CALLBACKS-1; cb_idx; cb_idx--)
759 if (mpt_callbacks[cb_idx] == NULL)
760 break;
761
762 mpt_callbacks[cb_idx] = cb_func;
763 return cb_idx;
764}
765
766/**
767 * mpt2sas_base_initialize_callback_handler - initialize the interrupt callback handler
768 *
769 * Return nothing.
770 */
771void
772mpt2sas_base_initialize_callback_handler(void)
773{
774 u8 cb_idx;
775
776 for (cb_idx = 0; cb_idx < MPT_MAX_CALLBACKS; cb_idx++)
777 mpt2sas_base_release_callback_handler(cb_idx);
778}
779
780/**
781 * mpt2sas_base_build_zero_len_sge - build zero length sg entry
782 * @ioc: per adapter object
783 * @paddr: virtual address for SGE
784 *
785 * Create a zero length scatter gather entry to insure the IOCs hardware has
786 * something to use if the target device goes brain dead and tries
787 * to send data even when none is asked for.
788 *
789 * Return nothing.
790 */
791void
792mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr)
793{
794 u32 flags_length = (u32)((MPI2_SGE_FLAGS_LAST_ELEMENT |
795 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST |
796 MPI2_SGE_FLAGS_SIMPLE_ELEMENT) <<
797 MPI2_SGE_FLAGS_SHIFT);
798 ioc->base_add_sg_single(paddr, flags_length, -1);
799}
800
801/**
802 * _base_add_sg_single_32 - Place a simple 32 bit SGE at address pAddr.
803 * @paddr: virtual address for SGE
804 * @flags_length: SGE flags and data transfer length
805 * @dma_addr: Physical address
806 *
807 * Return nothing.
808 */
809static void
810_base_add_sg_single_32(void *paddr, u32 flags_length, dma_addr_t dma_addr)
811{
812 Mpi2SGESimple32_t *sgel = paddr;
813
814 flags_length |= (MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
815 MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT;
816 sgel->FlagsLength = cpu_to_le32(flags_length);
817 sgel->Address = cpu_to_le32(dma_addr);
818}
819
820
821/**
822 * _base_add_sg_single_64 - Place a simple 64 bit SGE at address pAddr.
823 * @paddr: virtual address for SGE
824 * @flags_length: SGE flags and data transfer length
825 * @dma_addr: Physical address
826 *
827 * Return nothing.
828 */
829static void
830_base_add_sg_single_64(void *paddr, u32 flags_length, dma_addr_t dma_addr)
831{
832 Mpi2SGESimple64_t *sgel = paddr;
833
834 flags_length |= (MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
835 MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT;
836 sgel->FlagsLength = cpu_to_le32(flags_length);
837 sgel->Address = cpu_to_le64(dma_addr);
838}
839
840#define convert_to_kb(x) ((x) << (PAGE_SHIFT - 10))
841
842/**
843 * _base_config_dma_addressing - set dma addressing
844 * @ioc: per adapter object
845 * @pdev: PCI device struct
846 *
847 * Returns 0 for success, non-zero for failure.
848 */
849static int
850_base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
851{
852 struct sysinfo s;
853 char *desc = NULL;
854
855 if (sizeof(dma_addr_t) > 4) {
856 const uint64_t required_mask =
857 dma_get_required_mask(&pdev->dev);
858 if ((required_mask > DMA_32BIT_MASK) && !pci_set_dma_mask(pdev,
859 DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(pdev,
860 DMA_64BIT_MASK)) {
861 ioc->base_add_sg_single = &_base_add_sg_single_64;
862 ioc->sge_size = sizeof(Mpi2SGESimple64_t);
863 desc = "64";
864 goto out;
865 }
866 }
867
868 if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
869 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
870 ioc->base_add_sg_single = &_base_add_sg_single_32;
871 ioc->sge_size = sizeof(Mpi2SGESimple32_t);
872 desc = "32";
873 } else
874 return -ENODEV;
875
876 out:
877 si_meminfo(&s);
878 printk(MPT2SAS_INFO_FMT "%s BIT PCI BUS DMA ADDRESSING SUPPORTED, "
879 "total mem (%ld kB)\n", ioc->name, desc, convert_to_kb(s.totalram));
880
881 return 0;
882}
883
884/**
885 * _base_save_msix_table - backup msix vector table
886 * @ioc: per adapter object
887 *
888 * This address an errata where diag reset clears out the table
889 */
890static void
891_base_save_msix_table(struct MPT2SAS_ADAPTER *ioc)
892{
893 int i;
894
895 if (!ioc->msix_enable || ioc->msix_table_backup == NULL)
896 return;
897
898 for (i = 0; i < ioc->msix_vector_count; i++)
899 ioc->msix_table_backup[i] = ioc->msix_table[i];
900}
901
902/**
903 * _base_restore_msix_table - this restores the msix vector table
904 * @ioc: per adapter object
905 *
906 */
907static void
908_base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc)
909{
910 int i;
911
912 if (!ioc->msix_enable || ioc->msix_table_backup == NULL)
913 return;
914
915 for (i = 0; i < ioc->msix_vector_count; i++)
916 ioc->msix_table[i] = ioc->msix_table_backup[i];
917}
918
919/**
920 * _base_check_enable_msix - checks MSIX capabable.
921 * @ioc: per adapter object
922 *
923 * Check to see if card is capable of MSIX, and set number
924 * of avaliable msix vectors
925 */
926static int
927_base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc)
928{
929 int base;
930 u16 message_control;
931 u32 msix_table_offset;
932
933 base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
934 if (!base) {
935 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not "
936 "supported\n", ioc->name));
937 return -EINVAL;
938 }
939
940 /* get msix vector count */
941 pci_read_config_word(ioc->pdev, base + 2, &message_control);
942 ioc->msix_vector_count = (message_control & 0x3FF) + 1;
943
944 /* get msix table */
945 pci_read_config_dword(ioc->pdev, base + 4, &msix_table_offset);
946 msix_table_offset &= 0xFFFFFFF8;
947 ioc->msix_table = (u32 *)((void *)ioc->chip + msix_table_offset);
948
949 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, "
950 "vector_count(%d), table_offset(0x%08x), table(%p)\n", ioc->name,
951 ioc->msix_vector_count, msix_table_offset, ioc->msix_table));
952 return 0;
953}
954
955/**
956 * _base_disable_msix - disables msix
957 * @ioc: per adapter object
958 *
959 */
960static void
961_base_disable_msix(struct MPT2SAS_ADAPTER *ioc)
962{
963 if (ioc->msix_enable) {
964 pci_disable_msix(ioc->pdev);
965 kfree(ioc->msix_table_backup);
966 ioc->msix_table_backup = NULL;
967 ioc->msix_enable = 0;
968 }
969}
970
971/**
972 * _base_enable_msix - enables msix, failback to io_apic
973 * @ioc: per adapter object
974 *
975 */
976static int
977_base_enable_msix(struct MPT2SAS_ADAPTER *ioc)
978{
979 struct msix_entry entries;
980 int r;
981 u8 try_msix = 0;
982
983 if (msix_disable == -1 || msix_disable == 0)
984 try_msix = 1;
985
986 if (!try_msix)
987 goto try_ioapic;
988
989 if (_base_check_enable_msix(ioc) != 0)
990 goto try_ioapic;
991
992 ioc->msix_table_backup = kcalloc(ioc->msix_vector_count,
993 sizeof(u32), GFP_KERNEL);
994 if (!ioc->msix_table_backup) {
995 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for "
996 "msix_table_backup failed!!!\n", ioc->name));
997 goto try_ioapic;
998 }
999
1000 memset(&entries, 0, sizeof(struct msix_entry));
1001 r = pci_enable_msix(ioc->pdev, &entries, 1);
1002 if (r) {
1003 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "pci_enable_msix "
1004 "failed (r=%d) !!!\n", ioc->name, r));
1005 goto try_ioapic;
1006 }
1007
1008 r = request_irq(entries.vector, _base_interrupt, IRQF_SHARED,
1009 ioc->name, ioc);
1010 if (r) {
1011 dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "unable to allocate "
1012 "interrupt %d !!!\n", ioc->name, entries.vector));
1013 pci_disable_msix(ioc->pdev);
1014 goto try_ioapic;
1015 }
1016
1017 ioc->pci_irq = entries.vector;
1018 ioc->msix_enable = 1;
1019 return 0;
1020
1021/* failback to io_apic interrupt routing */
1022 try_ioapic:
1023
1024 r = request_irq(ioc->pdev->irq, _base_interrupt, IRQF_SHARED,
1025 ioc->name, ioc);
1026 if (r) {
1027 printk(MPT2SAS_ERR_FMT "unable to allocate interrupt %d!\n",
1028 ioc->name, ioc->pdev->irq);
1029 r = -EBUSY;
1030 goto out_fail;
1031 }
1032
1033 ioc->pci_irq = ioc->pdev->irq;
1034 return 0;
1035
1036 out_fail:
1037 return r;
1038}
1039
1040/**
1041 * mpt2sas_base_map_resources - map in controller resources (io/irq/memap)
1042 * @ioc: per adapter object
1043 *
1044 * Returns 0 for success, non-zero for failure.
1045 */
1046int
1047mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1048{
1049 struct pci_dev *pdev = ioc->pdev;
1050 u32 memap_sz;
1051 u32 pio_sz;
1052 int i, r = 0;
1053
1054 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n",
1055 ioc->name, __func__));
1056
1057 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1058 if (pci_enable_device_mem(pdev)) {
1059 printk(MPT2SAS_WARN_FMT "pci_enable_device_mem: "
1060 "failed\n", ioc->name);
1061 return -ENODEV;
1062 }
1063
1064
1065 if (pci_request_selected_regions(pdev, ioc->bars,
1066 MPT2SAS_DRIVER_NAME)) {
1067 printk(MPT2SAS_WARN_FMT "pci_request_selected_regions: "
1068 "failed\n", ioc->name);
1069 r = -ENODEV;
1070 goto out_fail;
1071 }
1072
1073 pci_set_master(pdev);
1074
1075 if (_base_config_dma_addressing(ioc, pdev) != 0) {
1076 printk(MPT2SAS_WARN_FMT "no suitable DMA mask for %s\n",
1077 ioc->name, pci_name(pdev));
1078 r = -ENODEV;
1079 goto out_fail;
1080 }
1081
1082 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) {
1083 if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) {
1084 if (pio_sz)
1085 continue;
1086 ioc->pio_chip = pci_resource_start(pdev, i);
1087 pio_sz = pci_resource_len(pdev, i);
1088 } else {
1089 if (memap_sz)
1090 continue;
1091 ioc->chip_phys = pci_resource_start(pdev, i);
1092 memap_sz = pci_resource_len(pdev, i);
1093 ioc->chip = ioremap(ioc->chip_phys, memap_sz);
1094 if (ioc->chip == NULL) {
1095 printk(MPT2SAS_ERR_FMT "unable to map adapter "
1096 "memory!\n", ioc->name);
1097 r = -EINVAL;
1098 goto out_fail;
1099 }
1100 }
1101 }
1102
1103 pci_set_drvdata(pdev, ioc->shost);
1104 _base_mask_interrupts(ioc);
1105 r = _base_enable_msix(ioc);
1106 if (r)
1107 goto out_fail;
1108
1109 printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n",
1110 ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" :
1111 "IO-APIC enabled"), ioc->pci_irq);
1112 printk(MPT2SAS_INFO_FMT "iomem(0x%lx), mapped(0x%p), size(%d)\n",
1113 ioc->name, ioc->chip_phys, ioc->chip, memap_sz);
1114 printk(MPT2SAS_INFO_FMT "ioport(0x%lx), size(%d)\n",
1115 ioc->name, ioc->pio_chip, pio_sz);
1116
1117 return 0;
1118
1119 out_fail:
1120 if (ioc->chip_phys)
1121 iounmap(ioc->chip);
1122 ioc->chip_phys = 0;
1123 ioc->pci_irq = -1;
1124 pci_release_selected_regions(ioc->pdev, ioc->bars);
1125 pci_disable_device(pdev);
1126 pci_set_drvdata(pdev, NULL);
1127 return r;
1128}
1129
1130/**
1131 * mpt2sas_base_get_msg_frame_dma - obtain request mf pointer phys addr
1132 * @ioc: per adapter object
1133 * @smid: system request message index(smid zero is invalid)
1134 *
1135 * Returns phys pointer to message frame.
1136 */
1137dma_addr_t
1138mpt2sas_base_get_msg_frame_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1139{
1140 return ioc->request_dma + (smid * ioc->request_sz);
1141}
1142
1143/**
1144 * mpt2sas_base_get_msg_frame - obtain request mf pointer
1145 * @ioc: per adapter object
1146 * @smid: system request message index(smid zero is invalid)
1147 *
1148 * Returns virt pointer to message frame.
1149 */
1150void *
1151mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1152{
1153 return (void *)(ioc->request + (smid * ioc->request_sz));
1154}
1155
1156/**
1157 * mpt2sas_base_get_sense_buffer - obtain a sense buffer assigned to a mf request
1158 * @ioc: per adapter object
1159 * @smid: system request message index
1160 *
1161 * Returns virt pointer to sense buffer.
1162 */
1163void *
1164mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1165{
1166 return (void *)(ioc->sense + ((smid - 1) * SCSI_SENSE_BUFFERSIZE));
1167}
1168
1169/**
1170 * mpt2sas_base_get_sense_buffer_dma - obtain a sense buffer assigned to a mf request
1171 * @ioc: per adapter object
1172 * @smid: system request message index
1173 *
1174 * Returns phys pointer to sense buffer.
1175 */
1176dma_addr_t
1177mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1178{
1179 return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE);
1180}
1181
1182/**
1183 * mpt2sas_base_get_reply_virt_addr - obtain reply frames virt address
1184 * @ioc: per adapter object
1185 * @phys_addr: lower 32 physical addr of the reply
1186 *
1187 * Converts 32bit lower physical addr into a virt address.
1188 */
1189void *
1190mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr)
1191{
1192 if (!phys_addr)
1193 return NULL;
1194 return ioc->reply + (phys_addr - (u32)ioc->reply_dma);
1195}
1196
1197/**
1198 * mpt2sas_base_get_smid - obtain a free smid
1199 * @ioc: per adapter object
1200 * @cb_idx: callback index
1201 *
1202 * Returns smid (zero is invalid)
1203 */
1204u16
1205mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
1206{
1207 unsigned long flags;
1208 struct request_tracker *request;
1209 u16 smid;
1210
1211 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1212 if (list_empty(&ioc->free_list)) {
1213 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1214 printk(MPT2SAS_ERR_FMT "%s: smid not available\n",
1215 ioc->name, __func__);
1216 return 0;
1217 }
1218
1219 request = list_entry(ioc->free_list.next,
1220 struct request_tracker, tracker_list);
1221 request->cb_idx = cb_idx;
1222 smid = request->smid;
1223 list_del(&request->tracker_list);
1224 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1225 return smid;
1226}
1227
1228
1229/**
1230 * mpt2sas_base_free_smid - put smid back on free_list
1231 * @ioc: per adapter object
1232 * @smid: system request message index
1233 *
1234 * Return nothing.
1235 */
1236void
1237mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1238{
1239 unsigned long flags;
1240
1241 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1242 ioc->scsi_lookup[smid - 1].cb_idx = 0xFF;
1243 list_add_tail(&ioc->scsi_lookup[smid - 1].tracker_list,
1244 &ioc->free_list);
1245 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1246
1247 /*
1248 * See _wait_for_commands_to_complete() call with regards to this code.
1249 */
1250 if (ioc->shost_recovery && ioc->pending_io_count) {
1251 if (ioc->pending_io_count == 1)
1252 wake_up(&ioc->reset_wq);
1253 ioc->pending_io_count--;
1254 }
1255}
1256
1257/**
1258 * _base_writeq - 64 bit write to MMIO
1259 * @ioc: per adapter object
1260 * @b: data payload
1261 * @addr: address in MMIO space
1262 * @writeq_lock: spin lock
1263 *
1264 * Glue for handling an atomic 64 bit word to MMIO. This special handling takes
1265 * care of 32 bit environment where its not quarenteed to send the entire word
1266 * in one transfer.
1267 */
1268#ifndef writeq
1269static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
1270 spinlock_t *writeq_lock)
1271{
1272 unsigned long flags;
1273 __u64 data_out = cpu_to_le64(b);
1274
1275 spin_lock_irqsave(writeq_lock, flags);
1276 writel((u32)(data_out), addr);
1277 writel((u32)(data_out >> 32), (addr + 4));
1278 spin_unlock_irqrestore(writeq_lock, flags);
1279}
1280#else
1281static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
1282 spinlock_t *writeq_lock)
1283{
1284 writeq(cpu_to_le64(b), addr);
1285}
1286#endif
1287
1288/**
1289 * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
1290 * @ioc: per adapter object
1291 * @smid: system request message index
1292 * @vf_id: virtual function id
1293 * @handle: device handle
1294 *
1295 * Return nothing.
1296 */
1297void
1298mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id,
1299 u16 handle)
1300{
1301 Mpi2RequestDescriptorUnion_t descriptor;
1302 u64 *request = (u64 *)&descriptor;
1303
1304
1305 descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
1306 descriptor.SCSIIO.VF_ID = vf_id;
1307 descriptor.SCSIIO.SMID = cpu_to_le16(smid);
1308 descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
1309 descriptor.SCSIIO.LMID = 0;
1310 _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
1311 &ioc->scsi_lookup_lock);
1312}
1313
1314
1315/**
1316 * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware
1317 * @ioc: per adapter object
1318 * @smid: system request message index
1319 * @vf_id: virtual function id
1320 *
1321 * Return nothing.
1322 */
1323void
1324mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1325 u8 vf_id)
1326{
1327 Mpi2RequestDescriptorUnion_t descriptor;
1328 u64 *request = (u64 *)&descriptor;
1329
1330 descriptor.HighPriority.RequestFlags =
1331 MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
1332 descriptor.HighPriority.VF_ID = vf_id;
1333 descriptor.HighPriority.SMID = cpu_to_le16(smid);
1334 descriptor.HighPriority.LMID = 0;
1335 descriptor.HighPriority.Reserved1 = 0;
1336 _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
1337 &ioc->scsi_lookup_lock);
1338}
1339
1340/**
1341 * mpt2sas_base_put_smid_default - Default, primarily used for config pages
1342 * @ioc: per adapter object
1343 * @smid: system request message index
1344 * @vf_id: virtual function id
1345 *
1346 * Return nothing.
1347 */
1348void
1349mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id)
1350{
1351 Mpi2RequestDescriptorUnion_t descriptor;
1352 u64 *request = (u64 *)&descriptor;
1353
1354 descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1355 descriptor.Default.VF_ID = vf_id;
1356 descriptor.Default.SMID = cpu_to_le16(smid);
1357 descriptor.Default.LMID = 0;
1358 descriptor.Default.DescriptorTypeDependent = 0;
1359 _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
1360 &ioc->scsi_lookup_lock);
1361}
1362
1363/**
1364 * mpt2sas_base_put_smid_target_assist - send Target Assist/Status to firmware
1365 * @ioc: per adapter object
1366 * @smid: system request message index
1367 * @vf_id: virtual function id
1368 * @io_index: value used to track the IO
1369 *
1370 * Return nothing.
1371 */
1372void
1373mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1374 u8 vf_id, u16 io_index)
1375{
1376 Mpi2RequestDescriptorUnion_t descriptor;
1377 u64 *request = (u64 *)&descriptor;
1378
1379 descriptor.SCSITarget.RequestFlags =
1380 MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET;
1381 descriptor.SCSITarget.VF_ID = vf_id;
1382 descriptor.SCSITarget.SMID = cpu_to_le16(smid);
1383 descriptor.SCSITarget.LMID = 0;
1384 descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index);
1385 _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow,
1386 &ioc->scsi_lookup_lock);
1387}
1388
1389/**
1390 * _base_display_ioc_capabilities - Disply IOC's capabilities.
1391 * @ioc: per adapter object
1392 *
1393 * Return nothing.
1394 */
1395static void
1396_base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
1397{
1398 int i = 0;
1399 char desc[16];
1400 u8 revision;
1401 u32 iounit_pg1_flags;
1402
1403 pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision);
1404 strncpy(desc, ioc->manu_pg0.ChipName, 16);
1405 printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), "
1406 "ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n",
1407 ioc->name, desc,
1408 (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
1409 (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
1410 (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
1411 ioc->facts.FWVersion.Word & 0x000000FF,
1412 revision,
1413 (ioc->bios_pg3.BiosVersion & 0xFF000000) >> 24,
1414 (ioc->bios_pg3.BiosVersion & 0x00FF0000) >> 16,
1415 (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8,
1416 ioc->bios_pg3.BiosVersion & 0x000000FF);
1417
1418 printk(MPT2SAS_INFO_FMT "Protocol=(", ioc->name);
1419
1420 if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
1421 printk("Initiator");
1422 i++;
1423 }
1424
1425 if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET) {
1426 printk("%sTarget", i ? "," : "");
1427 i++;
1428 }
1429
1430 i = 0;
1431 printk("), ");
1432 printk("Capabilities=(");
1433
1434 if (ioc->facts.IOCCapabilities &
1435 MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
1436 printk("Raid");
1437 i++;
1438 }
1439
1440 if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
1441 printk("%sTLR", i ? "," : "");
1442 i++;
1443 }
1444
1445 if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_MULTICAST) {
1446 printk("%sMulticast", i ? "," : "");
1447 i++;
1448 }
1449
1450 if (ioc->facts.IOCCapabilities &
1451 MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET) {
1452 printk("%sBIDI Target", i ? "," : "");
1453 i++;
1454 }
1455
1456 if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP) {
1457 printk("%sEEDP", i ? "," : "");
1458 i++;
1459 }
1460
1461 if (ioc->facts.IOCCapabilities &
1462 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) {
1463 printk("%sSnapshot Buffer", i ? "," : "");
1464 i++;
1465 }
1466
1467 if (ioc->facts.IOCCapabilities &
1468 MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) {
1469 printk("%sDiag Trace Buffer", i ? "," : "");
1470 i++;
1471 }
1472
1473 if (ioc->facts.IOCCapabilities &
1474 MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) {
1475 printk("%sTask Set Full", i ? "," : "");
1476 i++;
1477 }
1478
1479 iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags);
1480 if (!(iounit_pg1_flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE)) {
1481 printk("%sNCQ", i ? "," : "");
1482 i++;
1483 }
1484
1485 printk(")\n");
1486}
1487
1488/**
1489 * _base_static_config_pages - static start of day config pages
1490 * @ioc: per adapter object
1491 *
1492 * Return nothing.
1493 */
1494static void
1495_base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
1496{
1497 Mpi2ConfigReply_t mpi_reply;
1498 u32 iounit_pg1_flags;
1499
1500 mpt2sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
1501 mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
1502 mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
1503 mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8);
1504 mpt2sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0);
1505 mpt2sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
1506 _base_display_ioc_capabilities(ioc);
1507
1508 /*
1509 * Enable task_set_full handling in iounit_pg1 when the
1510 * facts capabilities indicate that its supported.
1511 */
1512 iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags);
1513 if ((ioc->facts.IOCCapabilities &
1514 MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING))
1515 iounit_pg1_flags &=
1516 ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
1517 else
1518 iounit_pg1_flags |=
1519 MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
1520 ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
1521 mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, ioc->iounit_pg1);
1522}
1523
1524/**
1525 * _base_release_memory_pools - release memory
1526 * @ioc: per adapter object
1527 *
1528 * Free memory allocated from _base_allocate_memory_pools.
1529 *
1530 * Return nothing.
1531 */
1532static void
1533_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1534{
1535 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1536 __func__));
1537
1538 if (ioc->request) {
1539 pci_free_consistent(ioc->pdev, ioc->request_dma_sz,
1540 ioc->request, ioc->request_dma);
1541 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "request_pool(0x%p)"
1542 ": free\n", ioc->name, ioc->request));
1543 ioc->request = NULL;
1544 }
1545
1546 if (ioc->sense) {
1547 pci_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
1548 if (ioc->sense_dma_pool)
1549 pci_pool_destroy(ioc->sense_dma_pool);
1550 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_pool(0x%p)"
1551 ": free\n", ioc->name, ioc->sense));
1552 ioc->sense = NULL;
1553 }
1554
1555 if (ioc->reply) {
1556 pci_pool_free(ioc->reply_dma_pool, ioc->reply, ioc->reply_dma);
1557 if (ioc->reply_dma_pool)
1558 pci_pool_destroy(ioc->reply_dma_pool);
1559 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_pool(0x%p)"
1560 ": free\n", ioc->name, ioc->reply));
1561 ioc->reply = NULL;
1562 }
1563
1564 if (ioc->reply_free) {
1565 pci_pool_free(ioc->reply_free_dma_pool, ioc->reply_free,
1566 ioc->reply_free_dma);
1567 if (ioc->reply_free_dma_pool)
1568 pci_pool_destroy(ioc->reply_free_dma_pool);
1569 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free_pool"
1570 "(0x%p): free\n", ioc->name, ioc->reply_free));
1571 ioc->reply_free = NULL;
1572 }
1573
1574 if (ioc->reply_post_free) {
1575 pci_pool_free(ioc->reply_post_free_dma_pool,
1576 ioc->reply_post_free, ioc->reply_post_free_dma);
1577 if (ioc->reply_post_free_dma_pool)
1578 pci_pool_destroy(ioc->reply_post_free_dma_pool);
1579 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT
1580 "reply_post_free_pool(0x%p): free\n", ioc->name,
1581 ioc->reply_post_free));
1582 ioc->reply_post_free = NULL;
1583 }
1584
1585 if (ioc->config_page) {
1586 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT
1587 "config_page(0x%p): free\n", ioc->name,
1588 ioc->config_page));
1589 pci_free_consistent(ioc->pdev, ioc->config_page_sz,
1590 ioc->config_page, ioc->config_page_dma);
1591 }
1592
1593 kfree(ioc->scsi_lookup);
1594}
1595
1596
1597/**
1598 * _base_allocate_memory_pools - allocate start of day memory pools
1599 * @ioc: per adapter object
1600 * @sleep_flag: CAN_SLEEP or NO_SLEEP
1601 *
1602 * Returns 0 success, anything else error
1603 */
1604static int
1605_base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1606{
1607 Mpi2IOCFactsReply_t *facts;
1608 u32 queue_size, queue_diff;
1609 u16 max_sge_elements;
1610 u16 num_of_reply_frames;
1611 u16 chains_needed_per_io;
1612 u32 sz, total_sz;
1613 u16 i;
1614 u32 retry_sz;
1615 u16 max_request_credit;
1616
1617 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1618 __func__));
1619
1620 retry_sz = 0;
1621 facts = &ioc->facts;
1622
1623 /* command line tunables for max sgl entries */
1624 if (max_sgl_entries != -1) {
1625 ioc->shost->sg_tablesize = (max_sgl_entries <
1626 MPT2SAS_SG_DEPTH) ? max_sgl_entries :
1627 MPT2SAS_SG_DEPTH;
1628 } else {
1629 ioc->shost->sg_tablesize = MPT2SAS_SG_DEPTH;
1630 }
1631
1632 /* command line tunables for max controller queue depth */
1633 if (max_queue_depth != -1) {
1634 max_request_credit = (max_queue_depth < facts->RequestCredit)
1635 ? max_queue_depth : facts->RequestCredit;
1636 } else {
1637 max_request_credit = (facts->RequestCredit >
1638 MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
1639 facts->RequestCredit;
1640 }
1641 ioc->request_depth = max_request_credit;
1642
1643 /* request frame size */
1644 ioc->request_sz = facts->IOCRequestFrameSize * 4;
1645
1646 /* reply frame size */
1647 ioc->reply_sz = facts->ReplyFrameSize * 4;
1648
1649 retry_allocation:
1650 total_sz = 0;
1651 /* calculate number of sg elements left over in the 1st frame */
1652 max_sge_elements = ioc->request_sz - ((sizeof(Mpi2SCSIIORequest_t) -
1653 sizeof(Mpi2SGEIOUnion_t)) + ioc->sge_size);
1654 ioc->max_sges_in_main_message = max_sge_elements/ioc->sge_size;
1655
1656 /* now do the same for a chain buffer */
1657 max_sge_elements = ioc->request_sz - ioc->sge_size;
1658 ioc->max_sges_in_chain_message = max_sge_elements/ioc->sge_size;
1659
1660 ioc->chain_offset_value_for_main_message =
1661 ((sizeof(Mpi2SCSIIORequest_t) - sizeof(Mpi2SGEIOUnion_t)) +
1662 (ioc->max_sges_in_chain_message * ioc->sge_size)) / 4;
1663
1664 /*
1665 * MPT2SAS_SG_DEPTH = CONFIG_FUSION_MAX_SGE
1666 */
1667 chains_needed_per_io = ((ioc->shost->sg_tablesize -
1668 ioc->max_sges_in_main_message)/ioc->max_sges_in_chain_message)
1669 + 1;
1670 if (chains_needed_per_io > facts->MaxChainDepth) {
1671 chains_needed_per_io = facts->MaxChainDepth;
1672 ioc->shost->sg_tablesize = min_t(u16,
1673 ioc->max_sges_in_main_message + (ioc->max_sges_in_chain_message
1674 * chains_needed_per_io), ioc->shost->sg_tablesize);
1675 }
1676 ioc->chains_needed_per_io = chains_needed_per_io;
1677
1678 /* reply free queue sizing - taking into account for events */
1679 num_of_reply_frames = ioc->request_depth + 32;
1680
1681 /* number of replies frames can't be a multiple of 16 */
1682 /* decrease number of reply frames by 1 */
1683 if (!(num_of_reply_frames % 16))
1684 num_of_reply_frames--;
1685
1686 /* calculate number of reply free queue entries
1687 * (must be multiple of 16)
1688 */
1689
1690 /* (we know reply_free_queue_depth is not a multiple of 16) */
1691 queue_size = num_of_reply_frames;
1692 queue_size += 16 - (queue_size % 16);
1693 ioc->reply_free_queue_depth = queue_size;
1694
1695 /* reply descriptor post queue sizing */
1696 /* this size should be the number of request frames + number of reply
1697 * frames
1698 */
1699
1700 queue_size = ioc->request_depth + num_of_reply_frames + 1;
1701 /* round up to 16 byte boundary */
1702 if (queue_size % 16)
1703 queue_size += 16 - (queue_size % 16);
1704
1705 /* check against IOC maximum reply post queue depth */
1706 if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) {
1707 queue_diff = queue_size -
1708 facts->MaxReplyDescriptorPostQueueDepth;
1709
1710 /* round queue_diff up to multiple of 16 */
1711 if (queue_diff % 16)
1712 queue_diff += 16 - (queue_diff % 16);
1713
1714 /* adjust request_depth, reply_free_queue_depth,
1715 * and queue_size
1716 */
1717 ioc->request_depth -= queue_diff;
1718 ioc->reply_free_queue_depth -= queue_diff;
1719 queue_size -= queue_diff;
1720 }
1721 ioc->reply_post_queue_depth = queue_size;
1722
1723 /* max scsi host queue depth */
1724 ioc->shost->can_queue = ioc->request_depth - INTERNAL_CMDS_COUNT;
1725 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host queue: depth"
1726 "(%d)\n", ioc->name, ioc->shost->can_queue));
1727
1728 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
1729 "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
1730 "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message,
1731 ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize,
1732 ioc->chains_needed_per_io));
1733
1734 /* contiguous pool for request and chains, 16 byte align, one extra "
1735 * "frame for smid=0
1736 */
1737 ioc->chain_depth = ioc->chains_needed_per_io * ioc->request_depth;
1738 sz = ((ioc->request_depth + 1 + ioc->chain_depth) * ioc->request_sz);
1739
1740 ioc->request_dma_sz = sz;
1741 ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma);
1742 if (!ioc->request) {
1743 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
1744 "failed: req_depth(%d), chains_per_io(%d), frame_sz(%d), "
1745 "total(%d kB)\n", ioc->name, ioc->request_depth,
1746 ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
1747 if (ioc->request_depth < MPT2SAS_SAS_QUEUE_DEPTH)
1748 goto out;
1749 retry_sz += 64;
1750 ioc->request_depth = max_request_credit - retry_sz;
1751 goto retry_allocation;
1752 }
1753
1754 if (retry_sz)
1755 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
1756 "succeed: req_depth(%d), chains_per_io(%d), frame_sz(%d), "
1757 "total(%d kb)\n", ioc->name, ioc->request_depth,
1758 ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
1759
1760 ioc->chain = ioc->request + ((ioc->request_depth + 1) *
1761 ioc->request_sz);
1762 ioc->chain_dma = ioc->request_dma + ((ioc->request_depth + 1) *
1763 ioc->request_sz);
1764 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
1765 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
1766 ioc->request, ioc->request_depth, ioc->request_sz,
1767 ((ioc->request_depth + 1) * ioc->request_sz)/1024));
1768 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
1769 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
1770 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
1771 ioc->request_sz))/1024));
1772 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
1773 ioc->name, (unsigned long long) ioc->request_dma));
1774 total_sz += sz;
1775
1776 ioc->scsi_lookup = kcalloc(ioc->request_depth,
1777 sizeof(struct request_tracker), GFP_KERNEL);
1778 if (!ioc->scsi_lookup) {
1779 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n",
1780 ioc->name);
1781 goto out;
1782 }
1783
1784 /* initialize some bits */
1785 for (i = 0; i < ioc->request_depth; i++)
1786 ioc->scsi_lookup[i].smid = i + 1;
1787
1788 /* sense buffers, 4 byte align */
1789 sz = ioc->request_depth * SCSI_SENSE_BUFFERSIZE;
1790 ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4,
1791 0);
1792 if (!ioc->sense_dma_pool) {
1793 printk(MPT2SAS_ERR_FMT "sense pool: pci_pool_create failed\n",
1794 ioc->name);
1795 goto out;
1796 }
1797 ioc->sense = pci_pool_alloc(ioc->sense_dma_pool , GFP_KERNEL,
1798 &ioc->sense_dma);
1799 if (!ioc->sense) {
1800 printk(MPT2SAS_ERR_FMT "sense pool: pci_pool_alloc failed\n",
1801 ioc->name);
1802 goto out;
1803 }
1804 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
1805 "sense pool(0x%p): depth(%d), element_size(%d), pool_size"
1806 "(%d kB)\n", ioc->name, ioc->sense, ioc->request_depth,
1807 SCSI_SENSE_BUFFERSIZE, sz/1024));
1808 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_dma(0x%llx)\n",
1809 ioc->name, (unsigned long long)ioc->sense_dma));
1810 total_sz += sz;
1811
1812 /* reply pool, 4 byte align */
1813 sz = ioc->reply_free_queue_depth * ioc->reply_sz;
1814 ioc->reply_dma_pool = pci_pool_create("reply pool", ioc->pdev, sz, 4,
1815 0);
1816 if (!ioc->reply_dma_pool) {
1817 printk(MPT2SAS_ERR_FMT "reply pool: pci_pool_create failed\n",
1818 ioc->name);
1819 goto out;
1820 }
1821 ioc->reply = pci_pool_alloc(ioc->reply_dma_pool , GFP_KERNEL,
1822 &ioc->reply_dma);
1823 if (!ioc->reply) {
1824 printk(MPT2SAS_ERR_FMT "reply pool: pci_pool_alloc failed\n",
1825 ioc->name);
1826 goto out;
1827 }
1828 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply pool(0x%p): depth"
1829 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->reply,
1830 ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024));
1831 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_dma(0x%llx)\n",
1832 ioc->name, (unsigned long long)ioc->reply_dma));
1833 total_sz += sz;
1834
1835 /* reply free queue, 16 byte align */
1836 sz = ioc->reply_free_queue_depth * 4;
1837 ioc->reply_free_dma_pool = pci_pool_create("reply_free pool",
1838 ioc->pdev, sz, 16, 0);
1839 if (!ioc->reply_free_dma_pool) {
1840 printk(MPT2SAS_ERR_FMT "reply_free pool: pci_pool_create "
1841 "failed\n", ioc->name);
1842 goto out;
1843 }
1844 ioc->reply_free = pci_pool_alloc(ioc->reply_free_dma_pool , GFP_KERNEL,
1845 &ioc->reply_free_dma);
1846 if (!ioc->reply_free) {
1847 printk(MPT2SAS_ERR_FMT "reply_free pool: pci_pool_alloc "
1848 "failed\n", ioc->name);
1849 goto out;
1850 }
1851 memset(ioc->reply_free, 0, sz);
1852 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free pool(0x%p): "
1853 "depth(%d), element_size(%d), pool_size(%d kB)\n", ioc->name,
1854 ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024));
1855 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_free_dma"
1856 "(0x%llx)\n", ioc->name, (unsigned long long)ioc->reply_free_dma));
1857 total_sz += sz;
1858
1859 /* reply post queue, 16 byte align */
1860 sz = ioc->reply_post_queue_depth * sizeof(Mpi2DefaultReplyDescriptor_t);
1861 ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool",
1862 ioc->pdev, sz, 16, 0);
1863 if (!ioc->reply_post_free_dma_pool) {
1864 printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_create "
1865 "failed\n", ioc->name);
1866 goto out;
1867 }
1868 ioc->reply_post_free = pci_pool_alloc(ioc->reply_post_free_dma_pool ,
1869 GFP_KERNEL, &ioc->reply_post_free_dma);
1870 if (!ioc->reply_post_free) {
1871 printk(MPT2SAS_ERR_FMT "reply_post_free pool: pci_pool_alloc "
1872 "failed\n", ioc->name);
1873 goto out;
1874 }
1875 memset(ioc->reply_post_free, 0, sz);
1876 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply post free pool"
1877 "(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n",
1878 ioc->name, ioc->reply_post_free, ioc->reply_post_queue_depth, 8,
1879 sz/1024));
1880 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "reply_post_free_dma = "
1881 "(0x%llx)\n", ioc->name, (unsigned long long)
1882 ioc->reply_post_free_dma));
1883 total_sz += sz;
1884
1885 ioc->config_page_sz = 512;
1886 ioc->config_page = pci_alloc_consistent(ioc->pdev,
1887 ioc->config_page_sz, &ioc->config_page_dma);
1888 if (!ioc->config_page) {
1889 printk(MPT2SAS_ERR_FMT "config page: pci_pool_alloc "
1890 "failed\n", ioc->name);
1891 goto out;
1892 }
1893 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "config page(0x%p): size"
1894 "(%d)\n", ioc->name, ioc->config_page, ioc->config_page_sz));
1895 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "config_page_dma"
1896 "(0x%llx)\n", ioc->name, (unsigned long long)ioc->config_page_dma));
1897 total_sz += ioc->config_page_sz;
1898
1899 printk(MPT2SAS_INFO_FMT "Allocated physical memory: size(%d kB)\n",
1900 ioc->name, total_sz/1024);
1901 printk(MPT2SAS_INFO_FMT "Current Controller Queue Depth(%d), "
1902 "Max Controller Queue Depth(%d)\n",
1903 ioc->name, ioc->shost->can_queue, facts->RequestCredit);
1904 printk(MPT2SAS_INFO_FMT "Scatter Gather Elements per IO(%d)\n",
1905 ioc->name, ioc->shost->sg_tablesize);
1906 return 0;
1907
1908 out:
1909 _base_release_memory_pools(ioc);
1910 return -ENOMEM;
1911}
1912
1913
1914/**
1915 * mpt2sas_base_get_iocstate - Get the current state of a MPT adapter.
1916 * @ioc: Pointer to MPT_ADAPTER structure
1917 * @cooked: Request raw or cooked IOC state
1918 *
1919 * Returns all IOC Doorbell register bits if cooked==0, else just the
1920 * Doorbell bits in MPI_IOC_STATE_MASK.
1921 */
1922u32
1923mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked)
1924{
1925 u32 s, sc;
1926
1927 s = readl(&ioc->chip->Doorbell);
1928 sc = s & MPI2_IOC_STATE_MASK;
1929 return cooked ? sc : s;
1930}
1931
1932/**
1933 * _base_wait_on_iocstate - waiting on a particular ioc state
1934 * @ioc_state: controller state { READY, OPERATIONAL, or RESET }
1935 * @timeout: timeout in second
1936 * @sleep_flag: CAN_SLEEP or NO_SLEEP
1937 *
1938 * Returns 0 for success, non-zero for failure.
1939 */
1940static int
1941_base_wait_on_iocstate(struct MPT2SAS_ADAPTER *ioc, u32 ioc_state, int timeout,
1942 int sleep_flag)
1943{
1944 u32 count, cntdn;
1945 u32 current_state;
1946
1947 count = 0;
1948 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
1949 do {
1950 current_state = mpt2sas_base_get_iocstate(ioc, 1);
1951 if (current_state == ioc_state)
1952 return 0;
1953 if (count && current_state == MPI2_IOC_STATE_FAULT)
1954 break;
1955 if (sleep_flag == CAN_SLEEP)
1956 msleep(1);
1957 else
1958 udelay(500);
1959 count++;
1960 } while (--cntdn);
1961
1962 return current_state;
1963}
1964
1965/**
1966 * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by
1967 * a write to the doorbell)
1968 * @ioc: per adapter object
1969 * @timeout: timeout in second
1970 * @sleep_flag: CAN_SLEEP or NO_SLEEP
1971 *
1972 * Returns 0 for success, non-zero for failure.
1973 *
1974 * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell.
1975 */
1976static int
1977_base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout,
1978 int sleep_flag)
1979{
1980 u32 cntdn, count;
1981 u32 int_status;
1982
1983 count = 0;
1984 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
1985 do {
1986 int_status = readl(&ioc->chip->HostInterruptStatus);
1987 if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
1988 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
1989 "successfull count(%d), timeout(%d)\n", ioc->name,
1990 __func__, count, timeout));
1991 return 0;
1992 }
1993 if (sleep_flag == CAN_SLEEP)
1994 msleep(1);
1995 else
1996 udelay(500);
1997 count++;
1998 } while (--cntdn);
1999
2000 printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
2001 "int_status(%x)!\n", ioc->name, __func__, count, int_status);
2002 return -EFAULT;
2003}
2004
2005/**
2006 * _base_wait_for_doorbell_ack - waiting for controller to read the doorbell.
2007 * @ioc: per adapter object
2008 * @timeout: timeout in second
2009 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2010 *
2011 * Returns 0 for success, non-zero for failure.
2012 *
2013 * Notes: MPI2_HIS_SYS2IOC_DB_STATUS - set to one when host writes to
2014 * doorbell.
2015 */
2016static int
2017_base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout,
2018 int sleep_flag)
2019{
2020 u32 cntdn, count;
2021 u32 int_status;
2022 u32 doorbell;
2023
2024 count = 0;
2025 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
2026 do {
2027 int_status = readl(&ioc->chip->HostInterruptStatus);
2028 if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) {
2029 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
2030 "successfull count(%d), timeout(%d)\n", ioc->name,
2031 __func__, count, timeout));
2032 return 0;
2033 } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) {
2034 doorbell = readl(&ioc->chip->Doorbell);
2035 if ((doorbell & MPI2_IOC_STATE_MASK) ==
2036 MPI2_IOC_STATE_FAULT) {
2037 mpt2sas_base_fault_info(ioc , doorbell);
2038 return -EFAULT;
2039 }
2040 } else if (int_status == 0xFFFFFFFF)
2041 goto out;
2042
2043 if (sleep_flag == CAN_SLEEP)
2044 msleep(1);
2045 else
2046 udelay(500);
2047 count++;
2048 } while (--cntdn);
2049
2050 out:
2051 printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
2052 "int_status(%x)!\n", ioc->name, __func__, count, int_status);
2053 return -EFAULT;
2054}
2055
2056/**
2057 * _base_wait_for_doorbell_not_used - waiting for doorbell to not be in use
2058 * @ioc: per adapter object
2059 * @timeout: timeout in second
2060 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2061 *
2062 * Returns 0 for success, non-zero for failure.
2063 *
2064 */
2065static int
2066_base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout,
2067 int sleep_flag)
2068{
2069 u32 cntdn, count;
2070 u32 doorbell_reg;
2071
2072 count = 0;
2073 cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout;
2074 do {
2075 doorbell_reg = readl(&ioc->chip->Doorbell);
2076 if (!(doorbell_reg & MPI2_DOORBELL_USED)) {
2077 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
2078 "successfull count(%d), timeout(%d)\n", ioc->name,
2079 __func__, count, timeout));
2080 return 0;
2081 }
2082 if (sleep_flag == CAN_SLEEP)
2083 msleep(1);
2084 else
2085 udelay(500);
2086 count++;
2087 } while (--cntdn);
2088
2089 printk(MPT2SAS_ERR_FMT "%s: failed due to timeout count(%d), "
2090 "doorbell_reg(%x)!\n", ioc->name, __func__, count, doorbell_reg);
2091 return -EFAULT;
2092}
2093
2094/**
2095 * _base_send_ioc_reset - send doorbell reset
2096 * @ioc: per adapter object
2097 * @reset_type: currently only supports: MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET
2098 * @timeout: timeout in second
2099 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2100 *
2101 * Returns 0 for success, non-zero for failure.
2102 */
2103static int
2104_base_send_ioc_reset(struct MPT2SAS_ADAPTER *ioc, u8 reset_type, int timeout,
2105 int sleep_flag)
2106{
2107 u32 ioc_state;
2108 int r = 0;
2109
2110 if (reset_type != MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET) {
2111 printk(MPT2SAS_ERR_FMT "%s: unknown reset_type\n",
2112 ioc->name, __func__);
2113 return -EFAULT;
2114 }
2115
2116 if (!(ioc->facts.IOCCapabilities &
2117 MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY))
2118 return -EFAULT;
2119
2120 printk(MPT2SAS_INFO_FMT "sending message unit reset !!\n", ioc->name);
2121
2122 writel(reset_type << MPI2_DOORBELL_FUNCTION_SHIFT,
2123 &ioc->chip->Doorbell);
2124 if ((_base_wait_for_doorbell_ack(ioc, 15, sleep_flag))) {
2125 r = -EFAULT;
2126 goto out;
2127 }
2128 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY,
2129 timeout, sleep_flag);
2130 if (ioc_state) {
2131 printk(MPT2SAS_ERR_FMT "%s: failed going to ready state "
2132 " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
2133 r = -EFAULT;
2134 goto out;
2135 }
2136 out:
2137 printk(MPT2SAS_INFO_FMT "message unit reset: %s\n",
2138 ioc->name, ((r == 0) ? "SUCCESS" : "FAILED"));
2139 return r;
2140}
2141
2142/**
2143 * _base_handshake_req_reply_wait - send request thru doorbell interface
2144 * @ioc: per adapter object
2145 * @request_bytes: request length
2146 * @request: pointer having request payload
2147 * @reply_bytes: reply length
2148 * @reply: pointer to reply payload
2149 * @timeout: timeout in second
2150 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2151 *
2152 * Returns 0 for success, non-zero for failure.
2153 */
2154static int
2155_base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes,
2156 u32 *request, int reply_bytes, u16 *reply, int timeout, int sleep_flag)
2157{
2158 MPI2DefaultReply_t *default_reply = (MPI2DefaultReply_t *)reply;
2159 int i;
2160 u8 failed;
2161 u16 dummy;
2162 u32 *mfp;
2163
2164 /* make sure doorbell is not in use */
2165 if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) {
2166 printk(MPT2SAS_ERR_FMT "doorbell is in use "
2167 " (line=%d)\n", ioc->name, __LINE__);
2168 return -EFAULT;
2169 }
2170
2171 /* clear pending doorbell interrupts from previous state changes */
2172 if (readl(&ioc->chip->HostInterruptStatus) &
2173 MPI2_HIS_IOC2SYS_DB_STATUS)
2174 writel(0, &ioc->chip->HostInterruptStatus);
2175
2176 /* send message to ioc */
2177 writel(((MPI2_FUNCTION_HANDSHAKE<<MPI2_DOORBELL_FUNCTION_SHIFT) |
2178 ((request_bytes/4)<<MPI2_DOORBELL_ADD_DWORDS_SHIFT)),
2179 &ioc->chip->Doorbell);
2180
2181 if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) {
2182 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2183 "int failed (line=%d)\n", ioc->name, __LINE__);
2184 return -EFAULT;
2185 }
2186 writel(0, &ioc->chip->HostInterruptStatus);
2187
2188 if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) {
2189 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2190 "ack failed (line=%d)\n", ioc->name, __LINE__);
2191 return -EFAULT;
2192 }
2193
2194 /* send message 32-bits at a time */
2195 for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) {
2196 writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell);
2197 if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag)))
2198 failed = 1;
2199 }
2200
2201 if (failed) {
2202 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2203 "sending request failed (line=%d)\n", ioc->name, __LINE__);
2204 return -EFAULT;
2205 }
2206
2207 /* now wait for the reply */
2208 if ((_base_wait_for_doorbell_int(ioc, timeout, sleep_flag))) {
2209 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2210 "int failed (line=%d)\n", ioc->name, __LINE__);
2211 return -EFAULT;
2212 }
2213
2214 /* read the first two 16-bits, it gives the total length of the reply */
2215 reply[0] = le16_to_cpu(readl(&ioc->chip->Doorbell)
2216 & MPI2_DOORBELL_DATA_MASK);
2217 writel(0, &ioc->chip->HostInterruptStatus);
2218 if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) {
2219 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2220 "int failed (line=%d)\n", ioc->name, __LINE__);
2221 return -EFAULT;
2222 }
2223 reply[1] = le16_to_cpu(readl(&ioc->chip->Doorbell)
2224 & MPI2_DOORBELL_DATA_MASK);
2225 writel(0, &ioc->chip->HostInterruptStatus);
2226
2227 for (i = 2; i < default_reply->MsgLength * 2; i++) {
2228 if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) {
2229 printk(MPT2SAS_ERR_FMT "doorbell "
2230 "handshake int failed (line=%d)\n", ioc->name,
2231 __LINE__);
2232 return -EFAULT;
2233 }
2234 if (i >= reply_bytes/2) /* overflow case */
2235 dummy = readl(&ioc->chip->Doorbell);
2236 else
2237 reply[i] = le16_to_cpu(readl(&ioc->chip->Doorbell)
2238 & MPI2_DOORBELL_DATA_MASK);
2239 writel(0, &ioc->chip->HostInterruptStatus);
2240 }
2241
2242 _base_wait_for_doorbell_int(ioc, 5, sleep_flag);
2243 if (_base_wait_for_doorbell_not_used(ioc, 5, sleep_flag) != 0) {
2244 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "doorbell is in use "
2245 " (line=%d)\n", ioc->name, __LINE__));
2246 }
2247 writel(0, &ioc->chip->HostInterruptStatus);
2248
2249 if (ioc->logging_level & MPT_DEBUG_INIT) {
2250 mfp = (u32 *)reply;
2251 printk(KERN_DEBUG "\toffset:data\n");
2252 for (i = 0; i < reply_bytes/4; i++)
2253 printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4,
2254 le32_to_cpu(mfp[i]));
2255 }
2256 return 0;
2257}
2258
2259/**
2260 * mpt2sas_base_sas_iounit_control - send sas iounit control to FW
2261 * @ioc: per adapter object
2262 * @mpi_reply: the reply payload from FW
2263 * @mpi_request: the request payload sent to FW
2264 *
2265 * The SAS IO Unit Control Request message allows the host to perform low-level
2266 * operations, such as resets on the PHYs of the IO Unit, also allows the host
2267 * to obtain the IOC assigned device handles for a device if it has other
2268 * identifying information about the device, in addition allows the host to
2269 * remove IOC resources associated with the device.
2270 *
2271 * Returns 0 for success, non-zero for failure.
2272 */
2273int
2274mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
2275 Mpi2SasIoUnitControlReply_t *mpi_reply,
2276 Mpi2SasIoUnitControlRequest_t *mpi_request)
2277{
2278 u16 smid;
2279 u32 ioc_state;
2280 unsigned long timeleft;
2281 u8 issue_reset;
2282 int rc;
2283 void *request;
2284 u16 wait_state_count;
2285
2286 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2287 __func__));
2288
2289 mutex_lock(&ioc->base_cmds.mutex);
2290
2291 if (ioc->base_cmds.status != MPT2_CMD_NOT_USED) {
2292 printk(MPT2SAS_ERR_FMT "%s: base_cmd in use\n",
2293 ioc->name, __func__);
2294 rc = -EAGAIN;
2295 goto out;
2296 }
2297
2298 wait_state_count = 0;
2299 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2300 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
2301 if (wait_state_count++ == 10) {
2302 printk(MPT2SAS_ERR_FMT
2303 "%s: failed due to ioc not operational\n",
2304 ioc->name, __func__);
2305 rc = -EFAULT;
2306 goto out;
2307 }
2308 ssleep(1);
2309 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2310 printk(MPT2SAS_INFO_FMT "%s: waiting for "
2311 "operational state(count=%d)\n", ioc->name,
2312 __func__, wait_state_count);
2313 }
2314
2315 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
2316 if (!smid) {
2317 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2318 ioc->name, __func__);
2319 rc = -EAGAIN;
2320 goto out;
2321 }
2322
2323 rc = 0;
2324 ioc->base_cmds.status = MPT2_CMD_PENDING;
2325 request = mpt2sas_base_get_msg_frame(ioc, smid);
2326 ioc->base_cmds.smid = smid;
2327 memcpy(request, mpi_request, sizeof(Mpi2SasIoUnitControlRequest_t));
2328 if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
2329 mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET)
2330 ioc->ioc_link_reset_in_progress = 1;
2331 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
2332 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2333 msecs_to_jiffies(10000));
2334 if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
2335 mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) &&
2336 ioc->ioc_link_reset_in_progress)
2337 ioc->ioc_link_reset_in_progress = 0;
2338 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
2339 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2340 ioc->name, __func__);
2341 _debug_dump_mf(mpi_request,
2342 sizeof(Mpi2SasIoUnitControlRequest_t)/4);
2343 if (!(ioc->base_cmds.status & MPT2_CMD_RESET))
2344 issue_reset = 1;
2345 goto issue_host_reset;
2346 }
2347 if (ioc->base_cmds.status & MPT2_CMD_REPLY_VALID)
2348 memcpy(mpi_reply, ioc->base_cmds.reply,
2349 sizeof(Mpi2SasIoUnitControlReply_t));
2350 else
2351 memset(mpi_reply, 0, sizeof(Mpi2SasIoUnitControlReply_t));
2352 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2353 goto out;
2354
2355 issue_host_reset:
2356 if (issue_reset)
2357 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2358 FORCE_BIG_HAMMER);
2359 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2360 rc = -EFAULT;
2361 out:
2362 mutex_unlock(&ioc->base_cmds.mutex);
2363 return rc;
2364}
2365
2366
2367/**
2368 * mpt2sas_base_scsi_enclosure_processor - sending request to sep device
2369 * @ioc: per adapter object
2370 * @mpi_reply: the reply payload from FW
2371 * @mpi_request: the request payload sent to FW
2372 *
2373 * The SCSI Enclosure Processor request message causes the IOC to
2374 * communicate with SES devices to control LED status signals.
2375 *
2376 * Returns 0 for success, non-zero for failure.
2377 */
2378int
2379mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
2380 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request)
2381{
2382 u16 smid;
2383 u32 ioc_state;
2384 unsigned long timeleft;
2385 u8 issue_reset;
2386 int rc;
2387 void *request;
2388 u16 wait_state_count;
2389
2390 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2391 __func__));
2392
2393 mutex_lock(&ioc->base_cmds.mutex);
2394
2395 if (ioc->base_cmds.status != MPT2_CMD_NOT_USED) {
2396 printk(MPT2SAS_ERR_FMT "%s: base_cmd in use\n",
2397 ioc->name, __func__);
2398 rc = -EAGAIN;
2399 goto out;
2400 }
2401
2402 wait_state_count = 0;
2403 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2404 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
2405 if (wait_state_count++ == 10) {
2406 printk(MPT2SAS_ERR_FMT
2407 "%s: failed due to ioc not operational\n",
2408 ioc->name, __func__);
2409 rc = -EFAULT;
2410 goto out;
2411 }
2412 ssleep(1);
2413 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2414 printk(MPT2SAS_INFO_FMT "%s: waiting for "
2415 "operational state(count=%d)\n", ioc->name,
2416 __func__, wait_state_count);
2417 }
2418
2419 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
2420 if (!smid) {
2421 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2422 ioc->name, __func__);
2423 rc = -EAGAIN;
2424 goto out;
2425 }
2426
2427 rc = 0;
2428 ioc->base_cmds.status = MPT2_CMD_PENDING;
2429 request = mpt2sas_base_get_msg_frame(ioc, smid);
2430 ioc->base_cmds.smid = smid;
2431 memcpy(request, mpi_request, sizeof(Mpi2SepReply_t));
2432 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
2433 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2434 msecs_to_jiffies(10000));
2435 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
2436 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2437 ioc->name, __func__);
2438 _debug_dump_mf(mpi_request,
2439 sizeof(Mpi2SepRequest_t)/4);
2440 if (!(ioc->base_cmds.status & MPT2_CMD_RESET))
2441 issue_reset = 1;
2442 goto issue_host_reset;
2443 }
2444 if (ioc->base_cmds.status & MPT2_CMD_REPLY_VALID)
2445 memcpy(mpi_reply, ioc->base_cmds.reply,
2446 sizeof(Mpi2SepReply_t));
2447 else
2448 memset(mpi_reply, 0, sizeof(Mpi2SepReply_t));
2449 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2450 goto out;
2451
2452 issue_host_reset:
2453 if (issue_reset)
2454 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2455 FORCE_BIG_HAMMER);
2456 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2457 rc = -EFAULT;
2458 out:
2459 mutex_unlock(&ioc->base_cmds.mutex);
2460 return rc;
2461}
2462
2463/**
2464 * _base_get_port_facts - obtain port facts reply and save in ioc
2465 * @ioc: per adapter object
2466 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2467 *
2468 * Returns 0 for success, non-zero for failure.
2469 */
2470static int
2471_base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
2472{
2473 Mpi2PortFactsRequest_t mpi_request;
2474 Mpi2PortFactsReply_t mpi_reply, *pfacts;
2475 int mpi_reply_sz, mpi_request_sz, r;
2476
2477 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2478 __func__));
2479
2480 mpi_reply_sz = sizeof(Mpi2PortFactsReply_t);
2481 mpi_request_sz = sizeof(Mpi2PortFactsRequest_t);
2482 memset(&mpi_request, 0, mpi_request_sz);
2483 mpi_request.Function = MPI2_FUNCTION_PORT_FACTS;
2484 mpi_request.PortNumber = port;
2485 r = _base_handshake_req_reply_wait(ioc, mpi_request_sz,
2486 (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP);
2487
2488 if (r != 0) {
2489 printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
2490 ioc->name, __func__, r);
2491 return r;
2492 }
2493
2494 pfacts = &ioc->pfacts[port];
2495 memset(pfacts, 0, sizeof(Mpi2PortFactsReply_t));
2496 pfacts->PortNumber = mpi_reply.PortNumber;
2497 pfacts->VP_ID = mpi_reply.VP_ID;
2498 pfacts->VF_ID = mpi_reply.VF_ID;
2499 pfacts->MaxPostedCmdBuffers =
2500 le16_to_cpu(mpi_reply.MaxPostedCmdBuffers);
2501
2502 return 0;
2503}
2504
2505/**
2506 * _base_get_ioc_facts - obtain ioc facts reply and save in ioc
2507 * @ioc: per adapter object
2508 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2509 *
2510 * Returns 0 for success, non-zero for failure.
2511 */
2512static int
2513_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2514{
2515 Mpi2IOCFactsRequest_t mpi_request;
2516 Mpi2IOCFactsReply_t mpi_reply, *facts;
2517 int mpi_reply_sz, mpi_request_sz, r;
2518
2519 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2520 __func__));
2521
2522 mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
2523 mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t);
2524 memset(&mpi_request, 0, mpi_request_sz);
2525 mpi_request.Function = MPI2_FUNCTION_IOC_FACTS;
2526 r = _base_handshake_req_reply_wait(ioc, mpi_request_sz,
2527 (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP);
2528
2529 if (r != 0) {
2530 printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
2531 ioc->name, __func__, r);
2532 return r;
2533 }
2534
2535 facts = &ioc->facts;
2536 memset(facts, 0, sizeof(Mpi2IOCFactsReply_t));
2537 facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion);
2538 facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion);
2539 facts->VP_ID = mpi_reply.VP_ID;
2540 facts->VF_ID = mpi_reply.VF_ID;
2541 facts->IOCExceptions = le16_to_cpu(mpi_reply.IOCExceptions);
2542 facts->MaxChainDepth = mpi_reply.MaxChainDepth;
2543 facts->WhoInit = mpi_reply.WhoInit;
2544 facts->NumberOfPorts = mpi_reply.NumberOfPorts;
2545 facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit);
2546 facts->MaxReplyDescriptorPostQueueDepth =
2547 le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth);
2548 facts->ProductID = le16_to_cpu(mpi_reply.ProductID);
2549 facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities);
2550 if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
2551 ioc->ir_firmware = 1;
2552 facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word);
2553 facts->IOCRequestFrameSize =
2554 le16_to_cpu(mpi_reply.IOCRequestFrameSize);
2555 facts->MaxInitiators = le16_to_cpu(mpi_reply.MaxInitiators);
2556 facts->MaxTargets = le16_to_cpu(mpi_reply.MaxTargets);
2557 ioc->shost->max_id = -1;
2558 facts->MaxSasExpanders = le16_to_cpu(mpi_reply.MaxSasExpanders);
2559 facts->MaxEnclosures = le16_to_cpu(mpi_reply.MaxEnclosures);
2560 facts->ProtocolFlags = le16_to_cpu(mpi_reply.ProtocolFlags);
2561 facts->HighPriorityCredit =
2562 le16_to_cpu(mpi_reply.HighPriorityCredit);
2563 facts->ReplyFrameSize = mpi_reply.ReplyFrameSize;
2564 facts->MaxDevHandle = le16_to_cpu(mpi_reply.MaxDevHandle);
2565
2566 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "hba queue depth(%d), "
2567 "max chains per io(%d)\n", ioc->name, facts->RequestCredit,
2568 facts->MaxChainDepth));
2569 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request frame size(%d), "
2570 "reply frame size(%d)\n", ioc->name,
2571 facts->IOCRequestFrameSize * 4, facts->ReplyFrameSize * 4));
2572 return 0;
2573}
2574
2575/**
2576 * _base_send_ioc_init - send ioc_init to firmware
2577 * @ioc: per adapter object
2578 * @VF_ID: virtual function id
2579 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2580 *
2581 * Returns 0 for success, non-zero for failure.
2582 */
2583static int
2584_base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2585{
2586 Mpi2IOCInitRequest_t mpi_request;
2587 Mpi2IOCInitReply_t mpi_reply;
2588 int r;
2589
2590 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2591 __func__));
2592
2593 memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t));
2594 mpi_request.Function = MPI2_FUNCTION_IOC_INIT;
2595 mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER;
2596 mpi_request.VF_ID = VF_ID;
2597 mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION);
2598 mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
2599
2600 /* In MPI Revision I (0xA), the SystemReplyFrameSize(offset 0x18) was
2601 * removed and made reserved. For those with older firmware will need
2602 * this fix. It was decided that the Reply and Request frame sizes are
2603 * the same.
2604 */
2605 if ((ioc->facts.HeaderVersion >> 8) < 0xA) {
2606 mpi_request.Reserved7 = cpu_to_le16(ioc->reply_sz);
2607/* mpi_request.SystemReplyFrameSize =
2608 * cpu_to_le16(ioc->reply_sz);
2609 */
2610 }
2611
2612 mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4);
2613 mpi_request.ReplyDescriptorPostQueueDepth =
2614 cpu_to_le16(ioc->reply_post_queue_depth);
2615 mpi_request.ReplyFreeQueueDepth =
2616 cpu_to_le16(ioc->reply_free_queue_depth);
2617
2618#if BITS_PER_LONG > 32
2619 mpi_request.SenseBufferAddressHigh =
2620 cpu_to_le32(ioc->sense_dma >> 32);
2621 mpi_request.SystemReplyAddressHigh =
2622 cpu_to_le32(ioc->reply_dma >> 32);
2623 mpi_request.SystemRequestFrameBaseAddress =
2624 cpu_to_le64(ioc->request_dma);
2625 mpi_request.ReplyFreeQueueAddress =
2626 cpu_to_le64(ioc->reply_free_dma);
2627 mpi_request.ReplyDescriptorPostQueueAddress =
2628 cpu_to_le64(ioc->reply_post_free_dma);
2629#else
2630 mpi_request.SystemRequestFrameBaseAddress =
2631 cpu_to_le32(ioc->request_dma);
2632 mpi_request.ReplyFreeQueueAddress =
2633 cpu_to_le32(ioc->reply_free_dma);
2634 mpi_request.ReplyDescriptorPostQueueAddress =
2635 cpu_to_le32(ioc->reply_post_free_dma);
2636#endif
2637
2638 if (ioc->logging_level & MPT_DEBUG_INIT) {
2639 u32 *mfp;
2640 int i;
2641
2642 mfp = (u32 *)&mpi_request;
2643 printk(KERN_DEBUG "\toffset:data\n");
2644 for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++)
2645 printk(KERN_DEBUG "\t[0x%02x]:%08x\n", i*4,
2646 le32_to_cpu(mfp[i]));
2647 }
2648
2649 r = _base_handshake_req_reply_wait(ioc,
2650 sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request,
2651 sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10,
2652 sleep_flag);
2653
2654 if (r != 0) {
2655 printk(MPT2SAS_ERR_FMT "%s: handshake failed (r=%d)\n",
2656 ioc->name, __func__, r);
2657 return r;
2658 }
2659
2660 if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS ||
2661 mpi_reply.IOCLogInfo) {
2662 printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__);
2663 r = -EIO;
2664 }
2665
2666 return 0;
2667}
2668
2669/**
2670 * _base_send_port_enable - send port_enable(discovery stuff) to firmware
2671 * @ioc: per adapter object
2672 * @VF_ID: virtual function id
2673 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2674 *
2675 * Returns 0 for success, non-zero for failure.
2676 */
2677static int
2678_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2679{
2680 Mpi2PortEnableRequest_t *mpi_request;
2681 u32 ioc_state;
2682 unsigned long timeleft;
2683 int r = 0;
2684 u16 smid;
2685
2686 printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
2687
2688 if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
2689 printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
2690 ioc->name, __func__);
2691 return -EAGAIN;
2692 }
2693
2694 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
2695 if (!smid) {
2696 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2697 ioc->name, __func__);
2698 return -EAGAIN;
2699 }
2700
2701 ioc->base_cmds.status = MPT2_CMD_PENDING;
2702 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2703 ioc->base_cmds.smid = smid;
2704 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
2705 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
2706 mpi_request->VF_ID = VF_ID;
2707
2708 mpt2sas_base_put_smid_default(ioc, smid, VF_ID);
2709 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2710 300*HZ);
2711 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
2712 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2713 ioc->name, __func__);
2714 _debug_dump_mf(mpi_request,
2715 sizeof(Mpi2PortEnableRequest_t)/4);
2716 if (ioc->base_cmds.status & MPT2_CMD_RESET)
2717 r = -EFAULT;
2718 else
2719 r = -ETIME;
2720 goto out;
2721 } else
2722 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n",
2723 ioc->name, __func__));
2724
2725 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL,
2726 60, sleep_flag);
2727 if (ioc_state) {
2728 printk(MPT2SAS_ERR_FMT "%s: failed going to operational state "
2729 " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
2730 r = -EFAULT;
2731 }
2732 out:
2733 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2734 printk(MPT2SAS_INFO_FMT "port enable: %s\n",
2735 ioc->name, ((r == 0) ? "SUCCESS" : "FAILED"));
2736 return r;
2737}
2738
2739/**
2740 * _base_unmask_events - turn on notification for this event
2741 * @ioc: per adapter object
2742 * @event: firmware event
2743 *
2744 * The mask is stored in ioc->event_masks.
2745 */
2746static void
2747_base_unmask_events(struct MPT2SAS_ADAPTER *ioc, u16 event)
2748{
2749 u32 desired_event;
2750
2751 if (event >= 128)
2752 return;
2753
2754 desired_event = (1 << (event % 32));
2755
2756 if (event < 32)
2757 ioc->event_masks[0] &= ~desired_event;
2758 else if (event < 64)
2759 ioc->event_masks[1] &= ~desired_event;
2760 else if (event < 96)
2761 ioc->event_masks[2] &= ~desired_event;
2762 else if (event < 128)
2763 ioc->event_masks[3] &= ~desired_event;
2764}
2765
2766/**
2767 * _base_event_notification - send event notification
2768 * @ioc: per adapter object
2769 * @VF_ID: virtual function id
2770 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2771 *
2772 * Returns 0 for success, non-zero for failure.
2773 */
2774static int
2775_base_event_notification(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2776{
2777 Mpi2EventNotificationRequest_t *mpi_request;
2778 unsigned long timeleft;
2779 u16 smid;
2780 int r = 0;
2781 int i;
2782
2783 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
2784 __func__));
2785
2786 if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
2787 printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
2788 ioc->name, __func__);
2789 return -EAGAIN;
2790 }
2791
2792 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
2793 if (!smid) {
2794 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2795 ioc->name, __func__);
2796 return -EAGAIN;
2797 }
2798 ioc->base_cmds.status = MPT2_CMD_PENDING;
2799 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2800 ioc->base_cmds.smid = smid;
2801 memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t));
2802 mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
2803 mpi_request->VF_ID = VF_ID;
2804 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
2805 mpi_request->EventMasks[i] =
2806 le32_to_cpu(ioc->event_masks[i]);
2807 mpt2sas_base_put_smid_default(ioc, smid, VF_ID);
2808 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
2809 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
2810 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
2811 ioc->name, __func__);
2812 _debug_dump_mf(mpi_request,
2813 sizeof(Mpi2EventNotificationRequest_t)/4);
2814 if (ioc->base_cmds.status & MPT2_CMD_RESET)
2815 r = -EFAULT;
2816 else
2817 r = -ETIME;
2818 } else
2819 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: complete\n",
2820 ioc->name, __func__));
2821 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
2822 return r;
2823}
2824
2825/**
2826 * mpt2sas_base_validate_event_type - validating event types
2827 * @ioc: per adapter object
2828 * @event: firmware event
2829 *
2830 * This will turn on firmware event notification when application
2831 * ask for that event. We don't mask events that are already enabled.
2832 */
2833void
2834mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type)
2835{
2836 int i, j;
2837 u32 event_mask, desired_event;
2838 u8 send_update_to_fw;
2839
2840 for (i = 0, send_update_to_fw = 0; i <
2841 MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) {
2842 event_mask = ~event_type[i];
2843 desired_event = 1;
2844 for (j = 0; j < 32; j++) {
2845 if (!(event_mask & desired_event) &&
2846 (ioc->event_masks[i] & desired_event)) {
2847 ioc->event_masks[i] &= ~desired_event;
2848 send_update_to_fw = 1;
2849 }
2850 desired_event = (desired_event << 1);
2851 }
2852 }
2853
2854 if (!send_update_to_fw)
2855 return;
2856
2857 mutex_lock(&ioc->base_cmds.mutex);
2858 _base_event_notification(ioc, 0, CAN_SLEEP);
2859 mutex_unlock(&ioc->base_cmds.mutex);
2860}
2861
2862/**
2863 * _base_diag_reset - the "big hammer" start of day reset
2864 * @ioc: per adapter object
2865 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2866 *
2867 * Returns 0 for success, non-zero for failure.
2868 */
2869static int
2870_base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2871{
2872 u32 host_diagnostic;
2873 u32 ioc_state;
2874 u32 count;
2875 u32 hcb_size;
2876
2877 printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name);
2878
2879 _base_save_msix_table(ioc);
2880
2881 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n",
2882 ioc->name));
2883 writel(0, &ioc->chip->HostInterruptStatus);
2884
2885 count = 0;
2886 do {
2887 /* Write magic sequence to WriteSequence register
2888 * Loop until in diagnostic mode
2889 */
2890 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "write magic "
2891 "sequence\n", ioc->name));
2892 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
2893 writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence);
2894 writel(MPI2_WRSEQ_2ND_KEY_VALUE, &ioc->chip->WriteSequence);
2895 writel(MPI2_WRSEQ_3RD_KEY_VALUE, &ioc->chip->WriteSequence);
2896 writel(MPI2_WRSEQ_4TH_KEY_VALUE, &ioc->chip->WriteSequence);
2897 writel(MPI2_WRSEQ_5TH_KEY_VALUE, &ioc->chip->WriteSequence);
2898 writel(MPI2_WRSEQ_6TH_KEY_VALUE, &ioc->chip->WriteSequence);
2899
2900 /* wait 100 msec */
2901 if (sleep_flag == CAN_SLEEP)
2902 msleep(100);
2903 else
2904 mdelay(100);
2905
2906 if (count++ > 20)
2907 goto out;
2908
2909 host_diagnostic = readl(&ioc->chip->HostDiagnostic);
2910 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "wrote magic "
2911 "sequence: count(%d), host_diagnostic(0x%08x)\n",
2912 ioc->name, count, host_diagnostic));
2913
2914 } while ((host_diagnostic & MPI2_DIAG_DIAG_WRITE_ENABLE) == 0);
2915
2916 hcb_size = readl(&ioc->chip->HCBSize);
2917
2918 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "diag reset: issued\n",
2919 ioc->name));
2920 writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
2921 &ioc->chip->HostDiagnostic);
2922
2923 /* don't access any registers for 50 milliseconds */
2924 msleep(50);
2925
2926 /* 300 second max wait */
2927 for (count = 0; count < 3000000 ; count++) {
2928
2929 host_diagnostic = readl(&ioc->chip->HostDiagnostic);
2930
2931 if (host_diagnostic == 0xFFFFFFFF)
2932 goto out;
2933 if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
2934 break;
2935
2936 /* wait 100 msec */
2937 if (sleep_flag == CAN_SLEEP)
2938 msleep(1);
2939 else
2940 mdelay(1);
2941 }
2942
2943 if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
2944
2945 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter "
2946 "assuming the HCB Address points to good F/W\n",
2947 ioc->name));
2948 host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
2949 host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
2950 writel(host_diagnostic, &ioc->chip->HostDiagnostic);
2951
2952 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT
2953 "re-enable the HCDW\n", ioc->name));
2954 writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE,
2955 &ioc->chip->HCBSize);
2956 }
2957
2958 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "restart the adapter\n",
2959 ioc->name));
2960 writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET,
2961 &ioc->chip->HostDiagnostic);
2962
2963 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "disable writes to the "
2964 "diagnostic register\n", ioc->name));
2965 writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence);
2966
2967 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "Wait for FW to go to the "
2968 "READY state\n", ioc->name));
2969 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20,
2970 sleep_flag);
2971 if (ioc_state) {
2972 printk(MPT2SAS_ERR_FMT "%s: failed going to ready state "
2973 " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
2974 goto out;
2975 }
2976
2977 _base_restore_msix_table(ioc);
2978 printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name);
2979 return 0;
2980
2981 out:
2982 printk(MPT2SAS_ERR_FMT "diag reset: FAILED\n", ioc->name);
2983 return -EFAULT;
2984}
2985
2986/**
2987 * _base_make_ioc_ready - put controller in READY state
2988 * @ioc: per adapter object
2989 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2990 * @type: FORCE_BIG_HAMMER or SOFT_RESET
2991 *
2992 * Returns 0 for success, non-zero for failure.
2993 */
2994static int
2995_base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
2996 enum reset_type type)
2997{
2998 u32 ioc_state;
2999
3000 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3001 __func__));
3002
3003 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
3004 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: ioc_state(0x%08x)\n",
3005 ioc->name, __func__, ioc_state));
3006
3007 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY)
3008 return 0;
3009
3010 if (ioc_state & MPI2_DOORBELL_USED) {
3011 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell "
3012 "active!\n", ioc->name));
3013 goto issue_diag_reset;
3014 }
3015
3016 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
3017 mpt2sas_base_fault_info(ioc, ioc_state &
3018 MPI2_DOORBELL_DATA_MASK);
3019 goto issue_diag_reset;
3020 }
3021
3022 if (type == FORCE_BIG_HAMMER)
3023 goto issue_diag_reset;
3024
3025 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL)
3026 if (!(_base_send_ioc_reset(ioc,
3027 MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP)))
3028 return 0;
3029
3030 issue_diag_reset:
3031 return _base_diag_reset(ioc, CAN_SLEEP);
3032}
3033
3034/**
3035 * _base_make_ioc_operational - put controller in OPERATIONAL state
3036 * @ioc: per adapter object
3037 * @VF_ID: virtual function id
3038 * @sleep_flag: CAN_SLEEP or NO_SLEEP
3039 *
3040 * Returns 0 for success, non-zero for failure.
3041 */
3042static int
3043_base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3044 int sleep_flag)
3045{
3046 int r, i;
3047 unsigned long flags;
3048 u32 reply_address;
3049
3050 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3051 __func__));
3052
3053 /* initialize the scsi lookup free list */
3054 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3055 INIT_LIST_HEAD(&ioc->free_list);
3056 for (i = 0; i < ioc->request_depth; i++) {
3057 ioc->scsi_lookup[i].cb_idx = 0xFF;
3058 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
3059 &ioc->free_list);
3060 }
3061 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3062
3063 /* initialize Reply Free Queue */
3064 for (i = 0, reply_address = (u32)ioc->reply_dma ;
3065 i < ioc->reply_free_queue_depth ; i++, reply_address +=
3066 ioc->reply_sz)
3067 ioc->reply_free[i] = cpu_to_le32(reply_address);
3068
3069 /* initialize Reply Post Free Queue */
3070 for (i = 0; i < ioc->reply_post_queue_depth; i++)
3071 ioc->reply_post_free[i].Words = ~0ULL;
3072
3073 r = _base_send_ioc_init(ioc, VF_ID, sleep_flag);
3074 if (r)
3075 return r;
3076
3077 /* initialize the index's */
3078 ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1;
3079 ioc->reply_post_host_index = 0;
3080 writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex);
3081 writel(0, &ioc->chip->ReplyPostHostIndex);
3082
3083 _base_unmask_interrupts(ioc);
3084 r = _base_event_notification(ioc, VF_ID, sleep_flag);
3085 if (r)
3086 return r;
3087
3088 if (sleep_flag == CAN_SLEEP)
3089 _base_static_config_pages(ioc);
3090
3091 r = _base_send_port_enable(ioc, VF_ID, sleep_flag);
3092 if (r)
3093 return r;
3094
3095 return r;
3096}
3097
3098/**
3099 * mpt2sas_base_free_resources - free resources controller resources (io/irq/memap)
3100 * @ioc: per adapter object
3101 *
3102 * Return nothing.
3103 */
3104void
3105mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3106{
3107 struct pci_dev *pdev = ioc->pdev;
3108
3109 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3110 __func__));
3111
3112 _base_mask_interrupts(ioc);
3113 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3114 if (ioc->pci_irq) {
3115 synchronize_irq(pdev->irq);
3116 free_irq(ioc->pci_irq, ioc);
3117 }
3118 _base_disable_msix(ioc);
3119 if (ioc->chip_phys)
3120 iounmap(ioc->chip);
3121 ioc->pci_irq = -1;
3122 ioc->chip_phys = 0;
3123 pci_release_selected_regions(ioc->pdev, ioc->bars);
3124 pci_disable_device(pdev);
3125 pci_set_drvdata(pdev, NULL);
3126 return;
3127}
3128
3129/**
3130 * mpt2sas_base_attach - attach controller instance
3131 * @ioc: per adapter object
3132 *
3133 * Returns 0 for success, non-zero for failure.
3134 */
3135int
3136mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3137{
3138 int r, i;
3139 unsigned long flags;
3140
3141 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3142 __func__));
3143
3144 r = mpt2sas_base_map_resources(ioc);
3145 if (r)
3146 return r;
3147
3148 r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3149 if (r)
3150 goto out_free_resources;
3151
3152 r = _base_get_ioc_facts(ioc, CAN_SLEEP);
3153 if (r)
3154 goto out_free_resources;
3155
3156 r = _base_allocate_memory_pools(ioc, CAN_SLEEP);
3157 if (r)
3158 goto out_free_resources;
3159
3160 init_waitqueue_head(&ioc->reset_wq);
3161
3162 /* base internal command bits */
3163 mutex_init(&ioc->base_cmds.mutex);
3164 init_completion(&ioc->base_cmds.done);
3165 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3166 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
3167
3168 /* transport internal command bits */
3169 ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3170 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
3171 mutex_init(&ioc->transport_cmds.mutex);
3172 init_completion(&ioc->transport_cmds.done);
3173
3174 /* task management internal command bits */
3175 ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3176 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
3177 mutex_init(&ioc->tm_cmds.mutex);
3178 init_completion(&ioc->tm_cmds.done);
3179
3180 /* config page internal command bits */
3181 ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3182 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
3183 mutex_init(&ioc->config_cmds.mutex);
3184 init_completion(&ioc->config_cmds.done);
3185
3186 /* ctl module internal command bits */
3187 ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3188 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
3189 mutex_init(&ioc->ctl_cmds.mutex);
3190 init_completion(&ioc->ctl_cmds.done);
3191
3192 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3193 ioc->event_masks[i] = -1;
3194
3195 /* here we enable the events we care about */
3196 _base_unmask_events(ioc, MPI2_EVENT_SAS_DISCOVERY);
3197 _base_unmask_events(ioc, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE);
3198 _base_unmask_events(ioc, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
3199 _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
3200 _base_unmask_events(ioc, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
3201 _base_unmask_events(ioc, MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST);
3202 _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME);
3203 _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK);
3204 _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
3205 _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL);
3206 _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
3207
3208 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3209 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3210 if (!ioc->pfacts)
3211 goto out_free_resources;
3212
3213 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3214 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
3215 if (r)
3216 goto out_free_resources;
3217 }
3218 r = _base_make_ioc_operational(ioc, 0, CAN_SLEEP);
3219 if (r)
3220 goto out_free_resources;
3221
3222 /* initialize fault polling */
3223 INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
3224 snprintf(ioc->fault_reset_work_q_name,
3225 sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
3226 ioc->fault_reset_work_q =
3227 create_singlethread_workqueue(ioc->fault_reset_work_q_name);
3228 if (!ioc->fault_reset_work_q) {
3229 printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
3230 ioc->name, __func__, __LINE__);
3231 goto out_free_resources;
3232 }
3233 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3234 if (ioc->fault_reset_work_q)
3235 queue_delayed_work(ioc->fault_reset_work_q,
3236 &ioc->fault_reset_work,
3237 msecs_to_jiffies(FAULT_POLLING_INTERVAL));
3238 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3239 return 0;
3240
3241 out_free_resources:
3242
3243 ioc->remove_host = 1;
3244 mpt2sas_base_free_resources(ioc);
3245 _base_release_memory_pools(ioc);
3246 kfree(ioc->tm_cmds.reply);
3247 kfree(ioc->transport_cmds.reply);
3248 kfree(ioc->config_cmds.reply);
3249 kfree(ioc->base_cmds.reply);
3250 kfree(ioc->ctl_cmds.reply);
3251 kfree(ioc->pfacts);
3252 ioc->ctl_cmds.reply = NULL;
3253 ioc->base_cmds.reply = NULL;
3254 ioc->tm_cmds.reply = NULL;
3255 ioc->transport_cmds.reply = NULL;
3256 ioc->config_cmds.reply = NULL;
3257 ioc->pfacts = NULL;
3258 return r;
3259}
3260
3261
3262/**
3263 * mpt2sas_base_detach - remove controller instance
3264 * @ioc: per adapter object
3265 *
3266 * Return nothing.
3267 */
3268void
3269mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3270{
3271 unsigned long flags;
3272 struct workqueue_struct *wq;
3273
3274 dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3275 __func__));
3276
3277 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3278 wq = ioc->fault_reset_work_q;
3279 ioc->fault_reset_work_q = NULL;
3280 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3281 if (!cancel_delayed_work(&ioc->fault_reset_work))
3282 flush_workqueue(wq);
3283 destroy_workqueue(wq);
3284
3285 mpt2sas_base_free_resources(ioc);
3286 _base_release_memory_pools(ioc);
3287 kfree(ioc->pfacts);
3288 kfree(ioc->ctl_cmds.reply);
3289 kfree(ioc->base_cmds.reply);
3290 kfree(ioc->tm_cmds.reply);
3291 kfree(ioc->transport_cmds.reply);
3292 kfree(ioc->config_cmds.reply);
3293}
3294
3295/**
3296 * _base_reset_handler - reset callback handler (for base)
3297 * @ioc: per adapter object
3298 * @reset_phase: phase
3299 *
3300 * The handler for doing any required cleanup or initialization.
3301 *
3302 * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
3303 * MPT2_IOC_DONE_RESET
3304 *
3305 * Return nothing.
3306 */
3307static void
3308_base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
3309{
3310 switch (reset_phase) {
3311 case MPT2_IOC_PRE_RESET:
3312 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
3313 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
3314 break;
3315 case MPT2_IOC_AFTER_RESET:
3316 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
3317 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
3318 if (ioc->transport_cmds.status & MPT2_CMD_PENDING) {
3319 ioc->transport_cmds.status |= MPT2_CMD_RESET;
3320 mpt2sas_base_free_smid(ioc, ioc->transport_cmds.smid);
3321 complete(&ioc->transport_cmds.done);
3322 }
3323 if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
3324 ioc->base_cmds.status |= MPT2_CMD_RESET;
3325 mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid);
3326 complete(&ioc->base_cmds.done);
3327 }
3328 if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
3329 ioc->config_cmds.status |= MPT2_CMD_RESET;
3330 mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid);
3331 complete(&ioc->config_cmds.done);
3332 }
3333 break;
3334 case MPT2_IOC_DONE_RESET:
3335 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
3336 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
3337 break;
3338 }
3339 mpt2sas_scsih_reset_handler(ioc, reset_phase);
3340 mpt2sas_ctl_reset_handler(ioc, reset_phase);
3341}
3342
3343/**
3344 * _wait_for_commands_to_complete - reset controller
3345 * @ioc: Pointer to MPT_ADAPTER structure
3346 * @sleep_flag: CAN_SLEEP or NO_SLEEP
3347 *
3348 * This function waiting(3s) for all pending commands to complete
3349 * prior to putting controller in reset.
3350 */
3351static void
3352_wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3353{
3354 u32 ioc_state;
3355 unsigned long flags;
3356 u16 i;
3357
3358 ioc->pending_io_count = 0;
3359 if (sleep_flag != CAN_SLEEP)
3360 return;
3361
3362 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
3363 if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL)
3364 return;
3365
3366 /* pending command count */
3367 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3368 for (i = 0; i < ioc->request_depth; i++)
3369 if (ioc->scsi_lookup[i].cb_idx != 0xFF)
3370 ioc->pending_io_count++;
3371 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3372
3373 if (!ioc->pending_io_count)
3374 return;
3375
3376 /* wait for pending commands to complete */
3377 wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 3 * HZ);
3378}
3379
3380/**
3381 * mpt2sas_base_hard_reset_handler - reset controller
3382 * @ioc: Pointer to MPT_ADAPTER structure
3383 * @sleep_flag: CAN_SLEEP or NO_SLEEP
3384 * @type: FORCE_BIG_HAMMER or SOFT_RESET
3385 *
3386 * Returns 0 for success, non-zero for failure.
3387 */
3388int
3389mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3390 enum reset_type type)
3391{
3392 int r, i;
3393 unsigned long flags;
3394
3395 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
3396 __func__));
3397
3398 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3399 if (ioc->ioc_reset_in_progress) {
3400 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3401 printk(MPT2SAS_ERR_FMT "%s: busy\n",
3402 ioc->name, __func__);
3403 return -EBUSY;
3404 }
3405 ioc->ioc_reset_in_progress = 1;
3406 ioc->shost_recovery = 1;
3407 if (ioc->shost->shost_state == SHOST_RUNNING) {
3408 /* set back to SHOST_RUNNING in mpt2sas_scsih.c */
3409 scsi_host_set_state(ioc->shost, SHOST_RECOVERY);
3410 printk(MPT2SAS_INFO_FMT "putting controller into "
3411 "SHOST_RECOVERY\n", ioc->name);
3412 }
3413 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3414
3415 _base_reset_handler(ioc, MPT2_IOC_PRE_RESET);
3416 _wait_for_commands_to_complete(ioc, sleep_flag);
3417 _base_mask_interrupts(ioc);
3418 r = _base_make_ioc_ready(ioc, sleep_flag, type);
3419 if (r)
3420 goto out;
3421 _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET);
3422 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++)
3423 r = _base_make_ioc_operational(ioc, ioc->pfacts[i].VF_ID,
3424 sleep_flag);
3425 if (!r)
3426 _base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
3427 out:
3428 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: %s\n",
3429 ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
3430
3431 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3432 ioc->ioc_reset_in_progress = 0;
3433 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3434 return r;
3435}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
new file mode 100644
index 000000000000..6945ff4d382e
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -0,0 +1,779 @@
1/*
2 * This is the Fusion MPT base driver providing common API layer interface
3 * for access to MPT (Message Passing Technology) firmware.
4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h
6 * Copyright (C) 2007-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
45#ifndef MPT2SAS_BASE_H_INCLUDED
46#define MPT2SAS_BASE_H_INCLUDED
47
48#include "mpi/mpi2_type.h"
49#include "mpi/mpi2.h"
50#include "mpi/mpi2_ioc.h"
51#include "mpi/mpi2_cnfg.h"
52#include "mpi/mpi2_init.h"
53#include "mpi/mpi2_raid.h"
54#include "mpi/mpi2_tool.h"
55#include "mpi/mpi2_sas.h"
56
57#include <scsi/scsi.h>
58#include <scsi/scsi_cmnd.h>
59#include <scsi/scsi_device.h>
60#include <scsi/scsi_host.h>
61#include <scsi/scsi_tcq.h>
62#include <scsi/scsi_transport_sas.h>
63#include <scsi/scsi_dbg.h>
64
65#include "mpt2sas_debug.h"
66
67/* driver versioning info */
68#define MPT2SAS_DRIVER_NAME "mpt2sas"
69#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
70#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
71#define MPT2SAS_DRIVER_VERSION "00.100.11.16"
72#define MPT2SAS_MAJOR_VERSION 00
73#define MPT2SAS_MINOR_VERSION 100
74#define MPT2SAS_BUILD_VERSION 11
75#define MPT2SAS_RELEASE_VERSION 16
76
77/*
78 * Set MPT2SAS_SG_DEPTH value based on user input.
79 */
80#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE
81#if CONFIG_SCSI_MPT2SAS_MAX_SGE < 16
82#define MPT2SAS_SG_DEPTH 16
83#elif CONFIG_SCSI_MPT2SAS_MAX_SGE > 128
84#define MPT2SAS_SG_DEPTH 128
85#else
86#define MPT2SAS_SG_DEPTH CONFIG_SCSI_MPT2SAS_MAX_SGE
87#endif
88#else
89#define MPT2SAS_SG_DEPTH 128 /* MAX_HW_SEGMENTS */
90#endif
91
92
93/*
94 * Generic Defines
95 */
96#define MPT2SAS_SATA_QUEUE_DEPTH 32
97#define MPT2SAS_SAS_QUEUE_DEPTH 254
98#define MPT2SAS_RAID_QUEUE_DEPTH 128
99
100#define MPT_NAME_LENGTH 32 /* generic length of strings */
101#define MPT_STRING_LENGTH 64
102
103#define MPT_MAX_CALLBACKS 16
104
105#define CAN_SLEEP 1
106#define NO_SLEEP 0
107
108#define INTERNAL_CMDS_COUNT 10 /* reserved cmds */
109
110#define MPI2_HIM_MASK 0xFFFFFFFF /* mask every bit*/
111
112#define MPT2SAS_INVALID_DEVICE_HANDLE 0xFFFF
113
114
115/*
116 * reset phases
117 */
118#define MPT2_IOC_PRE_RESET 1 /* prior to host reset */
119#define MPT2_IOC_AFTER_RESET 2 /* just after host reset */
120#define MPT2_IOC_DONE_RESET 3 /* links re-initialized */
121
122/*
123 * logging format
124 */
125#define MPT2SAS_FMT "%s: "
126#define MPT2SAS_DEBUG_FMT KERN_DEBUG MPT2SAS_FMT
127#define MPT2SAS_INFO_FMT KERN_INFO MPT2SAS_FMT
128#define MPT2SAS_NOTE_FMT KERN_NOTICE MPT2SAS_FMT
129#define MPT2SAS_WARN_FMT KERN_WARNING MPT2SAS_FMT
130#define MPT2SAS_ERR_FMT KERN_ERR MPT2SAS_FMT
131
132/*
133 * per target private data
134 */
135#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01
136#define MPT_TARGET_FLAGS_VOLUME 0x02
137#define MPT_TARGET_FLAGS_DELETED 0x04
138
139/**
140 * struct MPT2SAS_TARGET - starget private hostdata
141 * @starget: starget object
142 * @sas_address: target sas address
143 * @handle: device handle
144 * @num_luns: number luns
145 * @flags: MPT_TARGET_FLAGS_XXX flags
146 * @deleted: target flaged for deletion
147 * @tm_busy: target is busy with TM request.
148 */
149struct MPT2SAS_TARGET {
150 struct scsi_target *starget;
151 u64 sas_address;
152 u16 handle;
153 int num_luns;
154 u32 flags;
155 u8 deleted;
156 u8 tm_busy;
157};
158
159/*
160 * per device private data
161 */
162#define MPT_DEVICE_FLAGS_INIT 0x01
163#define MPT_DEVICE_TLR_ON 0x02
164
165/**
166 * struct MPT2SAS_DEVICE - sdev private hostdata
167 * @sas_target: starget private hostdata
168 * @lun: lun number
169 * @flags: MPT_DEVICE_XXX flags
170 * @configured_lun: lun is configured
171 * @block: device is in SDEV_BLOCK state
172 * @tlr_snoop_check: flag used in determining whether to disable TLR
173 */
174struct MPT2SAS_DEVICE {
175 struct MPT2SAS_TARGET *sas_target;
176 unsigned int lun;
177 u32 flags;
178 u8 configured_lun;
179 u8 block;
180 u8 tlr_snoop_check;
181};
182
183#define MPT2_CMD_NOT_USED 0x8000 /* free */
184#define MPT2_CMD_COMPLETE 0x0001 /* completed */
185#define MPT2_CMD_PENDING 0x0002 /* pending */
186#define MPT2_CMD_REPLY_VALID 0x0004 /* reply is valid */
187#define MPT2_CMD_RESET 0x0008 /* host reset dropped the command */
188
189/**
190 * struct _internal_cmd - internal commands struct
191 * @mutex: mutex
192 * @done: completion
193 * @reply: reply message pointer
194 * @status: MPT2_CMD_XXX status
195 * @smid: system message id
196 */
197struct _internal_cmd {
198 struct mutex mutex;
199 struct completion done;
200 void *reply;
201 u16 status;
202 u16 smid;
203};
204
205/*
206 * SAS Topology Structures
207 */
208
209/**
210 * struct _sas_device - attached device information
211 * @list: sas device list
212 * @starget: starget object
213 * @sas_address: device sas address
214 * @device_name: retrieved from the SAS IDENTIFY frame.
215 * @handle: device handle
216 * @parent_handle: handle to parent device
217 * @enclosure_handle: enclosure handle
218 * @enclosure_logical_id: enclosure logical identifier
219 * @volume_handle: volume handle (valid when hidden raid member)
220 * @volume_wwid: volume unique identifier
221 * @device_info: bitfield provides detailed info about the device
222 * @id: target id
223 * @channel: target channel
224 * @slot: number number
225 * @hidden_raid_component: set to 1 when this is a raid member
226 * @responding: used in _scsih_sas_device_mark_responding
227 */
228struct _sas_device {
229 struct list_head list;
230 struct scsi_target *starget;
231 u64 sas_address;
232 u64 device_name;
233 u16 handle;
234 u16 parent_handle;
235 u16 enclosure_handle;
236 u64 enclosure_logical_id;
237 u16 volume_handle;
238 u64 volume_wwid;
239 u32 device_info;
240 int id;
241 int channel;
242 u16 slot;
243 u8 hidden_raid_component;
244 u8 responding;
245};
246
247/**
248 * struct _raid_device - raid volume link list
249 * @list: sas device list
250 * @starget: starget object
251 * @sdev: scsi device struct (volumes are single lun)
252 * @wwid: unique identifier for the volume
253 * @handle: device handle
254 * @id: target id
255 * @channel: target channel
256 * @volume_type: the raid level
257 * @device_info: bitfield provides detailed info about the hidden components
258 * @num_pds: number of hidden raid components
259 * @responding: used in _scsih_raid_device_mark_responding
260 */
261struct _raid_device {
262 struct list_head list;
263 struct scsi_target *starget;
264 struct scsi_device *sdev;
265 u64 wwid;
266 u16 handle;
267 int id;
268 int channel;
269 u8 volume_type;
270 u32 device_info;
271 u8 num_pds;
272 u8 responding;
273};
274
275/**
276 * struct _boot_device - boot device info
277 * @is_raid: flag to indicate whether this is volume
278 * @device: holds pointer for either struct _sas_device or
279 * struct _raid_device
280 */
281struct _boot_device {
282 u8 is_raid;
283 void *device;
284};
285
286/**
287 * struct _sas_port - wide/narrow sas port information
288 * @port_list: list of ports belonging to expander
289 * @handle: device handle for this port
290 * @sas_address: sas address of this port
291 * @num_phys: number of phys belonging to this port
292 * @remote_identify: attached device identification
293 * @rphy: sas transport rphy object
294 * @port: sas transport wide/narrow port object
295 * @phy_list: _sas_phy list objects belonging to this port
296 */
297struct _sas_port {
298 struct list_head port_list;
299 u16 handle;
300 u64 sas_address;
301 u8 num_phys;
302 struct sas_identify remote_identify;
303 struct sas_rphy *rphy;
304 struct sas_port *port;
305 struct list_head phy_list;
306};
307
308/**
309 * struct _sas_phy - phy information
310 * @port_siblings: list of phys belonging to a port
311 * @identify: phy identification
312 * @remote_identify: attached device identification
313 * @phy: sas transport phy object
314 * @phy_id: unique phy id
315 * @handle: device handle for this phy
316 * @attached_handle: device handle for attached device
317 */
318struct _sas_phy {
319 struct list_head port_siblings;
320 struct sas_identify identify;
321 struct sas_identify remote_identify;
322 struct sas_phy *phy;
323 u8 phy_id;
324 u16 handle;
325 u16 attached_handle;
326};
327
328/**
329 * struct _sas_node - sas_host/expander information
330 * @list: list of expanders
331 * @parent_dev: parent device class
332 * @num_phys: number phys belonging to this sas_host/expander
333 * @sas_address: sas address of this sas_host/expander
334 * @handle: handle for this sas_host/expander
335 * @parent_handle: parent handle
336 * @enclosure_handle: handle for this a member of an enclosure
337 * @device_info: bitwise defining capabilities of this sas_host/expander
338 * @responding: used in _scsih_expander_device_mark_responding
339 * @phy: a list of phys that make up this sas_host/expander
340 * @sas_port_list: list of ports attached to this sas_host/expander
341 */
342struct _sas_node {
343 struct list_head list;
344 struct device *parent_dev;
345 u8 num_phys;
346 u64 sas_address;
347 u16 handle;
348 u16 parent_handle;
349 u16 enclosure_handle;
350 u64 enclosure_logical_id;
351 u8 responding;
352 struct _sas_phy *phy;
353 struct list_head sas_port_list;
354};
355
356/**
357 * enum reset_type - reset state
358 * @FORCE_BIG_HAMMER: issue diagnostic reset
359 * @SOFT_RESET: issue message_unit_reset, if fails to to big hammer
360 */
361enum reset_type {
362 FORCE_BIG_HAMMER,
363 SOFT_RESET,
364};
365
366/**
367 * struct request_tracker - firmware request tracker
368 * @smid: system message id
369 * @scmd: scsi request pointer
370 * @cb_idx: callback index
371 * @chain_list: list of chains associated to this IO
372 * @tracker_list: list of free request (ioc->free_list)
373 */
374struct request_tracker {
375 u16 smid;
376 struct scsi_cmnd *scmd;
377 u8 cb_idx;
378 struct list_head tracker_list;
379};
380
381typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
382
383/**
384 * struct MPT2SAS_ADAPTER - per adapter struct
385 * @list: ioc_list
386 * @shost: shost object
387 * @id: unique adapter id
388 * @pci_irq: irq number
389 * @name: generic ioc string
390 * @tmp_string: tmp string used for logging
391 * @pdev: pci pdev object
392 * @chip: memory mapped register space
393 * @chip_phys: physical addrss prior to mapping
394 * @pio_chip: I/O mapped register space
395 * @logging_level: see mpt2sas_debug.h
396 * @ir_firmware: IR firmware present
397 * @bars: bitmask of BAR's that must be configured
398 * @mask_interrupts: ignore interrupt
399 * @fault_reset_work_q_name: fw fault work queue
400 * @fault_reset_work_q: ""
401 * @fault_reset_work: ""
402 * @firmware_event_name: fw event work queue
403 * @firmware_event_thread: ""
404 * @fw_events_off: flag to turn off fw event handling
405 * @fw_event_lock:
406 * @fw_event_list: list of fw events
407 * @aen_event_read_flag: event log was read
408 * @broadcast_aen_busy: broadcast aen waiting to be serviced
409 * @ioc_reset_in_progress: host reset in progress
410 * @ioc_reset_in_progress_lock:
411 * @ioc_link_reset_in_progress: phy/hard reset in progress
412 * @ignore_loginfos: ignore loginfos during task managment
413 * @remove_host: flag for when driver unloads, to avoid sending dev resets
414 * @wait_for_port_enable_to_complete:
415 * @msix_enable: flag indicating msix is enabled
416 * @msix_vector_count: number msix vectors
417 * @msix_table: virt address to the msix table
418 * @msix_table_backup: backup msix table
419 * @scsi_io_cb_idx: shost generated commands
420 * @tm_cb_idx: task management commands
421 * @transport_cb_idx: transport internal commands
422 * @ctl_cb_idx: clt internal commands
423 * @base_cb_idx: base internal commands
424 * @config_cb_idx: base internal commands
425 * @base_cmds:
426 * @transport_cmds:
427 * @tm_cmds:
428 * @ctl_cmds:
429 * @config_cmds:
430 * @base_add_sg_single: handler for either 32/64 bit sgl's
431 * @event_type: bits indicating which events to log
432 * @event_context: unique id for each logged event
433 * @event_log: event log pointer
434 * @event_masks: events that are masked
435 * @facts: static facts data
436 * @pfacts: static port facts data
437 * @manu_pg0: static manufacturing page 0
438 * @bios_pg2: static bios page 2
439 * @bios_pg3: static bios page 3
440 * @ioc_pg8: static ioc page 8
441 * @iounit_pg0: static iounit page 0
442 * @iounit_pg1: static iounit page 1
443 * @sas_hba: sas host object
444 * @sas_expander_list: expander object list
445 * @sas_node_lock:
446 * @sas_device_list: sas device object list
447 * @sas_device_init_list: sas device object list (used only at init time)
448 * @sas_device_lock:
449 * @io_missing_delay: time for IO completed by fw when PDR enabled
450 * @device_missing_delay: time for device missing by fw when PDR enabled
451 * @config_page_sz: config page size
452 * @config_page: reserve memory for config page payload
453 * @config_page_dma:
454 * @sge_size: sg element size for either 32/64 bit
455 * @request_depth: hba request queue depth
456 * @request_sz: per request frame size
457 * @request: pool of request frames
458 * @request_dma:
459 * @request_dma_sz:
460 * @scsi_lookup: firmware request tracker list
461 * @scsi_lookup_lock:
462 * @free_list: free list of request
463 * @chain: pool of chains
464 * @pending_io_count:
465 * @reset_wq:
466 * @chain_dma:
467 * @max_sges_in_main_message: number sg elements in main message
468 * @max_sges_in_chain_message: number sg elements per chain
469 * @chains_needed_per_io: max chains per io
470 * @chain_offset_value_for_main_message: location 1st sg in main
471 * @chain_depth: total chains allocated
472 * @sense: pool of sense
473 * @sense_dma:
474 * @sense_dma_pool:
475 * @reply_depth: hba reply queue depth:
476 * @reply_sz: per reply frame size:
477 * @reply: pool of replys:
478 * @reply_dma:
479 * @reply_dma_pool:
480 * @reply_free_queue_depth: reply free depth
481 * @reply_free: pool for reply free queue (32 bit addr)
482 * @reply_free_dma:
483 * @reply_free_dma_pool:
484 * @reply_free_host_index: tail index in pool to insert free replys
485 * @reply_post_queue_depth: reply post queue depth
486 * @reply_post_free: pool for reply post (64bit descriptor)
487 * @reply_post_free_dma:
488 * @reply_post_free_dma_pool:
489 * @reply_post_host_index: head index in the pool where FW completes IO
490 */
491struct MPT2SAS_ADAPTER {
492 struct list_head list;
493 struct Scsi_Host *shost;
494 u8 id;
495 u32 pci_irq;
496 char name[MPT_NAME_LENGTH];
497 char tmp_string[MPT_STRING_LENGTH];
498 struct pci_dev *pdev;
499 Mpi2SystemInterfaceRegs_t __iomem *chip;
500 unsigned long chip_phys;
501 unsigned long pio_chip;
502 int logging_level;
503 u8 ir_firmware;
504 int bars;
505 u8 mask_interrupts;
506
507 /* fw fault handler */
508 char fault_reset_work_q_name[20];
509 struct workqueue_struct *fault_reset_work_q;
510 struct delayed_work fault_reset_work;
511
512 /* fw event handler */
513 char firmware_event_name[20];
514 struct workqueue_struct *firmware_event_thread;
515 u8 fw_events_off;
516 spinlock_t fw_event_lock;
517 struct list_head fw_event_list;
518
519 /* misc flags */
520 int aen_event_read_flag;
521 u8 broadcast_aen_busy;
522 u8 ioc_reset_in_progress;
523 u8 shost_recovery;
524 spinlock_t ioc_reset_in_progress_lock;
525 u8 ioc_link_reset_in_progress;
526 u8 ignore_loginfos;
527 u8 remove_host;
528 u8 wait_for_port_enable_to_complete;
529
530 u8 msix_enable;
531 u16 msix_vector_count;
532 u32 *msix_table;
533 u32 *msix_table_backup;
534
535 /* internal commands, callback index */
536 u8 scsi_io_cb_idx;
537 u8 tm_cb_idx;
538 u8 transport_cb_idx;
539 u8 ctl_cb_idx;
540 u8 base_cb_idx;
541 u8 config_cb_idx;
542 struct _internal_cmd base_cmds;
543 struct _internal_cmd transport_cmds;
544 struct _internal_cmd tm_cmds;
545 struct _internal_cmd ctl_cmds;
546 struct _internal_cmd config_cmds;
547
548 MPT_ADD_SGE base_add_sg_single;
549
550 /* event log */
551 u32 event_type[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
552 u32 event_context;
553 void *event_log;
554 u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
555
556 /* static config pages */
557 Mpi2IOCFactsReply_t facts;
558 Mpi2PortFactsReply_t *pfacts;
559 Mpi2ManufacturingPage0_t manu_pg0;
560 Mpi2BiosPage2_t bios_pg2;
561 Mpi2BiosPage3_t bios_pg3;
562 Mpi2IOCPage8_t ioc_pg8;
563 Mpi2IOUnitPage0_t iounit_pg0;
564 Mpi2IOUnitPage1_t iounit_pg1;
565
566 struct _boot_device req_boot_device;
567 struct _boot_device req_alt_boot_device;
568 struct _boot_device current_boot_device;
569
570 /* sas hba, expander, and device list */
571 struct _sas_node sas_hba;
572 struct list_head sas_expander_list;
573 spinlock_t sas_node_lock;
574 struct list_head sas_device_list;
575 struct list_head sas_device_init_list;
576 spinlock_t sas_device_lock;
577 struct list_head raid_device_list;
578 spinlock_t raid_device_lock;
579 u8 io_missing_delay;
580 u16 device_missing_delay;
581 int sas_id;
582
583 /* config page */
584 u16 config_page_sz;
585 void *config_page;
586 dma_addr_t config_page_dma;
587
588 /* request */
589 u16 sge_size;
590 u16 request_depth;
591 u16 request_sz;
592 u8 *request;
593 dma_addr_t request_dma;
594 u32 request_dma_sz;
595 struct request_tracker *scsi_lookup;
596 spinlock_t scsi_lookup_lock;
597 struct list_head free_list;
598 int pending_io_count;
599 wait_queue_head_t reset_wq;
600
601 /* chain */
602 u8 *chain;
603 dma_addr_t chain_dma;
604 u16 max_sges_in_main_message;
605 u16 max_sges_in_chain_message;
606 u16 chains_needed_per_io;
607 u16 chain_offset_value_for_main_message;
608 u16 chain_depth;
609
610 /* sense */
611 u8 *sense;
612 dma_addr_t sense_dma;
613 struct dma_pool *sense_dma_pool;
614
615 /* reply */
616 u16 reply_sz;
617 u8 *reply;
618 dma_addr_t reply_dma;
619 struct dma_pool *reply_dma_pool;
620
621 /* reply free queue */
622 u16 reply_free_queue_depth;
623 u32 *reply_free;
624 dma_addr_t reply_free_dma;
625 struct dma_pool *reply_free_dma_pool;
626 u32 reply_free_host_index;
627
628 /* reply post queue */
629 u16 reply_post_queue_depth;
630 Mpi2ReplyDescriptorsUnion_t *reply_post_free;
631 dma_addr_t reply_post_free_dma;
632 struct dma_pool *reply_post_free_dma_pool;
633 u32 reply_post_host_index;
634
635 /* diag buffer support */
636 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
637 u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT];
638 dma_addr_t diag_buffer_dma[MPI2_DIAG_BUF_TYPE_COUNT];
639 u8 diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT];
640 u32 unique_id[MPI2_DIAG_BUF_TYPE_COUNT];
641 u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23];
642 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
643};
644
645typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
646 u32 reply);
647
648
649/* base shared API */
650extern struct list_head mpt2sas_ioc_list;
651
652int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
653void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
654int mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc);
655void mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc);
656int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
657 enum reset_type type);
658
659void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
660void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
661void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
662dma_addr_t mpt2sas_base_get_msg_frame_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid);
663dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid);
664
665u16 mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
666void mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid);
667void mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id,
668 u16 handle);
669void mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id);
670void mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
671 u8 vf_id, u16 io_index);
672void mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id);
673void mpt2sas_base_initialize_callback_handler(void);
674u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func);
675void mpt2sas_base_release_callback_handler(u8 cb_idx);
676
677void mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply);
678void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);
679
680u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked);
681
682void mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code);
683int mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
684 Mpi2SasIoUnitControlReply_t *mpi_reply, Mpi2SasIoUnitControlRequest_t
685 *mpi_request);
686int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
687 Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request);
688void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
689
690/* scsih shared API */
691void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
692 u8 type, u16 smid_task, ulong timeout);
693void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
694void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
695struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc,
696 u16 handle);
697struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER
698 *ioc, u64 sas_address);
699struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address(
700 struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
701
702void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply);
703void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
704
705/* config shared API */
706void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply);
707int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
708int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
709 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page);
710int mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
711 *mpi_reply, Mpi2BiosPage2_t *config_page);
712int mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
713 *mpi_reply, Mpi2BiosPage3_t *config_page);
714int mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
715 *mpi_reply, Mpi2IOUnitPage0_t *config_page);
716int mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
717 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle);
718int mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
719 *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle);
720int mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
721 *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz);
722int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
723 *mpi_reply, Mpi2IOUnitPage1_t *config_page);
724int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
725 *mpi_reply, Mpi2IOUnitPage1_t config_page);
726int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
727 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
728int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
729 *mpi_reply, Mpi2IOCPage8_t *config_page);
730int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
731 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle);
732int mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
733 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, u16 handle);
734int mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
735 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle);
736int mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
737 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number);
738int mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
739 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number);
740int mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
741 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u32 handle);
742int mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 *num_pds);
743int mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
744 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, u32 handle, u16 sz);
745int mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
746 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
747 u32 form_specific);
748int mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
749 u16 *volume_handle);
750int mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
751 u64 *wwid);
752
753/* ctl shared API */
754extern struct device_attribute *mpt2sas_host_attrs[];
755extern struct device_attribute *mpt2sas_dev_attrs[];
756void mpt2sas_ctl_init(void);
757void mpt2sas_ctl_exit(void);
758void mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply);
759void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
760void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply);
761void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
762 Mpi2EventNotificationReply_t *mpi_reply);
763
764/* transport shared API */
765void mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply);
766struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
767 u16 handle, u16 parent_handle);
768void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
769 u16 parent_handle);
770int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
771 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
772int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
773 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
774void mpt2sas_transport_update_phy_link_change(struct MPT2SAS_ADAPTER *ioc, u16 handle,
775 u16 attached_handle, u8 phy_number, u8 link_rate);
776extern struct sas_function_template mpt2sas_transport_functions;
777extern struct scsi_transport_template *mpt2sas_transport_template;
778
779#endif /* MPT2SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
new file mode 100644
index 000000000000..58cfb97846f7
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -0,0 +1,1873 @@
1/*
2 * This module provides common API for accessing firmware configuration pages
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#include <linux/version.h>
45#include <linux/module.h>
46#include <linux/kernel.h>
47#include <linux/init.h>
48#include <linux/errno.h>
49#include <linux/blkdev.h>
50#include <linux/sched.h>
51#include <linux/workqueue.h>
52#include <linux/delay.h>
53#include <linux/pci.h>
54
55#include "mpt2sas_base.h"
56
57/* local definitions */
58
59/* Timeout for config page request (in seconds) */
60#define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
61
62/* Common sgl flags for READING a config page. */
63#define MPT2_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
64 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
65 | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
66
67/* Common sgl flags for WRITING a config page. */
68#define MPT2_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
69 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
70 | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
71 << MPI2_SGE_FLAGS_SHIFT)
72
73/**
74 * struct config_request - obtain dma memory via routine
75 * @config_page_sz: size
76 * @config_page: virt pointer
77 * @config_page_dma: phys pointer
78 *
79 */
80struct config_request{
81 u16 config_page_sz;
82 void *config_page;
83 dma_addr_t config_page_dma;
84};
85
86#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
87/**
88 * _config_display_some_debug - debug routine
89 * @ioc: per adapter object
90 * @smid: system request message index
91 * @calling_function_name: string pass from calling function
92 * @mpi_reply: reply message frame
93 * Context: none.
94 *
95 * Function for displaying debug info helpfull when debugging issues
96 * in this module.
97 */
98static void
99_config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
100 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
101{
102 Mpi2ConfigRequest_t *mpi_request;
103 char *desc = NULL;
104
105 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
106 return;
107
108 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
109 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
110 case MPI2_CONFIG_PAGETYPE_IO_UNIT:
111 desc = "io_unit";
112 break;
113 case MPI2_CONFIG_PAGETYPE_IOC:
114 desc = "ioc";
115 break;
116 case MPI2_CONFIG_PAGETYPE_BIOS:
117 desc = "bios";
118 break;
119 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
120 desc = "raid_volume";
121 break;
122 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
123 desc = "manufaucturing";
124 break;
125 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
126 desc = "physdisk";
127 break;
128 case MPI2_CONFIG_PAGETYPE_EXTENDED:
129 switch (mpi_request->ExtPageType) {
130 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
131 desc = "sas_io_unit";
132 break;
133 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
134 desc = "sas_expander";
135 break;
136 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
137 desc = "sas_device";
138 break;
139 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
140 desc = "sas_phy";
141 break;
142 case MPI2_CONFIG_EXTPAGETYPE_LOG:
143 desc = "log";
144 break;
145 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
146 desc = "enclosure";
147 break;
148 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
149 desc = "raid_config";
150 break;
151 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
152 desc = "driver_mappping";
153 break;
154 }
155 break;
156 }
157
158 if (!desc)
159 return;
160
161 printk(MPT2SAS_DEBUG_FMT "%s: %s(%d), action(%d), form(0x%08x), "
162 "smid(%d)\n", ioc->name, calling_function_name, desc,
163 mpi_request->Header.PageNumber, mpi_request->Action,
164 le32_to_cpu(mpi_request->PageAddress), smid);
165
166 if (!mpi_reply)
167 return;
168
169 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
170 printk(MPT2SAS_DEBUG_FMT
171 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
172 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
173 le32_to_cpu(mpi_reply->IOCLogInfo));
174}
175#endif
176
177/**
178 * mpt2sas_config_done - config page completion routine
179 * @ioc: per adapter object
180 * @smid: system request message index
181 * @VF_ID: virtual function id
182 * @reply: reply message frame(lower 32bit addr)
183 * Context: none.
184 *
185 * The callback handler when using _config_request.
186 *
187 * Return nothing.
188 */
189void
190mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
191{
192 MPI2DefaultReply_t *mpi_reply;
193
194 if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
195 return;
196 if (ioc->config_cmds.smid != smid)
197 return;
198 ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
199 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
200 if (mpi_reply) {
201 ioc->config_cmds.status |= MPT2_CMD_REPLY_VALID;
202 memcpy(ioc->config_cmds.reply, mpi_reply,
203 mpi_reply->MsgLength*4);
204 }
205 ioc->config_cmds.status &= ~MPT2_CMD_PENDING;
206#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
207 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
208#endif
209 complete(&ioc->config_cmds.done);
210}
211
212/**
213 * _config_request - main routine for sending config page requests
214 * @ioc: per adapter object
215 * @mpi_request: request message frame
216 * @mpi_reply: reply mf payload returned from firmware
217 * @timeout: timeout in seconds
218 * Context: sleep, the calling function needs to acquire the config_cmds.mutex
219 *
220 * A generic API for config page requests to firmware.
221 *
222 * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
223 * this API.
224 *
225 * The callback index is set inside `ioc->config_cb_idx.
226 *
227 * Returns 0 for success, non-zero for failure.
228 */
229static int
230_config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
231 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout)
232{
233 u16 smid;
234 u32 ioc_state;
235 unsigned long timeleft;
236 Mpi2ConfigRequest_t *config_request;
237 int r;
238 u8 retry_count;
239 u8 issue_reset;
240 u16 wait_state_count;
241
242 if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
243 printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
244 ioc->name, __func__);
245 return -EAGAIN;
246 }
247 retry_count = 0;
248
249 retry_config:
250 wait_state_count = 0;
251 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
252 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
253 if (wait_state_count++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT) {
254 printk(MPT2SAS_ERR_FMT
255 "%s: failed due to ioc not operational\n",
256 ioc->name, __func__);
257 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
258 return -EFAULT;
259 }
260 ssleep(1);
261 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
262 printk(MPT2SAS_INFO_FMT "%s: waiting for "
263 "operational state(count=%d)\n", ioc->name,
264 __func__, wait_state_count);
265 }
266 if (wait_state_count)
267 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
268 ioc->name, __func__);
269
270 smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx);
271 if (!smid) {
272 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
273 ioc->name, __func__);
274 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
275 return -EAGAIN;
276 }
277
278 r = 0;
279 memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
280 ioc->config_cmds.status = MPT2_CMD_PENDING;
281 config_request = mpt2sas_base_get_msg_frame(ioc, smid);
282 ioc->config_cmds.smid = smid;
283 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
284#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
285 _config_display_some_debug(ioc, smid, "config_request", NULL);
286#endif
287 mpt2sas_base_put_smid_default(ioc, smid, config_request->VF_ID);
288 timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
289 timeout*HZ);
290 if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
291 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
292 ioc->name, __func__);
293 _debug_dump_mf(mpi_request,
294 sizeof(Mpi2ConfigRequest_t)/4);
295 if (!(ioc->config_cmds.status & MPT2_CMD_RESET))
296 issue_reset = 1;
297 goto issue_host_reset;
298 }
299 if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
300 memcpy(mpi_reply, ioc->config_cmds.reply,
301 sizeof(Mpi2ConfigReply_t));
302 if (retry_count)
303 printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
304 ioc->name, __func__);
305 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
306 return r;
307
308 issue_host_reset:
309 if (issue_reset)
310 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
311 FORCE_BIG_HAMMER);
312 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
313 if (!retry_count) {
314 printk(MPT2SAS_INFO_FMT "%s: attempting retry\n",
315 ioc->name, __func__);
316 retry_count++;
317 goto retry_config;
318 }
319 return -EFAULT;
320}
321
322/**
323 * _config_alloc_config_dma_memory - obtain physical memory
324 * @ioc: per adapter object
325 * @mem: struct config_request
326 *
327 * A wrapper for obtaining dma-able memory for config page request.
328 *
329 * Returns 0 for success, non-zero for failure.
330 */
331static int
332_config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
333 struct config_request *mem)
334{
335 int r = 0;
336
337 mem->config_page = pci_alloc_consistent(ioc->pdev, mem->config_page_sz,
338 &mem->config_page_dma);
339 if (!mem->config_page)
340 r = -ENOMEM;
341 return r;
342}
343
344/**
345 * _config_free_config_dma_memory - wrapper to free the memory
346 * @ioc: per adapter object
347 * @mem: struct config_request
348 *
349 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
350 *
351 * Returns 0 for success, non-zero for failure.
352 */
353static void
354_config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
355 struct config_request *mem)
356{
357 pci_free_consistent(ioc->pdev, mem->config_page_sz, mem->config_page,
358 mem->config_page_dma);
359}
360
361/**
362 * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
363 * @ioc: per adapter object
364 * @mpi_reply: reply mf payload returned from firmware
365 * @config_page: contents of the config page
366 * Context: sleep.
367 *
368 * Returns 0 for success, non-zero for failure.
369 */
370int
371mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
372 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
373{
374 Mpi2ConfigRequest_t mpi_request;
375 int r;
376 struct config_request mem;
377
378 mutex_lock(&ioc->config_cmds.mutex);
379 memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
380 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
381 mpi_request.Function = MPI2_FUNCTION_CONFIG;
382 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
383 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
384 mpi_request.Header.PageNumber = 0;
385 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
386 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
387 r = _config_request(ioc, &mpi_request, mpi_reply,
388 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
389 if (r)
390 goto out;
391
392 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
393 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
394 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
395 mpi_request.Header.PageType = mpi_reply->Header.PageType;
396 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
397 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
398 if (mem.config_page_sz > ioc->config_page_sz) {
399 r = _config_alloc_config_dma_memory(ioc, &mem);
400 if (r)
401 goto out;
402 } else {
403 mem.config_page_dma = ioc->config_page_dma;
404 mem.config_page = ioc->config_page;
405 }
406 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
407 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
408 mem.config_page_dma);
409 r = _config_request(ioc, &mpi_request, mpi_reply,
410 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
411 if (!r)
412 memcpy(config_page, mem.config_page,
413 min_t(u16, mem.config_page_sz,
414 sizeof(Mpi2ManufacturingPage0_t)));
415
416 if (mem.config_page_sz > ioc->config_page_sz)
417 _config_free_config_dma_memory(ioc, &mem);
418
419 out:
420 mutex_unlock(&ioc->config_cmds.mutex);
421 return r;
422}
423
424/**
425 * mpt2sas_config_get_bios_pg2 - obtain bios page 2
426 * @ioc: per adapter object
427 * @mpi_reply: reply mf payload returned from firmware
428 * @config_page: contents of the config page
429 * Context: sleep.
430 *
431 * Returns 0 for success, non-zero for failure.
432 */
433int
434mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
435 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
436{
437 Mpi2ConfigRequest_t mpi_request;
438 int r;
439 struct config_request mem;
440
441 mutex_lock(&ioc->config_cmds.mutex);
442 memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
443 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
444 mpi_request.Function = MPI2_FUNCTION_CONFIG;
445 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
446 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
447 mpi_request.Header.PageNumber = 2;
448 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
449 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
450 r = _config_request(ioc, &mpi_request, mpi_reply,
451 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
452 if (r)
453 goto out;
454
455 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
456 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
457 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
458 mpi_request.Header.PageType = mpi_reply->Header.PageType;
459 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
460 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
461 if (mem.config_page_sz > ioc->config_page_sz) {
462 r = _config_alloc_config_dma_memory(ioc, &mem);
463 if (r)
464 goto out;
465 } else {
466 mem.config_page_dma = ioc->config_page_dma;
467 mem.config_page = ioc->config_page;
468 }
469 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
470 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
471 mem.config_page_dma);
472 r = _config_request(ioc, &mpi_request, mpi_reply,
473 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
474 if (!r)
475 memcpy(config_page, mem.config_page,
476 min_t(u16, mem.config_page_sz,
477 sizeof(Mpi2BiosPage2_t)));
478
479 if (mem.config_page_sz > ioc->config_page_sz)
480 _config_free_config_dma_memory(ioc, &mem);
481
482 out:
483 mutex_unlock(&ioc->config_cmds.mutex);
484 return r;
485}
486
487/**
488 * mpt2sas_config_get_bios_pg3 - obtain bios page 3
489 * @ioc: per adapter object
490 * @mpi_reply: reply mf payload returned from firmware
491 * @config_page: contents of the config page
492 * Context: sleep.
493 *
494 * Returns 0 for success, non-zero for failure.
495 */
496int
497mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
498 *mpi_reply, Mpi2BiosPage3_t *config_page)
499{
500 Mpi2ConfigRequest_t mpi_request;
501 int r;
502 struct config_request mem;
503
504 mutex_lock(&ioc->config_cmds.mutex);
505 memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
506 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
507 mpi_request.Function = MPI2_FUNCTION_CONFIG;
508 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
509 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
510 mpi_request.Header.PageNumber = 3;
511 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
512 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
513 r = _config_request(ioc, &mpi_request, mpi_reply,
514 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
515 if (r)
516 goto out;
517
518 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
519 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
520 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
521 mpi_request.Header.PageType = mpi_reply->Header.PageType;
522 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
523 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
524 if (mem.config_page_sz > ioc->config_page_sz) {
525 r = _config_alloc_config_dma_memory(ioc, &mem);
526 if (r)
527 goto out;
528 } else {
529 mem.config_page_dma = ioc->config_page_dma;
530 mem.config_page = ioc->config_page;
531 }
532 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
533 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
534 mem.config_page_dma);
535 r = _config_request(ioc, &mpi_request, mpi_reply,
536 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
537 if (!r)
538 memcpy(config_page, mem.config_page,
539 min_t(u16, mem.config_page_sz,
540 sizeof(Mpi2BiosPage3_t)));
541
542 if (mem.config_page_sz > ioc->config_page_sz)
543 _config_free_config_dma_memory(ioc, &mem);
544
545 out:
546 mutex_unlock(&ioc->config_cmds.mutex);
547 return r;
548}
549
550/**
551 * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
552 * @ioc: per adapter object
553 * @mpi_reply: reply mf payload returned from firmware
554 * @config_page: contents of the config page
555 * Context: sleep.
556 *
557 * Returns 0 for success, non-zero for failure.
558 */
559int
560mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
561 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
562{
563 Mpi2ConfigRequest_t mpi_request;
564 int r;
565 struct config_request mem;
566
567 mutex_lock(&ioc->config_cmds.mutex);
568 memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
569 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
570 mpi_request.Function = MPI2_FUNCTION_CONFIG;
571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
572 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
573 mpi_request.Header.PageNumber = 0;
574 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
575 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
576 r = _config_request(ioc, &mpi_request, mpi_reply,
577 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
578 if (r)
579 goto out;
580
581 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
582 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
583 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
584 mpi_request.Header.PageType = mpi_reply->Header.PageType;
585 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
586 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
587 if (mem.config_page_sz > ioc->config_page_sz) {
588 r = _config_alloc_config_dma_memory(ioc, &mem);
589 if (r)
590 goto out;
591 } else {
592 mem.config_page_dma = ioc->config_page_dma;
593 mem.config_page = ioc->config_page;
594 }
595 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
596 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
597 mem.config_page_dma);
598 r = _config_request(ioc, &mpi_request, mpi_reply,
599 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
600 if (!r)
601 memcpy(config_page, mem.config_page,
602 min_t(u16, mem.config_page_sz,
603 sizeof(Mpi2IOUnitPage0_t)));
604
605 if (mem.config_page_sz > ioc->config_page_sz)
606 _config_free_config_dma_memory(ioc, &mem);
607
608 out:
609 mutex_unlock(&ioc->config_cmds.mutex);
610 return r;
611}
612
613/**
614 * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
615 * @ioc: per adapter object
616 * @mpi_reply: reply mf payload returned from firmware
617 * @config_page: contents of the config page
618 * Context: sleep.
619 *
620 * Returns 0 for success, non-zero for failure.
621 */
622int
623mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
624 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
625{
626 Mpi2ConfigRequest_t mpi_request;
627 int r;
628 struct config_request mem;
629
630 mutex_lock(&ioc->config_cmds.mutex);
631 memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
632 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
633 mpi_request.Function = MPI2_FUNCTION_CONFIG;
634 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
635 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
636 mpi_request.Header.PageNumber = 1;
637 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
638 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
639 r = _config_request(ioc, &mpi_request, mpi_reply,
640 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
641 if (r)
642 goto out;
643
644 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
645 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
646 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
647 mpi_request.Header.PageType = mpi_reply->Header.PageType;
648 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
649 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
650 if (mem.config_page_sz > ioc->config_page_sz) {
651 r = _config_alloc_config_dma_memory(ioc, &mem);
652 if (r)
653 goto out;
654 } else {
655 mem.config_page_dma = ioc->config_page_dma;
656 mem.config_page = ioc->config_page;
657 }
658 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
659 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
660 mem.config_page_dma);
661 r = _config_request(ioc, &mpi_request, mpi_reply,
662 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
663 if (!r)
664 memcpy(config_page, mem.config_page,
665 min_t(u16, mem.config_page_sz,
666 sizeof(Mpi2IOUnitPage1_t)));
667
668 if (mem.config_page_sz > ioc->config_page_sz)
669 _config_free_config_dma_memory(ioc, &mem);
670
671 out:
672 mutex_unlock(&ioc->config_cmds.mutex);
673 return r;
674}
675
676/**
677 * mpt2sas_config_set_iounit_pg1 - set iounit page 1
678 * @ioc: per adapter object
679 * @mpi_reply: reply mf payload returned from firmware
680 * @config_page: contents of the config page
681 * Context: sleep.
682 *
683 * Returns 0 for success, non-zero for failure.
684 */
685int
686mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
687 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t config_page)
688{
689 Mpi2ConfigRequest_t mpi_request;
690 int r;
691 struct config_request mem;
692
693 mutex_lock(&ioc->config_cmds.mutex);
694 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
695 mpi_request.Function = MPI2_FUNCTION_CONFIG;
696 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
697 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
698 mpi_request.Header.PageNumber = 1;
699 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
700 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
701 r = _config_request(ioc, &mpi_request, mpi_reply,
702 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
703 if (r)
704 goto out;
705
706 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
707 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
708 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
709 mpi_request.Header.PageType = mpi_reply->Header.PageType;
710 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
711 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
712 if (mem.config_page_sz > ioc->config_page_sz) {
713 r = _config_alloc_config_dma_memory(ioc, &mem);
714 if (r)
715 goto out;
716 } else {
717 mem.config_page_dma = ioc->config_page_dma;
718 mem.config_page = ioc->config_page;
719 }
720
721 memset(mem.config_page, 0, mem.config_page_sz);
722 memcpy(mem.config_page, &config_page,
723 sizeof(Mpi2IOUnitPage1_t));
724
725 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
726 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.config_page_sz,
727 mem.config_page_dma);
728 r = _config_request(ioc, &mpi_request, mpi_reply,
729 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
730
731 if (mem.config_page_sz > ioc->config_page_sz)
732 _config_free_config_dma_memory(ioc, &mem);
733
734 out:
735 mutex_unlock(&ioc->config_cmds.mutex);
736 return r;
737}
738
739/**
740 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
741 * @ioc: per adapter object
742 * @mpi_reply: reply mf payload returned from firmware
743 * @config_page: contents of the config page
744 * Context: sleep.
745 *
746 * Returns 0 for success, non-zero for failure.
747 */
748int
749mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
750 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
751{
752 Mpi2ConfigRequest_t mpi_request;
753 int r;
754 struct config_request mem;
755
756 mutex_lock(&ioc->config_cmds.mutex);
757 memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
758 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
759 mpi_request.Function = MPI2_FUNCTION_CONFIG;
760 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
761 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
762 mpi_request.Header.PageNumber = 8;
763 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
764 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
765 r = _config_request(ioc, &mpi_request, mpi_reply,
766 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
767 if (r)
768 goto out;
769
770 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
771 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
772 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
773 mpi_request.Header.PageType = mpi_reply->Header.PageType;
774 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
775 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
776 if (mem.config_page_sz > ioc->config_page_sz) {
777 r = _config_alloc_config_dma_memory(ioc, &mem);
778 if (r)
779 goto out;
780 } else {
781 mem.config_page_dma = ioc->config_page_dma;
782 mem.config_page = ioc->config_page;
783 }
784 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
785 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
786 mem.config_page_dma);
787 r = _config_request(ioc, &mpi_request, mpi_reply,
788 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
789 if (!r)
790 memcpy(config_page, mem.config_page,
791 min_t(u16, mem.config_page_sz,
792 sizeof(Mpi2IOCPage8_t)));
793
794 if (mem.config_page_sz > ioc->config_page_sz)
795 _config_free_config_dma_memory(ioc, &mem);
796
797 out:
798 mutex_unlock(&ioc->config_cmds.mutex);
799 return r;
800}
801
802/**
803 * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
804 * @ioc: per adapter object
805 * @mpi_reply: reply mf payload returned from firmware
806 * @config_page: contents of the config page
807 * @form: GET_NEXT_HANDLE or HANDLE
808 * @handle: device handle
809 * Context: sleep.
810 *
811 * Returns 0 for success, non-zero for failure.
812 */
813int
814mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
815 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle)
816{
817 Mpi2ConfigRequest_t mpi_request;
818 int r;
819 struct config_request mem;
820
821 mutex_lock(&ioc->config_cmds.mutex);
822 memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
823 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
824 mpi_request.Function = MPI2_FUNCTION_CONFIG;
825 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
826 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
827 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
828 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
829 mpi_request.Header.PageNumber = 0;
830 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
831 r = _config_request(ioc, &mpi_request, mpi_reply,
832 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
833 if (r)
834 goto out;
835
836 mpi_request.PageAddress = cpu_to_le32(form | handle);
837 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
838 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
839 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
840 mpi_request.Header.PageType = mpi_reply->Header.PageType;
841 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
842 mpi_request.ExtPageType = mpi_reply->ExtPageType;
843 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
844 if (mem.config_page_sz > ioc->config_page_sz) {
845 r = _config_alloc_config_dma_memory(ioc, &mem);
846 if (r)
847 goto out;
848 } else {
849 mem.config_page_dma = ioc->config_page_dma;
850 mem.config_page = ioc->config_page;
851 }
852 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
853 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
854 mem.config_page_dma);
855 r = _config_request(ioc, &mpi_request, mpi_reply,
856 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
857 if (!r)
858 memcpy(config_page, mem.config_page,
859 min_t(u16, mem.config_page_sz,
860 sizeof(Mpi2SasDevicePage0_t)));
861
862 if (mem.config_page_sz > ioc->config_page_sz)
863 _config_free_config_dma_memory(ioc, &mem);
864
865 out:
866 mutex_unlock(&ioc->config_cmds.mutex);
867 return r;
868}
869
870/**
871 * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
872 * @ioc: per adapter object
873 * @mpi_reply: reply mf payload returned from firmware
874 * @config_page: contents of the config page
875 * @form: GET_NEXT_HANDLE or HANDLE
876 * @handle: device handle
877 * Context: sleep.
878 *
879 * Returns 0 for success, non-zero for failure.
880 */
881int
882mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
883 *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle)
884{
885 Mpi2ConfigRequest_t mpi_request;
886 int r;
887 struct config_request mem;
888
889 mutex_lock(&ioc->config_cmds.mutex);
890 memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
891 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
892 mpi_request.Function = MPI2_FUNCTION_CONFIG;
893 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
894 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
895 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
896 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
897 mpi_request.Header.PageNumber = 1;
898 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
899 r = _config_request(ioc, &mpi_request, mpi_reply,
900 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
901 if (r)
902 goto out;
903
904 mpi_request.PageAddress = cpu_to_le32(form | handle);
905 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
906 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
907 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
908 mpi_request.Header.PageType = mpi_reply->Header.PageType;
909 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
910 mpi_request.ExtPageType = mpi_reply->ExtPageType;
911 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
912 if (mem.config_page_sz > ioc->config_page_sz) {
913 r = _config_alloc_config_dma_memory(ioc, &mem);
914 if (r)
915 goto out;
916 } else {
917 mem.config_page_dma = ioc->config_page_dma;
918 mem.config_page = ioc->config_page;
919 }
920 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
921 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
922 mem.config_page_dma);
923 r = _config_request(ioc, &mpi_request, mpi_reply,
924 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
925 if (!r)
926 memcpy(config_page, mem.config_page,
927 min_t(u16, mem.config_page_sz,
928 sizeof(Mpi2SasDevicePage1_t)));
929
930 if (mem.config_page_sz > ioc->config_page_sz)
931 _config_free_config_dma_memory(ioc, &mem);
932
933 out:
934 mutex_unlock(&ioc->config_cmds.mutex);
935 return r;
936}
937
938/**
939 * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
940 * @ioc: per adapter object
941 * @num_phys: pointer returned with the number of phys
942 * Context: sleep.
943 *
944 * Returns 0 for success, non-zero for failure.
945 */
946int
947mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
948{
949 Mpi2ConfigRequest_t mpi_request;
950 int r;
951 struct config_request mem;
952 u16 ioc_status;
953 Mpi2ConfigReply_t mpi_reply;
954 Mpi2SasIOUnitPage0_t config_page;
955
956 mutex_lock(&ioc->config_cmds.mutex);
957 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
958 mpi_request.Function = MPI2_FUNCTION_CONFIG;
959 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
960 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
961 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
962 mpi_request.Header.PageNumber = 0;
963 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
964 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
965 r = _config_request(ioc, &mpi_request, &mpi_reply,
966 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
967 if (r)
968 goto out;
969
970 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
971 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
972 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
973 mpi_request.Header.PageType = mpi_reply.Header.PageType;
974 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
975 mpi_request.ExtPageType = mpi_reply.ExtPageType;
976 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
977 if (mem.config_page_sz > ioc->config_page_sz) {
978 r = _config_alloc_config_dma_memory(ioc, &mem);
979 if (r)
980 goto out;
981 } else {
982 mem.config_page_dma = ioc->config_page_dma;
983 mem.config_page = ioc->config_page;
984 }
985 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
986 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
987 mem.config_page_dma);
988 r = _config_request(ioc, &mpi_request, &mpi_reply,
989 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
990 if (!r) {
991 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
992 MPI2_IOCSTATUS_MASK;
993 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
994 memcpy(&config_page, mem.config_page,
995 min_t(u16, mem.config_page_sz,
996 sizeof(Mpi2SasIOUnitPage0_t)));
997 *num_phys = config_page.NumPhys;
998 }
999 }
1000
1001 if (mem.config_page_sz > ioc->config_page_sz)
1002 _config_free_config_dma_memory(ioc, &mem);
1003
1004 out:
1005 mutex_unlock(&ioc->config_cmds.mutex);
1006 return r;
1007}
1008
1009/**
1010 * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1011 * @ioc: per adapter object
1012 * @mpi_reply: reply mf payload returned from firmware
1013 * @config_page: contents of the config page
1014 * @sz: size of buffer passed in config_page
1015 * Context: sleep.
1016 *
1017 * Calling function should call config_get_number_hba_phys prior to
1018 * this function, so enough memory is allocated for config_page.
1019 *
1020 * Returns 0 for success, non-zero for failure.
1021 */
1022int
1023mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1024 *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz)
1025{
1026 Mpi2ConfigRequest_t mpi_request;
1027 int r;
1028 struct config_request mem;
1029
1030 mutex_lock(&ioc->config_cmds.mutex);
1031 memset(config_page, 0, sz);
1032 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1033 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1034 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1035 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1036 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1037 mpi_request.Header.PageNumber = 0;
1038 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1039 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1040 r = _config_request(ioc, &mpi_request, mpi_reply,
1041 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1042 if (r)
1043 goto out;
1044
1045 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1046 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1047 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1048 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1049 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1050 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1051 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1052 if (mem.config_page_sz > ioc->config_page_sz) {
1053 r = _config_alloc_config_dma_memory(ioc, &mem);
1054 if (r)
1055 goto out;
1056 } else {
1057 mem.config_page_dma = ioc->config_page_dma;
1058 mem.config_page = ioc->config_page;
1059 }
1060 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1061 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1062 mem.config_page_dma);
1063 r = _config_request(ioc, &mpi_request, mpi_reply,
1064 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1065 if (!r)
1066 memcpy(config_page, mem.config_page,
1067 min_t(u16, sz, mem.config_page_sz));
1068
1069 if (mem.config_page_sz > ioc->config_page_sz)
1070 _config_free_config_dma_memory(ioc, &mem);
1071
1072 out:
1073 mutex_unlock(&ioc->config_cmds.mutex);
1074 return r;
1075}
1076
1077/**
1078 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0
1079 * @ioc: per adapter object
1080 * @mpi_reply: reply mf payload returned from firmware
1081 * @config_page: contents of the config page
1082 * @sz: size of buffer passed in config_page
1083 * Context: sleep.
1084 *
1085 * Calling function should call config_get_number_hba_phys prior to
1086 * this function, so enough memory is allocated for config_page.
1087 *
1088 * Returns 0 for success, non-zero for failure.
1089 */
1090int
1091mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1092 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
1093{
1094 Mpi2ConfigRequest_t mpi_request;
1095 int r;
1096 struct config_request mem;
1097
1098 mutex_lock(&ioc->config_cmds.mutex);
1099 memset(config_page, 0, sz);
1100 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1101 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1102 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1103 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1104 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1105 mpi_request.Header.PageNumber = 1;
1106 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1107 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1108 r = _config_request(ioc, &mpi_request, mpi_reply,
1109 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1110 if (r)
1111 goto out;
1112
1113 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1114 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1115 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1116 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1117 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1118 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1119 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1120 if (mem.config_page_sz > ioc->config_page_sz) {
1121 r = _config_alloc_config_dma_memory(ioc, &mem);
1122 if (r)
1123 goto out;
1124 } else {
1125 mem.config_page_dma = ioc->config_page_dma;
1126 mem.config_page = ioc->config_page;
1127 }
1128 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1129 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1130 mem.config_page_dma);
1131 r = _config_request(ioc, &mpi_request, mpi_reply,
1132 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1133 if (!r)
1134 memcpy(config_page, mem.config_page,
1135 min_t(u16, sz, mem.config_page_sz));
1136
1137 if (mem.config_page_sz > ioc->config_page_sz)
1138 _config_free_config_dma_memory(ioc, &mem);
1139
1140 out:
1141 mutex_unlock(&ioc->config_cmds.mutex);
1142 return r;
1143}
1144
1145/**
1146 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
1147 * @ioc: per adapter object
1148 * @mpi_reply: reply mf payload returned from firmware
1149 * @config_page: contents of the config page
1150 * @form: GET_NEXT_HANDLE or HANDLE
1151 * @handle: expander handle
1152 * Context: sleep.
1153 *
1154 * Returns 0 for success, non-zero for failure.
1155 */
1156int
1157mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1158 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1159{
1160 Mpi2ConfigRequest_t mpi_request;
1161 int r;
1162 struct config_request mem;
1163
1164 mutex_lock(&ioc->config_cmds.mutex);
1165 memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
1166 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1167 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1168 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1169 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1170 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1171 mpi_request.Header.PageNumber = 0;
1172 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1173 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1174 r = _config_request(ioc, &mpi_request, mpi_reply,
1175 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1176 if (r)
1177 goto out;
1178
1179 mpi_request.PageAddress = cpu_to_le32(form | handle);
1180 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1181 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1182 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1183 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1184 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1185 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1186 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1187 if (mem.config_page_sz > ioc->config_page_sz) {
1188 r = _config_alloc_config_dma_memory(ioc, &mem);
1189 if (r)
1190 goto out;
1191 } else {
1192 mem.config_page_dma = ioc->config_page_dma;
1193 mem.config_page = ioc->config_page;
1194 }
1195 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1196 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1197 mem.config_page_dma);
1198 r = _config_request(ioc, &mpi_request, mpi_reply,
1199 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1200 if (!r)
1201 memcpy(config_page, mem.config_page,
1202 min_t(u16, mem.config_page_sz,
1203 sizeof(Mpi2ExpanderPage0_t)));
1204
1205 if (mem.config_page_sz > ioc->config_page_sz)
1206 _config_free_config_dma_memory(ioc, &mem);
1207
1208 out:
1209 mutex_unlock(&ioc->config_cmds.mutex);
1210 return r;
1211}
1212
1213/**
1214 * mpt2sas_config_get_expander_pg1 - obtain expander page 1
1215 * @ioc: per adapter object
1216 * @mpi_reply: reply mf payload returned from firmware
1217 * @config_page: contents of the config page
1218 * @phy_number: phy number
1219 * @handle: expander handle
1220 * Context: sleep.
1221 *
1222 * Returns 0 for success, non-zero for failure.
1223 */
1224int
1225mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1226 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1227 u16 handle)
1228{
1229 Mpi2ConfigRequest_t mpi_request;
1230 int r;
1231 struct config_request mem;
1232
1233 mutex_lock(&ioc->config_cmds.mutex);
1234 memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
1235 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1236 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1237 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1238 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1239 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1240 mpi_request.Header.PageNumber = 1;
1241 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1242 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1243 r = _config_request(ioc, &mpi_request, mpi_reply,
1244 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1245 if (r)
1246 goto out;
1247
1248 mpi_request.PageAddress =
1249 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1250 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1251 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1252 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1253 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1254 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1255 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1256 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1257 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1258 if (mem.config_page_sz > ioc->config_page_sz) {
1259 r = _config_alloc_config_dma_memory(ioc, &mem);
1260 if (r)
1261 goto out;
1262 } else {
1263 mem.config_page_dma = ioc->config_page_dma;
1264 mem.config_page = ioc->config_page;
1265 }
1266 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1267 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1268 mem.config_page_dma);
1269 r = _config_request(ioc, &mpi_request, mpi_reply,
1270 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1271 if (!r)
1272 memcpy(config_page, mem.config_page,
1273 min_t(u16, mem.config_page_sz,
1274 sizeof(Mpi2ExpanderPage1_t)));
1275
1276 if (mem.config_page_sz > ioc->config_page_sz)
1277 _config_free_config_dma_memory(ioc, &mem);
1278
1279 out:
1280 mutex_unlock(&ioc->config_cmds.mutex);
1281 return r;
1282}
1283
1284/**
1285 * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
1286 * @ioc: per adapter object
1287 * @mpi_reply: reply mf payload returned from firmware
1288 * @config_page: contents of the config page
1289 * @form: GET_NEXT_HANDLE or HANDLE
1290 * @handle: expander handle
1291 * Context: sleep.
1292 *
1293 * Returns 0 for success, non-zero for failure.
1294 */
1295int
1296mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1297 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1298{
1299 Mpi2ConfigRequest_t mpi_request;
1300 int r;
1301 struct config_request mem;
1302
1303 mutex_lock(&ioc->config_cmds.mutex);
1304 memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
1305 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1306 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1307 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1308 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1309 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1310 mpi_request.Header.PageNumber = 0;
1311 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1312 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1313 r = _config_request(ioc, &mpi_request, mpi_reply,
1314 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1315 if (r)
1316 goto out;
1317
1318 mpi_request.PageAddress = cpu_to_le32(form | handle);
1319 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1320 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1321 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1322 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1323 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1324 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1325 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1326 if (mem.config_page_sz > ioc->config_page_sz) {
1327 r = _config_alloc_config_dma_memory(ioc, &mem);
1328 if (r)
1329 goto out;
1330 } else {
1331 mem.config_page_dma = ioc->config_page_dma;
1332 mem.config_page = ioc->config_page;
1333 }
1334 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1335 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1336 mem.config_page_dma);
1337 r = _config_request(ioc, &mpi_request, mpi_reply,
1338 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1339 if (!r)
1340 memcpy(config_page, mem.config_page,
1341 min_t(u16, mem.config_page_sz,
1342 sizeof(Mpi2SasEnclosurePage0_t)));
1343
1344 if (mem.config_page_sz > ioc->config_page_sz)
1345 _config_free_config_dma_memory(ioc, &mem);
1346
1347 out:
1348 mutex_unlock(&ioc->config_cmds.mutex);
1349 return r;
1350}
1351
1352/**
1353 * mpt2sas_config_get_phy_pg0 - obtain phy page 0
1354 * @ioc: per adapter object
1355 * @mpi_reply: reply mf payload returned from firmware
1356 * @config_page: contents of the config page
1357 * @phy_number: phy number
1358 * Context: sleep.
1359 *
1360 * Returns 0 for success, non-zero for failure.
1361 */
1362int
1363mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1364 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1365{
1366 Mpi2ConfigRequest_t mpi_request;
1367 int r;
1368 struct config_request mem;
1369
1370 mutex_lock(&ioc->config_cmds.mutex);
1371 memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
1372 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1373 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1374 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1375 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1376 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1377 mpi_request.Header.PageNumber = 0;
1378 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1379 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1380 r = _config_request(ioc, &mpi_request, mpi_reply,
1381 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1382 if (r)
1383 goto out;
1384
1385 mpi_request.PageAddress =
1386 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1387 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1388 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1389 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1390 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1391 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1392 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1393 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1394 if (mem.config_page_sz > ioc->config_page_sz) {
1395 r = _config_alloc_config_dma_memory(ioc, &mem);
1396 if (r)
1397 goto out;
1398 } else {
1399 mem.config_page_dma = ioc->config_page_dma;
1400 mem.config_page = ioc->config_page;
1401 }
1402 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1403 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1404 mem.config_page_dma);
1405 r = _config_request(ioc, &mpi_request, mpi_reply,
1406 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1407 if (!r)
1408 memcpy(config_page, mem.config_page,
1409 min_t(u16, mem.config_page_sz,
1410 sizeof(Mpi2SasPhyPage0_t)));
1411
1412 if (mem.config_page_sz > ioc->config_page_sz)
1413 _config_free_config_dma_memory(ioc, &mem);
1414
1415 out:
1416 mutex_unlock(&ioc->config_cmds.mutex);
1417 return r;
1418}
1419
1420/**
1421 * mpt2sas_config_get_phy_pg1 - obtain phy page 1
1422 * @ioc: per adapter object
1423 * @mpi_reply: reply mf payload returned from firmware
1424 * @config_page: contents of the config page
1425 * @phy_number: phy number
1426 * Context: sleep.
1427 *
1428 * Returns 0 for success, non-zero for failure.
1429 */
1430int
1431mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1432 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1433{
1434 Mpi2ConfigRequest_t mpi_request;
1435 int r;
1436 struct config_request mem;
1437
1438 mutex_lock(&ioc->config_cmds.mutex);
1439 memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
1440 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1441 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1442 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1443 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1444 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1445 mpi_request.Header.PageNumber = 1;
1446 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1447 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1448 r = _config_request(ioc, &mpi_request, mpi_reply,
1449 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1450 if (r)
1451 goto out;
1452
1453 mpi_request.PageAddress =
1454 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1455 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1456 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1457 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1458 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1459 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1460 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1461 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1462 if (mem.config_page_sz > ioc->config_page_sz) {
1463 r = _config_alloc_config_dma_memory(ioc, &mem);
1464 if (r)
1465 goto out;
1466 } else {
1467 mem.config_page_dma = ioc->config_page_dma;
1468 mem.config_page = ioc->config_page;
1469 }
1470 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1471 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1472 mem.config_page_dma);
1473 r = _config_request(ioc, &mpi_request, mpi_reply,
1474 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1475 if (!r)
1476 memcpy(config_page, mem.config_page,
1477 min_t(u16, mem.config_page_sz,
1478 sizeof(Mpi2SasPhyPage1_t)));
1479
1480 if (mem.config_page_sz > ioc->config_page_sz)
1481 _config_free_config_dma_memory(ioc, &mem);
1482
1483 out:
1484 mutex_unlock(&ioc->config_cmds.mutex);
1485 return r;
1486}
1487
1488/**
1489 * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1490 * @ioc: per adapter object
1491 * @mpi_reply: reply mf payload returned from firmware
1492 * @config_page: contents of the config page
1493 * @form: GET_NEXT_HANDLE or HANDLE
1494 * @handle: volume handle
1495 * Context: sleep.
1496 *
1497 * Returns 0 for success, non-zero for failure.
1498 */
1499int
1500mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
1501 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1502 u32 handle)
1503{
1504 Mpi2ConfigRequest_t mpi_request;
1505 int r;
1506 struct config_request mem;
1507
1508 mutex_lock(&ioc->config_cmds.mutex);
1509 memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
1510 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1511 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1512 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1513 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1514 mpi_request.Header.PageNumber = 1;
1515 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1516 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1517 r = _config_request(ioc, &mpi_request, mpi_reply,
1518 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1519 if (r)
1520 goto out;
1521
1522 mpi_request.PageAddress = cpu_to_le32(form | handle);
1523 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1524 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1525 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1526 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1527 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1528 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1529 if (mem.config_page_sz > ioc->config_page_sz) {
1530 r = _config_alloc_config_dma_memory(ioc, &mem);
1531 if (r)
1532 goto out;
1533 } else {
1534 mem.config_page_dma = ioc->config_page_dma;
1535 mem.config_page = ioc->config_page;
1536 }
1537 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1538 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1539 mem.config_page_dma);
1540 r = _config_request(ioc, &mpi_request, mpi_reply,
1541 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1542 if (!r)
1543 memcpy(config_page, mem.config_page,
1544 min_t(u16, mem.config_page_sz,
1545 sizeof(Mpi2RaidVolPage1_t)));
1546
1547 if (mem.config_page_sz > ioc->config_page_sz)
1548 _config_free_config_dma_memory(ioc, &mem);
1549
1550 out:
1551 mutex_unlock(&ioc->config_cmds.mutex);
1552 return r;
1553}
1554
1555/**
1556 * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
1557 * @ioc: per adapter object
1558 * @handle: volume handle
1559 * @num_pds: returns pds count
1560 * Context: sleep.
1561 *
1562 * Returns 0 for success, non-zero for failure.
1563 */
1564int
1565mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
1566 u8 *num_pds)
1567{
1568 Mpi2ConfigRequest_t mpi_request;
1569 Mpi2RaidVolPage0_t *config_page;
1570 Mpi2ConfigReply_t mpi_reply;
1571 int r;
1572 struct config_request mem;
1573 u16 ioc_status;
1574
1575 mutex_lock(&ioc->config_cmds.mutex);
1576 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1577 *num_pds = 0;
1578 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1579 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1580 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1581 mpi_request.Header.PageNumber = 0;
1582 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1583 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1584 r = _config_request(ioc, &mpi_request, &mpi_reply,
1585 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1586 if (r)
1587 goto out;
1588
1589 mpi_request.PageAddress =
1590 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1591 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1592 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1593 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1594 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1595 mpi_request.Header.PageLength = mpi_reply.Header.PageLength;
1596 mem.config_page_sz = le16_to_cpu(mpi_reply.Header.PageLength) * 4;
1597 if (mem.config_page_sz > ioc->config_page_sz) {
1598 r = _config_alloc_config_dma_memory(ioc, &mem);
1599 if (r)
1600 goto out;
1601 } else {
1602 mem.config_page_dma = ioc->config_page_dma;
1603 mem.config_page = ioc->config_page;
1604 }
1605 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1606 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1607 mem.config_page_dma);
1608 r = _config_request(ioc, &mpi_request, &mpi_reply,
1609 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1610 if (!r) {
1611 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1612 MPI2_IOCSTATUS_MASK;
1613 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1614 config_page = mem.config_page;
1615 *num_pds = config_page->NumPhysDisks;
1616 }
1617 }
1618
1619 if (mem.config_page_sz > ioc->config_page_sz)
1620 _config_free_config_dma_memory(ioc, &mem);
1621
1622 out:
1623 mutex_unlock(&ioc->config_cmds.mutex);
1624 return r;
1625}
1626
1627/**
1628 * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1629 * @ioc: per adapter object
1630 * @mpi_reply: reply mf payload returned from firmware
1631 * @config_page: contents of the config page
1632 * @form: GET_NEXT_HANDLE or HANDLE
1633 * @handle: volume handle
1634 * @sz: size of buffer passed in config_page
1635 * Context: sleep.
1636 *
1637 * Returns 0 for success, non-zero for failure.
1638 */
1639int
1640mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
1641 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1642 u32 handle, u16 sz)
1643{
1644 Mpi2ConfigRequest_t mpi_request;
1645 int r;
1646 struct config_request mem;
1647
1648 mutex_lock(&ioc->config_cmds.mutex);
1649 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1650 memset(config_page, 0, sz);
1651 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1652 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1653 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1654 mpi_request.Header.PageNumber = 0;
1655 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1656 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1657 r = _config_request(ioc, &mpi_request, mpi_reply,
1658 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1659 if (r)
1660 goto out;
1661
1662 mpi_request.PageAddress = cpu_to_le32(form | handle);
1663 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1664 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1665 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1666 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1667 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1668 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1669 if (mem.config_page_sz > ioc->config_page_sz) {
1670 r = _config_alloc_config_dma_memory(ioc, &mem);
1671 if (r)
1672 goto out;
1673 } else {
1674 mem.config_page_dma = ioc->config_page_dma;
1675 mem.config_page = ioc->config_page;
1676 }
1677 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1678 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1679 mem.config_page_dma);
1680 r = _config_request(ioc, &mpi_request, mpi_reply,
1681 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1682 if (!r)
1683 memcpy(config_page, mem.config_page,
1684 min_t(u16, sz, mem.config_page_sz));
1685
1686 if (mem.config_page_sz > ioc->config_page_sz)
1687 _config_free_config_dma_memory(ioc, &mem);
1688
1689 out:
1690 mutex_unlock(&ioc->config_cmds.mutex);
1691 return r;
1692}
1693
1694/**
1695 * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1696 * @ioc: per adapter object
1697 * @mpi_reply: reply mf payload returned from firmware
1698 * @config_page: contents of the config page
1699 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1700 * @form_specific: specific to the form
1701 * Context: sleep.
1702 *
1703 * Returns 0 for success, non-zero for failure.
1704 */
1705int
1706mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1707 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1708 u32 form_specific)
1709{
1710 Mpi2ConfigRequest_t mpi_request;
1711 int r;
1712 struct config_request mem;
1713
1714 mutex_lock(&ioc->config_cmds.mutex);
1715 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1716 memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
1717 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1718 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1719 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1720 mpi_request.Header.PageNumber = 0;
1721 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1722 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1723 r = _config_request(ioc, &mpi_request, mpi_reply,
1724 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1725 if (r)
1726 goto out;
1727
1728 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1729 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1730 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1731 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1732 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1733 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1734 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1735 if (mem.config_page_sz > ioc->config_page_sz) {
1736 r = _config_alloc_config_dma_memory(ioc, &mem);
1737 if (r)
1738 goto out;
1739 } else {
1740 mem.config_page_dma = ioc->config_page_dma;
1741 mem.config_page = ioc->config_page;
1742 }
1743 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1744 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1745 mem.config_page_dma);
1746 r = _config_request(ioc, &mpi_request, mpi_reply,
1747 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1748 if (!r)
1749 memcpy(config_page, mem.config_page,
1750 min_t(u16, mem.config_page_sz,
1751 sizeof(Mpi2RaidPhysDiskPage0_t)));
1752
1753 if (mem.config_page_sz > ioc->config_page_sz)
1754 _config_free_config_dma_memory(ioc, &mem);
1755
1756 out:
1757 mutex_unlock(&ioc->config_cmds.mutex);
1758 return r;
1759}
1760
1761/**
1762 * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
1763 * @ioc: per adapter object
1764 * @pd_handle: phys disk handle
1765 * @volume_handle: volume handle
1766 * Context: sleep.
1767 *
1768 * Returns 0 for success, non-zero for failure.
1769 */
1770int
1771mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1772 u16 *volume_handle)
1773{
1774 Mpi2RaidConfigurationPage0_t *config_page;
1775 Mpi2ConfigRequest_t mpi_request;
1776 Mpi2ConfigReply_t mpi_reply;
1777 int r, i;
1778 struct config_request mem;
1779 u16 ioc_status;
1780
1781 mutex_lock(&ioc->config_cmds.mutex);
1782 *volume_handle = 0;
1783 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1784 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1785 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1786 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1787 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1788 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1789 mpi_request.Header.PageNumber = 0;
1790 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1791 r = _config_request(ioc, &mpi_request, &mpi_reply,
1792 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1793 if (r)
1794 goto out;
1795
1796 mpi_request.PageAddress =
1797 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
1798 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1799 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1800 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1801 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1802 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
1803 mpi_request.ExtPageType = mpi_reply.ExtPageType;
1804 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
1805 if (mem.config_page_sz > ioc->config_page_sz) {
1806 r = _config_alloc_config_dma_memory(ioc, &mem);
1807 if (r)
1808 goto out;
1809 } else {
1810 mem.config_page_dma = ioc->config_page_dma;
1811 mem.config_page = ioc->config_page;
1812 }
1813 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1814 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1815 mem.config_page_dma);
1816 r = _config_request(ioc, &mpi_request, &mpi_reply,
1817 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1818 if (r)
1819 goto out;
1820
1821 r = -1;
1822 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
1823 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1824 goto done;
1825 config_page = mem.config_page;
1826 for (i = 0; i < config_page->NumElements; i++) {
1827 if ((config_page->ConfigElement[i].ElementFlags &
1828 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
1829 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
1830 continue;
1831 if (config_page->ConfigElement[i].PhysDiskDevHandle ==
1832 pd_handle) {
1833 *volume_handle = le16_to_cpu(config_page->
1834 ConfigElement[i].VolDevHandle);
1835 r = 0;
1836 goto done;
1837 }
1838 }
1839
1840 done:
1841 if (mem.config_page_sz > ioc->config_page_sz)
1842 _config_free_config_dma_memory(ioc, &mem);
1843
1844 out:
1845 mutex_unlock(&ioc->config_cmds.mutex);
1846 return r;
1847}
1848
1849/**
1850 * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
1851 * @ioc: per adapter object
1852 * @volume_handle: volume handle
1853 * @wwid: volume wwid
1854 * Context: sleep.
1855 *
1856 * Returns 0 for success, non-zero for failure.
1857 */
1858int
1859mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
1860 u64 *wwid)
1861{
1862 Mpi2ConfigReply_t mpi_reply;
1863 Mpi2RaidVolPage1_t raid_vol_pg1;
1864
1865 *wwid = 0;
1866 if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1867 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1868 volume_handle))) {
1869 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
1870 return 0;
1871 } else
1872 return -1;
1873}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
new file mode 100644
index 000000000000..2d4f85c9d7a1
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -0,0 +1,2516 @@
1/*
2 * Management Module Support for MPT (Message Passing Technology) based
3 * controllers
4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
6 * Copyright (C) 2007-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
45#include <linux/version.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/errno.h>
49#include <linux/init.h>
50#include <linux/slab.h>
51#include <linux/types.h>
52#include <linux/pci.h>
53#include <linux/delay.h>
54#include <linux/smp_lock.h>
55#include <linux/compat.h>
56#include <linux/poll.h>
57
58#include <linux/io.h>
59#include <linux/uaccess.h>
60
61#include "mpt2sas_base.h"
62#include "mpt2sas_ctl.h"
63
64static struct fasync_struct *async_queue;
65static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);
66
67/**
68 * enum block_state - blocking state
69 * @NON_BLOCKING: non blocking
70 * @BLOCKING: blocking
71 *
72 * These states are for ioctls that need to wait for a response
73 * from firmware, so they probably require sleep.
74 */
75enum block_state {
76 NON_BLOCKING,
77 BLOCKING,
78};
79
80#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
81/**
82 * _ctl_display_some_debug - debug routine
83 * @ioc: per adapter object
84 * @smid: system request message index
85 * @calling_function_name: string pass from calling function
86 * @mpi_reply: reply message frame
87 * Context: none.
88 *
89 * Function for displaying debug info helpfull when debugging issues
90 * in this module.
91 */
92static void
93_ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
94 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
95{
96 Mpi2ConfigRequest_t *mpi_request;
97 char *desc = NULL;
98
99 if (!(ioc->logging_level & MPT_DEBUG_IOCTL))
100 return;
101
102 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
103 switch (mpi_request->Function) {
104 case MPI2_FUNCTION_SCSI_IO_REQUEST:
105 {
106 Mpi2SCSIIORequest_t *scsi_request =
107 (Mpi2SCSIIORequest_t *)mpi_request;
108
109 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
110 "scsi_io, cmd(0x%02x), cdb_len(%d)",
111 scsi_request->CDB.CDB32[0],
112 le16_to_cpu(scsi_request->IoFlags) & 0xF);
113 desc = ioc->tmp_string;
114 break;
115 }
116 case MPI2_FUNCTION_SCSI_TASK_MGMT:
117 desc = "task_mgmt";
118 break;
119 case MPI2_FUNCTION_IOC_INIT:
120 desc = "ioc_init";
121 break;
122 case MPI2_FUNCTION_IOC_FACTS:
123 desc = "ioc_facts";
124 break;
125 case MPI2_FUNCTION_CONFIG:
126 {
127 Mpi2ConfigRequest_t *config_request =
128 (Mpi2ConfigRequest_t *)mpi_request;
129
130 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
131 "config, type(0x%02x), ext_type(0x%02x), number(%d)",
132 (config_request->Header.PageType &
133 MPI2_CONFIG_PAGETYPE_MASK), config_request->ExtPageType,
134 config_request->Header.PageNumber);
135 desc = ioc->tmp_string;
136 break;
137 }
138 case MPI2_FUNCTION_PORT_FACTS:
139 desc = "port_facts";
140 break;
141 case MPI2_FUNCTION_PORT_ENABLE:
142 desc = "port_enable";
143 break;
144 case MPI2_FUNCTION_EVENT_NOTIFICATION:
145 desc = "event_notification";
146 break;
147 case MPI2_FUNCTION_FW_DOWNLOAD:
148 desc = "fw_download";
149 break;
150 case MPI2_FUNCTION_FW_UPLOAD:
151 desc = "fw_upload";
152 break;
153 case MPI2_FUNCTION_RAID_ACTION:
154 desc = "raid_action";
155 break;
156 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
157 {
158 Mpi2SCSIIORequest_t *scsi_request =
159 (Mpi2SCSIIORequest_t *)mpi_request;
160
161 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,
162 "raid_pass, cmd(0x%02x), cdb_len(%d)",
163 scsi_request->CDB.CDB32[0],
164 le16_to_cpu(scsi_request->IoFlags) & 0xF);
165 desc = ioc->tmp_string;
166 break;
167 }
168 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
169 desc = "sas_iounit_cntl";
170 break;
171 case MPI2_FUNCTION_SATA_PASSTHROUGH:
172 desc = "sata_pass";
173 break;
174 case MPI2_FUNCTION_DIAG_BUFFER_POST:
175 desc = "diag_buffer_post";
176 break;
177 case MPI2_FUNCTION_DIAG_RELEASE:
178 desc = "diag_release";
179 break;
180 case MPI2_FUNCTION_SMP_PASSTHROUGH:
181 desc = "smp_passthrough";
182 break;
183 }
184
185 if (!desc)
186 return;
187
188 printk(MPT2SAS_DEBUG_FMT "%s: %s, smid(%d)\n",
189 ioc->name, calling_function_name, desc, smid);
190
191 if (!mpi_reply)
192 return;
193
194 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
195 printk(MPT2SAS_DEBUG_FMT
196 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
197 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
198 le32_to_cpu(mpi_reply->IOCLogInfo));
199
200 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
201 mpi_request->Function ==
202 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
203 Mpi2SCSIIOReply_t *scsi_reply =
204 (Mpi2SCSIIOReply_t *)mpi_reply;
205 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
206 printk(MPT2SAS_DEBUG_FMT
207 "\tscsi_state(0x%02x), scsi_status"
208 "(0x%02x)\n", ioc->name,
209 scsi_reply->SCSIState,
210 scsi_reply->SCSIStatus);
211 }
212}
213#endif
214
215/**
216 * mpt2sas_ctl_done - ctl module completion routine
217 * @ioc: per adapter object
218 * @smid: system request message index
219 * @VF_ID: virtual function id
220 * @reply: reply message frame(lower 32bit addr)
221 * Context: none.
222 *
223 * The callback handler when using ioc->ctl_cb_idx.
224 *
225 * Return nothing.
226 */
227void
228mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
229{
230 MPI2DefaultReply_t *mpi_reply;
231
232 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
233 return;
234 if (ioc->ctl_cmds.smid != smid)
235 return;
236 ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE;
237 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
238 if (mpi_reply) {
239 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
240 ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID;
241 }
242#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
243 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
244#endif
245 ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING;
246 complete(&ioc->ctl_cmds.done);
247}
248
249/**
250 * _ctl_check_event_type - determines when an event needs logging
251 * @ioc: per adapter object
252 * @event: firmware event
253 *
254 * The bitmask in ioc->event_type[] indicates which events should be
255 * be saved in the driver event_log. This bitmask is set by application.
256 *
257 * Returns 1 when event should be captured, or zero means no match.
258 */
259static int
260_ctl_check_event_type(struct MPT2SAS_ADAPTER *ioc, u16 event)
261{
262 u16 i;
263 u32 desired_event;
264
265 if (event >= 128 || !event || !ioc->event_log)
266 return 0;
267
268 desired_event = (1 << (event % 32));
269 if (!desired_event)
270 desired_event = 1;
271 i = event / 32;
272 return desired_event & ioc->event_type[i];
273}
274
275/**
276 * mpt2sas_ctl_add_to_event_log - add event
277 * @ioc: per adapter object
278 * @mpi_reply: reply message frame
279 *
280 * Return nothing.
281 */
282void
283mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
284 Mpi2EventNotificationReply_t *mpi_reply)
285{
286 struct MPT2_IOCTL_EVENTS *event_log;
287 u16 event;
288 int i;
289 u32 sz, event_data_sz;
290 u8 send_aen = 0;
291
292 if (!ioc->event_log)
293 return;
294
295 event = le16_to_cpu(mpi_reply->Event);
296
297 if (_ctl_check_event_type(ioc, event)) {
298
299 /* insert entry into circular event_log */
300 i = ioc->event_context % MPT2SAS_CTL_EVENT_LOG_SIZE;
301 event_log = ioc->event_log;
302 event_log[i].event = event;
303 event_log[i].context = ioc->event_context++;
304
305 event_data_sz = le16_to_cpu(mpi_reply->EventDataLength)*4;
306 sz = min_t(u32, event_data_sz, MPT2_EVENT_DATA_SIZE);
307 memset(event_log[i].data, 0, MPT2_EVENT_DATA_SIZE);
308 memcpy(event_log[i].data, mpi_reply->EventData, sz);
309 send_aen = 1;
310 }
311
312 /* This aen_event_read_flag flag is set until the
313 * application has read the event log.
314 * For MPI2_EVENT_LOG_ENTRY_ADDED, we always notify.
315 */
316 if (event == MPI2_EVENT_LOG_ENTRY_ADDED ||
317 (send_aen && !ioc->aen_event_read_flag)) {
318 ioc->aen_event_read_flag = 1;
319 wake_up_interruptible(&ctl_poll_wait);
320 if (async_queue)
321 kill_fasync(&async_queue, SIGIO, POLL_IN);
322 }
323}
324
325/**
326 * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time)
327 * @ioc: per adapter object
328 * @VF_ID: virtual function id
329 * @reply: reply message frame(lower 32bit addr)
330 * Context: interrupt.
331 *
332 * This function merely adds a new work task into ioc->firmware_event_thread.
333 * The tasks are worked from _firmware_event_work in user context.
334 *
335 * Return nothing.
336 */
337void
338mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
339{
340 Mpi2EventNotificationReply_t *mpi_reply;
341
342 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
343 mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
344}
345
346/**
347 * _ctl_verify_adapter - validates ioc_number passed from application
348 * @ioc: per adapter object
349 * @iocpp: The ioc pointer is returned in this.
350 *
351 * Return (-1) means error, else ioc_number.
352 */
353static int
354_ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp)
355{
356 struct MPT2SAS_ADAPTER *ioc;
357
358 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
359 if (ioc->id != ioc_number)
360 continue;
361 *iocpp = ioc;
362 return ioc_number;
363 }
364 *iocpp = NULL;
365 return -1;
366}
367
368/**
369 * mpt2sas_ctl_reset_handler - reset callback handler (for ctl)
370 * @ioc: per adapter object
371 * @reset_phase: phase
372 *
373 * The handler for doing any required cleanup or initialization.
374 *
375 * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
376 * MPT2_IOC_DONE_RESET
377 */
378void
379mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
380{
381 switch (reset_phase) {
382 case MPT2_IOC_PRE_RESET:
383 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
384 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
385 break;
386 case MPT2_IOC_AFTER_RESET:
387 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
388 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
389 if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) {
390 ioc->ctl_cmds.status |= MPT2_CMD_RESET;
391 mpt2sas_base_free_smid(ioc, ioc->ctl_cmds.smid);
392 complete(&ioc->ctl_cmds.done);
393 }
394 break;
395 case MPT2_IOC_DONE_RESET:
396 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
397 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
398 break;
399 }
400}
401
402/**
403 * _ctl_fasync -
404 * @fd -
405 * @filep -
406 * @mode -
407 *
408 * Called when application request fasyn callback handler.
409 */
410static int
411_ctl_fasync(int fd, struct file *filep, int mode)
412{
413 return fasync_helper(fd, filep, mode, &async_queue);
414}
415
416/**
417 * _ctl_release -
418 * @inode -
419 * @filep -
420 *
421 * Called when application releases the fasyn callback handler.
422 */
423static int
424_ctl_release(struct inode *inode, struct file *filep)
425{
426 return fasync_helper(-1, filep, 0, &async_queue);
427}
428
429/**
430 * _ctl_poll -
431 * @file -
432 * @wait -
433 *
434 */
435static unsigned int
436_ctl_poll(struct file *filep, poll_table *wait)
437{
438 struct MPT2SAS_ADAPTER *ioc;
439
440 poll_wait(filep, &ctl_poll_wait, wait);
441
442 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
443 if (ioc->aen_event_read_flag)
444 return POLLIN | POLLRDNORM;
445 }
446 return 0;
447}
448
449/**
450 * _ctl_do_task_abort - assign an active smid to the abort_task
451 * @ioc: per adapter object
452 * @karg - (struct mpt2_ioctl_command)
453 * @tm_request - pointer to mf from user space
454 *
455 * Returns 0 when an smid if found, else fail.
456 * during failure, the reply frame is filled.
457 */
458static int
459_ctl_do_task_abort(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
460 Mpi2SCSITaskManagementRequest_t *tm_request)
461{
462 u8 found = 0;
463 u16 i;
464 u16 handle;
465 struct scsi_cmnd *scmd;
466 struct MPT2SAS_DEVICE *priv_data;
467 unsigned long flags;
468 Mpi2SCSITaskManagementReply_t *tm_reply;
469 u32 sz;
470 u32 lun;
471
472 lun = scsilun_to_int((struct scsi_lun *)tm_request->LUN);
473
474 handle = le16_to_cpu(tm_request->DevHandle);
475 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
476 for (i = ioc->request_depth; i && !found; i--) {
477 scmd = ioc->scsi_lookup[i - 1].scmd;
478 if (scmd == NULL || scmd->device == NULL ||
479 scmd->device->hostdata == NULL)
480 continue;
481 if (lun != scmd->device->lun)
482 continue;
483 priv_data = scmd->device->hostdata;
484 if (priv_data->sas_target == NULL)
485 continue;
486 if (priv_data->sas_target->handle != handle)
487 continue;
488 tm_request->TaskMID = cpu_to_le16(ioc->scsi_lookup[i - 1].smid);
489 found = 1;
490 }
491 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
492
493 if (!found) {
494 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ABORT_TASK: "
495 "DevHandle(0x%04x), lun(%d), no active mid!!\n", ioc->name,
496 tm_request->DevHandle, lun));
497 tm_reply = ioc->ctl_cmds.reply;
498 tm_reply->DevHandle = tm_request->DevHandle;
499 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
500 tm_reply->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
501 tm_reply->MsgLength = sizeof(Mpi2SCSITaskManagementReply_t)/4;
502 tm_reply->VP_ID = tm_request->VP_ID;
503 tm_reply->VF_ID = tm_request->VF_ID;
504 sz = min_t(u32, karg->max_reply_bytes, ioc->reply_sz);
505 if (copy_to_user(karg->reply_frame_buf_ptr, ioc->ctl_cmds.reply,
506 sz))
507 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
508 __LINE__, __func__);
509 return 1;
510 }
511
512 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ABORT_TASK: "
513 "DevHandle(0x%04x), lun(%d), smid(%d)\n", ioc->name,
514 tm_request->DevHandle, lun, tm_request->TaskMID));
515 return 0;
516}
517
518/**
519 * _ctl_do_mpt_command - main handler for MPT2COMMAND opcode
520 * @ioc: per adapter object
521 * @karg - (struct mpt2_ioctl_command)
522 * @mf - pointer to mf in user space
523 * @state - NON_BLOCKING or BLOCKING
524 */
525static long
526_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
527 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state)
528{
529 MPI2RequestHeader_t *mpi_request;
530 MPI2DefaultReply_t *mpi_reply;
531 u32 ioc_state;
532 u16 ioc_status;
533 u16 smid;
534 unsigned long timeout, timeleft;
535 u8 issue_reset;
536 u32 sz;
537 void *psge;
538 void *priv_sense = NULL;
539 void *data_out = NULL;
540 dma_addr_t data_out_dma;
541 size_t data_out_sz = 0;
542 void *data_in = NULL;
543 dma_addr_t data_in_dma;
544 size_t data_in_sz = 0;
545 u32 sgl_flags;
546 long ret;
547 u16 wait_state_count;
548
549 issue_reset = 0;
550
551 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
552 return -EAGAIN;
553 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
554 return -ERESTARTSYS;
555
556 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
557 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
558 ioc->name, __func__);
559 ret = -EAGAIN;
560 goto out;
561 }
562
563 wait_state_count = 0;
564 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
565 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
566 if (wait_state_count++ == 10) {
567 printk(MPT2SAS_ERR_FMT
568 "%s: failed due to ioc not operational\n",
569 ioc->name, __func__);
570 ret = -EFAULT;
571 goto out;
572 }
573 ssleep(1);
574 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
575 printk(MPT2SAS_INFO_FMT "%s: waiting for "
576 "operational state(count=%d)\n", ioc->name,
577 __func__, wait_state_count);
578 }
579 if (wait_state_count)
580 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
581 ioc->name, __func__);
582
583 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
584 if (!smid) {
585 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
586 ioc->name, __func__);
587 ret = -EAGAIN;
588 goto out;
589 }
590
591 ret = 0;
592 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
593 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
594 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
595 ioc->ctl_cmds.smid = smid;
596 data_out_sz = karg.data_out_size;
597 data_in_sz = karg.data_in_size;
598
599 /* copy in request message frame from user */
600 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {
601 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
602 __func__);
603 ret = -EFAULT;
604 mpt2sas_base_free_smid(ioc, smid);
605 goto out;
606 }
607
608 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
609 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
610 if (!mpi_request->FunctionDependent1 ||
611 mpi_request->FunctionDependent1 >
612 cpu_to_le16(ioc->facts.MaxDevHandle)) {
613 ret = -EINVAL;
614 mpt2sas_base_free_smid(ioc, smid);
615 goto out;
616 }
617 }
618
619 /* obtain dma-able memory for data transfer */
620 if (data_out_sz) /* WRITE */ {
621 data_out = pci_alloc_consistent(ioc->pdev, data_out_sz,
622 &data_out_dma);
623 if (!data_out) {
624 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
625 __LINE__, __func__);
626 ret = -ENOMEM;
627 mpt2sas_base_free_smid(ioc, smid);
628 goto out;
629 }
630 if (copy_from_user(data_out, karg.data_out_buf_ptr,
631 data_out_sz)) {
632 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
633 __LINE__, __func__);
634 ret = -EFAULT;
635 mpt2sas_base_free_smid(ioc, smid);
636 goto out;
637 }
638 }
639
640 if (data_in_sz) /* READ */ {
641 data_in = pci_alloc_consistent(ioc->pdev, data_in_sz,
642 &data_in_dma);
643 if (!data_in) {
644 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
645 __LINE__, __func__);
646 ret = -ENOMEM;
647 mpt2sas_base_free_smid(ioc, smid);
648 goto out;
649 }
650 }
651
652 /* add scatter gather elements */
653 psge = (void *)mpi_request + (karg.data_sge_offset*4);
654
655 if (!data_out_sz && !data_in_sz) {
656 mpt2sas_base_build_zero_len_sge(ioc, psge);
657 } else if (data_out_sz && data_in_sz) {
658 /* WRITE sgel first */
659 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
660 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
661 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
662 ioc->base_add_sg_single(psge, sgl_flags |
663 data_out_sz, data_out_dma);
664
665 /* incr sgel */
666 psge += ioc->sge_size;
667
668 /* READ sgel last */
669 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
670 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
671 MPI2_SGE_FLAGS_END_OF_LIST);
672 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
673 ioc->base_add_sg_single(psge, sgl_flags |
674 data_in_sz, data_in_dma);
675 } else if (data_out_sz) /* WRITE */ {
676 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
677 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
678 MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC);
679 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
680 ioc->base_add_sg_single(psge, sgl_flags |
681 data_out_sz, data_out_dma);
682 } else if (data_in_sz) /* READ */ {
683 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
684 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
685 MPI2_SGE_FLAGS_END_OF_LIST);
686 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
687 ioc->base_add_sg_single(psge, sgl_flags |
688 data_in_sz, data_in_dma);
689 }
690
691 /* send command to firmware */
692#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
693 _ctl_display_some_debug(ioc, smid, "ctl_request", NULL);
694#endif
695
696 switch (mpi_request->Function) {
697 case MPI2_FUNCTION_SCSI_IO_REQUEST:
698 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
699 {
700 Mpi2SCSIIORequest_t *scsiio_request =
701 (Mpi2SCSIIORequest_t *)mpi_request;
702 scsiio_request->SenseBufferLowAddress =
703 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
704 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
705 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
706 mpt2sas_base_put_smid_scsi_io(ioc, smid, 0,
707 le16_to_cpu(mpi_request->FunctionDependent1));
708 break;
709 }
710 case MPI2_FUNCTION_SCSI_TASK_MGMT:
711 {
712 Mpi2SCSITaskManagementRequest_t *tm_request =
713 (Mpi2SCSITaskManagementRequest_t *)mpi_request;
714
715 if (tm_request->TaskType ==
716 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
717 if (_ctl_do_task_abort(ioc, &karg, tm_request))
718 goto out;
719 }
720
721 mutex_lock(&ioc->tm_cmds.mutex);
722 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
723 tm_request->DevHandle));
724 mpt2sas_base_put_smid_hi_priority(ioc, smid,
725 mpi_request->VF_ID);
726 break;
727 }
728 case MPI2_FUNCTION_SMP_PASSTHROUGH:
729 {
730 Mpi2SmpPassthroughRequest_t *smp_request =
731 (Mpi2SmpPassthroughRequest_t *)mpi_request;
732 u8 *data;
733
734 /* ioc determines which port to use */
735 smp_request->PhysicalPort = 0xFF;
736 if (smp_request->PassthroughFlags &
737 MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE)
738 data = (u8 *)&smp_request->SGL;
739 else
740 data = data_out;
741
742 if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) {
743 ioc->ioc_link_reset_in_progress = 1;
744 ioc->ignore_loginfos = 1;
745 }
746 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
747 break;
748 }
749 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
750 {
751 Mpi2SasIoUnitControlRequest_t *sasiounit_request =
752 (Mpi2SasIoUnitControlRequest_t *)mpi_request;
753
754 if (sasiounit_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET
755 || sasiounit_request->Operation ==
756 MPI2_SAS_OP_PHY_LINK_RESET) {
757 ioc->ioc_link_reset_in_progress = 1;
758 ioc->ignore_loginfos = 1;
759 }
760 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
761 break;
762 }
763 default:
764 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
765 break;
766 }
767
768 if (karg.timeout < MPT2_IOCTL_DEFAULT_TIMEOUT)
769 timeout = MPT2_IOCTL_DEFAULT_TIMEOUT;
770 else
771 timeout = karg.timeout;
772 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
773 timeout*HZ);
774 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
775 Mpi2SCSITaskManagementRequest_t *tm_request =
776 (Mpi2SCSITaskManagementRequest_t *)mpi_request;
777 mutex_unlock(&ioc->tm_cmds.mutex);
778 mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu(
779 tm_request->DevHandle));
780 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH ||
781 mpi_request->Function == MPI2_FUNCTION_SAS_IO_UNIT_CONTROL) &&
782 ioc->ioc_link_reset_in_progress) {
783 ioc->ioc_link_reset_in_progress = 0;
784 ioc->ignore_loginfos = 0;
785 }
786 if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
787 printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
788 __func__);
789 _debug_dump_mf(mpi_request, karg.data_sge_offset);
790 if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
791 issue_reset = 1;
792 goto issue_host_reset;
793 }
794
795 mpi_reply = ioc->ctl_cmds.reply;
796 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
797
798#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
799 if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT &&
800 (ioc->logging_level & MPT_DEBUG_TM)) {
801 Mpi2SCSITaskManagementReply_t *tm_reply =
802 (Mpi2SCSITaskManagementReply_t *)mpi_reply;
803
804 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
805 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
806 "TerminationCount(0x%08x)\n", ioc->name,
807 tm_reply->IOCStatus, tm_reply->IOCLogInfo,
808 tm_reply->TerminationCount);
809 }
810#endif
811 /* copy out xdata to user */
812 if (data_in_sz) {
813 if (copy_to_user(karg.data_in_buf_ptr, data_in,
814 data_in_sz)) {
815 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
816 __LINE__, __func__);
817 ret = -ENODATA;
818 goto out;
819 }
820 }
821
822 /* copy out reply message frame to user */
823 if (karg.max_reply_bytes) {
824 sz = min_t(u32, karg.max_reply_bytes, ioc->reply_sz);
825 if (copy_to_user(karg.reply_frame_buf_ptr, ioc->ctl_cmds.reply,
826 sz)) {
827 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
828 __LINE__, __func__);
829 ret = -ENODATA;
830 goto out;
831 }
832 }
833
834 /* copy out sense to user */
835 if (karg.max_sense_bytes && (mpi_request->Function ==
836 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
837 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
838 sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
839 if (copy_to_user(karg.sense_data_ptr, priv_sense, sz)) {
840 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
841 __LINE__, __func__);
842 ret = -ENODATA;
843 goto out;
844 }
845 }
846
847 issue_host_reset:
848 if (issue_reset) {
849 if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
850 mpi_request->Function ==
851 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
852 printk(MPT2SAS_INFO_FMT "issue target reset: handle "
853 "= (0x%04x)\n", ioc->name,
854 mpi_request->FunctionDependent1);
855 mutex_lock(&ioc->tm_cmds.mutex);
856 mpt2sas_scsih_issue_tm(ioc,
857 mpi_request->FunctionDependent1, 0,
858 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10);
859 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
860 mutex_unlock(&ioc->tm_cmds.mutex);
861 } else
862 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
863 FORCE_BIG_HAMMER);
864 }
865
866 out:
867
868 /* free memory associated with sg buffers */
869 if (data_in)
870 pci_free_consistent(ioc->pdev, data_in_sz, data_in,
871 data_in_dma);
872
873 if (data_out)
874 pci_free_consistent(ioc->pdev, data_out_sz, data_out,
875 data_out_dma);
876
877 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
878 mutex_unlock(&ioc->ctl_cmds.mutex);
879 return ret;
880}
881
882/**
883 * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode
884 * @arg - user space buffer containing ioctl content
885 */
886static long
887_ctl_getiocinfo(void __user *arg)
888{
889 struct mpt2_ioctl_iocinfo karg;
890 struct MPT2SAS_ADAPTER *ioc;
891 u8 revision;
892
893 if (copy_from_user(&karg, arg, sizeof(karg))) {
894 printk(KERN_ERR "failure at %s:%d/%s()!\n",
895 __FILE__, __LINE__, __func__);
896 return -EFAULT;
897 }
898 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
899 return -ENODEV;
900
901 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
902 __func__));
903
904 memset(&karg, 0 , sizeof(karg));
905 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
906 if (ioc->pfacts)
907 karg.port_number = ioc->pfacts[0].PortNumber;
908 pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision);
909 karg.hw_rev = revision;
910 karg.pci_id = ioc->pdev->device;
911 karg.subsystem_device = ioc->pdev->subsystem_device;
912 karg.subsystem_vendor = ioc->pdev->subsystem_vendor;
913 karg.pci_information.u.bits.bus = ioc->pdev->bus->number;
914 karg.pci_information.u.bits.device = PCI_SLOT(ioc->pdev->devfn);
915 karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
916 karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
917 karg.firmware_version = ioc->facts.FWVersion.Word;
918 strncpy(karg.driver_version, MPT2SAS_DRIVER_VERSION,
919 MPT2_IOCTL_VERSION_LENGTH);
920 karg.driver_version[MPT2_IOCTL_VERSION_LENGTH - 1] = '\0';
921 karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
922
923 if (copy_to_user(arg, &karg, sizeof(karg))) {
924 printk(KERN_ERR "failure at %s:%d/%s()!\n",
925 __FILE__, __LINE__, __func__);
926 return -EFAULT;
927 }
928 return 0;
929}
930
931/**
932 * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode
933 * @arg - user space buffer containing ioctl content
934 */
935static long
936_ctl_eventquery(void __user *arg)
937{
938 struct mpt2_ioctl_eventquery karg;
939 struct MPT2SAS_ADAPTER *ioc;
940
941 if (copy_from_user(&karg, arg, sizeof(karg))) {
942 printk(KERN_ERR "failure at %s:%d/%s()!\n",
943 __FILE__, __LINE__, __func__);
944 return -EFAULT;
945 }
946 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
947 return -ENODEV;
948
949 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
950 __func__));
951
952 karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE;
953 memcpy(karg.event_types, ioc->event_type,
954 MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));
955
956 if (copy_to_user(arg, &karg, sizeof(karg))) {
957 printk(KERN_ERR "failure at %s:%d/%s()!\n",
958 __FILE__, __LINE__, __func__);
959 return -EFAULT;
960 }
961 return 0;
962}
963
964/**
965 * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode
966 * @arg - user space buffer containing ioctl content
967 */
968static long
969_ctl_eventenable(void __user *arg)
970{
971 struct mpt2_ioctl_eventenable karg;
972 struct MPT2SAS_ADAPTER *ioc;
973
974 if (copy_from_user(&karg, arg, sizeof(karg))) {
975 printk(KERN_ERR "failure at %s:%d/%s()!\n",
976 __FILE__, __LINE__, __func__);
977 return -EFAULT;
978 }
979 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
980 return -ENODEV;
981
982 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
983 __func__));
984
985 if (ioc->event_log)
986 return 0;
987 memcpy(ioc->event_type, karg.event_types,
988 MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));
989 mpt2sas_base_validate_event_type(ioc, ioc->event_type);
990
991 /* initialize event_log */
992 ioc->event_context = 0;
993 ioc->aen_event_read_flag = 0;
994 ioc->event_log = kcalloc(MPT2SAS_CTL_EVENT_LOG_SIZE,
995 sizeof(struct MPT2_IOCTL_EVENTS), GFP_KERNEL);
996 if (!ioc->event_log) {
997 printk(KERN_ERR "failure at %s:%d/%s()!\n",
998 __FILE__, __LINE__, __func__);
999 return -ENOMEM;
1000 }
1001 return 0;
1002}
1003
1004/**
1005 * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode
1006 * @arg - user space buffer containing ioctl content
1007 */
1008static long
1009_ctl_eventreport(void __user *arg)
1010{
1011 struct mpt2_ioctl_eventreport karg;
1012 struct MPT2SAS_ADAPTER *ioc;
1013 u32 number_bytes, max_events, max;
1014 struct mpt2_ioctl_eventreport __user *uarg = arg;
1015
1016 if (copy_from_user(&karg, arg, sizeof(karg))) {
1017 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1018 __FILE__, __LINE__, __func__);
1019 return -EFAULT;
1020 }
1021 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1022 return -ENODEV;
1023
1024 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
1025 __func__));
1026
1027 number_bytes = karg.hdr.max_data_size -
1028 sizeof(struct mpt2_ioctl_header);
1029 max_events = number_bytes/sizeof(struct MPT2_IOCTL_EVENTS);
1030 max = min_t(u32, MPT2SAS_CTL_EVENT_LOG_SIZE, max_events);
1031
1032 /* If fewer than 1 event is requested, there must have
1033 * been some type of error.
1034 */
1035 if (!max || !ioc->event_log)
1036 return -ENODATA;
1037
1038 number_bytes = max * sizeof(struct MPT2_IOCTL_EVENTS);
1039 if (copy_to_user(uarg->event_data, ioc->event_log, number_bytes)) {
1040 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1041 __FILE__, __LINE__, __func__);
1042 return -EFAULT;
1043 }
1044
1045 /* reset flag so SIGIO can restart */
1046 ioc->aen_event_read_flag = 0;
1047 return 0;
1048}
1049
1050/**
1051 * _ctl_do_reset - main handler for MPT2HARDRESET opcode
1052 * @arg - user space buffer containing ioctl content
1053 */
1054static long
1055_ctl_do_reset(void __user *arg)
1056{
1057 struct mpt2_ioctl_diag_reset karg;
1058 struct MPT2SAS_ADAPTER *ioc;
1059 int retval;
1060
1061 if (copy_from_user(&karg, arg, sizeof(karg))) {
1062 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1063 __FILE__, __LINE__, __func__);
1064 return -EFAULT;
1065 }
1066 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1067 return -ENODEV;
1068
1069 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
1070 __func__));
1071
1072 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1073 FORCE_BIG_HAMMER);
1074 printk(MPT2SAS_INFO_FMT "host reset: %s\n",
1075 ioc->name, ((!retval) ? "SUCCESS" : "FAILED"));
1076 return 0;
1077}
1078
1079/**
1080 * _ctl_btdh_search_sas_device - searching for sas device
1081 * @ioc: per adapter object
1082 * @btdh: btdh ioctl payload
1083 */
1084static int
1085_ctl_btdh_search_sas_device(struct MPT2SAS_ADAPTER *ioc,
1086 struct mpt2_ioctl_btdh_mapping *btdh)
1087{
1088 struct _sas_device *sas_device;
1089 unsigned long flags;
1090 int rc = 0;
1091
1092 if (list_empty(&ioc->sas_device_list))
1093 return rc;
1094
1095 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1096 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
1097 if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&
1098 btdh->handle == sas_device->handle) {
1099 btdh->bus = sas_device->channel;
1100 btdh->id = sas_device->id;
1101 rc = 1;
1102 goto out;
1103 } else if (btdh->bus == sas_device->channel && btdh->id ==
1104 sas_device->id && btdh->handle == 0xFFFF) {
1105 btdh->handle = sas_device->handle;
1106 rc = 1;
1107 goto out;
1108 }
1109 }
1110 out:
1111 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1112 return rc;
1113}
1114
1115/**
1116 * _ctl_btdh_search_raid_device - searching for raid device
1117 * @ioc: per adapter object
1118 * @btdh: btdh ioctl payload
1119 */
1120static int
1121_ctl_btdh_search_raid_device(struct MPT2SAS_ADAPTER *ioc,
1122 struct mpt2_ioctl_btdh_mapping *btdh)
1123{
1124 struct _raid_device *raid_device;
1125 unsigned long flags;
1126 int rc = 0;
1127
1128 if (list_empty(&ioc->raid_device_list))
1129 return rc;
1130
1131 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1132 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
1133 if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&
1134 btdh->handle == raid_device->handle) {
1135 btdh->bus = raid_device->channel;
1136 btdh->id = raid_device->id;
1137 rc = 1;
1138 goto out;
1139 } else if (btdh->bus == raid_device->channel && btdh->id ==
1140 raid_device->id && btdh->handle == 0xFFFF) {
1141 btdh->handle = raid_device->handle;
1142 rc = 1;
1143 goto out;
1144 }
1145 }
1146 out:
1147 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1148 return rc;
1149}
1150
1151/**
1152 * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode
1153 * @arg - user space buffer containing ioctl content
1154 */
1155static long
1156_ctl_btdh_mapping(void __user *arg)
1157{
1158 struct mpt2_ioctl_btdh_mapping karg;
1159 struct MPT2SAS_ADAPTER *ioc;
1160 int rc;
1161
1162 if (copy_from_user(&karg, arg, sizeof(karg))) {
1163 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1164 __FILE__, __LINE__, __func__);
1165 return -EFAULT;
1166 }
1167 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1168 return -ENODEV;
1169
1170 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1171 __func__));
1172
1173 rc = _ctl_btdh_search_sas_device(ioc, &karg);
1174 if (!rc)
1175 _ctl_btdh_search_raid_device(ioc, &karg);
1176
1177 if (copy_to_user(arg, &karg, sizeof(karg))) {
1178 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1179 __FILE__, __LINE__, __func__);
1180 return -EFAULT;
1181 }
1182 return 0;
1183}
1184
1185/**
1186 * _ctl_diag_capability - return diag buffer capability
1187 * @ioc: per adapter object
1188 * @buffer_type: specifies either TRACE or SNAPSHOT
1189 *
1190 * returns 1 when diag buffer support is enabled in firmware
1191 */
1192static u8
1193_ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type)
1194{
1195 u8 rc = 0;
1196
1197 switch (buffer_type) {
1198 case MPI2_DIAG_BUF_TYPE_TRACE:
1199 if (ioc->facts.IOCCapabilities &
1200 MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER)
1201 rc = 1;
1202 break;
1203 case MPI2_DIAG_BUF_TYPE_SNAPSHOT:
1204 if (ioc->facts.IOCCapabilities &
1205 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
1206 rc = 1;
1207 break;
1208 }
1209
1210 return rc;
1211}
1212
1213/**
1214 * _ctl_diag_register - application register with driver
1215 * @arg - user space buffer containing ioctl content
1216 * @state - NON_BLOCKING or BLOCKING
1217 *
1218 * This will allow the driver to setup any required buffers that will be
1219 * needed by firmware to communicate with the driver.
1220 */
1221static long
1222_ctl_diag_register(void __user *arg, enum block_state state)
1223{
1224 struct mpt2_diag_register karg;
1225 struct MPT2SAS_ADAPTER *ioc;
1226 int rc, i;
1227 void *request_data = NULL;
1228 dma_addr_t request_data_dma;
1229 u32 request_data_sz = 0;
1230 Mpi2DiagBufferPostRequest_t *mpi_request;
1231 Mpi2DiagBufferPostReply_t *mpi_reply;
1232 u8 buffer_type;
1233 unsigned long timeleft;
1234 u16 smid;
1235 u16 ioc_status;
1236 u8 issue_reset = 0;
1237
1238 if (copy_from_user(&karg, arg, sizeof(karg))) {
1239 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1240 __FILE__, __LINE__, __func__);
1241 return -EFAULT;
1242 }
1243 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1244 return -ENODEV;
1245
1246 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1247 __func__));
1248
1249 buffer_type = karg.buffer_type;
1250 if (!_ctl_diag_capability(ioc, buffer_type)) {
1251 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1252 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1253 return -EPERM;
1254 }
1255
1256 if (ioc->diag_buffer_status[buffer_type] &
1257 MPT2_DIAG_BUFFER_IS_REGISTERED) {
1258 printk(MPT2SAS_ERR_FMT "%s: already has a registered "
1259 "buffer for buffer_type(0x%02x)\n", ioc->name, __func__,
1260 buffer_type);
1261 return -EINVAL;
1262 }
1263
1264 if (karg.requested_buffer_size % 4) {
1265 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
1266 "is not 4 byte aligned\n", ioc->name, __func__);
1267 return -EINVAL;
1268 }
1269
1270 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1271 return -EAGAIN;
1272 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1273 return -ERESTARTSYS;
1274
1275 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1276 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1277 ioc->name, __func__);
1278 rc = -EAGAIN;
1279 goto out;
1280 }
1281
1282 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1283 if (!smid) {
1284 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1285 ioc->name, __func__);
1286 rc = -EAGAIN;
1287 goto out;
1288 }
1289
1290 rc = 0;
1291 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
1292 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
1293 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1294 ioc->ctl_cmds.smid = smid;
1295
1296 request_data = ioc->diag_buffer[buffer_type];
1297 request_data_sz = karg.requested_buffer_size;
1298 ioc->unique_id[buffer_type] = karg.unique_id;
1299 ioc->diag_buffer_status[buffer_type] = 0;
1300 memcpy(ioc->product_specific[buffer_type], karg.product_specific,
1301 MPT2_PRODUCT_SPECIFIC_DWORDS);
1302 ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags;
1303
1304 if (request_data) {
1305 request_data_dma = ioc->diag_buffer_dma[buffer_type];
1306 if (request_data_sz != ioc->diag_buffer_sz[buffer_type]) {
1307 pci_free_consistent(ioc->pdev,
1308 ioc->diag_buffer_sz[buffer_type],
1309 request_data, request_data_dma);
1310 request_data = NULL;
1311 }
1312 }
1313
1314 if (request_data == NULL) {
1315 ioc->diag_buffer_sz[buffer_type] = 0;
1316 ioc->diag_buffer_dma[buffer_type] = 0;
1317 request_data = pci_alloc_consistent(
1318 ioc->pdev, request_data_sz, &request_data_dma);
1319 if (request_data == NULL) {
1320 printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"
1321 " for diag buffers, requested size(%d)\n",
1322 ioc->name, __func__, request_data_sz);
1323 mpt2sas_base_free_smid(ioc, smid);
1324 return -ENOMEM;
1325 }
1326 ioc->diag_buffer[buffer_type] = request_data;
1327 ioc->diag_buffer_sz[buffer_type] = request_data_sz;
1328 ioc->diag_buffer_dma[buffer_type] = request_data_dma;
1329 }
1330
1331 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
1332 mpi_request->BufferType = karg.buffer_type;
1333 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags);
1334 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
1335 mpi_request->BufferLength = cpu_to_le32(request_data_sz);
1336
1337 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), "
1338 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
1339 (unsigned long long)request_data_dma, mpi_request->BufferLength));
1340
1341 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1342 mpi_request->ProductSpecific[i] =
1343 cpu_to_le32(ioc->product_specific[buffer_type][i]);
1344
1345 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
1346 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1347 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1348
1349 if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
1350 printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
1351 __func__);
1352 _debug_dump_mf(mpi_request,
1353 sizeof(Mpi2DiagBufferPostRequest_t)/4);
1354 if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
1355 issue_reset = 1;
1356 goto issue_host_reset;
1357 }
1358
1359 /* process the completed Reply Message Frame */
1360 if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
1361 printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
1362 ioc->name, __func__);
1363 rc = -EFAULT;
1364 goto out;
1365 }
1366
1367 mpi_reply = ioc->ctl_cmds.reply;
1368 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1369
1370 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1371 ioc->diag_buffer_status[buffer_type] |=
1372 MPT2_DIAG_BUFFER_IS_REGISTERED;
1373 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n",
1374 ioc->name, __func__));
1375 } else {
1376 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1377 "log_info(0x%08x)\n", ioc->name, __func__,
1378 ioc_status, mpi_reply->IOCLogInfo);
1379 rc = -EFAULT;
1380 }
1381
1382 issue_host_reset:
1383 if (issue_reset)
1384 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1385 FORCE_BIG_HAMMER);
1386
1387 out:
1388
1389 if (rc && request_data)
1390 pci_free_consistent(ioc->pdev, request_data_sz,
1391 request_data, request_data_dma);
1392
1393 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1394 mutex_unlock(&ioc->ctl_cmds.mutex);
1395 return rc;
1396}
1397
1398/**
1399 * _ctl_diag_unregister - application unregister with driver
1400 * @arg - user space buffer containing ioctl content
1401 *
1402 * This will allow the driver to cleanup any memory allocated for diag
1403 * messages and to free up any resources.
1404 */
1405static long
1406_ctl_diag_unregister(void __user *arg)
1407{
1408 struct mpt2_diag_unregister karg;
1409 struct MPT2SAS_ADAPTER *ioc;
1410 void *request_data;
1411 dma_addr_t request_data_dma;
1412 u32 request_data_sz;
1413 u8 buffer_type;
1414
1415 if (copy_from_user(&karg, arg, sizeof(karg))) {
1416 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1417 __FILE__, __LINE__, __func__);
1418 return -EFAULT;
1419 }
1420 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1421 return -ENODEV;
1422
1423 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1424 __func__));
1425
1426 buffer_type = karg.unique_id & 0x000000ff;
1427 if (!_ctl_diag_capability(ioc, buffer_type)) {
1428 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1429 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1430 return -EPERM;
1431 }
1432
1433 if ((ioc->diag_buffer_status[buffer_type] &
1434 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
1435 printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
1436 "registered\n", ioc->name, __func__, buffer_type);
1437 return -EINVAL;
1438 }
1439 if ((ioc->diag_buffer_status[buffer_type] &
1440 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
1441 printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) has not been "
1442 "released\n", ioc->name, __func__, buffer_type);
1443 return -EINVAL;
1444 }
1445
1446 if (karg.unique_id != ioc->unique_id[buffer_type]) {
1447 printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
1448 "registered\n", ioc->name, __func__, karg.unique_id);
1449 return -EINVAL;
1450 }
1451
1452 request_data = ioc->diag_buffer[buffer_type];
1453 if (!request_data) {
1454 printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
1455 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1456 return -ENOMEM;
1457 }
1458
1459 request_data_sz = ioc->diag_buffer_sz[buffer_type];
1460 request_data_dma = ioc->diag_buffer_dma[buffer_type];
1461 pci_free_consistent(ioc->pdev, request_data_sz,
1462 request_data, request_data_dma);
1463 ioc->diag_buffer[buffer_type] = NULL;
1464 ioc->diag_buffer_status[buffer_type] = 0;
1465 return 0;
1466}
1467
1468/**
1469 * _ctl_diag_query - query relevant info associated with diag buffers
1470 * @arg - user space buffer containing ioctl content
1471 *
1472 * The application will send only buffer_type and unique_id. Driver will
1473 * inspect unique_id first, if valid, fill in all the info. If unique_id is
1474 * 0x00, the driver will return info specified by Buffer Type.
1475 */
1476static long
1477_ctl_diag_query(void __user *arg)
1478{
1479 struct mpt2_diag_query karg;
1480 struct MPT2SAS_ADAPTER *ioc;
1481 void *request_data;
1482 int i;
1483 u8 buffer_type;
1484
1485 if (copy_from_user(&karg, arg, sizeof(karg))) {
1486 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1487 __FILE__, __LINE__, __func__);
1488 return -EFAULT;
1489 }
1490 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1491 return -ENODEV;
1492
1493 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1494 __func__));
1495
1496 karg.application_flags = 0;
1497 buffer_type = karg.buffer_type;
1498
1499 if (!_ctl_diag_capability(ioc, buffer_type)) {
1500 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1501 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1502 return -EPERM;
1503 }
1504
1505 if ((ioc->diag_buffer_status[buffer_type] &
1506 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
1507 printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
1508 "registered\n", ioc->name, __func__, buffer_type);
1509 return -EINVAL;
1510 }
1511
1512 if (karg.unique_id & 0xffffff00) {
1513 if (karg.unique_id != ioc->unique_id[buffer_type]) {
1514 printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
1515 "registered\n", ioc->name, __func__,
1516 karg.unique_id);
1517 return -EINVAL;
1518 }
1519 }
1520
1521 request_data = ioc->diag_buffer[buffer_type];
1522 if (!request_data) {
1523 printk(MPT2SAS_ERR_FMT "%s: doesn't have buffer for "
1524 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1525 return -ENOMEM;
1526 }
1527
1528 if (ioc->diag_buffer_status[buffer_type] & MPT2_DIAG_BUFFER_IS_RELEASED)
1529 karg.application_flags = (MPT2_APP_FLAGS_APP_OWNED |
1530 MPT2_APP_FLAGS_BUFFER_VALID);
1531 else
1532 karg.application_flags = (MPT2_APP_FLAGS_APP_OWNED |
1533 MPT2_APP_FLAGS_BUFFER_VALID |
1534 MPT2_APP_FLAGS_FW_BUFFER_ACCESS);
1535
1536 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1537 karg.product_specific[i] =
1538 ioc->product_specific[buffer_type][i];
1539
1540 karg.total_buffer_size = ioc->diag_buffer_sz[buffer_type];
1541 karg.driver_added_buffer_size = 0;
1542 karg.unique_id = ioc->unique_id[buffer_type];
1543 karg.diagnostic_flags = ioc->diagnostic_flags[buffer_type];
1544
1545 if (copy_to_user(arg, &karg, sizeof(struct mpt2_diag_query))) {
1546 printk(MPT2SAS_ERR_FMT "%s: unable to write mpt2_diag_query "
1547 "data @ %p\n", ioc->name, __func__, arg);
1548 return -EFAULT;
1549 }
1550 return 0;
1551}
1552
1553/**
1554 * _ctl_diag_release - request to send Diag Release Message to firmware
1555 * @arg - user space buffer containing ioctl content
1556 * @state - NON_BLOCKING or BLOCKING
1557 *
1558 * This allows ownership of the specified buffer to returned to the driver,
1559 * allowing an application to read the buffer without fear that firmware is
1560 * overwritting information in the buffer.
1561 */
1562static long
1563_ctl_diag_release(void __user *arg, enum block_state state)
1564{
1565 struct mpt2_diag_release karg;
1566 struct MPT2SAS_ADAPTER *ioc;
1567 void *request_data;
1568 int rc;
1569 Mpi2DiagReleaseRequest_t *mpi_request;
1570 Mpi2DiagReleaseReply_t *mpi_reply;
1571 u8 buffer_type;
1572 unsigned long timeleft;
1573 u16 smid;
1574 u16 ioc_status;
1575 u8 issue_reset = 0;
1576
1577 if (copy_from_user(&karg, arg, sizeof(karg))) {
1578 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1579 __FILE__, __LINE__, __func__);
1580 return -EFAULT;
1581 }
1582 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1583 return -ENODEV;
1584
1585 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1586 __func__));
1587
1588 buffer_type = karg.unique_id & 0x000000ff;
1589 if (!_ctl_diag_capability(ioc, buffer_type)) {
1590 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1591 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1592 return -EPERM;
1593 }
1594
1595 if ((ioc->diag_buffer_status[buffer_type] &
1596 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
1597 printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
1598 "registered\n", ioc->name, __func__, buffer_type);
1599 return -EINVAL;
1600 }
1601
1602 if (karg.unique_id != ioc->unique_id[buffer_type]) {
1603 printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
1604 "registered\n", ioc->name, __func__, karg.unique_id);
1605 return -EINVAL;
1606 }
1607
1608 if (ioc->diag_buffer_status[buffer_type] &
1609 MPT2_DIAG_BUFFER_IS_RELEASED) {
1610 printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
1611 "is already released\n", ioc->name, __func__,
1612 buffer_type);
1613 return 0;
1614 }
1615
1616 request_data = ioc->diag_buffer[buffer_type];
1617
1618 if (!request_data) {
1619 printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
1620 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1621 return -ENOMEM;
1622 }
1623
1624 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1625 return -EAGAIN;
1626 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1627 return -ERESTARTSYS;
1628
1629 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1630 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1631 ioc->name, __func__);
1632 rc = -EAGAIN;
1633 goto out;
1634 }
1635
1636 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1637 if (!smid) {
1638 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1639 ioc->name, __func__);
1640 rc = -EAGAIN;
1641 goto out;
1642 }
1643
1644 rc = 0;
1645 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
1646 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
1647 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1648 ioc->ctl_cmds.smid = smid;
1649
1650 mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE;
1651 mpi_request->BufferType = buffer_type;
1652
1653 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
1654 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1655 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1656
1657 if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
1658 printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
1659 __func__);
1660 _debug_dump_mf(mpi_request,
1661 sizeof(Mpi2DiagReleaseRequest_t)/4);
1662 if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
1663 issue_reset = 1;
1664 goto issue_host_reset;
1665 }
1666
1667 /* process the completed Reply Message Frame */
1668 if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
1669 printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
1670 ioc->name, __func__);
1671 rc = -EFAULT;
1672 goto out;
1673 }
1674
1675 mpi_reply = ioc->ctl_cmds.reply;
1676 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1677
1678 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1679 ioc->diag_buffer_status[buffer_type] |=
1680 MPT2_DIAG_BUFFER_IS_RELEASED;
1681 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n",
1682 ioc->name, __func__));
1683 } else {
1684 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1685 "log_info(0x%08x)\n", ioc->name, __func__,
1686 ioc_status, mpi_reply->IOCLogInfo);
1687 rc = -EFAULT;
1688 }
1689
1690 issue_host_reset:
1691 if (issue_reset)
1692 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1693 FORCE_BIG_HAMMER);
1694
1695 out:
1696
1697 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1698 mutex_unlock(&ioc->ctl_cmds.mutex);
1699 return rc;
1700}
1701
1702/**
1703 * _ctl_diag_read_buffer - request for copy of the diag buffer
1704 * @arg - user space buffer containing ioctl content
1705 * @state - NON_BLOCKING or BLOCKING
1706 */
1707static long
1708_ctl_diag_read_buffer(void __user *arg, enum block_state state)
1709{
1710 struct mpt2_diag_read_buffer karg;
1711 struct mpt2_diag_read_buffer __user *uarg = arg;
1712 struct MPT2SAS_ADAPTER *ioc;
1713 void *request_data, *diag_data;
1714 Mpi2DiagBufferPostRequest_t *mpi_request;
1715 Mpi2DiagBufferPostReply_t *mpi_reply;
1716 int rc, i;
1717 u8 buffer_type;
1718 unsigned long timeleft;
1719 u16 smid;
1720 u16 ioc_status;
1721 u8 issue_reset = 0;
1722
1723 if (copy_from_user(&karg, arg, sizeof(karg))) {
1724 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1725 __FILE__, __LINE__, __func__);
1726 return -EFAULT;
1727 }
1728 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1729 return -ENODEV;
1730
1731 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1732 __func__));
1733
1734 buffer_type = karg.unique_id & 0x000000ff;
1735 if (!_ctl_diag_capability(ioc, buffer_type)) {
1736 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1737 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1738 return -EPERM;
1739 }
1740
1741 if (karg.unique_id != ioc->unique_id[buffer_type]) {
1742 printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
1743 "registered\n", ioc->name, __func__, karg.unique_id);
1744 return -EINVAL;
1745 }
1746
1747 request_data = ioc->diag_buffer[buffer_type];
1748 if (!request_data) {
1749 printk(MPT2SAS_ERR_FMT "%s: doesn't have buffer for "
1750 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
1751 return -ENOMEM;
1752 }
1753
1754 if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) {
1755 printk(MPT2SAS_ERR_FMT "%s: either the starting_offset "
1756 "or bytes_to_read are not 4 byte aligned\n", ioc->name,
1757 __func__);
1758 return -EINVAL;
1759 }
1760
1761 diag_data = (void *)(request_data + karg.starting_offset);
1762 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(%p), "
1763 "offset(%d), sz(%d)\n", ioc->name, __func__,
1764 diag_data, karg.starting_offset, karg.bytes_to_read));
1765
1766 if (copy_to_user((void __user *)uarg->diagnostic_data,
1767 diag_data, karg.bytes_to_read)) {
1768 printk(MPT2SAS_ERR_FMT "%s: Unable to write "
1769 "mpt_diag_read_buffer_t data @ %p\n", ioc->name,
1770 __func__, diag_data);
1771 return -EFAULT;
1772 }
1773
1774 if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0)
1775 return 0;
1776
1777 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: Reregister "
1778 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type));
1779 if ((ioc->diag_buffer_status[buffer_type] &
1780 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
1781 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
1782 "buffer_type(0x%02x) is still registered\n", ioc->name,
1783 __func__, buffer_type));
1784 return 0;
1785 }
1786 /* Get a free request frame and save the message context.
1787 */
1788 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1789 return -EAGAIN;
1790 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1791 return -ERESTARTSYS;
1792
1793 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1794 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1795 ioc->name, __func__);
1796 rc = -EAGAIN;
1797 goto out;
1798 }
1799
1800 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1801 if (!smid) {
1802 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1803 ioc->name, __func__);
1804 rc = -EAGAIN;
1805 goto out;
1806 }
1807
1808 rc = 0;
1809 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
1810 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
1811 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1812 ioc->ctl_cmds.smid = smid;
1813
1814 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
1815 mpi_request->BufferType = buffer_type;
1816 mpi_request->BufferLength =
1817 cpu_to_le32(ioc->diag_buffer_sz[buffer_type]);
1818 mpi_request->BufferAddress =
1819 cpu_to_le64(ioc->diag_buffer_dma[buffer_type]);
1820 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1821 mpi_request->ProductSpecific[i] =
1822 cpu_to_le32(ioc->product_specific[buffer_type][i]);
1823
1824 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
1825 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1826 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1827
1828 if (!(ioc->ctl_cmds.status & MPT2_CMD_COMPLETE)) {
1829 printk(MPT2SAS_ERR_FMT "%s: timeout\n", ioc->name,
1830 __func__);
1831 _debug_dump_mf(mpi_request,
1832 sizeof(Mpi2DiagBufferPostRequest_t)/4);
1833 if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
1834 issue_reset = 1;
1835 goto issue_host_reset;
1836 }
1837
1838 /* process the completed Reply Message Frame */
1839 if ((ioc->ctl_cmds.status & MPT2_CMD_REPLY_VALID) == 0) {
1840 printk(MPT2SAS_ERR_FMT "%s: no reply message\n",
1841 ioc->name, __func__);
1842 rc = -EFAULT;
1843 goto out;
1844 }
1845
1846 mpi_reply = ioc->ctl_cmds.reply;
1847 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1848
1849 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1850 ioc->diag_buffer_status[buffer_type] |=
1851 MPT2_DIAG_BUFFER_IS_REGISTERED;
1852 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n",
1853 ioc->name, __func__));
1854 } else {
1855 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1856 "log_info(0x%08x)\n", ioc->name, __func__,
1857 ioc_status, mpi_reply->IOCLogInfo);
1858 rc = -EFAULT;
1859 }
1860
1861 issue_host_reset:
1862 if (issue_reset)
1863 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1864 FORCE_BIG_HAMMER);
1865
1866 out:
1867
1868 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1869 mutex_unlock(&ioc->ctl_cmds.mutex);
1870 return rc;
1871}
1872
1873/**
1874 * _ctl_ioctl_main - main ioctl entry point
1875 * @file - (struct file)
1876 * @cmd - ioctl opcode
1877 * @arg -
1878 */
1879static long
1880_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
1881{
1882 enum block_state state;
1883 long ret = -EINVAL;
1884 unsigned long flags;
1885
1886 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING :
1887 BLOCKING;
1888
1889 switch (cmd) {
1890 case MPT2IOCINFO:
1891 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo))
1892 ret = _ctl_getiocinfo(arg);
1893 break;
1894 case MPT2COMMAND:
1895 {
1896 struct mpt2_ioctl_command karg;
1897 struct mpt2_ioctl_command __user *uarg;
1898 struct MPT2SAS_ADAPTER *ioc;
1899
1900 if (copy_from_user(&karg, arg, sizeof(karg))) {
1901 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1902 __FILE__, __LINE__, __func__);
1903 return -EFAULT;
1904 }
1905
1906 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 ||
1907 !ioc)
1908 return -ENODEV;
1909
1910 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
1911 if (ioc->shost_recovery) {
1912 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
1913 flags);
1914 return -EAGAIN;
1915 }
1916 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1917
1918 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
1919 uarg = arg;
1920 ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
1921 }
1922 break;
1923 }
1924 case MPT2EVENTQUERY:
1925 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery))
1926 ret = _ctl_eventquery(arg);
1927 break;
1928 case MPT2EVENTENABLE:
1929 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable))
1930 ret = _ctl_eventenable(arg);
1931 break;
1932 case MPT2EVENTREPORT:
1933 ret = _ctl_eventreport(arg);
1934 break;
1935 case MPT2HARDRESET:
1936 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset))
1937 ret = _ctl_do_reset(arg);
1938 break;
1939 case MPT2BTDHMAPPING:
1940 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping))
1941 ret = _ctl_btdh_mapping(arg);
1942 break;
1943 case MPT2DIAGREGISTER:
1944 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register))
1945 ret = _ctl_diag_register(arg, state);
1946 break;
1947 case MPT2DIAGUNREGISTER:
1948 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister))
1949 ret = _ctl_diag_unregister(arg);
1950 break;
1951 case MPT2DIAGQUERY:
1952 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query))
1953 ret = _ctl_diag_query(arg);
1954 break;
1955 case MPT2DIAGRELEASE:
1956 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release))
1957 ret = _ctl_diag_release(arg, state);
1958 break;
1959 case MPT2DIAGREADBUFFER:
1960 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer))
1961 ret = _ctl_diag_read_buffer(arg, state);
1962 break;
1963 default:
1964 {
1965 struct mpt2_ioctl_command karg;
1966 struct MPT2SAS_ADAPTER *ioc;
1967
1968 if (copy_from_user(&karg, arg, sizeof(karg))) {
1969 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1970 __FILE__, __LINE__, __func__);
1971 return -EFAULT;
1972 }
1973
1974 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 ||
1975 !ioc)
1976 return -ENODEV;
1977
1978 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT
1979 "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
1980 break;
1981 }
1982 }
1983 return ret;
1984}
1985
1986/**
1987 * _ctl_ioctl - main ioctl entry point (unlocked)
1988 * @file - (struct file)
1989 * @cmd - ioctl opcode
1990 * @arg -
1991 */
1992static long
1993_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1994{
1995 long ret;
1996 lock_kernel();
1997 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
1998 unlock_kernel();
1999 return ret;
2000}
2001
2002#ifdef CONFIG_COMPAT
2003/**
2004 * _ctl_compat_mpt_command - convert 32bit pointers to 64bit.
2005 * @file - (struct file)
2006 * @cmd - ioctl opcode
2007 * @arg - (struct mpt2_ioctl_command32)
2008 *
2009 * MPT2COMMAND32 - Handle 32bit applications running on 64bit os.
2010 */
2011static long
2012_ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
2013{
2014 struct mpt2_ioctl_command32 karg32;
2015 struct mpt2_ioctl_command32 __user *uarg;
2016 struct mpt2_ioctl_command karg;
2017 struct MPT2SAS_ADAPTER *ioc;
2018 enum block_state state;
2019 unsigned long flags;
2020
2021 if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
2022 return -EINVAL;
2023
2024 uarg = (struct mpt2_ioctl_command32 __user *) arg;
2025
2026 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) {
2027 printk(KERN_ERR "failure at %s:%d/%s()!\n",
2028 __FILE__, __LINE__, __func__);
2029 return -EFAULT;
2030 }
2031 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
2032 return -ENODEV;
2033
2034 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
2035 if (ioc->shost_recovery) {
2036 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
2037 flags);
2038 return -EAGAIN;
2039 }
2040 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2041
2042 memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
2043 karg.hdr.ioc_number = karg32.hdr.ioc_number;
2044 karg.hdr.port_number = karg32.hdr.port_number;
2045 karg.hdr.max_data_size = karg32.hdr.max_data_size;
2046 karg.timeout = karg32.timeout;
2047 karg.max_reply_bytes = karg32.max_reply_bytes;
2048 karg.data_in_size = karg32.data_in_size;
2049 karg.data_out_size = karg32.data_out_size;
2050 karg.max_sense_bytes = karg32.max_sense_bytes;
2051 karg.data_sge_offset = karg32.data_sge_offset;
2052 memcpy(&karg.reply_frame_buf_ptr, &karg32.reply_frame_buf_ptr,
2053 sizeof(uint32_t));
2054 memcpy(&karg.data_in_buf_ptr, &karg32.data_in_buf_ptr,
2055 sizeof(uint32_t));
2056 memcpy(&karg.data_out_buf_ptr, &karg32.data_out_buf_ptr,
2057 sizeof(uint32_t));
2058 memcpy(&karg.sense_data_ptr, &karg32.sense_data_ptr,
2059 sizeof(uint32_t));
2060 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
2061 return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
2062}
2063
2064/**
2065 * _ctl_ioctl_compat - main ioctl entry point (compat)
2066 * @file -
2067 * @cmd -
2068 * @arg -
2069 *
2070 * This routine handles 32 bit applications in 64bit os.
2071 */
2072static long
2073_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
2074{
2075 long ret;
2076 lock_kernel();
2077 if (cmd == MPT2COMMAND32)
2078 ret = _ctl_compat_mpt_command(file, cmd, arg);
2079 else
2080 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
2081 unlock_kernel();
2082 return ret;
2083}
2084#endif
2085
2086/* scsi host attributes */
2087
2088/**
2089 * _ctl_version_fw_show - firmware version
2090 * @cdev - pointer to embedded class device
2091 * @buf - the buffer returned
2092 *
2093 * A sysfs 'read-only' shost attribute.
2094 */
2095static ssize_t
2096_ctl_version_fw_show(struct device *cdev, struct device_attribute *attr,
2097 char *buf)
2098{
2099 struct Scsi_Host *shost = class_to_shost(cdev);
2100 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2101
2102 return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
2103 (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
2104 (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
2105 (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
2106 ioc->facts.FWVersion.Word & 0x000000FF);
2107}
2108static DEVICE_ATTR(version_fw, S_IRUGO, _ctl_version_fw_show, NULL);
2109
2110/**
2111 * _ctl_version_bios_show - bios version
2112 * @cdev - pointer to embedded class device
2113 * @buf - the buffer returned
2114 *
2115 * A sysfs 'read-only' shost attribute.
2116 */
2117static ssize_t
2118_ctl_version_bios_show(struct device *cdev, struct device_attribute *attr,
2119 char *buf)
2120{
2121 struct Scsi_Host *shost = class_to_shost(cdev);
2122 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2123
2124 u32 version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
2125
2126 return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
2127 (version & 0xFF000000) >> 24,
2128 (version & 0x00FF0000) >> 16,
2129 (version & 0x0000FF00) >> 8,
2130 version & 0x000000FF);
2131}
2132static DEVICE_ATTR(version_bios, S_IRUGO, _ctl_version_bios_show, NULL);
2133
2134/**
2135 * _ctl_version_mpi_show - MPI (message passing interface) version
2136 * @cdev - pointer to embedded class device
2137 * @buf - the buffer returned
2138 *
2139 * A sysfs 'read-only' shost attribute.
2140 */
2141static ssize_t
2142_ctl_version_mpi_show(struct device *cdev, struct device_attribute *attr,
2143 char *buf)
2144{
2145 struct Scsi_Host *shost = class_to_shost(cdev);
2146 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2147
2148 return snprintf(buf, PAGE_SIZE, "%03x.%02x\n",
2149 ioc->facts.MsgVersion, ioc->facts.HeaderVersion >> 8);
2150}
2151static DEVICE_ATTR(version_mpi, S_IRUGO, _ctl_version_mpi_show, NULL);
2152
2153/**
2154 * _ctl_version_product_show - product name
2155 * @cdev - pointer to embedded class device
2156 * @buf - the buffer returned
2157 *
2158 * A sysfs 'read-only' shost attribute.
2159 */
2160static ssize_t
2161_ctl_version_product_show(struct device *cdev, struct device_attribute *attr,
2162 char *buf)
2163{
2164 struct Scsi_Host *shost = class_to_shost(cdev);
2165 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2166
2167 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.ChipName);
2168}
2169static DEVICE_ATTR(version_product, S_IRUGO,
2170 _ctl_version_product_show, NULL);
2171
2172/**
2173 * _ctl_version_nvdata_persistent_show - ndvata persistent version
2174 * @cdev - pointer to embedded class device
2175 * @buf - the buffer returned
2176 *
2177 * A sysfs 'read-only' shost attribute.
2178 */
2179static ssize_t
2180_ctl_version_nvdata_persistent_show(struct device *cdev,
2181 struct device_attribute *attr, char *buf)
2182{
2183 struct Scsi_Host *shost = class_to_shost(cdev);
2184 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2185
2186 return snprintf(buf, PAGE_SIZE, "%02xh\n",
2187 le16_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word));
2188}
2189static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
2190 _ctl_version_nvdata_persistent_show, NULL);
2191
2192/**
2193 * _ctl_version_nvdata_default_show - nvdata default version
2194 * @cdev - pointer to embedded class device
2195 * @buf - the buffer returned
2196 *
2197 * A sysfs 'read-only' shost attribute.
2198 */
2199static ssize_t
2200_ctl_version_nvdata_default_show(struct device *cdev,
2201 struct device_attribute *attr, char *buf)
2202{
2203 struct Scsi_Host *shost = class_to_shost(cdev);
2204 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2205
2206 return snprintf(buf, PAGE_SIZE, "%02xh\n",
2207 le16_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word));
2208}
2209static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
2210 _ctl_version_nvdata_default_show, NULL);
2211
2212/**
2213 * _ctl_board_name_show - board name
2214 * @cdev - pointer to embedded class device
2215 * @buf - the buffer returned
2216 *
2217 * A sysfs 'read-only' shost attribute.
2218 */
2219static ssize_t
2220_ctl_board_name_show(struct device *cdev, struct device_attribute *attr,
2221 char *buf)
2222{
2223 struct Scsi_Host *shost = class_to_shost(cdev);
2224 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2225
2226 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardName);
2227}
2228static DEVICE_ATTR(board_name, S_IRUGO, _ctl_board_name_show, NULL);
2229
2230/**
2231 * _ctl_board_assembly_show - board assembly name
2232 * @cdev - pointer to embedded class device
2233 * @buf - the buffer returned
2234 *
2235 * A sysfs 'read-only' shost attribute.
2236 */
2237static ssize_t
2238_ctl_board_assembly_show(struct device *cdev, struct device_attribute *attr,
2239 char *buf)
2240{
2241 struct Scsi_Host *shost = class_to_shost(cdev);
2242 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2243
2244 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardAssembly);
2245}
2246static DEVICE_ATTR(board_assembly, S_IRUGO,
2247 _ctl_board_assembly_show, NULL);
2248
2249/**
2250 * _ctl_board_tracer_show - board tracer number
2251 * @cdev - pointer to embedded class device
2252 * @buf - the buffer returned
2253 *
2254 * A sysfs 'read-only' shost attribute.
2255 */
2256static ssize_t
2257_ctl_board_tracer_show(struct device *cdev, struct device_attribute *attr,
2258 char *buf)
2259{
2260 struct Scsi_Host *shost = class_to_shost(cdev);
2261 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2262
2263 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardTracerNumber);
2264}
2265static DEVICE_ATTR(board_tracer, S_IRUGO,
2266 _ctl_board_tracer_show, NULL);
2267
2268/**
2269 * _ctl_io_delay_show - io missing delay
2270 * @cdev - pointer to embedded class device
2271 * @buf - the buffer returned
2272 *
2273 * This is for firmware implemention for deboucing device
2274 * removal events.
2275 *
2276 * A sysfs 'read-only' shost attribute.
2277 */
2278static ssize_t
2279_ctl_io_delay_show(struct device *cdev, struct device_attribute *attr,
2280 char *buf)
2281{
2282 struct Scsi_Host *shost = class_to_shost(cdev);
2283 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2284
2285 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
2286}
2287static DEVICE_ATTR(io_delay, S_IRUGO,
2288 _ctl_io_delay_show, NULL);
2289
2290/**
2291 * _ctl_device_delay_show - device missing delay
2292 * @cdev - pointer to embedded class device
2293 * @buf - the buffer returned
2294 *
2295 * This is for firmware implemention for deboucing device
2296 * removal events.
2297 *
2298 * A sysfs 'read-only' shost attribute.
2299 */
2300static ssize_t
2301_ctl_device_delay_show(struct device *cdev, struct device_attribute *attr,
2302 char *buf)
2303{
2304 struct Scsi_Host *shost = class_to_shost(cdev);
2305 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2306
2307 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
2308}
2309static DEVICE_ATTR(device_delay, S_IRUGO,
2310 _ctl_device_delay_show, NULL);
2311
2312/**
2313 * _ctl_fw_queue_depth_show - global credits
2314 * @cdev - pointer to embedded class device
2315 * @buf - the buffer returned
2316 *
2317 * This is firmware queue depth limit
2318 *
2319 * A sysfs 'read-only' shost attribute.
2320 */
2321static ssize_t
2322_ctl_fw_queue_depth_show(struct device *cdev, struct device_attribute *attr,
2323 char *buf)
2324{
2325 struct Scsi_Host *shost = class_to_shost(cdev);
2326 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2327
2328 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->facts.RequestCredit);
2329}
2330static DEVICE_ATTR(fw_queue_depth, S_IRUGO,
2331 _ctl_fw_queue_depth_show, NULL);
2332
2333/**
2334 * _ctl_sas_address_show - sas address
2335 * @cdev - pointer to embedded class device
2336 * @buf - the buffer returned
2337 *
2338 * This is the controller sas address
2339 *
2340 * A sysfs 'read-only' shost attribute.
2341 */
2342static ssize_t
2343_ctl_host_sas_address_show(struct device *cdev, struct device_attribute *attr,
2344 char *buf)
2345{
2346 struct Scsi_Host *shost = class_to_shost(cdev);
2347 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2348
2349 return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
2350 (unsigned long long)ioc->sas_hba.sas_address);
2351}
2352static DEVICE_ATTR(host_sas_address, S_IRUGO,
2353 _ctl_host_sas_address_show, NULL);
2354
2355/**
2356 * _ctl_logging_level_show - logging level
2357 * @cdev - pointer to embedded class device
2358 * @buf - the buffer returned
2359 *
2360 * A sysfs 'read/write' shost attribute.
2361 */
2362static ssize_t
2363_ctl_logging_level_show(struct device *cdev, struct device_attribute *attr,
2364 char *buf)
2365{
2366 struct Scsi_Host *shost = class_to_shost(cdev);
2367 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2368
2369 return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->logging_level);
2370}
2371static ssize_t
2372_ctl_logging_level_store(struct device *cdev, struct device_attribute *attr,
2373 const char *buf, size_t count)
2374{
2375 struct Scsi_Host *shost = class_to_shost(cdev);
2376 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2377 int val = 0;
2378
2379 if (sscanf(buf, "%x", &val) != 1)
2380 return -EINVAL;
2381
2382 ioc->logging_level = val;
2383 printk(MPT2SAS_INFO_FMT "logging_level=%08xh\n", ioc->name,
2384 ioc->logging_level);
2385 return strlen(buf);
2386}
2387static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
2388 _ctl_logging_level_show, _ctl_logging_level_store);
2389
2390struct device_attribute *mpt2sas_host_attrs[] = {
2391 &dev_attr_version_fw,
2392 &dev_attr_version_bios,
2393 &dev_attr_version_mpi,
2394 &dev_attr_version_product,
2395 &dev_attr_version_nvdata_persistent,
2396 &dev_attr_version_nvdata_default,
2397 &dev_attr_board_name,
2398 &dev_attr_board_assembly,
2399 &dev_attr_board_tracer,
2400 &dev_attr_io_delay,
2401 &dev_attr_device_delay,
2402 &dev_attr_logging_level,
2403 &dev_attr_fw_queue_depth,
2404 &dev_attr_host_sas_address,
2405 NULL,
2406};
2407
2408/* device attributes */
2409
2410/**
2411 * _ctl_device_sas_address_show - sas address
2412 * @cdev - pointer to embedded class device
2413 * @buf - the buffer returned
2414 *
2415 * This is the sas address for the target
2416 *
2417 * A sysfs 'read-only' shost attribute.
2418 */
2419static ssize_t
2420_ctl_device_sas_address_show(struct device *dev, struct device_attribute *attr,
2421 char *buf)
2422{
2423 struct scsi_device *sdev = to_scsi_device(dev);
2424 struct MPT2SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
2425
2426 return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
2427 (unsigned long long)sas_device_priv_data->sas_target->sas_address);
2428}
2429static DEVICE_ATTR(sas_address, S_IRUGO, _ctl_device_sas_address_show, NULL);
2430
2431/**
2432 * _ctl_device_handle_show - device handle
2433 * @cdev - pointer to embedded class device
2434 * @buf - the buffer returned
2435 *
2436 * This is the firmware assigned device handle
2437 *
2438 * A sysfs 'read-only' shost attribute.
2439 */
2440static ssize_t
2441_ctl_device_handle_show(struct device *dev, struct device_attribute *attr,
2442 char *buf)
2443{
2444 struct scsi_device *sdev = to_scsi_device(dev);
2445 struct MPT2SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
2446
2447 return snprintf(buf, PAGE_SIZE, "0x%04x\n",
2448 sas_device_priv_data->sas_target->handle);
2449}
2450static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL);
2451
2452struct device_attribute *mpt2sas_dev_attrs[] = {
2453 &dev_attr_sas_address,
2454 &dev_attr_sas_device_handle,
2455 NULL,
2456};
2457
2458static const struct file_operations ctl_fops = {
2459 .owner = THIS_MODULE,
2460 .unlocked_ioctl = _ctl_ioctl,
2461 .release = _ctl_release,
2462 .poll = _ctl_poll,
2463 .fasync = _ctl_fasync,
2464#ifdef CONFIG_COMPAT
2465 .compat_ioctl = _ctl_ioctl_compat,
2466#endif
2467};
2468
2469static struct miscdevice ctl_dev = {
2470 .minor = MPT2SAS_MINOR,
2471 .name = MPT2SAS_DEV_NAME,
2472 .fops = &ctl_fops,
2473};
2474
2475/**
2476 * mpt2sas_ctl_init - main entry point for ctl.
2477 *
2478 */
2479void
2480mpt2sas_ctl_init(void)
2481{
2482 async_queue = NULL;
2483 if (misc_register(&ctl_dev) < 0)
2484 printk(KERN_ERR "%s can't register misc device [minor=%d]\n",
2485 MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
2486
2487 init_waitqueue_head(&ctl_poll_wait);
2488}
2489
2490/**
2491 * mpt2sas_ctl_exit - exit point for ctl
2492 *
2493 */
2494void
2495mpt2sas_ctl_exit(void)
2496{
2497 struct MPT2SAS_ADAPTER *ioc;
2498 int i;
2499
2500 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
2501
2502 /* free memory associated to diag buffers */
2503 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
2504 if (!ioc->diag_buffer[i])
2505 continue;
2506 pci_free_consistent(ioc->pdev, ioc->diag_buffer_sz[i],
2507 ioc->diag_buffer[i], ioc->diag_buffer_dma[i]);
2508 ioc->diag_buffer[i] = NULL;
2509 ioc->diag_buffer_status[i] = 0;
2510 }
2511
2512 kfree(ioc->event_log);
2513 }
2514 misc_deregister(&ctl_dev);
2515}
2516
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
new file mode 100644
index 000000000000..dbb6c0cf8889
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -0,0 +1,416 @@
1/*
2 * Management Module Support for MPT (Message Passing Technology) based
3 * controllers
4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
6 * Copyright (C) 2007-2008 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * NO WARRANTY
20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24 * solely responsible for determining the appropriateness of using and
25 * distributing the Program and assumes all risks associated with its
26 * exercise of rights under this Agreement, including but not limited to
27 * the risks and costs of program errors, damage to or loss of data,
28 * programs or equipment, and unavailability or interruption of operations.
29
30 * DISCLAIMER OF LIABILITY
31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
42 * USA.
43 */
44
45#ifndef MPT2SAS_CTL_H_INCLUDED
46#define MPT2SAS_CTL_H_INCLUDED
47
48#ifdef __KERNEL__
49#include <linux/miscdevice.h>
50#endif
51
52#define MPT2SAS_DEV_NAME "mpt2ctl"
53#define MPT2_MAGIC_NUMBER 'm'
54#define MPT2_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */
55
56/**
57 * IOCTL opcodes
58 */
59#define MPT2IOCINFO _IOWR(MPT2_MAGIC_NUMBER, 17, \
60 struct mpt2_ioctl_iocinfo)
61#define MPT2COMMAND _IOWR(MPT2_MAGIC_NUMBER, 20, \
62 struct mpt2_ioctl_command)
63#ifdef CONFIG_COMPAT
64#define MPT2COMMAND32 _IOWR(MPT2_MAGIC_NUMBER, 20, \
65 struct mpt2_ioctl_command32)
66#endif
67#define MPT2EVENTQUERY _IOWR(MPT2_MAGIC_NUMBER, 21, \
68 struct mpt2_ioctl_eventquery)
69#define MPT2EVENTENABLE _IOWR(MPT2_MAGIC_NUMBER, 22, \
70 struct mpt2_ioctl_eventenable)
71#define MPT2EVENTREPORT _IOWR(MPT2_MAGIC_NUMBER, 23, \
72 struct mpt2_ioctl_eventreport)
73#define MPT2HARDRESET _IOWR(MPT2_MAGIC_NUMBER, 24, \
74 struct mpt2_ioctl_diag_reset)
75#define MPT2BTDHMAPPING _IOWR(MPT2_MAGIC_NUMBER, 31, \
76 struct mpt2_ioctl_btdh_mapping)
77
78/* diag buffer support */
79#define MPT2DIAGREGISTER _IOWR(MPT2_MAGIC_NUMBER, 26, \
80 struct mpt2_diag_register)
81#define MPT2DIAGRELEASE _IOWR(MPT2_MAGIC_NUMBER, 27, \
82 struct mpt2_diag_release)
83#define MPT2DIAGUNREGISTER _IOWR(MPT2_MAGIC_NUMBER, 28, \
84 struct mpt2_diag_unregister)
85#define MPT2DIAGQUERY _IOWR(MPT2_MAGIC_NUMBER, 29, \
86 struct mpt2_diag_query)
87#define MPT2DIAGREADBUFFER _IOWR(MPT2_MAGIC_NUMBER, 30, \
88 struct mpt2_diag_read_buffer)
89
90/**
91 * struct mpt2_ioctl_header - main header structure
92 * @ioc_number - IOC unit number
93 * @port_number - IOC port number
94 * @max_data_size - maximum number bytes to transfer on read
95 */
96struct mpt2_ioctl_header {
97 uint32_t ioc_number;
98 uint32_t port_number;
99 uint32_t max_data_size;
100};
101
102/**
103 * struct mpt2_ioctl_diag_reset - diagnostic reset
104 * @hdr - generic header
105 */
106struct mpt2_ioctl_diag_reset {
107 struct mpt2_ioctl_header hdr;
108};
109
110
111/**
112 * struct mpt2_ioctl_pci_info - pci device info
113 * @device - pci device id
114 * @function - pci function id
115 * @bus - pci bus id
116 * @segment_id - pci segment id
117 */
118struct mpt2_ioctl_pci_info {
119 union {
120 struct {
121 uint32_t device:5;
122 uint32_t function:3;
123 uint32_t bus:24;
124 } bits;
125 uint32_t word;
126 } u;
127 uint32_t segment_id;
128};
129
130
131#define MPT2_IOCTL_INTERFACE_SCSI (0x00)
132#define MPT2_IOCTL_INTERFACE_FC (0x01)
133#define MPT2_IOCTL_INTERFACE_FC_IP (0x02)
134#define MPT2_IOCTL_INTERFACE_SAS (0x03)
135#define MPT2_IOCTL_INTERFACE_SAS2 (0x04)
136#define MPT2_IOCTL_VERSION_LENGTH (32)
137
138/**
139 * struct mpt2_ioctl_iocinfo - generic controller info
140 * @hdr - generic header
141 * @adapter_type - type of adapter (spi, fc, sas)
142 * @port_number - port number
143 * @pci_id - PCI Id
144 * @hw_rev - hardware revision
145 * @sub_system_device - PCI subsystem Device ID
146 * @sub_system_vendor - PCI subsystem Vendor ID
147 * @rsvd0 - reserved
148 * @firmware_version - firmware version
149 * @bios_version - BIOS version
150 * @driver_version - driver version - 32 ASCII characters
151 * @rsvd1 - reserved
152 * @scsi_id - scsi id of adapter 0
153 * @rsvd2 - reserved
154 * @pci_information - pci info (2nd revision)
155 */
156struct mpt2_ioctl_iocinfo {
157 struct mpt2_ioctl_header hdr;
158 uint32_t adapter_type;
159 uint32_t port_number;
160 uint32_t pci_id;
161 uint32_t hw_rev;
162 uint32_t subsystem_device;
163 uint32_t subsystem_vendor;
164 uint32_t rsvd0;
165 uint32_t firmware_version;
166 uint32_t bios_version;
167 uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH];
168 uint8_t rsvd1;
169 uint8_t scsi_id;
170 uint16_t rsvd2;
171 struct mpt2_ioctl_pci_info pci_information;
172};
173
174
175/* number of event log entries */
176#define MPT2SAS_CTL_EVENT_LOG_SIZE (50)
177
178/**
179 * struct mpt2_ioctl_eventquery - query event count and type
180 * @hdr - generic header
181 * @event_entries - number of events returned by get_event_report
182 * @rsvd - reserved
183 * @event_types - type of events currently being captured
184 */
185struct mpt2_ioctl_eventquery {
186 struct mpt2_ioctl_header hdr;
187 uint16_t event_entries;
188 uint16_t rsvd;
189 uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
190};
191
192/**
193 * struct mpt2_ioctl_eventenable - enable/disable event capturing
194 * @hdr - generic header
195 * @event_types - toggle off/on type of events to be captured
196 */
197struct mpt2_ioctl_eventenable {
198 struct mpt2_ioctl_header hdr;
199 uint32_t event_types[4];
200};
201
202#define MPT2_EVENT_DATA_SIZE (192)
203/**
204 * struct MPT2_IOCTL_EVENTS -
205 * @event - the event that was reported
206 * @context - unique value for each event assigned by driver
207 * @data - event data returned in fw reply message
208 */
209struct MPT2_IOCTL_EVENTS {
210 uint32_t event;
211 uint32_t context;
212 uint8_t data[MPT2_EVENT_DATA_SIZE];
213};
214
215/**
216 * struct mpt2_ioctl_eventreport - returing event log
217 * @hdr - generic header
218 * @event_data - (see struct MPT2_IOCTL_EVENTS)
219 */
220struct mpt2_ioctl_eventreport {
221 struct mpt2_ioctl_header hdr;
222 struct MPT2_IOCTL_EVENTS event_data[1];
223};
224
225/**
226 * struct mpt2_ioctl_command - generic mpt firmware passthru ioclt
227 * @hdr - generic header
228 * @timeout - command timeout in seconds. (if zero then use driver default
229 * value).
230 * @reply_frame_buf_ptr - reply location
231 * @data_in_buf_ptr - destination for read
232 * @data_out_buf_ptr - data source for write
233 * @sense_data_ptr - sense data location
234 * @max_reply_bytes - maximum number of reply bytes to be sent to app.
235 * @data_in_size - number bytes for data transfer in (read)
236 * @data_out_size - number bytes for data transfer out (write)
237 * @max_sense_bytes - maximum number of bytes for auto sense buffers
238 * @data_sge_offset - offset in words from the start of the request message to
239 * the first SGL
240 * @mf[1];
241 */
242struct mpt2_ioctl_command {
243 struct mpt2_ioctl_header hdr;
244 uint32_t timeout;
245 void __user *reply_frame_buf_ptr;
246 void __user *data_in_buf_ptr;
247 void __user *data_out_buf_ptr;
248 void __user *sense_data_ptr;
249 uint32_t max_reply_bytes;
250 uint32_t data_in_size;
251 uint32_t data_out_size;
252 uint32_t max_sense_bytes;
253 uint32_t data_sge_offset;
254 uint8_t mf[1];
255};
256
257#ifdef CONFIG_COMPAT
258struct mpt2_ioctl_command32 {
259 struct mpt2_ioctl_header hdr;
260 uint32_t timeout;
261 uint32_t reply_frame_buf_ptr;
262 uint32_t data_in_buf_ptr;
263 uint32_t data_out_buf_ptr;
264 uint32_t sense_data_ptr;
265 uint32_t max_reply_bytes;
266 uint32_t data_in_size;
267 uint32_t data_out_size;
268 uint32_t max_sense_bytes;
269 uint32_t data_sge_offset;
270 uint8_t mf[1];
271};
272#endif
273
274/**
275 * struct mpt2_ioctl_btdh_mapping - mapping info
276 * @hdr - generic header
277 * @id - target device identification number
278 * @bus - SCSI bus number that the target device exists on
279 * @handle - device handle for the target device
280 * @rsvd - reserved
281 *
282 * To obtain a bus/id the application sets
283 * handle to valid handle, and bus/id to 0xFFFF.
284 *
285 * To obtain the device handle the application sets
286 * bus/id valid value, and the handle to 0xFFFF.
287 */
288struct mpt2_ioctl_btdh_mapping {
289 struct mpt2_ioctl_header hdr;
290 uint32_t id;
291 uint32_t bus;
292 uint16_t handle;
293 uint16_t rsvd;
294};
295
296
297/* status bits for ioc->diag_buffer_status */
298#define MPT2_DIAG_BUFFER_IS_REGISTERED (0x01)
299#define MPT2_DIAG_BUFFER_IS_RELEASED (0x02)
300
301/* application flags for mpt2_diag_register, mpt2_diag_query */
302#define MPT2_APP_FLAGS_APP_OWNED (0x0001)
303#define MPT2_APP_FLAGS_BUFFER_VALID (0x0002)
304#define MPT2_APP_FLAGS_FW_BUFFER_ACCESS (0x0004)
305
306/* flags for mpt2_diag_read_buffer */
307#define MPT2_FLAGS_REREGISTER (0x0001)
308
309#define MPT2_PRODUCT_SPECIFIC_DWORDS 23
310
311/**
312 * struct mpt2_diag_register - application register with driver
313 * @hdr - generic header
314 * @reserved -
315 * @buffer_type - specifies either TRACE or SNAPSHOT
316 * @application_flags - misc flags
317 * @diagnostic_flags - specifies flags affecting command processing
318 * @product_specific - product specific information
319 * @requested_buffer_size - buffers size in bytes
320 * @unique_id - tag specified by application that is used to signal ownership
321 * of the buffer.
322 *
323 * This will allow the driver to setup any required buffers that will be
324 * needed by firmware to communicate with the driver.
325 */
326struct mpt2_diag_register {
327 struct mpt2_ioctl_header hdr;
328 uint8_t reserved;
329 uint8_t buffer_type;
330 uint16_t application_flags;
331 uint32_t diagnostic_flags;
332 uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
333 uint32_t requested_buffer_size;
334 uint32_t unique_id;
335};
336
337/**
338 * struct mpt2_diag_unregister - application unregister with driver
339 * @hdr - generic header
340 * @unique_id - tag uniquely identifies the buffer to be unregistered
341 *
342 * This will allow the driver to cleanup any memory allocated for diag
343 * messages and to free up any resources.
344 */
345struct mpt2_diag_unregister {
346 struct mpt2_ioctl_header hdr;
347 uint32_t unique_id;
348};
349
350/**
351 * struct mpt2_diag_query - query relevant info associated with diag buffers
352 * @hdr - generic header
353 * @reserved -
354 * @buffer_type - specifies either TRACE or SNAPSHOT
355 * @application_flags - misc flags
356 * @diagnostic_flags - specifies flags affecting command processing
357 * @product_specific - product specific information
358 * @total_buffer_size - diag buffer size in bytes
359 * @driver_added_buffer_size - size of extra space appended to end of buffer
360 * @unique_id - unique id associated with this buffer.
361 *
362 * The application will send only buffer_type and unique_id. Driver will
363 * inspect unique_id first, if valid, fill in all the info. If unique_id is
364 * 0x00, the driver will return info specified by Buffer Type.
365 */
366struct mpt2_diag_query {
367 struct mpt2_ioctl_header hdr;
368 uint8_t reserved;
369 uint8_t buffer_type;
370 uint16_t application_flags;
371 uint32_t diagnostic_flags;
372 uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
373 uint32_t total_buffer_size;
374 uint32_t driver_added_buffer_size;
375 uint32_t unique_id;
376};
377
378/**
379 * struct mpt2_diag_release - request to send Diag Release Message to firmware
380 * @hdr - generic header
381 * @unique_id - tag uniquely identifies the buffer to be released
382 *
383 * This allows ownership of the specified buffer to returned to the driver,
384 * allowing an application to read the buffer without fear that firmware is
385 * overwritting information in the buffer.
386 */
387struct mpt2_diag_release {
388 struct mpt2_ioctl_header hdr;
389 uint32_t unique_id;
390};
391
392/**
393 * struct mpt2_diag_read_buffer - request for copy of the diag buffer
394 * @hdr - generic header
395 * @status -
396 * @reserved -
397 * @flags - misc flags
398 * @starting_offset - starting offset within drivers buffer where to start
399 * reading data at into the specified application buffer
400 * @bytes_to_read - number of bytes to copy from the drivers buffer into the
401 * application buffer starting at starting_offset.
402 * @unique_id - unique id associated with this buffer.
403 * @diagnostic_data - data payload
404 */
405struct mpt2_diag_read_buffer {
406 struct mpt2_ioctl_header hdr;
407 uint8_t status;
408 uint8_t reserved;
409 uint16_t flags;
410 uint32_t starting_offset;
411 uint32_t bytes_to_read;
412 uint32_t unique_id;
413 uint32_t diagnostic_data[1];
414};
415
416#endif /* MPT2SAS_CTL_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
new file mode 100644
index 000000000000..ad325096e842
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h
@@ -0,0 +1,181 @@
1/*
2 * Logging Support for MPT (Message Passing Technology) based controllers
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#ifndef MPT2SAS_DEBUG_H_INCLUDED
45#define MPT2SAS_DEBUG_H_INCLUDED
46
47#define MPT_DEBUG 0x00000001
48#define MPT_DEBUG_MSG_FRAME 0x00000002
49#define MPT_DEBUG_SG 0x00000004
50#define MPT_DEBUG_EVENTS 0x00000008
51#define MPT_DEBUG_EVENT_WORK_TASK 0x00000010
52#define MPT_DEBUG_INIT 0x00000020
53#define MPT_DEBUG_EXIT 0x00000040
54#define MPT_DEBUG_FAIL 0x00000080
55#define MPT_DEBUG_TM 0x00000100
56#define MPT_DEBUG_REPLY 0x00000200
57#define MPT_DEBUG_HANDSHAKE 0x00000400
58#define MPT_DEBUG_CONFIG 0x00000800
59#define MPT_DEBUG_DL 0x00001000
60#define MPT_DEBUG_RESET 0x00002000
61#define MPT_DEBUG_SCSI 0x00004000
62#define MPT_DEBUG_IOCTL 0x00008000
63#define MPT_DEBUG_CSMISAS 0x00010000
64#define MPT_DEBUG_SAS 0x00020000
65#define MPT_DEBUG_TRANSPORT 0x00040000
66#define MPT_DEBUG_TASK_SET_FULL 0x00080000
67
68#define MPT_DEBUG_TARGET_MODE 0x00100000
69
70
71/*
72 * CONFIG_SCSI_MPT2SAS_LOGGING - enabled in Kconfig
73 */
74
75#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
76#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \
77{ \
78 if (IOC->logging_level & BITS) \
79 CMD; \
80}
81#else
82#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
83#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
84
85
86/*
87 * debug macros
88 */
89
90#define dprintk(IOC, CMD) \
91 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG)
92
93#define dsgprintk(IOC, CMD) \
94 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SG)
95
96#define devtprintk(IOC, CMD) \
97 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENTS)
98
99#define dewtprintk(IOC, CMD) \
100 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENT_WORK_TASK)
101
102#define dinitprintk(IOC, CMD) \
103 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_INIT)
104
105#define dexitprintk(IOC, CMD) \
106 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EXIT)
107
108#define dfailprintk(IOC, CMD) \
109 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_FAIL)
110
111#define dtmprintk(IOC, CMD) \
112 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TM)
113
114#define dreplyprintk(IOC, CMD) \
115 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_REPLY)
116
117#define dhsprintk(IOC, CMD) \
118 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_HANDSHAKE)
119
120#define dcprintk(IOC, CMD) \
121 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CONFIG)
122
123#define ddlprintk(IOC, CMD) \
124 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_DL)
125
126#define drsprintk(IOC, CMD) \
127 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_RESET)
128
129#define dsprintk(IOC, CMD) \
130 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SCSI)
131
132#define dctlprintk(IOC, CMD) \
133 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_IOCTL)
134
135#define dcsmisasprintk(IOC, CMD) \
136 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CSMISAS)
137
138#define dsasprintk(IOC, CMD) \
139 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS)
140
141#define dsastransport(IOC, CMD) \
142 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE)
143
144#define dmfprintk(IOC, CMD) \
145 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_MSG_FRAME)
146
147#define dtsfprintk(IOC, CMD) \
148 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TASK_SET_FULL)
149
150#define dtransportprintk(IOC, CMD) \
151 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRANSPORT)
152
153#define dTMprintk(IOC, CMD) \
154 MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TARGET_MODE)
155
156/* inline functions for dumping debug data*/
157#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
158/**
159 * _debug_dump_mf - print message frame contents
160 * @mpi_request: pointer to message frame
161 * @sz: number of dwords
162 */
163static inline void
164_debug_dump_mf(void *mpi_request, int sz)
165{
166 int i;
167 u32 *mfp = (u32 *)mpi_request;
168
169 printk(KERN_INFO "mf:\n\t");
170 for (i = 0; i < sz; i++) {
171 if (i && ((i % 8) == 0))
172 printk("\n\t");
173 printk("%08x ", le32_to_cpu(mfp[i]));
174 }
175 printk("\n");
176}
177#else
178#define _debug_dump_mf(mpi_request, sz)
179#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
180
181#endif /* MPT2SAS_DEBUG_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
new file mode 100644
index 000000000000..0c463c483c02
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -0,0 +1,5687 @@
1/*
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#include <linux/version.h>
45#include <linux/module.h>
46#include <linux/kernel.h>
47#include <linux/init.h>
48#include <linux/errno.h>
49#include <linux/blkdev.h>
50#include <linux/sched.h>
51#include <linux/workqueue.h>
52#include <linux/delay.h>
53#include <linux/pci.h>
54#include <linux/interrupt.h>
55
56#include "mpt2sas_base.h"
57
58MODULE_AUTHOR(MPT2SAS_AUTHOR);
59MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION);
60MODULE_LICENSE("GPL");
61MODULE_VERSION(MPT2SAS_DRIVER_VERSION);
62
63#define RAID_CHANNEL 1
64
65/* forward proto's */
66static void _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
67 struct _sas_node *sas_expander);
68static void _firmware_event_work(struct work_struct *work);
69
70/* global parameters */
71LIST_HEAD(mpt2sas_ioc_list);
72
73/* local parameters */
74static u8 scsi_io_cb_idx = -1;
75static u8 tm_cb_idx = -1;
76static u8 ctl_cb_idx = -1;
77static u8 base_cb_idx = -1;
78static u8 transport_cb_idx = -1;
79static u8 config_cb_idx = -1;
80static int mpt_ids;
81
82/* command line options */
83static u32 logging_level;
84MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
85 "(default=0)");
86
87/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
88#define MPT2SAS_MAX_LUN (16895)
89static int max_lun = MPT2SAS_MAX_LUN;
90module_param(max_lun, int, 0);
91MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92
93/**
94 * struct sense_info - common structure for obtaining sense keys
95 * @skey: sense key
96 * @asc: additional sense code
97 * @ascq: additional sense code qualifier
98 */
99struct sense_info {
100 u8 skey;
101 u8 asc;
102 u8 ascq;
103};
104
105
106#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
107/**
108 * struct fw_event_work - firmware event struct
109 * @list: link list framework
110 * @work: work object (ioc->fault_reset_work_q)
111 * @ioc: per adapter object
112 * @VF_ID: virtual function id
113 * @host_reset_handling: handling events during host reset
114 * @ignore: flag meaning this event has been marked to ignore
115 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
116 * @event_data: reply event data payload follows
117 *
118 * This object stored on ioc->fw_event_list.
119 */
120struct fw_event_work {
121 struct list_head list;
122 struct delayed_work work;
123 struct MPT2SAS_ADAPTER *ioc;
124 u8 VF_ID;
125 u8 host_reset_handling;
126 u8 ignore;
127 u16 event;
128 void *event_data;
129};
130
131/**
132 * struct _scsi_io_transfer - scsi io transfer
133 * @handle: sas device handle (assigned by firmware)
134 * @is_raid: flag set for hidden raid components
135 * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE,
136 * @data_length: data transfer length
137 * @data_dma: dma pointer to data
138 * @sense: sense data
139 * @lun: lun number
140 * @cdb_length: cdb length
141 * @cdb: cdb contents
142 * @valid_reply: flag set for reply message
143 * @timeout: timeout for this command
144 * @sense_length: sense length
145 * @ioc_status: ioc status
146 * @scsi_state: scsi state
147 * @scsi_status: scsi staus
148 * @log_info: log information
149 * @transfer_length: data length transfer when there is a reply message
150 *
151 * Used for sending internal scsi commands to devices within this module.
152 * Refer to _scsi_send_scsi_io().
153 */
154struct _scsi_io_transfer {
155 u16 handle;
156 u8 is_raid;
157 enum dma_data_direction dir;
158 u32 data_length;
159 dma_addr_t data_dma;
160 u8 sense[SCSI_SENSE_BUFFERSIZE];
161 u32 lun;
162 u8 cdb_length;
163 u8 cdb[32];
164 u8 timeout;
165 u8 valid_reply;
166 /* the following bits are only valid when 'valid_reply = 1' */
167 u32 sense_length;
168 u16 ioc_status;
169 u8 scsi_state;
170 u8 scsi_status;
171 u32 log_info;
172 u32 transfer_length;
173};
174
175/*
176 * The pci device ids are defined in mpi/mpi2_cnfg.h.
177 */
178static struct pci_device_id scsih_pci_table[] = {
179 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
180 PCI_ANY_ID, PCI_ANY_ID },
181 /* Falcon ~ 2008*/
182 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
183 PCI_ANY_ID, PCI_ANY_ID },
184 /* Liberator ~ 2108 */
185 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
186 PCI_ANY_ID, PCI_ANY_ID },
187 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
188 PCI_ANY_ID, PCI_ANY_ID },
189 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
190 PCI_ANY_ID, PCI_ANY_ID },
191 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
192 PCI_ANY_ID, PCI_ANY_ID },
193 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
194 PCI_ANY_ID, PCI_ANY_ID },
195 {0} /* Terminating entry */
196};
197MODULE_DEVICE_TABLE(pci, scsih_pci_table);
198
199/**
200 * scsih_set_debug_level - global setting of ioc->logging_level.
201 *
202 * Note: The logging levels are defined in mpt2sas_debug.h.
203 */
204static int
205scsih_set_debug_level(const char *val, struct kernel_param *kp)
206{
207 int ret = param_set_int(val, kp);
208 struct MPT2SAS_ADAPTER *ioc;
209
210 if (ret)
211 return ret;
212
213 printk(KERN_INFO "setting logging_level(0x%08x)\n", logging_level);
214 list_for_each_entry(ioc, &mpt2sas_ioc_list, list)
215 ioc->logging_level = logging_level;
216 return 0;
217}
218module_param_call(logging_level, scsih_set_debug_level, param_get_int,
219 &logging_level, 0644);
220
221/**
222 * _scsih_srch_boot_sas_address - search based on sas_address
223 * @sas_address: sas address
224 * @boot_device: boot device object from bios page 2
225 *
226 * Returns 1 when there's a match, 0 means no match.
227 */
228static inline int
229_scsih_srch_boot_sas_address(u64 sas_address,
230 Mpi2BootDeviceSasWwid_t *boot_device)
231{
232 return (sas_address == le64_to_cpu(boot_device->SASAddress)) ? 1 : 0;
233}
234
235/**
236 * _scsih_srch_boot_device_name - search based on device name
237 * @device_name: device name specified in INDENTIFY fram
238 * @boot_device: boot device object from bios page 2
239 *
240 * Returns 1 when there's a match, 0 means no match.
241 */
242static inline int
243_scsih_srch_boot_device_name(u64 device_name,
244 Mpi2BootDeviceDeviceName_t *boot_device)
245{
246 return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0;
247}
248
249/**
250 * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot
251 * @enclosure_logical_id: enclosure logical id
252 * @slot_number: slot number
253 * @boot_device: boot device object from bios page 2
254 *
255 * Returns 1 when there's a match, 0 means no match.
256 */
257static inline int
258_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number,
259 Mpi2BootDeviceEnclosureSlot_t *boot_device)
260{
261 return (enclosure_logical_id == le64_to_cpu(boot_device->
262 EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device->
263 SlotNumber)) ? 1 : 0;
264}
265
266/**
267 * _scsih_is_boot_device - search for matching boot device.
268 * @sas_address: sas address
269 * @device_name: device name specified in INDENTIFY fram
270 * @enclosure_logical_id: enclosure logical id
271 * @slot_number: slot number
272 * @form: specifies boot device form
273 * @boot_device: boot device object from bios page 2
274 *
275 * Returns 1 when there's a match, 0 means no match.
276 */
277static int
278_scsih_is_boot_device(u64 sas_address, u64 device_name,
279 u64 enclosure_logical_id, u16 slot, u8 form,
280 Mpi2BiosPage2BootDevice_t *boot_device)
281{
282 int rc = 0;
283
284 switch (form) {
285 case MPI2_BIOSPAGE2_FORM_SAS_WWID:
286 if (!sas_address)
287 break;
288 rc = _scsih_srch_boot_sas_address(
289 sas_address, &boot_device->SasWwid);
290 break;
291 case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT:
292 if (!enclosure_logical_id)
293 break;
294 rc = _scsih_srch_boot_encl_slot(
295 enclosure_logical_id,
296 slot, &boot_device->EnclosureSlot);
297 break;
298 case MPI2_BIOSPAGE2_FORM_DEVICE_NAME:
299 if (!device_name)
300 break;
301 rc = _scsih_srch_boot_device_name(
302 device_name, &boot_device->DeviceName);
303 break;
304 case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED:
305 break;
306 }
307
308 return rc;
309}
310
311/**
312 * _scsih_determine_boot_device - determine boot device.
313 * @ioc: per adapter object
314 * @device: either sas_device or raid_device object
315 * @is_raid: [flag] 1 = raid object, 0 = sas object
316 *
317 * Determines whether this device should be first reported device to
318 * to scsi-ml or sas transport, this purpose is for persistant boot device.
319 * There are primary, alternate, and current entries in bios page 2. The order
320 * priority is primary, alternate, then current. This routine saves
321 * the corresponding device object and is_raid flag in the ioc object.
322 * The saved data to be used later in _scsih_probe_boot_devices().
323 */
324static void
325_scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
326 void *device, u8 is_raid)
327{
328 struct _sas_device *sas_device;
329 struct _raid_device *raid_device;
330 u64 sas_address;
331 u64 device_name;
332 u64 enclosure_logical_id;
333 u16 slot;
334
335 /* only process this function when driver loads */
336 if (!ioc->wait_for_port_enable_to_complete)
337 return;
338
339 if (!is_raid) {
340 sas_device = device;
341 sas_address = sas_device->sas_address;
342 device_name = sas_device->device_name;
343 enclosure_logical_id = sas_device->enclosure_logical_id;
344 slot = sas_device->slot;
345 } else {
346 raid_device = device;
347 sas_address = raid_device->wwid;
348 device_name = 0;
349 enclosure_logical_id = 0;
350 slot = 0;
351 }
352
353 if (!ioc->req_boot_device.device) {
354 if (_scsih_is_boot_device(sas_address, device_name,
355 enclosure_logical_id, slot,
356 (ioc->bios_pg2.ReqBootDeviceForm &
357 MPI2_BIOSPAGE2_FORM_MASK),
358 &ioc->bios_pg2.RequestedBootDevice)) {
359 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
360 "%s: req_boot_device(0x%016llx)\n",
361 ioc->name, __func__,
362 (unsigned long long)sas_address));
363 ioc->req_boot_device.device = device;
364 ioc->req_boot_device.is_raid = is_raid;
365 }
366 }
367
368 if (!ioc->req_alt_boot_device.device) {
369 if (_scsih_is_boot_device(sas_address, device_name,
370 enclosure_logical_id, slot,
371 (ioc->bios_pg2.ReqAltBootDeviceForm &
372 MPI2_BIOSPAGE2_FORM_MASK),
373 &ioc->bios_pg2.RequestedAltBootDevice)) {
374 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
375 "%s: req_alt_boot_device(0x%016llx)\n",
376 ioc->name, __func__,
377 (unsigned long long)sas_address));
378 ioc->req_alt_boot_device.device = device;
379 ioc->req_alt_boot_device.is_raid = is_raid;
380 }
381 }
382
383 if (!ioc->current_boot_device.device) {
384 if (_scsih_is_boot_device(sas_address, device_name,
385 enclosure_logical_id, slot,
386 (ioc->bios_pg2.CurrentBootDeviceForm &
387 MPI2_BIOSPAGE2_FORM_MASK),
388 &ioc->bios_pg2.CurrentBootDevice)) {
389 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT
390 "%s: current_boot_device(0x%016llx)\n",
391 ioc->name, __func__,
392 (unsigned long long)sas_address));
393 ioc->current_boot_device.device = device;
394 ioc->current_boot_device.is_raid = is_raid;
395 }
396 }
397}
398
399/**
400 * mpt2sas_scsih_sas_device_find_by_sas_address - sas device search
401 * @ioc: per adapter object
402 * @sas_address: sas address
403 * Context: Calling function should acquire ioc->sas_device_lock
404 *
405 * This searches for sas_device based on sas_address, then return sas_device
406 * object.
407 */
408struct _sas_device *
409mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
410 u64 sas_address)
411{
412 struct _sas_device *sas_device, *r;
413
414 r = NULL;
415 /* check the sas_device_init_list */
416 list_for_each_entry(sas_device, &ioc->sas_device_init_list,
417 list) {
418 if (sas_device->sas_address != sas_address)
419 continue;
420 r = sas_device;
421 goto out;
422 }
423
424 /* then check the sas_device_list */
425 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
426 if (sas_device->sas_address != sas_address)
427 continue;
428 r = sas_device;
429 goto out;
430 }
431 out:
432 return r;
433}
434
435/**
436 * _scsih_sas_device_find_by_handle - sas device search
437 * @ioc: per adapter object
438 * @handle: sas device handle (assigned by firmware)
439 * Context: Calling function should acquire ioc->sas_device_lock
440 *
441 * This searches for sas_device based on sas_address, then return sas_device
442 * object.
443 */
444static struct _sas_device *
445_scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
446{
447 struct _sas_device *sas_device, *r;
448
449 r = NULL;
450 if (ioc->wait_for_port_enable_to_complete) {
451 list_for_each_entry(sas_device, &ioc->sas_device_init_list,
452 list) {
453 if (sas_device->handle != handle)
454 continue;
455 r = sas_device;
456 goto out;
457 }
458 } else {
459 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
460 if (sas_device->handle != handle)
461 continue;
462 r = sas_device;
463 goto out;
464 }
465 }
466
467 out:
468 return r;
469}
470
471/**
472 * _scsih_sas_device_remove - remove sas_device from list.
473 * @ioc: per adapter object
474 * @sas_device: the sas_device object
475 * Context: This function will acquire ioc->sas_device_lock.
476 *
477 * Removing object and freeing associated memory from the ioc->sas_device_list.
478 */
479static void
480_scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc,
481 struct _sas_device *sas_device)
482{
483 unsigned long flags;
484
485 spin_lock_irqsave(&ioc->sas_device_lock, flags);
486 list_del(&sas_device->list);
487 memset(sas_device, 0, sizeof(struct _sas_device));
488 kfree(sas_device);
489 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
490}
491
492/**
493 * _scsih_sas_device_add - insert sas_device to the list.
494 * @ioc: per adapter object
495 * @sas_device: the sas_device object
496 * Context: This function will acquire ioc->sas_device_lock.
497 *
498 * Adding new object to the ioc->sas_device_list.
499 */
500static void
501_scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
502 struct _sas_device *sas_device)
503{
504 unsigned long flags;
505 u16 handle, parent_handle;
506 u64 sas_address;
507
508 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
509 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
510 sas_device->handle, (unsigned long long)sas_device->sas_address));
511
512 spin_lock_irqsave(&ioc->sas_device_lock, flags);
513 list_add_tail(&sas_device->list, &ioc->sas_device_list);
514 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
515
516 handle = sas_device->handle;
517 parent_handle = sas_device->parent_handle;
518 sas_address = sas_device->sas_address;
519 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
520 _scsih_sas_device_remove(ioc, sas_device);
521 } else if (!sas_device->starget) {
522 mpt2sas_transport_port_remove(ioc, sas_address, parent_handle);
523 _scsih_sas_device_remove(ioc, sas_device);
524 }
525}
526
527/**
528 * _scsih_sas_device_init_add - insert sas_device to the list.
529 * @ioc: per adapter object
530 * @sas_device: the sas_device object
531 * Context: This function will acquire ioc->sas_device_lock.
532 *
533 * Adding new object at driver load time to the ioc->sas_device_init_list.
534 */
535static void
536_scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc,
537 struct _sas_device *sas_device)
538{
539 unsigned long flags;
540
541 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
542 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
543 sas_device->handle, (unsigned long long)sas_device->sas_address));
544
545 spin_lock_irqsave(&ioc->sas_device_lock, flags);
546 list_add_tail(&sas_device->list, &ioc->sas_device_init_list);
547 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
548 _scsih_determine_boot_device(ioc, sas_device, 0);
549}
550
551/**
552 * mpt2sas_scsih_expander_find_by_handle - expander device search
553 * @ioc: per adapter object
554 * @handle: expander handle (assigned by firmware)
555 * Context: Calling function should acquire ioc->sas_device_lock
556 *
557 * This searches for expander device based on handle, then returns the
558 * sas_node object.
559 */
560struct _sas_node *
561mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
562{
563 struct _sas_node *sas_expander, *r;
564
565 r = NULL;
566 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
567 if (sas_expander->handle != handle)
568 continue;
569 r = sas_expander;
570 goto out;
571 }
572 out:
573 return r;
574}
575
576/**
577 * _scsih_raid_device_find_by_id - raid device search
578 * @ioc: per adapter object
579 * @id: sas device target id
580 * @channel: sas device channel
581 * Context: Calling function should acquire ioc->raid_device_lock
582 *
583 * This searches for raid_device based on target id, then return raid_device
584 * object.
585 */
586static struct _raid_device *
587_scsih_raid_device_find_by_id(struct MPT2SAS_ADAPTER *ioc, int id, int channel)
588{
589 struct _raid_device *raid_device, *r;
590
591 r = NULL;
592 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
593 if (raid_device->id == id && raid_device->channel == channel) {
594 r = raid_device;
595 goto out;
596 }
597 }
598
599 out:
600 return r;
601}
602
603/**
604 * _scsih_raid_device_find_by_handle - raid device search
605 * @ioc: per adapter object
606 * @handle: sas device handle (assigned by firmware)
607 * Context: Calling function should acquire ioc->raid_device_lock
608 *
609 * This searches for raid_device based on handle, then return raid_device
610 * object.
611 */
612static struct _raid_device *
613_scsih_raid_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
614{
615 struct _raid_device *raid_device, *r;
616
617 r = NULL;
618 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
619 if (raid_device->handle != handle)
620 continue;
621 r = raid_device;
622 goto out;
623 }
624
625 out:
626 return r;
627}
628
629/**
630 * _scsih_raid_device_find_by_wwid - raid device search
631 * @ioc: per adapter object
632 * @handle: sas device handle (assigned by firmware)
633 * Context: Calling function should acquire ioc->raid_device_lock
634 *
635 * This searches for raid_device based on wwid, then return raid_device
636 * object.
637 */
638static struct _raid_device *
639_scsih_raid_device_find_by_wwid(struct MPT2SAS_ADAPTER *ioc, u64 wwid)
640{
641 struct _raid_device *raid_device, *r;
642
643 r = NULL;
644 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
645 if (raid_device->wwid != wwid)
646 continue;
647 r = raid_device;
648 goto out;
649 }
650
651 out:
652 return r;
653}
654
655/**
656 * _scsih_raid_device_add - add raid_device object
657 * @ioc: per adapter object
658 * @raid_device: raid_device object
659 *
660 * This is added to the raid_device_list link list.
661 */
662static void
663_scsih_raid_device_add(struct MPT2SAS_ADAPTER *ioc,
664 struct _raid_device *raid_device)
665{
666 unsigned long flags;
667
668 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle"
669 "(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__,
670 raid_device->handle, (unsigned long long)raid_device->wwid));
671
672 spin_lock_irqsave(&ioc->raid_device_lock, flags);
673 list_add_tail(&raid_device->list, &ioc->raid_device_list);
674 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
675}
676
677/**
678 * _scsih_raid_device_remove - delete raid_device object
679 * @ioc: per adapter object
680 * @raid_device: raid_device object
681 *
682 * This is removed from the raid_device_list link list.
683 */
684static void
685_scsih_raid_device_remove(struct MPT2SAS_ADAPTER *ioc,
686 struct _raid_device *raid_device)
687{
688 unsigned long flags;
689
690 spin_lock_irqsave(&ioc->raid_device_lock, flags);
691 list_del(&raid_device->list);
692 memset(raid_device, 0, sizeof(struct _raid_device));
693 kfree(raid_device);
694 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
695}
696
697/**
698 * mpt2sas_scsih_expander_find_by_sas_address - expander device search
699 * @ioc: per adapter object
700 * @sas_address: sas address
701 * Context: Calling function should acquire ioc->sas_node_lock.
702 *
703 * This searches for expander device based on sas_address, then returns the
704 * sas_node object.
705 */
706struct _sas_node *
707mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
708 u64 sas_address)
709{
710 struct _sas_node *sas_expander, *r;
711
712 r = NULL;
713 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
714 if (sas_expander->sas_address != sas_address)
715 continue;
716 r = sas_expander;
717 goto out;
718 }
719 out:
720 return r;
721}
722
723/**
724 * _scsih_expander_node_add - insert expander device to the list.
725 * @ioc: per adapter object
726 * @sas_expander: the sas_device object
727 * Context: This function will acquire ioc->sas_node_lock.
728 *
729 * Adding new object to the ioc->sas_expander_list.
730 *
731 * Return nothing.
732 */
733static void
734_scsih_expander_node_add(struct MPT2SAS_ADAPTER *ioc,
735 struct _sas_node *sas_expander)
736{
737 unsigned long flags;
738
739 spin_lock_irqsave(&ioc->sas_node_lock, flags);
740 list_add_tail(&sas_expander->list, &ioc->sas_expander_list);
741 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
742}
743
744/**
745 * _scsih_is_end_device - determines if device is an end device
746 * @device_info: bitfield providing information about the device.
747 * Context: none
748 *
749 * Returns 1 if end device.
750 */
751static int
752_scsih_is_end_device(u32 device_info)
753{
754 if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE &&
755 ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) |
756 (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) |
757 (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)))
758 return 1;
759 else
760 return 0;
761}
762
763/**
764 * _scsih_scsi_lookup_get - returns scmd entry
765 * @ioc: per adapter object
766 * @smid: system request message index
767 * Context: This function will acquire ioc->scsi_lookup_lock.
768 *
769 * Returns the smid stored scmd pointer.
770 */
771static struct scsi_cmnd *
772_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
773{
774 unsigned long flags;
775 struct scsi_cmnd *scmd;
776
777 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
778 scmd = ioc->scsi_lookup[smid - 1].scmd;
779 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
780 return scmd;
781}
782
783/**
784 * mptscsih_getclear_scsi_lookup - returns scmd entry
785 * @ioc: per adapter object
786 * @smid: system request message index
787 * Context: This function will acquire ioc->scsi_lookup_lock.
788 *
789 * Returns the smid stored scmd pointer, as well as clearing the scmd pointer.
790 */
791static struct scsi_cmnd *
792_scsih_scsi_lookup_getclear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
793{
794 unsigned long flags;
795 struct scsi_cmnd *scmd;
796
797 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
798 scmd = ioc->scsi_lookup[smid - 1].scmd;
799 ioc->scsi_lookup[smid - 1].scmd = NULL;
800 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
801 return scmd;
802}
803
804/**
805 * _scsih_scsi_lookup_set - updates scmd entry in lookup
806 * @ioc: per adapter object
807 * @smid: system request message index
808 * @scmd: pointer to scsi command object
809 * Context: This function will acquire ioc->scsi_lookup_lock.
810 *
811 * This will save scmd pointer in the scsi_lookup array.
812 *
813 * Return nothing.
814 */
815static void
816_scsih_scsi_lookup_set(struct MPT2SAS_ADAPTER *ioc, u16 smid,
817 struct scsi_cmnd *scmd)
818{
819 unsigned long flags;
820
821 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
822 ioc->scsi_lookup[smid - 1].scmd = scmd;
823 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
824}
825
826/**
827 * _scsih_scsi_lookup_find_by_scmd - scmd lookup
828 * @ioc: per adapter object
829 * @smid: system request message index
830 * @scmd: pointer to scsi command object
831 * Context: This function will acquire ioc->scsi_lookup_lock.
832 *
833 * This will search for a scmd pointer in the scsi_lookup array,
834 * returning the revelent smid. A returned value of zero means invalid.
835 */
836static u16
837_scsih_scsi_lookup_find_by_scmd(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd
838 *scmd)
839{
840 u16 smid;
841 unsigned long flags;
842 int i;
843
844 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
845 smid = 0;
846 for (i = 0; i < ioc->request_depth; i++) {
847 if (ioc->scsi_lookup[i].scmd == scmd) {
848 smid = i + 1;
849 goto out;
850 }
851 }
852 out:
853 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
854 return smid;
855}
856
857/**
858 * _scsih_scsi_lookup_find_by_target - search for matching channel:id
859 * @ioc: per adapter object
860 * @id: target id
861 * @channel: channel
862 * Context: This function will acquire ioc->scsi_lookup_lock.
863 *
864 * This will search for a matching channel:id in the scsi_lookup array,
865 * returning 1 if found.
866 */
867static u8
868_scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
869 int channel)
870{
871 u8 found;
872 unsigned long flags;
873 int i;
874
875 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
876 found = 0;
877 for (i = 0 ; i < ioc->request_depth; i++) {
878 if (ioc->scsi_lookup[i].scmd &&
879 (ioc->scsi_lookup[i].scmd->device->id == id &&
880 ioc->scsi_lookup[i].scmd->device->channel == channel)) {
881 found = 1;
882 goto out;
883 }
884 }
885 out:
886 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
887 return found;
888}
889
890/**
891 * _scsih_get_chain_buffer_dma - obtain block of chains (dma address)
892 * @ioc: per adapter object
893 * @smid: system request message index
894 *
895 * Returns phys pointer to chain buffer.
896 */
897static dma_addr_t
898_scsih_get_chain_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
899{
900 return ioc->chain_dma + ((smid - 1) * (ioc->request_sz *
901 ioc->chains_needed_per_io));
902}
903
904/**
905 * _scsih_get_chain_buffer - obtain block of chains assigned to a mf request
906 * @ioc: per adapter object
907 * @smid: system request message index
908 *
909 * Returns virt pointer to chain buffer.
910 */
911static void *
912_scsih_get_chain_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid)
913{
914 return (void *)(ioc->chain + ((smid - 1) * (ioc->request_sz *
915 ioc->chains_needed_per_io)));
916}
917
918/**
919 * _scsih_build_scatter_gather - main sg creation routine
920 * @ioc: per adapter object
921 * @scmd: scsi command
922 * @smid: system request message index
923 * Context: none.
924 *
925 * The main routine that builds scatter gather table from a given
926 * scsi request sent via the .queuecommand main handler.
927 *
928 * Returns 0 success, anything else error
929 */
930static int
931_scsih_build_scatter_gather(struct MPT2SAS_ADAPTER *ioc,
932 struct scsi_cmnd *scmd, u16 smid)
933{
934 Mpi2SCSIIORequest_t *mpi_request;
935 dma_addr_t chain_dma;
936 struct scatterlist *sg_scmd;
937 void *sg_local, *chain;
938 u32 chain_offset;
939 u32 chain_length;
940 u32 chain_flags;
941 u32 sges_left;
942 u32 sges_in_segment;
943 u32 sgl_flags;
944 u32 sgl_flags_last_element;
945 u32 sgl_flags_end_buffer;
946
947 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
948
949 /* init scatter gather flags */
950 sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT;
951 if (scmd->sc_data_direction == DMA_TO_DEVICE)
952 sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC;
953 sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT)
954 << MPI2_SGE_FLAGS_SHIFT;
955 sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT |
956 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST)
957 << MPI2_SGE_FLAGS_SHIFT;
958 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
959
960 sg_scmd = scsi_sglist(scmd);
961 sges_left = scsi_dma_map(scmd);
962 if (!sges_left) {
963 sdev_printk(KERN_ERR, scmd->device, "pci_map_sg"
964 " failed: request for %d bytes!\n", scsi_bufflen(scmd));
965 return -ENOMEM;
966 }
967
968 sg_local = &mpi_request->SGL;
969 sges_in_segment = ioc->max_sges_in_main_message;
970 if (sges_left <= sges_in_segment)
971 goto fill_in_last_segment;
972
973 mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) +
974 (sges_in_segment * ioc->sge_size))/4;
975
976 /* fill in main message segment when there is a chain following */
977 while (sges_in_segment) {
978 if (sges_in_segment == 1)
979 ioc->base_add_sg_single(sg_local,
980 sgl_flags_last_element | sg_dma_len(sg_scmd),
981 sg_dma_address(sg_scmd));
982 else
983 ioc->base_add_sg_single(sg_local, sgl_flags |
984 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
985 sg_scmd = sg_next(sg_scmd);
986 sg_local += ioc->sge_size;
987 sges_left--;
988 sges_in_segment--;
989 }
990
991 /* initializing the chain flags and pointers */
992 chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
993 chain = _scsih_get_chain_buffer(ioc, smid);
994 chain_dma = _scsih_get_chain_buffer_dma(ioc, smid);
995 do {
996 sges_in_segment = (sges_left <=
997 ioc->max_sges_in_chain_message) ? sges_left :
998 ioc->max_sges_in_chain_message;
999 chain_offset = (sges_left == sges_in_segment) ?
1000 0 : (sges_in_segment * ioc->sge_size)/4;
1001 chain_length = sges_in_segment * ioc->sge_size;
1002 if (chain_offset) {
1003 chain_offset = chain_offset <<
1004 MPI2_SGE_CHAIN_OFFSET_SHIFT;
1005 chain_length += ioc->sge_size;
1006 }
1007 ioc->base_add_sg_single(sg_local, chain_flags | chain_offset |
1008 chain_length, chain_dma);
1009 sg_local = chain;
1010 if (!chain_offset)
1011 goto fill_in_last_segment;
1012
1013 /* fill in chain segments */
1014 while (sges_in_segment) {
1015 if (sges_in_segment == 1)
1016 ioc->base_add_sg_single(sg_local,
1017 sgl_flags_last_element |
1018 sg_dma_len(sg_scmd),
1019 sg_dma_address(sg_scmd));
1020 else
1021 ioc->base_add_sg_single(sg_local, sgl_flags |
1022 sg_dma_len(sg_scmd),
1023 sg_dma_address(sg_scmd));
1024 sg_scmd = sg_next(sg_scmd);
1025 sg_local += ioc->sge_size;
1026 sges_left--;
1027 sges_in_segment--;
1028 }
1029
1030 chain_dma += ioc->request_sz;
1031 chain += ioc->request_sz;
1032 } while (1);
1033
1034
1035 fill_in_last_segment:
1036
1037 /* fill the last segment */
1038 while (sges_left) {
1039 if (sges_left == 1)
1040 ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer |
1041 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
1042 else
1043 ioc->base_add_sg_single(sg_local, sgl_flags |
1044 sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
1045 sg_scmd = sg_next(sg_scmd);
1046 sg_local += ioc->sge_size;
1047 sges_left--;
1048 }
1049
1050 return 0;
1051}
1052
1053/**
1054 * scsih_change_queue_depth - setting device queue depth
1055 * @sdev: scsi device struct
1056 * @qdepth: requested queue depth
1057 *
1058 * Returns queue depth.
1059 */
1060static int
1061scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
1062{
1063 struct Scsi_Host *shost = sdev->host;
1064 int max_depth;
1065 int tag_type;
1066
1067 max_depth = shost->can_queue;
1068 if (!sdev->tagged_supported)
1069 max_depth = 1;
1070 if (qdepth > max_depth)
1071 qdepth = max_depth;
1072 tag_type = (qdepth == 1) ? 0 : MSG_SIMPLE_TAG;
1073 scsi_adjust_queue_depth(sdev, tag_type, qdepth);
1074
1075 if (sdev->inquiry_len > 7)
1076 sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), "
1077 "simple(%d), ordered(%d), scsi_level(%d), cmd_que(%d)\n",
1078 sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags,
1079 sdev->ordered_tags, sdev->scsi_level,
1080 (sdev->inquiry[7] & 2) >> 1);
1081
1082 return sdev->queue_depth;
1083}
1084
1085/**
1086 * scsih_change_queue_depth - changing device queue tag type
1087 * @sdev: scsi device struct
1088 * @tag_type: requested tag type
1089 *
1090 * Returns queue tag type.
1091 */
1092static int
1093scsih_change_queue_type(struct scsi_device *sdev, int tag_type)
1094{
1095 if (sdev->tagged_supported) {
1096 scsi_set_tag_type(sdev, tag_type);
1097 if (tag_type)
1098 scsi_activate_tcq(sdev, sdev->queue_depth);
1099 else
1100 scsi_deactivate_tcq(sdev, sdev->queue_depth);
1101 } else
1102 tag_type = 0;
1103
1104 return tag_type;
1105}
1106
1107/**
1108 * scsih_target_alloc - target add routine
1109 * @starget: scsi target struct
1110 *
1111 * Returns 0 if ok. Any other return is assumed to be an error and
1112 * the device is ignored.
1113 */
1114static int
1115scsih_target_alloc(struct scsi_target *starget)
1116{
1117 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1118 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1119 struct MPT2SAS_TARGET *sas_target_priv_data;
1120 struct _sas_device *sas_device;
1121 struct _raid_device *raid_device;
1122 unsigned long flags;
1123 struct sas_rphy *rphy;
1124
1125 sas_target_priv_data = kzalloc(sizeof(struct scsi_target), GFP_KERNEL);
1126 if (!sas_target_priv_data)
1127 return -ENOMEM;
1128
1129 starget->hostdata = sas_target_priv_data;
1130 sas_target_priv_data->starget = starget;
1131 sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
1132
1133 /* RAID volumes */
1134 if (starget->channel == RAID_CHANNEL) {
1135 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1136 raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
1137 starget->channel);
1138 if (raid_device) {
1139 sas_target_priv_data->handle = raid_device->handle;
1140 sas_target_priv_data->sas_address = raid_device->wwid;
1141 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
1142 raid_device->starget = starget;
1143 }
1144 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1145 return 0;
1146 }
1147
1148 /* sas/sata devices */
1149 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1150 rphy = dev_to_rphy(starget->dev.parent);
1151 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1152 rphy->identify.sas_address);
1153
1154 if (sas_device) {
1155 sas_target_priv_data->handle = sas_device->handle;
1156 sas_target_priv_data->sas_address = sas_device->sas_address;
1157 sas_device->starget = starget;
1158 sas_device->id = starget->id;
1159 sas_device->channel = starget->channel;
1160 if (sas_device->hidden_raid_component)
1161 sas_target_priv_data->flags |=
1162 MPT_TARGET_FLAGS_RAID_COMPONENT;
1163 }
1164 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1165
1166 return 0;
1167}
1168
1169/**
1170 * scsih_target_destroy - target destroy routine
1171 * @starget: scsi target struct
1172 *
1173 * Returns nothing.
1174 */
1175static void
1176scsih_target_destroy(struct scsi_target *starget)
1177{
1178 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
1179 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1180 struct MPT2SAS_TARGET *sas_target_priv_data;
1181 struct _sas_device *sas_device;
1182 struct _raid_device *raid_device;
1183 unsigned long flags;
1184 struct sas_rphy *rphy;
1185
1186 sas_target_priv_data = starget->hostdata;
1187 if (!sas_target_priv_data)
1188 return;
1189
1190 if (starget->channel == RAID_CHANNEL) {
1191 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1192 raid_device = _scsih_raid_device_find_by_id(ioc, starget->id,
1193 starget->channel);
1194 if (raid_device) {
1195 raid_device->starget = NULL;
1196 raid_device->sdev = NULL;
1197 }
1198 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1199 goto out;
1200 }
1201
1202 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1203 rphy = dev_to_rphy(starget->dev.parent);
1204 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1205 rphy->identify.sas_address);
1206 if (sas_device)
1207 sas_device->starget = NULL;
1208
1209 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1210
1211 out:
1212 kfree(sas_target_priv_data);
1213 starget->hostdata = NULL;
1214}
1215
1216/**
1217 * scsih_slave_alloc - device add routine
1218 * @sdev: scsi device struct
1219 *
1220 * Returns 0 if ok. Any other return is assumed to be an error and
1221 * the device is ignored.
1222 */
1223static int
1224scsih_slave_alloc(struct scsi_device *sdev)
1225{
1226 struct Scsi_Host *shost;
1227 struct MPT2SAS_ADAPTER *ioc;
1228 struct MPT2SAS_TARGET *sas_target_priv_data;
1229 struct MPT2SAS_DEVICE *sas_device_priv_data;
1230 struct scsi_target *starget;
1231 struct _raid_device *raid_device;
1232 struct _sas_device *sas_device;
1233 unsigned long flags;
1234
1235 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
1236 if (!sas_device_priv_data)
1237 return -ENOMEM;
1238
1239 sas_device_priv_data->lun = sdev->lun;
1240 sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT;
1241
1242 starget = scsi_target(sdev);
1243 sas_target_priv_data = starget->hostdata;
1244 sas_target_priv_data->num_luns++;
1245 sas_device_priv_data->sas_target = sas_target_priv_data;
1246 sdev->hostdata = sas_device_priv_data;
1247 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT))
1248 sdev->no_uld_attach = 1;
1249
1250 shost = dev_to_shost(&starget->dev);
1251 ioc = shost_priv(shost);
1252 if (starget->channel == RAID_CHANNEL) {
1253 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1254 raid_device = _scsih_raid_device_find_by_id(ioc,
1255 starget->id, starget->channel);
1256 if (raid_device)
1257 raid_device->sdev = sdev; /* raid is single lun */
1258 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1259 } else {
1260 /* set TLR bit for SSP devices */
1261 if (!(ioc->facts.IOCCapabilities &
1262 MPI2_IOCFACTS_CAPABILITY_TLR))
1263 goto out;
1264 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1265 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1266 sas_device_priv_data->sas_target->sas_address);
1267 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1268 if (sas_device && sas_device->device_info &
1269 MPI2_SAS_DEVICE_INFO_SSP_TARGET)
1270 sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON;
1271 }
1272
1273 out:
1274 return 0;
1275}
1276
1277/**
1278 * scsih_slave_destroy - device destroy routine
1279 * @sdev: scsi device struct
1280 *
1281 * Returns nothing.
1282 */
1283static void
1284scsih_slave_destroy(struct scsi_device *sdev)
1285{
1286 struct MPT2SAS_TARGET *sas_target_priv_data;
1287 struct scsi_target *starget;
1288
1289 if (!sdev->hostdata)
1290 return;
1291
1292 starget = scsi_target(sdev);
1293 sas_target_priv_data = starget->hostdata;
1294 sas_target_priv_data->num_luns--;
1295 kfree(sdev->hostdata);
1296 sdev->hostdata = NULL;
1297}
1298
1299/**
1300 * scsih_display_sata_capabilities - sata capabilities
1301 * @ioc: per adapter object
1302 * @sas_device: the sas_device object
1303 * @sdev: scsi device struct
1304 */
1305static void
1306scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc,
1307 struct _sas_device *sas_device, struct scsi_device *sdev)
1308{
1309 Mpi2ConfigReply_t mpi_reply;
1310 Mpi2SasDevicePage0_t sas_device_pg0;
1311 u32 ioc_status;
1312 u16 flags;
1313 u32 device_info;
1314
1315 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
1316 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, sas_device->handle))) {
1317 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1318 ioc->name, __FILE__, __LINE__, __func__);
1319 return;
1320 }
1321
1322 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1323 MPI2_IOCSTATUS_MASK;
1324 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1325 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1326 ioc->name, __FILE__, __LINE__, __func__);
1327 return;
1328 }
1329
1330 flags = le16_to_cpu(sas_device_pg0.Flags);
1331 device_info = le16_to_cpu(sas_device_pg0.DeviceInfo);
1332
1333 sdev_printk(KERN_INFO, sdev,
1334 "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), "
1335 "sw_preserve(%s)\n",
1336 (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n",
1337 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n",
1338 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" :
1339 "n",
1340 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n",
1341 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n",
1342 (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n");
1343}
1344
1345/**
1346 * _scsih_get_volume_capabilities - volume capabilities
1347 * @ioc: per adapter object
1348 * @sas_device: the raid_device object
1349 */
1350static void
1351_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1352 struct _raid_device *raid_device)
1353{
1354 Mpi2RaidVolPage0_t *vol_pg0;
1355 Mpi2RaidPhysDiskPage0_t pd_pg0;
1356 Mpi2SasDevicePage0_t sas_device_pg0;
1357 Mpi2ConfigReply_t mpi_reply;
1358 u16 sz;
1359 u8 num_pds;
1360
1361 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1362 &num_pds)) || !num_pds) {
1363 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1364 ioc->name, __FILE__, __LINE__, __func__);
1365 return;
1366 }
1367
1368 raid_device->num_pds = num_pds;
1369 sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
1370 sizeof(Mpi2RaidVol0PhysDisk_t));
1371 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1372 if (!vol_pg0) {
1373 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1374 ioc->name, __FILE__, __LINE__, __func__);
1375 return;
1376 }
1377
1378 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1379 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1380 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1381 ioc->name, __FILE__, __LINE__, __func__);
1382 kfree(vol_pg0);
1383 return;
1384 }
1385
1386 raid_device->volume_type = vol_pg0->VolumeType;
1387
1388 /* figure out what the underlying devices are by
1389 * obtaining the device_info bits for the 1st device
1390 */
1391 if (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
1392 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
1393 vol_pg0->PhysDisk[0].PhysDiskNum))) {
1394 if (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
1395 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
1396 le16_to_cpu(pd_pg0.DevHandle)))) {
1397 raid_device->device_info =
1398 le32_to_cpu(sas_device_pg0.DeviceInfo);
1399 }
1400 }
1401
1402 kfree(vol_pg0);
1403}
1404
1405/**
1406 * scsih_slave_configure - device configure routine.
1407 * @sdev: scsi device struct
1408 *
1409 * Returns 0 if ok. Any other return is assumed to be an error and
1410 * the device is ignored.
1411 */
1412static int
1413scsih_slave_configure(struct scsi_device *sdev)
1414{
1415 struct Scsi_Host *shost = sdev->host;
1416 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1417 struct MPT2SAS_DEVICE *sas_device_priv_data;
1418 struct MPT2SAS_TARGET *sas_target_priv_data;
1419 struct _sas_device *sas_device;
1420 struct _raid_device *raid_device;
1421 unsigned long flags;
1422 int qdepth;
1423 u8 ssp_target = 0;
1424 char *ds = "";
1425 char *r_level = "";
1426
1427 qdepth = 1;
1428 sas_device_priv_data = sdev->hostdata;
1429 sas_device_priv_data->configured_lun = 1;
1430 sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT;
1431 sas_target_priv_data = sas_device_priv_data->sas_target;
1432
1433 /* raid volume handling */
1434 if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
1435
1436 spin_lock_irqsave(&ioc->raid_device_lock, flags);
1437 raid_device = _scsih_raid_device_find_by_handle(ioc,
1438 sas_target_priv_data->handle);
1439 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1440 if (!raid_device) {
1441 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1442 ioc->name, __FILE__, __LINE__, __func__);
1443 return 0;
1444 }
1445
1446 _scsih_get_volume_capabilities(ioc, raid_device);
1447
1448 /* RAID Queue Depth Support
1449 * IS volume = underlying qdepth of drive type, either
1450 * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
1451 * IM/IME/R10 = 128 (MPT2SAS_RAID_QUEUE_DEPTH)
1452 */
1453 if (raid_device->device_info &
1454 MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1455 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
1456 ds = "SSP";
1457 } else {
1458 qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
1459 if (raid_device->device_info &
1460 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1461 ds = "SATA";
1462 else
1463 ds = "STP";
1464 }
1465
1466 switch (raid_device->volume_type) {
1467 case MPI2_RAID_VOL_TYPE_RAID0:
1468 r_level = "RAID0";
1469 break;
1470 case MPI2_RAID_VOL_TYPE_RAID1E:
1471 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1472 r_level = "RAID1E";
1473 break;
1474 case MPI2_RAID_VOL_TYPE_RAID1:
1475 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1476 r_level = "RAID1";
1477 break;
1478 case MPI2_RAID_VOL_TYPE_RAID10:
1479 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1480 r_level = "RAID10";
1481 break;
1482 case MPI2_RAID_VOL_TYPE_UNKNOWN:
1483 default:
1484 qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
1485 r_level = "RAIDX";
1486 break;
1487 }
1488
1489 sdev_printk(KERN_INFO, sdev, "%s: "
1490 "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n",
1491 r_level, raid_device->handle,
1492 (unsigned long long)raid_device->wwid,
1493 raid_device->num_pds, ds);
1494 scsih_change_queue_depth(sdev, qdepth);
1495 return 0;
1496 }
1497
1498 /* non-raid handling */
1499 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1500 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1501 sas_device_priv_data->sas_target->sas_address);
1502 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1503 if (sas_device) {
1504 if (sas_target_priv_data->flags &
1505 MPT_TARGET_FLAGS_RAID_COMPONENT) {
1506 mpt2sas_config_get_volume_handle(ioc,
1507 sas_device->handle, &sas_device->volume_handle);
1508 mpt2sas_config_get_volume_wwid(ioc,
1509 sas_device->volume_handle,
1510 &sas_device->volume_wwid);
1511 }
1512 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
1513 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
1514 ssp_target = 1;
1515 ds = "SSP";
1516 } else {
1517 qdepth = MPT2SAS_SATA_QUEUE_DEPTH;
1518 if (sas_device->device_info &
1519 MPI2_SAS_DEVICE_INFO_STP_TARGET)
1520 ds = "STP";
1521 else if (sas_device->device_info &
1522 MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
1523 ds = "SATA";
1524 }
1525
1526 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
1527 "sas_addr(0x%016llx), device_name(0x%016llx)\n",
1528 ds, sas_device->handle,
1529 (unsigned long long)sas_device->sas_address,
1530 (unsigned long long)sas_device->device_name);
1531 sdev_printk(KERN_INFO, sdev, "%s: "
1532 "enclosure_logical_id(0x%016llx), slot(%d)\n", ds,
1533 (unsigned long long) sas_device->enclosure_logical_id,
1534 sas_device->slot);
1535
1536 if (!ssp_target)
1537 scsih_display_sata_capabilities(ioc, sas_device, sdev);
1538 }
1539
1540 scsih_change_queue_depth(sdev, qdepth);
1541
1542 if (ssp_target)
1543 sas_read_port_mode_page(sdev);
1544 return 0;
1545}
1546
1547/**
1548 * scsih_bios_param - fetch head, sector, cylinder info for a disk
1549 * @sdev: scsi device struct
1550 * @bdev: pointer to block device context
1551 * @capacity: device size (in 512 byte sectors)
1552 * @params: three element array to place output:
1553 * params[0] number of heads (max 255)
1554 * params[1] number of sectors (max 63)
1555 * params[2] number of cylinders
1556 *
1557 * Return nothing.
1558 */
1559static int
1560scsih_bios_param(struct scsi_device *sdev, struct block_device *bdev,
1561 sector_t capacity, int params[])
1562{
1563 int heads;
1564 int sectors;
1565 sector_t cylinders;
1566 ulong dummy;
1567
1568 heads = 64;
1569 sectors = 32;
1570
1571 dummy = heads * sectors;
1572 cylinders = capacity;
1573 sector_div(cylinders, dummy);
1574
1575 /*
1576 * Handle extended translation size for logical drives
1577 * > 1Gb
1578 */
1579 if ((ulong)capacity >= 0x200000) {
1580 heads = 255;
1581 sectors = 63;
1582 dummy = heads * sectors;
1583 cylinders = capacity;
1584 sector_div(cylinders, dummy);
1585 }
1586
1587 /* return result */
1588 params[0] = heads;
1589 params[1] = sectors;
1590 params[2] = cylinders;
1591
1592 return 0;
1593}
1594
1595/**
1596 * _scsih_response_code - translation of device response code
1597 * @ioc: per adapter object
1598 * @response_code: response code returned by the device
1599 *
1600 * Return nothing.
1601 */
1602static void
1603_scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
1604{
1605 char *desc;
1606
1607 switch (response_code) {
1608 case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
1609 desc = "task management request completed";
1610 break;
1611 case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
1612 desc = "invalid frame";
1613 break;
1614 case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1615 desc = "task management request not supported";
1616 break;
1617 case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
1618 desc = "task management request failed";
1619 break;
1620 case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1621 desc = "task management request succeeded";
1622 break;
1623 case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1624 desc = "invalid lun";
1625 break;
1626 case 0xA:
1627 desc = "overlapped tag attempted";
1628 break;
1629 case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1630 desc = "task queued, however not sent to target";
1631 break;
1632 default:
1633 desc = "unknown";
1634 break;
1635 }
1636 printk(MPT2SAS_WARN_FMT "response_code(0x%01x): %s\n",
1637 ioc->name, response_code, desc);
1638}
1639
1640/**
1641 * scsih_tm_done - tm completion routine
1642 * @ioc: per adapter object
1643 * @smid: system request message index
1644 * @VF_ID: virtual function id
1645 * @reply: reply message frame(lower 32bit addr)
1646 * Context: none.
1647 *
1648 * The callback handler when using scsih_issue_tm.
1649 *
1650 * Return nothing.
1651 */
1652static void
1653scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
1654{
1655 MPI2DefaultReply_t *mpi_reply;
1656
1657 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
1658 return;
1659 if (ioc->tm_cmds.smid != smid)
1660 return;
1661 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
1662 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
1663 if (mpi_reply) {
1664 memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
1665 ioc->tm_cmds.status |= MPT2_CMD_REPLY_VALID;
1666 }
1667 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
1668 complete(&ioc->tm_cmds.done);
1669}
1670
1671/**
1672 * mpt2sas_scsih_set_tm_flag - set per target tm_busy
1673 * @ioc: per adapter object
1674 * @handle: device handle
1675 *
1676 * During taskmangement request, we need to freeze the device queue.
1677 */
1678void
1679mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1680{
1681 struct MPT2SAS_DEVICE *sas_device_priv_data;
1682 struct scsi_device *sdev;
1683 u8 skip = 0;
1684
1685 shost_for_each_device(sdev, ioc->shost) {
1686 if (skip)
1687 continue;
1688 sas_device_priv_data = sdev->hostdata;
1689 if (!sas_device_priv_data)
1690 continue;
1691 if (sas_device_priv_data->sas_target->handle == handle) {
1692 sas_device_priv_data->sas_target->tm_busy = 1;
1693 skip = 1;
1694 ioc->ignore_loginfos = 1;
1695 }
1696 }
1697}
1698
1699/**
1700 * mpt2sas_scsih_clear_tm_flag - clear per target tm_busy
1701 * @ioc: per adapter object
1702 * @handle: device handle
1703 *
1704 * During taskmangement request, we need to freeze the device queue.
1705 */
1706void
1707mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
1708{
1709 struct MPT2SAS_DEVICE *sas_device_priv_data;
1710 struct scsi_device *sdev;
1711 u8 skip = 0;
1712
1713 shost_for_each_device(sdev, ioc->shost) {
1714 if (skip)
1715 continue;
1716 sas_device_priv_data = sdev->hostdata;
1717 if (!sas_device_priv_data)
1718 continue;
1719 if (sas_device_priv_data->sas_target->handle == handle) {
1720 sas_device_priv_data->sas_target->tm_busy = 0;
1721 skip = 1;
1722 ioc->ignore_loginfos = 0;
1723 }
1724 }
1725}
1726
1727/**
1728 * mpt2sas_scsih_issue_tm - main routine for sending tm requests
1729 * @ioc: per adapter struct
1730 * @device_handle: device handle
1731 * @lun: lun number
1732 * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
1733 * @smid_task: smid assigned to the task
1734 * @timeout: timeout in seconds
1735 * Context: The calling function needs to acquire the tm_cmds.mutex
1736 *
1737 * A generic API for sending task management requests to firmware.
1738 *
1739 * The ioc->tm_cmds.status flag should be MPT2_CMD_NOT_USED before calling
1740 * this API.
1741 *
1742 * The callback index is set inside `ioc->tm_cb_idx`.
1743 *
1744 * Return nothing.
1745 */
1746void
1747mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1748 u8 type, u16 smid_task, ulong timeout)
1749{
1750 Mpi2SCSITaskManagementRequest_t *mpi_request;
1751 Mpi2SCSITaskManagementReply_t *mpi_reply;
1752 u16 smid = 0;
1753 u32 ioc_state;
1754 unsigned long timeleft;
1755 u8 VF_ID = 0;
1756 unsigned long flags;
1757
1758 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
1759 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED ||
1760 ioc->shost_recovery) {
1761 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1762 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1763 __func__, ioc->name);
1764 return;
1765 }
1766 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1767
1768 ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
1769 if (ioc_state & MPI2_DOORBELL_USED) {
1770 dhsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "unexpected doorbell "
1771 "active!\n", ioc->name));
1772 goto issue_host_reset;
1773 }
1774
1775 if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
1776 mpt2sas_base_fault_info(ioc, ioc_state &
1777 MPI2_DOORBELL_DATA_MASK);
1778 goto issue_host_reset;
1779 }
1780
1781 smid = mpt2sas_base_get_smid(ioc, ioc->tm_cb_idx);
1782 if (!smid) {
1783 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1784 ioc->name, __func__);
1785 return;
1786 }
1787
1788 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
1789 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type, smid));
1790 ioc->tm_cmds.status = MPT2_CMD_PENDING;
1791 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1792 ioc->tm_cmds.smid = smid;
1793 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
1794 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
1795 mpi_request->DevHandle = cpu_to_le16(handle);
1796 mpi_request->TaskType = type;
1797 mpi_request->TaskMID = cpu_to_le16(smid_task);
1798 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
1799 mpt2sas_scsih_set_tm_flag(ioc, handle);
1800 mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID);
1801 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
1802 mpt2sas_scsih_clear_tm_flag(ioc, handle);
1803 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
1804 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1805 ioc->name, __func__);
1806 _debug_dump_mf(mpi_request,
1807 sizeof(Mpi2SCSITaskManagementRequest_t)/4);
1808 if (!(ioc->tm_cmds.status & MPT2_CMD_RESET))
1809 goto issue_host_reset;
1810 }
1811
1812 if (ioc->tm_cmds.status & MPT2_CMD_REPLY_VALID) {
1813 mpi_reply = ioc->tm_cmds.reply;
1814 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "complete tm: "
1815 "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n",
1816 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
1817 le32_to_cpu(mpi_reply->IOCLogInfo),
1818 le32_to_cpu(mpi_reply->TerminationCount)));
1819 if (ioc->logging_level & MPT_DEBUG_TM)
1820 _scsih_response_code(ioc, mpi_reply->ResponseCode);
1821 }
1822 return;
1823 issue_host_reset:
1824 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, FORCE_BIG_HAMMER);
1825}
1826
1827/**
1828 * scsih_abort - eh threads main abort routine
1829 * @sdev: scsi device struct
1830 *
1831 * Returns SUCCESS if command aborted else FAILED
1832 */
1833static int
1834scsih_abort(struct scsi_cmnd *scmd)
1835{
1836 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
1837 struct MPT2SAS_DEVICE *sas_device_priv_data;
1838 u16 smid;
1839 u16 handle;
1840 int r;
1841 struct scsi_cmnd *scmd_lookup;
1842
1843 printk(MPT2SAS_INFO_FMT "attempting task abort! scmd(%p)\n",
1844 ioc->name, scmd);
1845 scsi_print_command(scmd);
1846
1847 sas_device_priv_data = scmd->device->hostdata;
1848 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
1849 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n",
1850 ioc->name, scmd);
1851 scmd->result = DID_NO_CONNECT << 16;
1852 scmd->scsi_done(scmd);
1853 r = SUCCESS;
1854 goto out;
1855 }
1856
1857 /* search for the command */
1858 smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd);
1859 if (!smid) {
1860 scmd->result = DID_RESET << 16;
1861 r = SUCCESS;
1862 goto out;
1863 }
1864
1865 /* for hidden raid components and volumes this is not supported */
1866 if (sas_device_priv_data->sas_target->flags &
1867 MPT_TARGET_FLAGS_RAID_COMPONENT ||
1868 sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) {
1869 scmd->result = DID_RESET << 16;
1870 r = FAILED;
1871 goto out;
1872 }
1873
1874 mutex_lock(&ioc->tm_cmds.mutex);
1875 handle = sas_device_priv_data->sas_target->handle;
1876 mpt2sas_scsih_issue_tm(ioc, handle, sas_device_priv_data->lun,
1877 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30);
1878
1879 /* sanity check - see whether command actually completed */
1880 scmd_lookup = _scsih_scsi_lookup_get(ioc, smid);
1881 if (scmd_lookup && (scmd_lookup->serial_number == scmd->serial_number))
1882 r = FAILED;
1883 else
1884 r = SUCCESS;
1885 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
1886 mutex_unlock(&ioc->tm_cmds.mutex);
1887
1888 out:
1889 printk(MPT2SAS_INFO_FMT "task abort: %s scmd(%p)\n",
1890 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
1891 return r;
1892}
1893
1894
1895/**
1896 * scsih_dev_reset - eh threads main device reset routine
1897 * @sdev: scsi device struct
1898 *
1899 * Returns SUCCESS if command aborted else FAILED
1900 */
1901static int
1902scsih_dev_reset(struct scsi_cmnd *scmd)
1903{
1904 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
1905 struct MPT2SAS_DEVICE *sas_device_priv_data;
1906 struct _sas_device *sas_device;
1907 unsigned long flags;
1908 u16 handle;
1909 int r;
1910
1911 printk(MPT2SAS_INFO_FMT "attempting target reset! scmd(%p)\n",
1912 ioc->name, scmd);
1913 scsi_print_command(scmd);
1914
1915 sas_device_priv_data = scmd->device->hostdata;
1916 if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
1917 printk(MPT2SAS_INFO_FMT "device been deleted! scmd(%p)\n",
1918 ioc->name, scmd);
1919 scmd->result = DID_NO_CONNECT << 16;
1920 scmd->scsi_done(scmd);
1921 r = SUCCESS;
1922 goto out;
1923 }
1924
1925 /* for hidden raid components obtain the volume_handle */
1926 handle = 0;
1927 if (sas_device_priv_data->sas_target->flags &
1928 MPT_TARGET_FLAGS_RAID_COMPONENT) {
1929 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1930 sas_device = _scsih_sas_device_find_by_handle(ioc,
1931 sas_device_priv_data->sas_target->handle);
1932 if (sas_device)
1933 handle = sas_device->volume_handle;
1934 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1935 } else
1936 handle = sas_device_priv_data->sas_target->handle;
1937
1938 if (!handle) {
1939 scmd->result = DID_RESET << 16;
1940 r = FAILED;
1941 goto out;
1942 }
1943
1944 mutex_lock(&ioc->tm_cmds.mutex);
1945 mpt2sas_scsih_issue_tm(ioc, handle, 0,
1946 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30);
1947
1948 /*
1949 * sanity check see whether all commands to this target been
1950 * completed
1951 */
1952 if (_scsih_scsi_lookup_find_by_target(ioc, scmd->device->id,
1953 scmd->device->channel))
1954 r = FAILED;
1955 else
1956 r = SUCCESS;
1957 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
1958 mutex_unlock(&ioc->tm_cmds.mutex);
1959
1960 out:
1961 printk(MPT2SAS_INFO_FMT "target reset: %s scmd(%p)\n",
1962 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
1963 return r;
1964}
1965
1966/**
1967 * scsih_abort - eh threads main host reset routine
1968 * @sdev: scsi device struct
1969 *
1970 * Returns SUCCESS if command aborted else FAILED
1971 */
1972static int
1973scsih_host_reset(struct scsi_cmnd *scmd)
1974{
1975 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
1976 int r, retval;
1977
1978 printk(MPT2SAS_INFO_FMT "attempting host reset! scmd(%p)\n",
1979 ioc->name, scmd);
1980 scsi_print_command(scmd);
1981
1982 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1983 FORCE_BIG_HAMMER);
1984 r = (retval < 0) ? FAILED : SUCCESS;
1985 printk(MPT2SAS_INFO_FMT "host reset: %s scmd(%p)\n",
1986 ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
1987
1988 return r;
1989}
1990
1991/**
1992 * _scsih_fw_event_add - insert and queue up fw_event
1993 * @ioc: per adapter object
1994 * @fw_event: object describing the event
1995 * Context: This function will acquire ioc->fw_event_lock.
1996 *
1997 * This adds the firmware event object into link list, then queues it up to
1998 * be processed from user context.
1999 *
2000 * Return nothing.
2001 */
2002static void
2003_scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
2004{
2005 unsigned long flags;
2006
2007 if (ioc->firmware_event_thread == NULL)
2008 return;
2009
2010 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2011 list_add_tail(&fw_event->list, &ioc->fw_event_list);
2012 INIT_DELAYED_WORK(&fw_event->work, _firmware_event_work);
2013 queue_delayed_work(ioc->firmware_event_thread, &fw_event->work, 1);
2014 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2015}
2016
2017/**
2018 * _scsih_fw_event_free - delete fw_event
2019 * @ioc: per adapter object
2020 * @fw_event: object describing the event
2021 * Context: This function will acquire ioc->fw_event_lock.
2022 *
2023 * This removes firmware event object from link list, frees associated memory.
2024 *
2025 * Return nothing.
2026 */
2027static void
2028_scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2029 *fw_event)
2030{
2031 unsigned long flags;
2032
2033 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2034 list_del(&fw_event->list);
2035 kfree(fw_event->event_data);
2036 kfree(fw_event);
2037 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2038}
2039
2040/**
2041 * _scsih_fw_event_add - requeue an event
2042 * @ioc: per adapter object
2043 * @fw_event: object describing the event
2044 * Context: This function will acquire ioc->fw_event_lock.
2045 *
2046 * Return nothing.
2047 */
2048static void
2049_scsih_fw_event_requeue(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2050 *fw_event, unsigned long delay)
2051{
2052 unsigned long flags;
2053 if (ioc->firmware_event_thread == NULL)
2054 return;
2055
2056 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2057 queue_delayed_work(ioc->firmware_event_thread, &fw_event->work, delay);
2058 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2059}
2060
2061/**
2062 * _scsih_fw_event_off - turn flag off preventing event handling
2063 * @ioc: per adapter object
2064 *
2065 * Used to prevent handling of firmware events during adapter reset
2066 * driver unload.
2067 *
2068 * Return nothing.
2069 */
2070static void
2071_scsih_fw_event_off(struct MPT2SAS_ADAPTER *ioc)
2072{
2073 unsigned long flags;
2074
2075 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2076 ioc->fw_events_off = 1;
2077 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2078
2079}
2080
2081/**
2082 * _scsih_fw_event_on - turn flag on allowing firmware event handling
2083 * @ioc: per adapter object
2084 *
2085 * Returns nothing.
2086 */
2087static void
2088_scsih_fw_event_on(struct MPT2SAS_ADAPTER *ioc)
2089{
2090 unsigned long flags;
2091
2092 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2093 ioc->fw_events_off = 0;
2094 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2095}
2096
2097/**
2098 * _scsih_ublock_io_device - set the device state to SDEV_RUNNING
2099 * @ioc: per adapter object
2100 * @handle: device handle
2101 *
2102 * During device pull we need to appropiately set the sdev state.
2103 */
2104static void
2105_scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2106{
2107 struct MPT2SAS_DEVICE *sas_device_priv_data;
2108 struct scsi_device *sdev;
2109
2110 shost_for_each_device(sdev, ioc->shost) {
2111 sas_device_priv_data = sdev->hostdata;
2112 if (!sas_device_priv_data)
2113 continue;
2114 if (!sas_device_priv_data->block)
2115 continue;
2116 if (sas_device_priv_data->sas_target->handle == handle) {
2117 dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
2118 MPT2SAS_INFO_FMT "SDEV_RUNNING: "
2119 "handle(0x%04x)\n", ioc->name, handle));
2120 sas_device_priv_data->block = 0;
2121 scsi_device_set_state(sdev, SDEV_RUNNING);
2122 }
2123 }
2124}
2125
2126/**
2127 * _scsih_block_io_device - set the device state to SDEV_BLOCK
2128 * @ioc: per adapter object
2129 * @handle: device handle
2130 *
2131 * During device pull we need to appropiately set the sdev state.
2132 */
2133static void
2134_scsih_block_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2135{
2136 struct MPT2SAS_DEVICE *sas_device_priv_data;
2137 struct scsi_device *sdev;
2138
2139 shost_for_each_device(sdev, ioc->shost) {
2140 sas_device_priv_data = sdev->hostdata;
2141 if (!sas_device_priv_data)
2142 continue;
2143 if (sas_device_priv_data->block)
2144 continue;
2145 if (sas_device_priv_data->sas_target->handle == handle) {
2146 dewtprintk(ioc, sdev_printk(KERN_INFO, sdev,
2147 MPT2SAS_INFO_FMT "SDEV_BLOCK: "
2148 "handle(0x%04x)\n", ioc->name, handle));
2149 sas_device_priv_data->block = 1;
2150 scsi_device_set_state(sdev, SDEV_BLOCK);
2151 }
2152 }
2153}
2154
2155/**
2156 * _scsih_block_io_to_children_attached_to_ex
2157 * @ioc: per adapter object
2158 * @sas_expander: the sas_device object
2159 *
2160 * This routine set sdev state to SDEV_BLOCK for all devices
2161 * attached to this expander. This function called when expander is
2162 * pulled.
2163 */
2164static void
2165_scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc,
2166 struct _sas_node *sas_expander)
2167{
2168 struct _sas_port *mpt2sas_port;
2169 struct _sas_device *sas_device;
2170 struct _sas_node *expander_sibling;
2171 unsigned long flags;
2172
2173 if (!sas_expander)
2174 return;
2175
2176 list_for_each_entry(mpt2sas_port,
2177 &sas_expander->sas_port_list, port_list) {
2178 if (mpt2sas_port->remote_identify.device_type ==
2179 SAS_END_DEVICE) {
2180 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2181 sas_device =
2182 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
2183 mpt2sas_port->remote_identify.sas_address);
2184 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2185 if (!sas_device)
2186 continue;
2187 _scsih_block_io_device(ioc, sas_device->handle);
2188 }
2189 }
2190
2191 list_for_each_entry(mpt2sas_port,
2192 &sas_expander->sas_port_list, port_list) {
2193
2194 if (mpt2sas_port->remote_identify.device_type ==
2195 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
2196 mpt2sas_port->remote_identify.device_type ==
2197 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
2198
2199 spin_lock_irqsave(&ioc->sas_node_lock, flags);
2200 expander_sibling =
2201 mpt2sas_scsih_expander_find_by_sas_address(
2202 ioc, mpt2sas_port->remote_identify.sas_address);
2203 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
2204 _scsih_block_io_to_children_attached_to_ex(ioc,
2205 expander_sibling);
2206 }
2207 }
2208}
2209
2210/**
2211 * _scsih_block_io_to_children_attached_directly
2212 * @ioc: per adapter object
2213 * @event_data: topology change event data
2214 *
2215 * This routine set sdev state to SDEV_BLOCK for all devices
2216 * direct attached during device pull.
2217 */
2218static void
2219_scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2220 Mpi2EventDataSasTopologyChangeList_t *event_data)
2221{
2222 int i;
2223 u16 handle;
2224 u16 reason_code;
2225 u8 phy_number;
2226
2227 for (i = 0; i < event_data->NumEntries; i++) {
2228 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
2229 if (!handle)
2230 continue;
2231 phy_number = event_data->StartPhyNum + i;
2232 reason_code = event_data->PHY[i].PhyStatus &
2233 MPI2_EVENT_SAS_TOPO_RC_MASK;
2234 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
2235 _scsih_block_io_device(ioc, handle);
2236 }
2237}
2238
2239/**
2240 * _scsih_check_topo_delete_events - sanity check on topo events
2241 * @ioc: per adapter object
2242 * @event_data: the event data payload
2243 *
2244 * This routine added to better handle cable breaker.
2245 *
2246 * This handles the case where driver recieves multiple expander
2247 * add and delete events in a single shot. When there is a delete event
2248 * the routine will void any pending add events waiting in the event queue.
2249 *
2250 * Return nothing.
2251 */
2252static void
2253_scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2254 Mpi2EventDataSasTopologyChangeList_t *event_data)
2255{
2256 struct fw_event_work *fw_event;
2257 Mpi2EventDataSasTopologyChangeList_t *local_event_data;
2258 u16 expander_handle;
2259 struct _sas_node *sas_expander;
2260 unsigned long flags;
2261
2262 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
2263 if (expander_handle < ioc->sas_hba.num_phys) {
2264 _scsih_block_io_to_children_attached_directly(ioc, event_data);
2265 return;
2266 }
2267
2268 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING
2269 || event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) {
2270 spin_lock_irqsave(&ioc->sas_node_lock, flags);
2271 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
2272 expander_handle);
2273 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
2274 _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander);
2275 } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING)
2276 _scsih_block_io_to_children_attached_directly(ioc, event_data);
2277
2278 if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
2279 return;
2280
2281 /* mark ignore flag for pending events */
2282 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2283 list_for_each_entry(fw_event, &ioc->fw_event_list, list) {
2284 if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
2285 fw_event->ignore)
2286 continue;
2287 local_event_data = fw_event->event_data;
2288 if (local_event_data->ExpStatus ==
2289 MPI2_EVENT_SAS_TOPO_ES_ADDED ||
2290 local_event_data->ExpStatus ==
2291 MPI2_EVENT_SAS_TOPO_ES_RESPONDING) {
2292 if (le16_to_cpu(local_event_data->ExpanderDevHandle) ==
2293 expander_handle) {
2294 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT
2295 "setting ignoring flag\n", ioc->name));
2296 fw_event->ignore = 1;
2297 }
2298 }
2299 }
2300 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2301}
2302
2303/**
2304 * _scsih_queue_rescan - queue a topology rescan from user context
2305 * @ioc: per adapter object
2306 *
2307 * Return nothing.
2308 */
2309static void
2310_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
2311{
2312 struct fw_event_work *fw_event;
2313
2314 if (ioc->wait_for_port_enable_to_complete)
2315 return;
2316 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2317 if (!fw_event)
2318 return;
2319 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
2320 fw_event->ioc = ioc;
2321 _scsih_fw_event_add(ioc, fw_event);
2322}
2323
2324/**
2325 * _scsih_flush_running_cmds - completing outstanding commands.
2326 * @ioc: per adapter object
2327 *
2328 * The flushing out of all pending scmd commands following host reset,
2329 * where all IO is dropped to the floor.
2330 *
2331 * Return nothing.
2332 */
2333static void
2334_scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2335{
2336 struct scsi_cmnd *scmd;
2337 u16 smid;
2338 u16 count = 0;
2339
2340 for (smid = 1; smid <= ioc->request_depth; smid++) {
2341 scmd = _scsih_scsi_lookup_getclear(ioc, smid);
2342 if (!scmd)
2343 continue;
2344 count++;
2345 mpt2sas_base_free_smid(ioc, smid);
2346 scsi_dma_unmap(scmd);
2347 scmd->result = DID_RESET << 16;
2348 scmd->scsi_done(scmd);
2349 }
2350 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "completing %d cmds\n",
2351 ioc->name, count));
2352}
2353
2354/**
2355 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
2356 * @ioc: per adapter object
2357 * @reset_phase: phase
2358 *
2359 * The handler for doing any required cleanup or initialization.
2360 *
2361 * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
2362 * MPT2_IOC_DONE_RESET
2363 *
2364 * Return nothing.
2365 */
2366void
2367mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
2368{
2369 switch (reset_phase) {
2370 case MPT2_IOC_PRE_RESET:
2371 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
2372 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
2373 _scsih_fw_event_off(ioc);
2374 break;
2375 case MPT2_IOC_AFTER_RESET:
2376 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
2377 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
2378 if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
2379 ioc->tm_cmds.status |= MPT2_CMD_RESET;
2380 mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
2381 complete(&ioc->tm_cmds.done);
2382 }
2383 _scsih_fw_event_on(ioc);
2384 _scsih_flush_running_cmds(ioc);
2385 break;
2386 case MPT2_IOC_DONE_RESET:
2387 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
2388 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
2389 _scsih_queue_rescan(ioc);
2390 break;
2391 }
2392}
2393
2394/**
2395 * scsih_qcmd - main scsi request entry point
2396 * @scmd: pointer to scsi command object
2397 * @done: function pointer to be invoked on completion
2398 *
2399 * The callback index is set inside `ioc->scsi_io_cb_idx`.
2400 *
2401 * Returns 0 on success. If there's a failure, return either:
2402 * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or
2403 * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
2404 */
2405static int
2406scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2407{
2408 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
2409 struct MPT2SAS_DEVICE *sas_device_priv_data;
2410 struct MPT2SAS_TARGET *sas_target_priv_data;
2411 Mpi2SCSIIORequest_t *mpi_request;
2412 u32 mpi_control;
2413 u16 smid;
2414 unsigned long flags;
2415
2416 scmd->scsi_done = done;
2417 sas_device_priv_data = scmd->device->hostdata;
2418 if (!sas_device_priv_data) {
2419 scmd->result = DID_NO_CONNECT << 16;
2420 scmd->scsi_done(scmd);
2421 return 0;
2422 }
2423
2424 sas_target_priv_data = sas_device_priv_data->sas_target;
2425 if (!sas_target_priv_data || sas_target_priv_data->handle ==
2426 MPT2SAS_INVALID_DEVICE_HANDLE || sas_target_priv_data->deleted) {
2427 scmd->result = DID_NO_CONNECT << 16;
2428 scmd->scsi_done(scmd);
2429 return 0;
2430 }
2431
2432 /* see if we are busy with task managment stuff */
2433 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
2434 if (sas_target_priv_data->tm_busy ||
2435 ioc->shost_recovery || ioc->ioc_link_reset_in_progress) {
2436 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2437 return SCSI_MLQUEUE_HOST_BUSY;
2438 }
2439 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
2440
2441 if (scmd->sc_data_direction == DMA_FROM_DEVICE)
2442 mpi_control = MPI2_SCSIIO_CONTROL_READ;
2443 else if (scmd->sc_data_direction == DMA_TO_DEVICE)
2444 mpi_control = MPI2_SCSIIO_CONTROL_WRITE;
2445 else
2446 mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
2447
2448 /* set tags */
2449 if (!(sas_device_priv_data->flags & MPT_DEVICE_FLAGS_INIT)) {
2450 if (scmd->device->tagged_supported) {
2451 if (scmd->device->ordered_tags)
2452 mpi_control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
2453 else
2454 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
2455 } else
2456/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */
2457/* mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED;
2458 */
2459 mpi_control |= (0x500);
2460
2461 } else
2462 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
2463
2464 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON))
2465 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
2466
2467 smid = mpt2sas_base_get_smid(ioc, ioc->scsi_io_cb_idx);
2468 if (!smid) {
2469 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2470 ioc->name, __func__);
2471 goto out;
2472 }
2473 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2474 memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
2475 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
2476 if (sas_device_priv_data->sas_target->flags &
2477 MPT_TARGET_FLAGS_RAID_COMPONENT)
2478 mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2479 else
2480 mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
2481 mpi_request->DevHandle =
2482 cpu_to_le16(sas_device_priv_data->sas_target->handle);
2483 mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
2484 mpi_request->Control = cpu_to_le32(mpi_control);
2485 mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len);
2486 mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR;
2487 mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
2488 mpi_request->SenseBufferLowAddress =
2489 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
2490 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2491 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2492 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
2493
2494 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
2495 mpi_request->LUN);
2496 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
2497
2498 if (!mpi_request->DataLength) {
2499 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request->SGL);
2500 } else {
2501 if (_scsih_build_scatter_gather(ioc, scmd, smid)) {
2502 mpt2sas_base_free_smid(ioc, smid);
2503 goto out;
2504 }
2505 }
2506
2507 _scsih_scsi_lookup_set(ioc, smid, scmd);
2508 mpt2sas_base_put_smid_scsi_io(ioc, smid, 0,
2509 sas_device_priv_data->sas_target->handle);
2510 return 0;
2511
2512 out:
2513 return SCSI_MLQUEUE_HOST_BUSY;
2514}
2515
2516/**
2517 * _scsih_normalize_sense - normalize descriptor and fixed format sense data
2518 * @sense_buffer: sense data returned by target
2519 * @data: normalized skey/asc/ascq
2520 *
2521 * Return nothing.
2522 */
2523static void
2524_scsih_normalize_sense(char *sense_buffer, struct sense_info *data)
2525{
2526 if ((sense_buffer[0] & 0x7F) >= 0x72) {
2527 /* descriptor format */
2528 data->skey = sense_buffer[1] & 0x0F;
2529 data->asc = sense_buffer[2];
2530 data->ascq = sense_buffer[3];
2531 } else {
2532 /* fixed format */
2533 data->skey = sense_buffer[2] & 0x0F;
2534 data->asc = sense_buffer[12];
2535 data->ascq = sense_buffer[13];
2536 }
2537}
2538
2539#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
2540/**
2541 * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request
2542 * @ioc: per adapter object
2543 * @scmd: pointer to scsi command object
2544 * @mpi_reply: reply mf payload returned from firmware
2545 *
2546 * scsi_status - SCSI Status code returned from target device
2547 * scsi_state - state info associated with SCSI_IO determined by ioc
2548 * ioc_status - ioc supplied status info
2549 *
2550 * Return nothing.
2551 */
2552static void
2553_scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
2554 Mpi2SCSIIOReply_t *mpi_reply, u16 smid)
2555{
2556 u32 response_info;
2557 u8 *response_bytes;
2558 u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) &
2559 MPI2_IOCSTATUS_MASK;
2560 u8 scsi_state = mpi_reply->SCSIState;
2561 u8 scsi_status = mpi_reply->SCSIStatus;
2562 char *desc_ioc_state = NULL;
2563 char *desc_scsi_status = NULL;
2564 char *desc_scsi_state = ioc->tmp_string;
2565
2566 switch (ioc_status) {
2567 case MPI2_IOCSTATUS_SUCCESS:
2568 desc_ioc_state = "success";
2569 break;
2570 case MPI2_IOCSTATUS_INVALID_FUNCTION:
2571 desc_ioc_state = "invalid function";
2572 break;
2573 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
2574 desc_ioc_state = "scsi recovered error";
2575 break;
2576 case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
2577 desc_ioc_state = "scsi invalid dev handle";
2578 break;
2579 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
2580 desc_ioc_state = "scsi device not there";
2581 break;
2582 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
2583 desc_ioc_state = "scsi data overrun";
2584 break;
2585 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
2586 desc_ioc_state = "scsi data underrun";
2587 break;
2588 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
2589 desc_ioc_state = "scsi io data error";
2590 break;
2591 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
2592 desc_ioc_state = "scsi protocol error";
2593 break;
2594 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
2595 desc_ioc_state = "scsi task terminated";
2596 break;
2597 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
2598 desc_ioc_state = "scsi residual mismatch";
2599 break;
2600 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
2601 desc_ioc_state = "scsi task mgmt failed";
2602 break;
2603 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
2604 desc_ioc_state = "scsi ioc terminated";
2605 break;
2606 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
2607 desc_ioc_state = "scsi ext terminated";
2608 break;
2609 default:
2610 desc_ioc_state = "unknown";
2611 break;
2612 }
2613
2614 switch (scsi_status) {
2615 case MPI2_SCSI_STATUS_GOOD:
2616 desc_scsi_status = "good";
2617 break;
2618 case MPI2_SCSI_STATUS_CHECK_CONDITION:
2619 desc_scsi_status = "check condition";
2620 break;
2621 case MPI2_SCSI_STATUS_CONDITION_MET:
2622 desc_scsi_status = "condition met";
2623 break;
2624 case MPI2_SCSI_STATUS_BUSY:
2625 desc_scsi_status = "busy";
2626 break;
2627 case MPI2_SCSI_STATUS_INTERMEDIATE:
2628 desc_scsi_status = "intermediate";
2629 break;
2630 case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
2631 desc_scsi_status = "intermediate condmet";
2632 break;
2633 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
2634 desc_scsi_status = "reservation conflict";
2635 break;
2636 case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
2637 desc_scsi_status = "command terminated";
2638 break;
2639 case MPI2_SCSI_STATUS_TASK_SET_FULL:
2640 desc_scsi_status = "task set full";
2641 break;
2642 case MPI2_SCSI_STATUS_ACA_ACTIVE:
2643 desc_scsi_status = "aca active";
2644 break;
2645 case MPI2_SCSI_STATUS_TASK_ABORTED:
2646 desc_scsi_status = "task aborted";
2647 break;
2648 default:
2649 desc_scsi_status = "unknown";
2650 break;
2651 }
2652
2653 desc_scsi_state[0] = '\0';
2654 if (!scsi_state)
2655 desc_scsi_state = " ";
2656 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
2657 strcat(desc_scsi_state, "response info ");
2658 if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
2659 strcat(desc_scsi_state, "state terminated ");
2660 if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
2661 strcat(desc_scsi_state, "no status ");
2662 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
2663 strcat(desc_scsi_state, "autosense failed ");
2664 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
2665 strcat(desc_scsi_state, "autosense valid ");
2666
2667 scsi_print_command(scmd);
2668 printk(MPT2SAS_WARN_FMT "\tdev handle(0x%04x), "
2669 "ioc_status(%s)(0x%04x), smid(%d)\n", ioc->name,
2670 le16_to_cpu(mpi_reply->DevHandle), desc_ioc_state,
2671 ioc_status, smid);
2672 printk(MPT2SAS_WARN_FMT "\trequest_len(%d), underflow(%d), "
2673 "resid(%d)\n", ioc->name, scsi_bufflen(scmd), scmd->underflow,
2674 scsi_get_resid(scmd));
2675 printk(MPT2SAS_WARN_FMT "\ttag(%d), transfer_count(%d), "
2676 "sc->result(0x%08x)\n", ioc->name, le16_to_cpu(mpi_reply->TaskTag),
2677 le32_to_cpu(mpi_reply->TransferCount), scmd->result);
2678 printk(MPT2SAS_WARN_FMT "\tscsi_status(%s)(0x%02x), "
2679 "scsi_state(%s)(0x%02x)\n", ioc->name, desc_scsi_status,
2680 scsi_status, desc_scsi_state, scsi_state);
2681
2682 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
2683 struct sense_info data;
2684 _scsih_normalize_sense(scmd->sense_buffer, &data);
2685 printk(MPT2SAS_WARN_FMT "\t[sense_key,asc,ascq]: "
2686 "[0x%02x,0x%02x,0x%02x]\n", ioc->name, data.skey,
2687 data.asc, data.ascq);
2688 }
2689
2690 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
2691 response_info = le32_to_cpu(mpi_reply->ResponseInfo);
2692 response_bytes = (u8 *)&response_info;
2693 _scsih_response_code(ioc, response_bytes[3]);
2694 }
2695}
2696#endif
2697
2698/**
2699 * _scsih_smart_predicted_fault - illuminate Fault LED
2700 * @ioc: per adapter object
2701 * @handle: device handle
2702 *
2703 * Return nothing.
2704 */
2705static void
2706_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2707{
2708 Mpi2SepReply_t mpi_reply;
2709 Mpi2SepRequest_t mpi_request;
2710 struct scsi_target *starget;
2711 struct MPT2SAS_TARGET *sas_target_priv_data;
2712 Mpi2EventNotificationReply_t *event_reply;
2713 Mpi2EventDataSasDeviceStatusChange_t *event_data;
2714 struct _sas_device *sas_device;
2715 ssize_t sz;
2716 unsigned long flags;
2717
2718 /* only handle non-raid devices */
2719 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2720 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2721 if (!sas_device) {
2722 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2723 return;
2724 }
2725 starget = sas_device->starget;
2726 sas_target_priv_data = starget->hostdata;
2727
2728 if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) ||
2729 ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) {
2730 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2731 return;
2732 }
2733 starget_printk(KERN_WARNING, starget, "predicted fault\n");
2734 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2735
2736 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) {
2737 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
2738 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
2739 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
2740 mpi_request.SlotStatus =
2741 MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
2742 mpi_request.DevHandle = cpu_to_le16(handle);
2743 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
2744 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
2745 &mpi_request)) != 0) {
2746 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
2747 ioc->name, __FILE__, __LINE__, __func__);
2748 return;
2749 }
2750
2751 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
2752 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2753 "enclosure_processor: ioc_status (0x%04x), "
2754 "loginfo(0x%08x)\n", ioc->name,
2755 le16_to_cpu(mpi_reply.IOCStatus),
2756 le32_to_cpu(mpi_reply.IOCLogInfo)));
2757 return;
2758 }
2759 }
2760
2761 /* insert into event log */
2762 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
2763 sizeof(Mpi2EventDataSasDeviceStatusChange_t);
2764 event_reply = kzalloc(sz, GFP_KERNEL);
2765 if (!event_reply) {
2766 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
2767 ioc->name, __FILE__, __LINE__, __func__);
2768 return;
2769 }
2770
2771 event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
2772 event_reply->Event =
2773 cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
2774 event_reply->MsgLength = sz/4;
2775 event_reply->EventDataLength =
2776 cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4);
2777 event_data = (Mpi2EventDataSasDeviceStatusChange_t *)
2778 event_reply->EventData;
2779 event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA;
2780 event_data->ASC = 0x5D;
2781 event_data->DevHandle = cpu_to_le16(handle);
2782 event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address);
2783 mpt2sas_ctl_add_to_event_log(ioc, event_reply);
2784 kfree(event_reply);
2785}
2786
2787/**
2788 * scsih_io_done - scsi request callback
2789 * @ioc: per adapter object
2790 * @smid: system request message index
2791 * @VF_ID: virtual function id
2792 * @reply: reply message frame(lower 32bit addr)
2793 *
2794 * Callback handler when using scsih_qcmd.
2795 *
2796 * Return nothing.
2797 */
2798static void
2799scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
2800{
2801 Mpi2SCSIIORequest_t *mpi_request;
2802 Mpi2SCSIIOReply_t *mpi_reply;
2803 struct scsi_cmnd *scmd;
2804 u16 ioc_status;
2805 u32 xfer_cnt;
2806 u8 scsi_state;
2807 u8 scsi_status;
2808 u32 log_info;
2809 struct MPT2SAS_DEVICE *sas_device_priv_data;
2810 u32 response_code;
2811
2812 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
2813 scmd = _scsih_scsi_lookup_getclear(ioc, smid);
2814 if (scmd == NULL)
2815 return;
2816
2817 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2818
2819 if (mpi_reply == NULL) {
2820 scmd->result = DID_OK << 16;
2821 goto out;
2822 }
2823
2824 sas_device_priv_data = scmd->device->hostdata;
2825 if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
2826 sas_device_priv_data->sas_target->deleted) {
2827 scmd->result = DID_NO_CONNECT << 16;
2828 goto out;
2829 }
2830
2831 /* turning off TLR */
2832 if (!sas_device_priv_data->tlr_snoop_check) {
2833 sas_device_priv_data->tlr_snoop_check++;
2834 if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) {
2835 response_code = (le32_to_cpu(mpi_reply->ResponseInfo)
2836 >> 24);
2837 if (response_code ==
2838 MPI2_SCSITASKMGMT_RSP_INVALID_FRAME)
2839 sas_device_priv_data->flags &=
2840 ~MPT_DEVICE_TLR_ON;
2841 }
2842 }
2843
2844 xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
2845 scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
2846 ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
2847 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
2848 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
2849 else
2850 log_info = 0;
2851 ioc_status &= MPI2_IOCSTATUS_MASK;
2852 scsi_state = mpi_reply->SCSIState;
2853 scsi_status = mpi_reply->SCSIStatus;
2854
2855 if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
2856 (scsi_status == MPI2_SCSI_STATUS_BUSY ||
2857 scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT ||
2858 scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) {
2859 ioc_status = MPI2_IOCSTATUS_SUCCESS;
2860 }
2861
2862 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
2863 struct sense_info data;
2864 const void *sense_data = mpt2sas_base_get_sense_buffer(ioc,
2865 smid);
2866 memcpy(scmd->sense_buffer, sense_data,
2867 le32_to_cpu(mpi_reply->SenseCount));
2868 _scsih_normalize_sense(scmd->sense_buffer, &data);
2869 /* failure prediction threshold exceeded */
2870 if (data.asc == 0x5D)
2871 _scsih_smart_predicted_fault(ioc,
2872 le16_to_cpu(mpi_reply->DevHandle));
2873 }
2874
2875 switch (ioc_status) {
2876 case MPI2_IOCSTATUS_BUSY:
2877 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
2878 scmd->result = SAM_STAT_BUSY;
2879 break;
2880
2881 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
2882 scmd->result = DID_NO_CONNECT << 16;
2883 break;
2884
2885 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
2886 if (sas_device_priv_data->block) {
2887 scmd->result = (DID_BUS_BUSY << 16);
2888 break;
2889 }
2890
2891 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
2892 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
2893 scmd->result = DID_RESET << 16;
2894 break;
2895
2896 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
2897 if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt))
2898 scmd->result = DID_SOFT_ERROR << 16;
2899 else
2900 scmd->result = (DID_OK << 16) | scsi_status;
2901 break;
2902
2903 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
2904 scmd->result = (DID_OK << 16) | scsi_status;
2905
2906 if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID))
2907 break;
2908
2909 if (xfer_cnt < scmd->underflow) {
2910 if (scsi_status == SAM_STAT_BUSY)
2911 scmd->result = SAM_STAT_BUSY;
2912 else
2913 scmd->result = DID_SOFT_ERROR << 16;
2914 } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
2915 MPI2_SCSI_STATE_NO_SCSI_STATUS))
2916 scmd->result = DID_SOFT_ERROR << 16;
2917 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
2918 scmd->result = DID_RESET << 16;
2919 else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) {
2920 mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID;
2921 mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION;
2922 scmd->result = (DRIVER_SENSE << 24) |
2923 SAM_STAT_CHECK_CONDITION;
2924 scmd->sense_buffer[0] = 0x70;
2925 scmd->sense_buffer[2] = ILLEGAL_REQUEST;
2926 scmd->sense_buffer[12] = 0x20;
2927 scmd->sense_buffer[13] = 0;
2928 }
2929 break;
2930
2931 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
2932 scsi_set_resid(scmd, 0);
2933 case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
2934 case MPI2_IOCSTATUS_SUCCESS:
2935 scmd->result = (DID_OK << 16) | scsi_status;
2936 if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED |
2937 MPI2_SCSI_STATE_NO_SCSI_STATUS))
2938 scmd->result = DID_SOFT_ERROR << 16;
2939 else if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
2940 scmd->result = DID_RESET << 16;
2941 break;
2942
2943 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
2944 case MPI2_IOCSTATUS_INVALID_FUNCTION:
2945 case MPI2_IOCSTATUS_INVALID_SGL:
2946 case MPI2_IOCSTATUS_INTERNAL_ERROR:
2947 case MPI2_IOCSTATUS_INVALID_FIELD:
2948 case MPI2_IOCSTATUS_INVALID_STATE:
2949 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
2950 case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
2951 default:
2952 scmd->result = DID_SOFT_ERROR << 16;
2953 break;
2954
2955 }
2956
2957#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
2958 if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY))
2959 _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid);
2960#endif
2961
2962 out:
2963 scsi_dma_unmap(scmd);
2964 scmd->scsi_done(scmd);
2965}
2966
2967/**
2968 * _scsih_link_change - process phy link changes
2969 * @ioc: per adapter object
2970 * @handle: phy handle
2971 * @attached_handle: valid for devices attached to link
2972 * @phy_number: phy number
2973 * @link_rate: new link rate
2974 * Context: user.
2975 *
2976 * Return nothing.
2977 */
2978static void
2979_scsih_link_change(struct MPT2SAS_ADAPTER *ioc, u16 handle, u16 attached_handle,
2980 u8 phy_number, u8 link_rate)
2981{
2982 mpt2sas_transport_update_phy_link_change(ioc, handle, attached_handle,
2983 phy_number, link_rate);
2984}
2985
2986/**
2987 * _scsih_sas_host_refresh - refreshing sas host object contents
2988 * @ioc: per adapter object
2989 * @update: update link information
2990 * Context: user
2991 *
2992 * During port enable, fw will send topology events for every device. Its
2993 * possible that the handles may change from the previous setting, so this
2994 * code keeping handles updating if changed.
2995 *
2996 * Return nothing.
2997 */
2998static void
2999_scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
3000{
3001 u16 sz;
3002 u16 ioc_status;
3003 int i;
3004 Mpi2ConfigReply_t mpi_reply;
3005 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3006
3007 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT
3008 "updating handles for sas_host(0x%016llx)\n",
3009 ioc->name, (unsigned long long)ioc->sas_hba.sas_address));
3010
3011 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys
3012 * sizeof(Mpi2SasIOUnit0PhyData_t));
3013 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
3014 if (!sas_iounit_pg0) {
3015 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3016 ioc->name, __FILE__, __LINE__, __func__);
3017 return;
3018 }
3019 if (!(mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3020 sas_iounit_pg0, sz))) {
3021 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3022 MPI2_IOCSTATUS_MASK;
3023 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3024 goto out;
3025 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3026 ioc->sas_hba.phy[i].handle =
3027 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3028 ControllerDevHandle);
3029 if (update)
3030 _scsih_link_change(ioc,
3031 ioc->sas_hba.phy[i].handle,
3032 le16_to_cpu(sas_iounit_pg0->PhyData[i].
3033 AttachedDevHandle), i,
3034 sas_iounit_pg0->PhyData[i].
3035 NegotiatedLinkRate >> 4);
3036 }
3037 }
3038
3039 out:
3040 kfree(sas_iounit_pg0);
3041}
3042
3043/**
3044 * _scsih_sas_host_add - create sas host object
3045 * @ioc: per adapter object
3046 *
3047 * Creating host side data object, stored in ioc->sas_hba
3048 *
3049 * Return nothing.
3050 */
3051static void
3052_scsih_sas_host_add(struct MPT2SAS_ADAPTER *ioc)
3053{
3054 int i;
3055 Mpi2ConfigReply_t mpi_reply;
3056 Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
3057 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
3058 Mpi2SasPhyPage0_t phy_pg0;
3059 Mpi2SasDevicePage0_t sas_device_pg0;
3060 Mpi2SasEnclosurePage0_t enclosure_pg0;
3061 u16 ioc_status;
3062 u16 sz;
3063 u16 device_missing_delay;
3064
3065 mpt2sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys);
3066 if (!ioc->sas_hba.num_phys) {
3067 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3068 ioc->name, __FILE__, __LINE__, __func__);
3069 return;
3070 }
3071
3072 /* sas_iounit page 0 */
3073 sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
3074 sizeof(Mpi2SasIOUnit0PhyData_t));
3075 sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
3076 if (!sas_iounit_pg0) {
3077 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3078 ioc->name, __FILE__, __LINE__, __func__);
3079 return;
3080 }
3081 if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
3082 sas_iounit_pg0, sz))) {
3083 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3084 ioc->name, __FILE__, __LINE__, __func__);
3085 goto out;
3086 }
3087 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3088 MPI2_IOCSTATUS_MASK;
3089 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3090 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3091 ioc->name, __FILE__, __LINE__, __func__);
3092 goto out;
3093 }
3094
3095 /* sas_iounit page 1 */
3096 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
3097 sizeof(Mpi2SasIOUnit1PhyData_t));
3098 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
3099 if (!sas_iounit_pg1) {
3100 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3101 ioc->name, __FILE__, __LINE__, __func__);
3102 goto out;
3103 }
3104 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
3105 sas_iounit_pg1, sz))) {
3106 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3107 ioc->name, __FILE__, __LINE__, __func__);
3108 goto out;
3109 }
3110 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3111 MPI2_IOCSTATUS_MASK;
3112 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3113 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3114 ioc->name, __FILE__, __LINE__, __func__);
3115 goto out;
3116 }
3117
3118 ioc->io_missing_delay =
3119 le16_to_cpu(sas_iounit_pg1->IODeviceMissingDelay);
3120 device_missing_delay =
3121 le16_to_cpu(sas_iounit_pg1->ReportDeviceMissingDelay);
3122 if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16)
3123 ioc->device_missing_delay = (device_missing_delay &
3124 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16;
3125 else
3126 ioc->device_missing_delay = device_missing_delay &
3127 MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
3128
3129 ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev;
3130 ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys,
3131 sizeof(struct _sas_phy), GFP_KERNEL);
3132 if (!ioc->sas_hba.phy) {
3133 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3134 ioc->name, __FILE__, __LINE__, __func__);
3135 goto out;
3136 }
3137 for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
3138 if ((mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
3139 i))) {
3140 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3141 ioc->name, __FILE__, __LINE__, __func__);
3142 goto out;
3143 }
3144 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3145 MPI2_IOCSTATUS_MASK;
3146 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3147 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3148 ioc->name, __FILE__, __LINE__, __func__);
3149 goto out;
3150 }
3151 ioc->sas_hba.phy[i].handle =
3152 le16_to_cpu(sas_iounit_pg0->PhyData[i].ControllerDevHandle);
3153 ioc->sas_hba.phy[i].phy_id = i;
3154 mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i],
3155 phy_pg0, ioc->sas_hba.parent_dev);
3156 }
3157 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
3158 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.phy[0].handle))) {
3159 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3160 ioc->name, __FILE__, __LINE__, __func__);
3161 goto out;
3162 }
3163 ioc->sas_hba.handle = le16_to_cpu(sas_device_pg0.DevHandle);
3164 ioc->sas_hba.enclosure_handle =
3165 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3166 ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
3167 printk(MPT2SAS_INFO_FMT "host_add: handle(0x%04x), "
3168 "sas_addr(0x%016llx), phys(%d)\n", ioc->name, ioc->sas_hba.handle,
3169 (unsigned long long) ioc->sas_hba.sas_address,
3170 ioc->sas_hba.num_phys) ;
3171
3172 if (ioc->sas_hba.enclosure_handle) {
3173 if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
3174 &enclosure_pg0,
3175 MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
3176 ioc->sas_hba.enclosure_handle))) {
3177 ioc->sas_hba.enclosure_logical_id =
3178 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
3179 }
3180 }
3181
3182 out:
3183 kfree(sas_iounit_pg1);
3184 kfree(sas_iounit_pg0);
3185}
3186
3187/**
3188 * _scsih_expander_add - creating expander object
3189 * @ioc: per adapter object
3190 * @handle: expander handle
3191 *
3192 * Creating expander object, stored in ioc->sas_expander_list.
3193 *
3194 * Return 0 for success, else error.
3195 */
3196static int
3197_scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3198{
3199 struct _sas_node *sas_expander;
3200 Mpi2ConfigReply_t mpi_reply;
3201 Mpi2ExpanderPage0_t expander_pg0;
3202 Mpi2ExpanderPage1_t expander_pg1;
3203 Mpi2SasEnclosurePage0_t enclosure_pg0;
3204 u32 ioc_status;
3205 u16 parent_handle;
3206 __le64 sas_address;
3207 int i;
3208 unsigned long flags;
3209 struct _sas_port *mpt2sas_port;
3210 int rc = 0;
3211
3212 if (!handle)
3213 return -1;
3214
3215 if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
3216 MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
3217 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3218 ioc->name, __FILE__, __LINE__, __func__);
3219 return -1;
3220 }
3221
3222 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3223 MPI2_IOCSTATUS_MASK;
3224 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3225 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3226 ioc->name, __FILE__, __LINE__, __func__);
3227 return -1;
3228 }
3229
3230 /* handle out of order topology events */
3231 parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle);
3232 if (parent_handle >= ioc->sas_hba.num_phys) {
3233 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3234 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc,
3235 parent_handle);
3236 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3237 if (!sas_expander) {
3238 rc = _scsih_expander_add(ioc, parent_handle);
3239 if (rc != 0)
3240 return rc;
3241 }
3242 }
3243
3244 sas_address = le64_to_cpu(expander_pg0.SASAddress);
3245
3246 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3247 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3248 sas_address);
3249 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3250
3251 if (sas_expander)
3252 return 0;
3253
3254 sas_expander = kzalloc(sizeof(struct _sas_node),
3255 GFP_KERNEL);
3256 if (!sas_expander) {
3257 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3258 ioc->name, __FILE__, __LINE__, __func__);
3259 return -1;
3260 }
3261
3262 sas_expander->handle = handle;
3263 sas_expander->num_phys = expander_pg0.NumPhys;
3264 sas_expander->parent_handle = parent_handle;
3265 sas_expander->enclosure_handle =
3266 le16_to_cpu(expander_pg0.EnclosureHandle);
3267 sas_expander->sas_address = sas_address;
3268
3269 printk(MPT2SAS_INFO_FMT "expander_add: handle(0x%04x),"
3270 " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name,
3271 handle, sas_expander->parent_handle, (unsigned long long)
3272 sas_expander->sas_address, sas_expander->num_phys);
3273
3274 if (!sas_expander->num_phys)
3275 goto out_fail;
3276 sas_expander->phy = kcalloc(sas_expander->num_phys,
3277 sizeof(struct _sas_phy), GFP_KERNEL);
3278 if (!sas_expander->phy) {
3279 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3280 ioc->name, __FILE__, __LINE__, __func__);
3281 rc = -1;
3282 goto out_fail;
3283 }
3284
3285 INIT_LIST_HEAD(&sas_expander->sas_port_list);
3286 mpt2sas_port = mpt2sas_transport_port_add(ioc, handle,
3287 sas_expander->parent_handle);
3288 if (!mpt2sas_port) {
3289 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3290 ioc->name, __FILE__, __LINE__, __func__);
3291 rc = -1;
3292 goto out_fail;
3293 }
3294 sas_expander->parent_dev = &mpt2sas_port->rphy->dev;
3295
3296 for (i = 0 ; i < sas_expander->num_phys ; i++) {
3297 if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
3298 &expander_pg1, i, handle))) {
3299 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3300 ioc->name, __FILE__, __LINE__, __func__);
3301 continue;
3302 }
3303 sas_expander->phy[i].handle = handle;
3304 sas_expander->phy[i].phy_id = i;
3305 mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i],
3306 expander_pg1, sas_expander->parent_dev);
3307 }
3308
3309 if (sas_expander->enclosure_handle) {
3310 if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply,
3311 &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
3312 sas_expander->enclosure_handle))) {
3313 sas_expander->enclosure_logical_id =
3314 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
3315 }
3316 }
3317
3318 _scsih_expander_node_add(ioc, sas_expander);
3319 return 0;
3320
3321 out_fail:
3322
3323 if (sas_expander)
3324 kfree(sas_expander->phy);
3325 kfree(sas_expander);
3326 return rc;
3327}
3328
3329/**
3330 * _scsih_expander_remove - removing expander object
3331 * @ioc: per adapter object
3332 * @handle: expander handle
3333 *
3334 * Return nothing.
3335 */
3336static void
3337_scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3338{
3339 struct _sas_node *sas_expander;
3340 unsigned long flags;
3341
3342 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3343 sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
3344 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
3345 _scsih_expander_node_remove(ioc, sas_expander);
3346}
3347
3348/**
3349 * _scsih_add_device - creating sas device object
3350 * @ioc: per adapter object
3351 * @handle: sas device handle
3352 * @phy_num: phy number end device attached to
3353 * @is_pd: is this hidden raid component
3354 *
3355 * Creating end device object, stored in ioc->sas_device_list.
3356 *
3357 * Returns 0 for success, non-zero for failure.
3358 */
3359static int
3360_scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
3361{
3362 Mpi2ConfigReply_t mpi_reply;
3363 Mpi2SasDevicePage0_t sas_device_pg0;
3364 Mpi2SasEnclosurePage0_t enclosure_pg0;
3365 struct _sas_device *sas_device;
3366 u32 ioc_status;
3367 __le64 sas_address;
3368 u32 device_info;
3369 unsigned long flags;
3370
3371 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
3372 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
3373 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3374 ioc->name, __FILE__, __LINE__, __func__);
3375 return -1;
3376 }
3377
3378 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
3379 MPI2_IOCSTATUS_MASK;
3380 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3381 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3382 ioc->name, __FILE__, __LINE__, __func__);
3383 return -1;
3384 }
3385
3386 /* check if device is present */
3387 if (!(le16_to_cpu(sas_device_pg0.Flags) &
3388 MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) {
3389 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3390 ioc->name, __FILE__, __LINE__, __func__);
3391 printk(MPT2SAS_ERR_FMT "Flags = 0x%04x\n",
3392 ioc->name, le16_to_cpu(sas_device_pg0.Flags));
3393 return -1;
3394 }
3395
3396 /* check if there were any issus with discovery */
3397 if (sas_device_pg0.AccessStatus ==
3398 MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED) {
3399 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3400 ioc->name, __FILE__, __LINE__, __func__);
3401 printk(MPT2SAS_ERR_FMT "AccessStatus = 0x%02x\n",
3402 ioc->name, sas_device_pg0.AccessStatus);
3403 return -1;
3404 }
3405
3406 /* check if this is end device */
3407 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
3408 if (!(_scsih_is_end_device(device_info))) {
3409 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3410 ioc->name, __FILE__, __LINE__, __func__);
3411 return -1;
3412 }
3413
3414 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
3415
3416 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3417 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
3418 sas_address);
3419 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3420
3421 if (sas_device) {
3422 _scsih_ublock_io_device(ioc, handle);
3423 return 0;
3424 }
3425
3426 sas_device = kzalloc(sizeof(struct _sas_device),
3427 GFP_KERNEL);
3428 if (!sas_device) {
3429 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3430 ioc->name, __FILE__, __LINE__, __func__);
3431 return -1;
3432 }
3433
3434 sas_device->handle = handle;
3435 sas_device->parent_handle =
3436 le16_to_cpu(sas_device_pg0.ParentDevHandle);
3437 sas_device->enclosure_handle =
3438 le16_to_cpu(sas_device_pg0.EnclosureHandle);
3439 sas_device->slot =
3440 le16_to_cpu(sas_device_pg0.Slot);
3441 sas_device->device_info = device_info;
3442 sas_device->sas_address = sas_address;
3443 sas_device->hidden_raid_component = is_pd;
3444
3445 /* get enclosure_logical_id */
3446 if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0,
3447 MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
3448 sas_device->enclosure_handle))) {
3449 sas_device->enclosure_logical_id =
3450 le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
3451 }
3452
3453 /* get device name */
3454 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
3455
3456 if (ioc->wait_for_port_enable_to_complete)
3457 _scsih_sas_device_init_add(ioc, sas_device);
3458 else
3459 _scsih_sas_device_add(ioc, sas_device);
3460
3461 return 0;
3462}
3463
3464/**
3465 * _scsih_remove_device - removing sas device object
3466 * @ioc: per adapter object
3467 * @handle: sas device handle
3468 *
3469 * Return nothing.
3470 */
3471static void
3472_scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3473{
3474 struct MPT2SAS_TARGET *sas_target_priv_data;
3475 struct _sas_device *sas_device;
3476 unsigned long flags;
3477 Mpi2SasIoUnitControlReply_t mpi_reply;
3478 Mpi2SasIoUnitControlRequest_t mpi_request;
3479 u16 device_handle;
3480
3481 /* lookup sas_device */
3482 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3483 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
3484 if (!sas_device) {
3485 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3486 return;
3487 }
3488
3489 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle"
3490 "(0x%04x)\n", ioc->name, __func__, handle));
3491
3492 if (sas_device->starget && sas_device->starget->hostdata) {
3493 sas_target_priv_data = sas_device->starget->hostdata;
3494 sas_target_priv_data->deleted = 1;
3495 }
3496 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3497
3498 if (ioc->remove_host)
3499 goto out;
3500
3501 /* Target Reset to flush out all the outstanding IO */
3502 device_handle = (sas_device->hidden_raid_component) ?
3503 sas_device->volume_handle : handle;
3504 if (device_handle) {
3505 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
3506 "handle(0x%04x)\n", ioc->name, device_handle));
3507 mutex_lock(&ioc->tm_cmds.mutex);
3508 mpt2sas_scsih_issue_tm(ioc, device_handle, 0,
3509 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10);
3510 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
3511 mutex_unlock(&ioc->tm_cmds.mutex);
3512 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
3513 "done: handle(0x%04x)\n", ioc->name, device_handle));
3514 }
3515
3516 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
3517 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
3518 "(0x%04x)\n", ioc->name, handle));
3519 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
3520 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
3521 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
3522 mpi_request.DevHandle = handle;
3523 mpi_request.VF_ID = 0;
3524 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
3525 &mpi_request)) != 0) {
3526 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
3527 ioc->name, __FILE__, __LINE__, __func__);
3528 }
3529
3530 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status"
3531 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
3532 le16_to_cpu(mpi_reply.IOCStatus),
3533 le32_to_cpu(mpi_reply.IOCLogInfo)));
3534
3535 out:
3536 mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
3537 sas_device->parent_handle);
3538
3539 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
3540 "(0x%016llx)\n", ioc->name, sas_device->handle,
3541 (unsigned long long) sas_device->sas_address);
3542 _scsih_sas_device_remove(ioc, sas_device);
3543
3544 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle"
3545 "(0x%04x)\n", ioc->name, __func__, handle));
3546}
3547
3548#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3549/**
3550 * _scsih_sas_topology_change_event_debug - debug for topology event
3551 * @ioc: per adapter object
3552 * @event_data: event data payload
3553 * Context: user.
3554 */
3555static void
3556_scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3557 Mpi2EventDataSasTopologyChangeList_t *event_data)
3558{
3559 int i;
3560 u16 handle;
3561 u16 reason_code;
3562 u8 phy_number;
3563 char *status_str = NULL;
3564 char link_rate[25];
3565
3566 switch (event_data->ExpStatus) {
3567 case MPI2_EVENT_SAS_TOPO_ES_ADDED:
3568 status_str = "add";
3569 break;
3570 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
3571 status_str = "remove";
3572 break;
3573 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
3574 status_str = "responding";
3575 break;
3576 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
3577 status_str = "remove delay";
3578 break;
3579 default:
3580 status_str = "unknown status";
3581 break;
3582 }
3583 printk(MPT2SAS_DEBUG_FMT "sas topology change: (%s)\n",
3584 ioc->name, status_str);
3585 printk(KERN_DEBUG "\thandle(0x%04x), enclosure_handle(0x%04x) "
3586 "start_phy(%02d), count(%d)\n",
3587 le16_to_cpu(event_data->ExpanderDevHandle),
3588 le16_to_cpu(event_data->EnclosureHandle),
3589 event_data->StartPhyNum, event_data->NumEntries);
3590 for (i = 0; i < event_data->NumEntries; i++) {
3591 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3592 if (!handle)
3593 continue;
3594 phy_number = event_data->StartPhyNum + i;
3595 reason_code = event_data->PHY[i].PhyStatus &
3596 MPI2_EVENT_SAS_TOPO_RC_MASK;
3597 switch (reason_code) {
3598 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3599 snprintf(link_rate, 25, ": add, link(0x%02x)",
3600 (event_data->PHY[i].LinkRate >> 4));
3601 status_str = link_rate;
3602 break;
3603 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
3604 status_str = ": remove";
3605 break;
3606 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
3607 status_str = ": remove_delay";
3608 break;
3609 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
3610 snprintf(link_rate, 25, ": link(0x%02x)",
3611 (event_data->PHY[i].LinkRate >> 4));
3612 status_str = link_rate;
3613 break;
3614 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
3615 status_str = ": responding";
3616 break;
3617 default:
3618 status_str = ": unknown";
3619 break;
3620 }
3621 printk(KERN_DEBUG "\tphy(%02d), attached_handle(0x%04x)%s\n",
3622 phy_number, handle, status_str);
3623 }
3624}
3625#endif
3626
3627/**
3628 * _scsih_sas_topology_change_event - handle topology changes
3629 * @ioc: per adapter object
3630 * @VF_ID:
3631 * @event_data: event data payload
3632 * fw_event:
3633 * Context: user.
3634 *
3635 */
3636static void
3637_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3638 Mpi2EventDataSasTopologyChangeList_t *event_data,
3639 struct fw_event_work *fw_event)
3640{
3641 int i;
3642 u16 parent_handle, handle;
3643 u16 reason_code;
3644 u8 phy_number;
3645 struct _sas_node *sas_expander;
3646 unsigned long flags;
3647 u8 link_rate_;
3648
3649#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3650 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
3651 _scsih_sas_topology_change_event_debug(ioc, event_data);
3652#endif
3653
3654 if (!ioc->sas_hba.num_phys)
3655 _scsih_sas_host_add(ioc);
3656 else
3657 _scsih_sas_host_refresh(ioc, 0);
3658
3659 if (fw_event->ignore) {
3660 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring expander "
3661 "event\n", ioc->name));
3662 return;
3663 }
3664
3665 parent_handle = le16_to_cpu(event_data->ExpanderDevHandle);
3666
3667 /* handle expander add */
3668 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED)
3669 if (_scsih_expander_add(ioc, parent_handle) != 0)
3670 return;
3671
3672 /* handle siblings events */
3673 for (i = 0; i < event_data->NumEntries; i++) {
3674 if (fw_event->ignore) {
3675 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "ignoring "
3676 "expander event\n", ioc->name));
3677 return;
3678 }
3679 if (event_data->PHY[i].PhyStatus &
3680 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
3681 continue;
3682 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3683 if (!handle)
3684 continue;
3685 phy_number = event_data->StartPhyNum + i;
3686 reason_code = event_data->PHY[i].PhyStatus &
3687 MPI2_EVENT_SAS_TOPO_RC_MASK;
3688 link_rate_ = event_data->PHY[i].LinkRate >> 4;
3689 switch (reason_code) {
3690 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
3691 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
3692 if (!parent_handle) {
3693 if (phy_number < ioc->sas_hba.num_phys)
3694 _scsih_link_change(ioc,
3695 ioc->sas_hba.phy[phy_number].handle,
3696 handle, phy_number, link_rate_);
3697 } else {
3698 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3699 sas_expander =
3700 mpt2sas_scsih_expander_find_by_handle(ioc,
3701 parent_handle);
3702 spin_unlock_irqrestore(&ioc->sas_node_lock,
3703 flags);
3704 if (sas_expander) {
3705 if (phy_number < sas_expander->num_phys)
3706 _scsih_link_change(ioc,
3707 sas_expander->
3708 phy[phy_number].handle,
3709 handle, phy_number,
3710 link_rate_);
3711 }
3712 }
3713 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
3714 if (link_rate_ >= MPI2_SAS_NEG_LINK_RATE_1_5)
3715 _scsih_ublock_io_device(ioc, handle);
3716 }
3717 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
3718 if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
3719 break;
3720 _scsih_add_device(ioc, handle, phy_number, 0);
3721 }
3722 break;
3723 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
3724 _scsih_remove_device(ioc, handle);
3725 break;
3726 }
3727 }
3728
3729 /* handle expander removal */
3730 if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING)
3731 _scsih_expander_remove(ioc, parent_handle);
3732
3733}
3734
3735#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3736/**
3737 * _scsih_sas_device_status_change_event_debug - debug for device event
3738 * @event_data: event data payload
3739 * Context: user.
3740 *
3741 * Return nothing.
3742 */
3743static void
3744_scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3745 Mpi2EventDataSasDeviceStatusChange_t *event_data)
3746{
3747 char *reason_str = NULL;
3748
3749 switch (event_data->ReasonCode) {
3750 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
3751 reason_str = "smart data";
3752 break;
3753 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
3754 reason_str = "unsupported device discovered";
3755 break;
3756 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
3757 reason_str = "internal device reset";
3758 break;
3759 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
3760 reason_str = "internal task abort";
3761 break;
3762 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
3763 reason_str = "internal task abort set";
3764 break;
3765 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
3766 reason_str = "internal clear task set";
3767 break;
3768 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
3769 reason_str = "internal query task";
3770 break;
3771 case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE:
3772 reason_str = "sata init failure";
3773 break;
3774 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
3775 reason_str = "internal device reset complete";
3776 break;
3777 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
3778 reason_str = "internal task abort complete";
3779 break;
3780 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
3781 reason_str = "internal async notification";
3782 break;
3783 default:
3784 reason_str = "unknown reason";
3785 break;
3786 }
3787 printk(MPT2SAS_DEBUG_FMT "device status change: (%s)\n"
3788 "\thandle(0x%04x), sas address(0x%016llx)", ioc->name,
3789 reason_str, le16_to_cpu(event_data->DevHandle),
3790 (unsigned long long)le64_to_cpu(event_data->SASAddress));
3791 if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA)
3792 printk(MPT2SAS_DEBUG_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name,
3793 event_data->ASC, event_data->ASCQ);
3794 printk(KERN_INFO "\n");
3795}
3796#endif
3797
3798/**
3799 * _scsih_sas_device_status_change_event - handle device status change
3800 * @ioc: per adapter object
3801 * @VF_ID:
3802 * @event_data: event data payload
3803 * Context: user.
3804 *
3805 * Return nothing.
3806 */
3807static void
3808_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3809 Mpi2EventDataSasDeviceStatusChange_t *event_data)
3810{
3811#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3812 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
3813 _scsih_sas_device_status_change_event_debug(ioc, event_data);
3814#endif
3815}
3816
3817#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3818/**
3819 * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure event
3820 * @ioc: per adapter object
3821 * @event_data: event data payload
3822 * Context: user.
3823 *
3824 * Return nothing.
3825 */
3826static void
3827_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3828 Mpi2EventDataSasEnclDevStatusChange_t *event_data)
3829{
3830 char *reason_str = NULL;
3831
3832 switch (event_data->ReasonCode) {
3833 case MPI2_EVENT_SAS_ENCL_RC_ADDED:
3834 reason_str = "enclosure add";
3835 break;
3836 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
3837 reason_str = "enclosure remove";
3838 break;
3839 default:
3840 reason_str = "unknown reason";
3841 break;
3842 }
3843
3844 printk(MPT2SAS_DEBUG_FMT "enclosure status change: (%s)\n"
3845 "\thandle(0x%04x), enclosure logical id(0x%016llx)"
3846 " number slots(%d)\n", ioc->name, reason_str,
3847 le16_to_cpu(event_data->EnclosureHandle),
3848 (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID),
3849 le16_to_cpu(event_data->StartSlot));
3850}
3851#endif
3852
3853/**
3854 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
3855 * @ioc: per adapter object
3856 * @VF_ID:
3857 * @event_data: event data payload
3858 * Context: user.
3859 *
3860 * Return nothing.
3861 */
3862static void
3863_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
3864 u8 VF_ID, Mpi2EventDataSasEnclDevStatusChange_t *event_data)
3865{
3866#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3867 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
3868 _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
3869 event_data);
3870#endif
3871}
3872
3873/**
3874 * _scsih_sas_broadcast_primative_event - handle broadcast events
3875 * @ioc: per adapter object
3876 * @event_data: event data payload
3877 * Context: user.
3878 *
3879 * Return nothing.
3880 */
3881static void
3882_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3883 Mpi2EventDataSasBroadcastPrimitive_t *event_data)
3884{
3885 struct scsi_cmnd *scmd;
3886 u16 smid, handle;
3887 u32 lun;
3888 struct MPT2SAS_DEVICE *sas_device_priv_data;
3889 u32 termination_count;
3890 u32 query_count;
3891 Mpi2SCSITaskManagementReply_t *mpi_reply;
3892
3893 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
3894 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
3895 event_data->PortWidth));
3896
3897 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
3898 __func__));
3899
3900 mutex_lock(&ioc->tm_cmds.mutex);
3901 termination_count = 0;
3902 query_count = 0;
3903 mpi_reply = ioc->tm_cmds.reply;
3904 for (smid = 1; smid <= ioc->request_depth; smid++) {
3905 scmd = _scsih_scsi_lookup_get(ioc, smid);
3906 if (!scmd)
3907 continue;
3908 sas_device_priv_data = scmd->device->hostdata;
3909 if (!sas_device_priv_data || !sas_device_priv_data->sas_target)
3910 continue;
3911 /* skip hidden raid components */
3912 if (sas_device_priv_data->sas_target->flags &
3913 MPT_TARGET_FLAGS_RAID_COMPONENT)
3914 continue;
3915 /* skip volumes */
3916 if (sas_device_priv_data->sas_target->flags &
3917 MPT_TARGET_FLAGS_VOLUME)
3918 continue;
3919
3920 handle = sas_device_priv_data->sas_target->handle;
3921 lun = sas_device_priv_data->lun;
3922 query_count++;
3923
3924 mpt2sas_scsih_issue_tm(ioc, handle, lun,
3925 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30);
3926 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
3927
3928 if ((mpi_reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) &&
3929 (mpi_reply->ResponseCode ==
3930 MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
3931 mpi_reply->ResponseCode ==
3932 MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
3933 continue;
3934
3935 mpt2sas_scsih_issue_tm(ioc, handle, lun,
3936 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, smid, 30);
3937 termination_count += le32_to_cpu(mpi_reply->TerminationCount);
3938 }
3939 ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
3940 ioc->broadcast_aen_busy = 0;
3941 mutex_unlock(&ioc->tm_cmds.mutex);
3942
3943 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT
3944 "%s - exit, query_count = %d termination_count = %d\n",
3945 ioc->name, __func__, query_count, termination_count));
3946}
3947
3948/**
3949 * _scsih_sas_discovery_event - handle discovery events
3950 * @ioc: per adapter object
3951 * @event_data: event data payload
3952 * Context: user.
3953 *
3954 * Return nothing.
3955 */
3956static void
3957_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3958 Mpi2EventDataSasDiscovery_t *event_data)
3959{
3960#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3961 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
3962 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name,
3963 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
3964 "start" : "stop");
3965 if (event_data->DiscoveryStatus)
3966 printk(MPT2SAS_DEBUG_FMT ", discovery_status(0x%08x)",
3967 ioc->name, le32_to_cpu(event_data->DiscoveryStatus));
3968 printk("\n");
3969 }
3970#endif
3971
3972 if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
3973 !ioc->sas_hba.num_phys)
3974 _scsih_sas_host_add(ioc);
3975}
3976
3977/**
3978 * _scsih_reprobe_lun - reprobing lun
3979 * @sdev: scsi device struct
3980 * @no_uld_attach: sdev->no_uld_attach flag setting
3981 *
3982 **/
3983static void
3984_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
3985{
3986 int rc;
3987
3988 sdev->no_uld_attach = no_uld_attach ? 1 : 0;
3989 sdev_printk(KERN_INFO, sdev, "%s raid component\n",
3990 sdev->no_uld_attach ? "hidding" : "exposing");
3991 rc = scsi_device_reprobe(sdev);
3992}
3993
3994/**
3995 * _scsih_reprobe_target - reprobing target
3996 * @starget: scsi target struct
3997 * @no_uld_attach: sdev->no_uld_attach flag setting
3998 *
3999 * Note: no_uld_attach flag determines whether the disk device is attached
4000 * to block layer. A value of `1` means to not attach.
4001 **/
4002static void
4003_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
4004{
4005 struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata;
4006
4007 if (no_uld_attach)
4008 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4009 else
4010 sas_target_priv_data->flags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4011
4012 starget_for_each_device(starget, no_uld_attach ? (void *)1 : NULL,
4013 _scsih_reprobe_lun);
4014}
4015/**
4016 * _scsih_sas_volume_add - add new volume
4017 * @ioc: per adapter object
4018 * @element: IR config element data
4019 * Context: user.
4020 *
4021 * Return nothing.
4022 */
4023static void
4024_scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
4025 Mpi2EventIrConfigElement_t *element)
4026{
4027 struct _raid_device *raid_device;
4028 unsigned long flags;
4029 u64 wwid;
4030 u16 handle = le16_to_cpu(element->VolDevHandle);
4031 int rc;
4032
4033#if 0 /* RAID_HACKS */
4034 if (le32_to_cpu(event_data->Flags) &
4035 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
4036 return;
4037#endif
4038
4039 mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
4040 if (!wwid) {
4041 printk(MPT2SAS_ERR_FMT
4042 "failure at %s:%d/%s()!\n", ioc->name,
4043 __FILE__, __LINE__, __func__);
4044 return;
4045 }
4046
4047 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4048 raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid);
4049 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4050
4051 if (raid_device)
4052 return;
4053
4054 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
4055 if (!raid_device) {
4056 printk(MPT2SAS_ERR_FMT
4057 "failure at %s:%d/%s()!\n", ioc->name,
4058 __FILE__, __LINE__, __func__);
4059 return;
4060 }
4061
4062 raid_device->id = ioc->sas_id++;
4063 raid_device->channel = RAID_CHANNEL;
4064 raid_device->handle = handle;
4065 raid_device->wwid = wwid;
4066 _scsih_raid_device_add(ioc, raid_device);
4067 if (!ioc->wait_for_port_enable_to_complete) {
4068 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
4069 raid_device->id, 0);
4070 if (rc)
4071 _scsih_raid_device_remove(ioc, raid_device);
4072 } else
4073 _scsih_determine_boot_device(ioc, raid_device, 1);
4074}
4075
4076/**
4077 * _scsih_sas_volume_delete - delete volume
4078 * @ioc: per adapter object
4079 * @element: IR config element data
4080 * Context: user.
4081 *
4082 * Return nothing.
4083 */
4084static void
4085_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
4086 Mpi2EventIrConfigElement_t *element)
4087{
4088 struct _raid_device *raid_device;
4089 u16 handle = le16_to_cpu(element->VolDevHandle);
4090 unsigned long flags;
4091 struct MPT2SAS_TARGET *sas_target_priv_data;
4092
4093#if 0 /* RAID_HACKS */
4094 if (le32_to_cpu(event_data->Flags) &
4095 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
4096 return;
4097#endif
4098
4099 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4100 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
4101 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4102 if (!raid_device)
4103 return;
4104 if (raid_device->starget) {
4105 sas_target_priv_data = raid_device->starget->hostdata;
4106 sas_target_priv_data->deleted = 1;
4107 scsi_remove_target(&raid_device->starget->dev);
4108 }
4109 _scsih_raid_device_remove(ioc, raid_device);
4110}
4111
4112/**
4113 * _scsih_sas_pd_expose - expose pd component to /dev/sdX
4114 * @ioc: per adapter object
4115 * @element: IR config element data
4116 * Context: user.
4117 *
4118 * Return nothing.
4119 */
4120static void
4121_scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
4122 Mpi2EventIrConfigElement_t *element)
4123{
4124 struct _sas_device *sas_device;
4125 unsigned long flags;
4126 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4127
4128 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4129 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4130 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4131 if (!sas_device)
4132 return;
4133
4134 /* exposing raid component */
4135 sas_device->volume_handle = 0;
4136 sas_device->volume_wwid = 0;
4137 sas_device->hidden_raid_component = 0;
4138 _scsih_reprobe_target(sas_device->starget, 0);
4139}
4140
4141/**
4142 * _scsih_sas_pd_hide - hide pd component from /dev/sdX
4143 * @ioc: per adapter object
4144 * @element: IR config element data
4145 * Context: user.
4146 *
4147 * Return nothing.
4148 */
4149static void
4150_scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
4151 Mpi2EventIrConfigElement_t *element)
4152{
4153 struct _sas_device *sas_device;
4154 unsigned long flags;
4155 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4156
4157 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4158 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4159 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4160 if (!sas_device)
4161 return;
4162
4163 /* hiding raid component */
4164 mpt2sas_config_get_volume_handle(ioc, handle,
4165 &sas_device->volume_handle);
4166 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle,
4167 &sas_device->volume_wwid);
4168 sas_device->hidden_raid_component = 1;
4169 _scsih_reprobe_target(sas_device->starget, 1);
4170}
4171
4172/**
4173 * _scsih_sas_pd_delete - delete pd component
4174 * @ioc: per adapter object
4175 * @element: IR config element data
4176 * Context: user.
4177 *
4178 * Return nothing.
4179 */
4180static void
4181_scsih_sas_pd_delete(struct MPT2SAS_ADAPTER *ioc,
4182 Mpi2EventIrConfigElement_t *element)
4183{
4184 struct _sas_device *sas_device;
4185 unsigned long flags;
4186 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4187
4188 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4189 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4190 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4191 if (!sas_device)
4192 return;
4193 _scsih_remove_device(ioc, handle);
4194}
4195
4196/**
4197 * _scsih_sas_pd_add - remove pd component
4198 * @ioc: per adapter object
4199 * @element: IR config element data
4200 * Context: user.
4201 *
4202 * Return nothing.
4203 */
4204static void
4205_scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
4206 Mpi2EventIrConfigElement_t *element)
4207{
4208 struct _sas_device *sas_device;
4209 unsigned long flags;
4210 u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
4211
4212 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4213 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4214 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4215 if (sas_device)
4216 sas_device->hidden_raid_component = 1;
4217 else
4218 _scsih_add_device(ioc, handle, 0, 1);
4219}
4220
4221#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4222/**
4223 * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events
4224 * @ioc: per adapter object
4225 * @event_data: event data payload
4226 * Context: user.
4227 *
4228 * Return nothing.
4229 */
4230static void
4231_scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4232 Mpi2EventDataIrConfigChangeList_t *event_data)
4233{
4234 Mpi2EventIrConfigElement_t *element;
4235 u8 element_type;
4236 int i;
4237 char *reason_str = NULL, *element_str = NULL;
4238
4239 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
4240
4241 printk(MPT2SAS_DEBUG_FMT "raid config change: (%s), elements(%d)\n",
4242 ioc->name, (le32_to_cpu(event_data->Flags) &
4243 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ?
4244 "foreign" : "native", event_data->NumElements);
4245 for (i = 0; i < event_data->NumElements; i++, element++) {
4246 switch (element->ReasonCode) {
4247 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
4248 reason_str = "add";
4249 break;
4250 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
4251 reason_str = "remove";
4252 break;
4253 case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE:
4254 reason_str = "no change";
4255 break;
4256 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
4257 reason_str = "hide";
4258 break;
4259 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
4260 reason_str = "unhide";
4261 break;
4262 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
4263 reason_str = "volume_created";
4264 break;
4265 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
4266 reason_str = "volume_deleted";
4267 break;
4268 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
4269 reason_str = "pd_created";
4270 break;
4271 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
4272 reason_str = "pd_deleted";
4273 break;
4274 default:
4275 reason_str = "unknown reason";
4276 break;
4277 }
4278 element_type = le16_to_cpu(element->ElementFlags) &
4279 MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK;
4280 switch (element_type) {
4281 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT:
4282 element_str = "volume";
4283 break;
4284 case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT:
4285 element_str = "phys disk";
4286 break;
4287 case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT:
4288 element_str = "hot spare";
4289 break;
4290 default:
4291 element_str = "unknown element";
4292 break;
4293 }
4294 printk(KERN_DEBUG "\t(%s:%s), vol handle(0x%04x), "
4295 "pd handle(0x%04x), pd num(0x%02x)\n", element_str,
4296 reason_str, le16_to_cpu(element->VolDevHandle),
4297 le16_to_cpu(element->PhysDiskDevHandle),
4298 element->PhysDiskNum);
4299 }
4300}
4301#endif
4302
4303/**
4304 * _scsih_sas_ir_config_change_event - handle ir configuration change events
4305 * @ioc: per adapter object
4306 * @VF_ID:
4307 * @event_data: event data payload
4308 * Context: user.
4309 *
4310 * Return nothing.
4311 */
4312static void
4313_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4314 Mpi2EventDataIrConfigChangeList_t *event_data)
4315{
4316 Mpi2EventIrConfigElement_t *element;
4317 int i;
4318
4319#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4320 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4321 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
4322
4323#endif
4324
4325 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
4326 for (i = 0; i < event_data->NumElements; i++, element++) {
4327
4328 switch (element->ReasonCode) {
4329 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
4330 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
4331 _scsih_sas_volume_add(ioc, element);
4332 break;
4333 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
4334 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
4335 _scsih_sas_volume_delete(ioc, element);
4336 break;
4337 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
4338 _scsih_sas_pd_hide(ioc, element);
4339 break;
4340 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
4341 _scsih_sas_pd_expose(ioc, element);
4342 break;
4343 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
4344 _scsih_sas_pd_add(ioc, element);
4345 break;
4346 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
4347 _scsih_sas_pd_delete(ioc, element);
4348 break;
4349 }
4350 }
4351}
4352
4353/**
4354 * _scsih_sas_ir_volume_event - IR volume event
4355 * @ioc: per adapter object
4356 * @event_data: event data payload
4357 * Context: user.
4358 *
4359 * Return nothing.
4360 */
4361static void
4362_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4363 Mpi2EventDataIrVolume_t *event_data)
4364{
4365 u64 wwid;
4366 unsigned long flags;
4367 struct _raid_device *raid_device;
4368 u16 handle;
4369 u32 state;
4370 int rc;
4371 struct MPT2SAS_TARGET *sas_target_priv_data;
4372
4373 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
4374 return;
4375
4376 handle = le16_to_cpu(event_data->VolDevHandle);
4377 state = le32_to_cpu(event_data->NewValue);
4378 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), "
4379 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
4380 le32_to_cpu(event_data->PreviousValue), state));
4381
4382 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4383 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
4384 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4385
4386 switch (state) {
4387 case MPI2_RAID_VOL_STATE_MISSING:
4388 case MPI2_RAID_VOL_STATE_FAILED:
4389 if (!raid_device)
4390 break;
4391 if (raid_device->starget) {
4392 sas_target_priv_data = raid_device->starget->hostdata;
4393 sas_target_priv_data->deleted = 1;
4394 scsi_remove_target(&raid_device->starget->dev);
4395 }
4396 _scsih_raid_device_remove(ioc, raid_device);
4397 break;
4398
4399 case MPI2_RAID_VOL_STATE_ONLINE:
4400 case MPI2_RAID_VOL_STATE_DEGRADED:
4401 case MPI2_RAID_VOL_STATE_OPTIMAL:
4402 if (raid_device)
4403 break;
4404
4405 mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
4406 if (!wwid) {
4407 printk(MPT2SAS_ERR_FMT
4408 "failure at %s:%d/%s()!\n", ioc->name,
4409 __FILE__, __LINE__, __func__);
4410 break;
4411 }
4412
4413 raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL);
4414 if (!raid_device) {
4415 printk(MPT2SAS_ERR_FMT
4416 "failure at %s:%d/%s()!\n", ioc->name,
4417 __FILE__, __LINE__, __func__);
4418 break;
4419 }
4420
4421 raid_device->id = ioc->sas_id++;
4422 raid_device->channel = RAID_CHANNEL;
4423 raid_device->handle = handle;
4424 raid_device->wwid = wwid;
4425 _scsih_raid_device_add(ioc, raid_device);
4426 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
4427 raid_device->id, 0);
4428 if (rc)
4429 _scsih_raid_device_remove(ioc, raid_device);
4430 break;
4431
4432 case MPI2_RAID_VOL_STATE_INITIALIZING:
4433 default:
4434 break;
4435 }
4436}
4437
4438/**
4439 * _scsih_sas_ir_physical_disk_event - PD event
4440 * @ioc: per adapter object
4441 * @event_data: event data payload
4442 * Context: user.
4443 *
4444 * Return nothing.
4445 */
4446static void
4447_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4448 Mpi2EventDataIrPhysicalDisk_t *event_data)
4449{
4450 u16 handle;
4451 u32 state;
4452 struct _sas_device *sas_device;
4453 unsigned long flags;
4454
4455 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4456 return;
4457
4458 handle = le16_to_cpu(event_data->PhysDiskDevHandle);
4459 state = le32_to_cpu(event_data->NewValue);
4460
4461 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: handle(0x%04x), "
4462 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
4463 le32_to_cpu(event_data->PreviousValue), state));
4464
4465 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4466 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4467 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4468
4469 switch (state) {
4470#if 0
4471 case MPI2_RAID_PD_STATE_OFFLINE:
4472 if (sas_device)
4473 _scsih_remove_device(ioc, handle);
4474 break;
4475#endif
4476 case MPI2_RAID_PD_STATE_ONLINE:
4477 case MPI2_RAID_PD_STATE_DEGRADED:
4478 case MPI2_RAID_PD_STATE_REBUILDING:
4479 case MPI2_RAID_PD_STATE_OPTIMAL:
4480 if (sas_device)
4481 sas_device->hidden_raid_component = 1;
4482 else
4483 _scsih_add_device(ioc, handle, 0, 1);
4484 break;
4485
4486 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
4487 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
4488 case MPI2_RAID_PD_STATE_HOT_SPARE:
4489 default:
4490 break;
4491 }
4492}
4493
4494#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4495/**
4496 * _scsih_sas_ir_operation_status_event_debug - debug for IR op event
4497 * @ioc: per adapter object
4498 * @event_data: event data payload
4499 * Context: user.
4500 *
4501 * Return nothing.
4502 */
4503static void
4504_scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4505 Mpi2EventDataIrOperationStatus_t *event_data)
4506{
4507 char *reason_str = NULL;
4508
4509 switch (event_data->RAIDOperation) {
4510 case MPI2_EVENT_IR_RAIDOP_RESYNC:
4511 reason_str = "resync";
4512 break;
4513 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
4514 reason_str = "online capacity expansion";
4515 break;
4516 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
4517 reason_str = "consistency check";
4518 break;
4519 default:
4520 reason_str = "unknown reason";
4521 break;
4522 }
4523
4524 printk(MPT2SAS_INFO_FMT "raid operational status: (%s)"
4525 "\thandle(0x%04x), percent complete(%d)\n",
4526 ioc->name, reason_str,
4527 le16_to_cpu(event_data->VolDevHandle),
4528 event_data->PercentComplete);
4529}
4530#endif
4531
4532/**
4533 * _scsih_sas_ir_operation_status_event - handle RAID operation events
4534 * @ioc: per adapter object
4535 * @VF_ID:
4536 * @event_data: event data payload
4537 * Context: user.
4538 *
4539 * Return nothing.
4540 */
4541static void
4542_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4543 Mpi2EventDataIrOperationStatus_t *event_data)
4544{
4545#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4546 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4547 _scsih_sas_ir_operation_status_event_debug(ioc, event_data);
4548#endif
4549}
4550
4551/**
4552 * _scsih_task_set_full - handle task set full
4553 * @ioc: per adapter object
4554 * @event_data: event data payload
4555 * Context: user.
4556 *
4557 * Throttle back qdepth.
4558 */
4559static void
4560_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4561 Mpi2EventDataTaskSetFull_t *event_data)
4562{
4563 unsigned long flags;
4564 struct _sas_device *sas_device;
4565 static struct _raid_device *raid_device;
4566 struct scsi_device *sdev;
4567 int depth;
4568 u16 current_depth;
4569 u16 handle;
4570 int id, channel;
4571 u64 sas_address;
4572
4573 current_depth = le16_to_cpu(event_data->CurrentDepth);
4574 handle = le16_to_cpu(event_data->DevHandle);
4575 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4576 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4577 if (!sas_device) {
4578 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4579 return;
4580 }
4581 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4582 id = sas_device->id;
4583 channel = sas_device->channel;
4584 sas_address = sas_device->sas_address;
4585
4586 /* if hidden raid component, then change to volume characteristics */
4587 if (sas_device->hidden_raid_component && sas_device->volume_handle) {
4588 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4589 raid_device = _scsih_raid_device_find_by_handle(
4590 ioc, sas_device->volume_handle);
4591 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4592 if (raid_device) {
4593 id = raid_device->id;
4594 channel = raid_device->channel;
4595 handle = raid_device->handle;
4596 sas_address = raid_device->wwid;
4597 }
4598 }
4599
4600 if (ioc->logging_level & MPT_DEBUG_TASK_SET_FULL)
4601 starget_printk(KERN_DEBUG, sas_device->starget, "task set "
4602 "full: handle(0x%04x), sas_addr(0x%016llx), depth(%d)\n",
4603 handle, (unsigned long long)sas_address, current_depth);
4604
4605 shost_for_each_device(sdev, ioc->shost) {
4606 if (sdev->id == id && sdev->channel == channel) {
4607 if (current_depth > sdev->queue_depth) {
4608 if (ioc->logging_level &
4609 MPT_DEBUG_TASK_SET_FULL)
4610 sdev_printk(KERN_INFO, sdev, "strange "
4611 "observation, the queue depth is"
4612 " (%d) meanwhile fw queue depth "
4613 "is (%d)\n", sdev->queue_depth,
4614 current_depth);
4615 continue;
4616 }
4617 depth = scsi_track_queue_full(sdev,
4618 current_depth - 1);
4619 if (depth > 0)
4620 sdev_printk(KERN_INFO, sdev, "Queue depth "
4621 "reduced to (%d)\n", depth);
4622 else if (depth < 0)
4623 sdev_printk(KERN_INFO, sdev, "Tagged Command "
4624 "Queueing is being disabled\n");
4625 else if (depth == 0)
4626 if (ioc->logging_level &
4627 MPT_DEBUG_TASK_SET_FULL)
4628 sdev_printk(KERN_INFO, sdev,
4629 "Queue depth not changed yet\n");
4630 }
4631 }
4632}
4633
4634/**
4635 * _scsih_mark_responding_sas_device - mark a sas_devices as responding
4636 * @ioc: per adapter object
4637 * @sas_address: sas address
4638 * @slot: enclosure slot id
4639 * @handle: device handle
4640 *
4641 * After host reset, find out whether devices are still responding.
4642 * Used in _scsi_remove_unresponsive_sas_devices.
4643 *
4644 * Return nothing.
4645 */
4646static void
4647_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4648 u16 slot, u16 handle)
4649{
4650 struct MPT2SAS_TARGET *sas_target_priv_data;
4651 struct scsi_target *starget;
4652 struct _sas_device *sas_device;
4653 unsigned long flags;
4654
4655 spin_lock_irqsave(&ioc->sas_device_lock, flags);
4656 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
4657 if (sas_device->sas_address == sas_address &&
4658 sas_device->slot == slot && sas_device->starget) {
4659 sas_device->responding = 1;
4660 starget_printk(KERN_INFO, sas_device->starget,
4661 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
4662 "logical id(0x%016llx), slot(%d)\n", handle,
4663 (unsigned long long)sas_device->sas_address,
4664 (unsigned long long)
4665 sas_device->enclosure_logical_id,
4666 sas_device->slot);
4667 if (sas_device->handle == handle)
4668 goto out;
4669 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
4670 sas_device->handle);
4671 sas_device->handle = handle;
4672 starget = sas_device->starget;
4673 sas_target_priv_data = starget->hostdata;
4674 sas_target_priv_data->handle = handle;
4675 goto out;
4676 }
4677 }
4678 out:
4679 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4680}
4681
4682/**
4683 * _scsih_search_responding_sas_devices -
4684 * @ioc: per adapter object
4685 *
4686 * After host reset, find out whether devices are still responding.
4687 * If not remove.
4688 *
4689 * Return nothing.
4690 */
4691static void
4692_scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
4693{
4694 Mpi2SasDevicePage0_t sas_device_pg0;
4695 Mpi2ConfigReply_t mpi_reply;
4696 u16 ioc_status;
4697 __le64 sas_address;
4698 u16 handle;
4699 u32 device_info;
4700 u16 slot;
4701
4702 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
4703
4704 if (list_empty(&ioc->sas_device_list))
4705 return;
4706
4707 handle = 0xFFFF;
4708 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
4709 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
4710 handle))) {
4711 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4712 MPI2_IOCSTATUS_MASK;
4713 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
4714 break;
4715 handle = le16_to_cpu(sas_device_pg0.DevHandle);
4716 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
4717 if (!(_scsih_is_end_device(device_info)))
4718 continue;
4719 sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
4720 slot = le16_to_cpu(sas_device_pg0.Slot);
4721 _scsih_mark_responding_sas_device(ioc, sas_address, slot,
4722 handle);
4723 }
4724}
4725
4726/**
4727 * _scsih_mark_responding_raid_device - mark a raid_device as responding
4728 * @ioc: per adapter object
4729 * @wwid: world wide identifier for raid volume
4730 * @handle: device handle
4731 *
4732 * After host reset, find out whether devices are still responding.
4733 * Used in _scsi_remove_unresponsive_raid_devices.
4734 *
4735 * Return nothing.
4736 */
4737static void
4738_scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
4739 u16 handle)
4740{
4741 struct MPT2SAS_TARGET *sas_target_priv_data;
4742 struct scsi_target *starget;
4743 struct _raid_device *raid_device;
4744 unsigned long flags;
4745
4746 spin_lock_irqsave(&ioc->raid_device_lock, flags);
4747 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {
4748 if (raid_device->wwid == wwid && raid_device->starget) {
4749 raid_device->responding = 1;
4750 starget_printk(KERN_INFO, raid_device->starget,
4751 "handle(0x%04x), wwid(0x%016llx)\n", handle,
4752 (unsigned long long)raid_device->wwid);
4753 if (raid_device->handle == handle)
4754 goto out;
4755 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
4756 raid_device->handle);
4757 raid_device->handle = handle;
4758 starget = raid_device->starget;
4759 sas_target_priv_data = starget->hostdata;
4760 sas_target_priv_data->handle = handle;
4761 goto out;
4762 }
4763 }
4764 out:
4765 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
4766}
4767
4768/**
4769 * _scsih_search_responding_raid_devices -
4770 * @ioc: per adapter object
4771 *
4772 * After host reset, find out whether devices are still responding.
4773 * If not remove.
4774 *
4775 * Return nothing.
4776 */
4777static void
4778_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
4779{
4780 Mpi2RaidVolPage1_t volume_pg1;
4781 Mpi2ConfigReply_t mpi_reply;
4782 u16 ioc_status;
4783 u16 handle;
4784
4785 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
4786
4787 if (list_empty(&ioc->raid_device_list))
4788 return;
4789
4790 handle = 0xFFFF;
4791 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
4792 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
4793 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4794 MPI2_IOCSTATUS_MASK;
4795 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
4796 break;
4797 handle = le16_to_cpu(volume_pg1.DevHandle);
4798 _scsih_mark_responding_raid_device(ioc,
4799 le64_to_cpu(volume_pg1.WWID), handle);
4800 }
4801}
4802
4803/**
4804 * _scsih_mark_responding_expander - mark a expander as responding
4805 * @ioc: per adapter object
4806 * @sas_address: sas address
4807 * @handle:
4808 *
4809 * After host reset, find out whether devices are still responding.
4810 * Used in _scsi_remove_unresponsive_expanders.
4811 *
4812 * Return nothing.
4813 */
4814static void
4815_scsih_mark_responding_expander(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4816 u16 handle)
4817{
4818 struct _sas_node *sas_expander;
4819 unsigned long flags;
4820
4821 spin_lock_irqsave(&ioc->sas_node_lock, flags);
4822 list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
4823 if (sas_expander->sas_address == sas_address) {
4824 sas_expander->responding = 1;
4825 if (sas_expander->handle != handle) {
4826 printk(KERN_INFO "old handle(0x%04x)\n",
4827 sas_expander->handle);
4828 sas_expander->handle = handle;
4829 }
4830 goto out;
4831 }
4832 }
4833 out:
4834 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
4835}
4836
4837/**
4838 * _scsih_search_responding_expanders -
4839 * @ioc: per adapter object
4840 *
4841 * After host reset, find out whether devices are still responding.
4842 * If not remove.
4843 *
4844 * Return nothing.
4845 */
4846static void
4847_scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
4848{
4849 Mpi2ExpanderPage0_t expander_pg0;
4850 Mpi2ConfigReply_t mpi_reply;
4851 u16 ioc_status;
4852 __le64 sas_address;
4853 u16 handle;
4854
4855 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
4856
4857 if (list_empty(&ioc->sas_expander_list))
4858 return;
4859
4860 handle = 0xFFFF;
4861 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
4862 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
4863
4864 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
4865 MPI2_IOCSTATUS_MASK;
4866 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
4867 break;
4868
4869 handle = le16_to_cpu(expander_pg0.DevHandle);
4870 sas_address = le64_to_cpu(expander_pg0.SASAddress);
4871 printk(KERN_INFO "\texpander present: handle(0x%04x), "
4872 "sas_addr(0x%016llx)\n", handle,
4873 (unsigned long long)sas_address);
4874 _scsih_mark_responding_expander(ioc, sas_address, handle);
4875 }
4876
4877}
4878
4879/**
4880 * _scsih_remove_unresponding_devices - removing unresponding devices
4881 * @ioc: per adapter object
4882 *
4883 * Return nothing.
4884 */
4885static void
4886_scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
4887{
4888 struct _sas_device *sas_device, *sas_device_next;
4889 struct _sas_node *sas_expander, *sas_expander_next;
4890 struct _raid_device *raid_device, *raid_device_next;
4891 unsigned long flags;
4892
4893 _scsih_search_responding_sas_devices(ioc);
4894 _scsih_search_responding_raid_devices(ioc);
4895 _scsih_search_responding_expanders(ioc);
4896
4897 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
4898 ioc->shost_recovery = 0;
4899 if (ioc->shost->shost_state == SHOST_RECOVERY) {
4900 printk(MPT2SAS_INFO_FMT "putting controller into "
4901 "SHOST_RUNNING\n", ioc->name);
4902 scsi_host_set_state(ioc->shost, SHOST_RUNNING);
4903 }
4904 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
4905
4906 list_for_each_entry_safe(sas_device, sas_device_next,
4907 &ioc->sas_device_list, list) {
4908 if (sas_device->responding) {
4909 sas_device->responding = 0;
4910 continue;
4911 }
4912 if (sas_device->starget)
4913 starget_printk(KERN_INFO, sas_device->starget,
4914 "removing: handle(0x%04x), sas_addr(0x%016llx), "
4915 "enclosure logical id(0x%016llx), slot(%d)\n",
4916 sas_device->handle,
4917 (unsigned long long)sas_device->sas_address,
4918 (unsigned long long)
4919 sas_device->enclosure_logical_id,
4920 sas_device->slot);
4921 _scsih_remove_device(ioc, sas_device->handle);
4922 }
4923
4924 list_for_each_entry_safe(raid_device, raid_device_next,
4925 &ioc->raid_device_list, list) {
4926 if (raid_device->responding) {
4927 raid_device->responding = 0;
4928 continue;
4929 }
4930 if (raid_device->starget) {
4931 starget_printk(KERN_INFO, raid_device->starget,
4932 "removing: handle(0x%04x), wwid(0x%016llx)\n",
4933 raid_device->handle,
4934 (unsigned long long)raid_device->wwid);
4935 scsi_remove_target(&raid_device->starget->dev);
4936 }
4937 _scsih_raid_device_remove(ioc, raid_device);
4938 }
4939
4940 list_for_each_entry_safe(sas_expander, sas_expander_next,
4941 &ioc->sas_expander_list, list) {
4942 if (sas_expander->responding) {
4943 sas_expander->responding = 0;
4944 continue;
4945 }
4946 printk("\tremoving expander: handle(0x%04x), "
4947 " sas_addr(0x%016llx)\n", sas_expander->handle,
4948 (unsigned long long)sas_expander->sas_address);
4949 _scsih_expander_remove(ioc, sas_expander->handle);
4950 }
4951}
4952
4953/**
4954 * _firmware_event_work - delayed task for processing firmware events
4955 * @ioc: per adapter object
4956 * @work: equal to the fw_event_work object
4957 * Context: user.
4958 *
4959 * Return nothing.
4960 */
4961static void
4962_firmware_event_work(struct work_struct *work)
4963{
4964 struct fw_event_work *fw_event = container_of(work,
4965 struct fw_event_work, work.work);
4966 unsigned long flags;
4967 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
4968
4969 /* This is invoked by calling _scsih_queue_rescan(). */
4970 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
4971 _scsih_fw_event_free(ioc, fw_event);
4972 _scsih_sas_host_refresh(ioc, 1);
4973 _scsih_remove_unresponding_devices(ioc);
4974 return;
4975 }
4976
4977 /* the queue is being flushed so ignore this event */
4978 spin_lock_irqsave(&ioc->fw_event_lock, flags);
4979 if (ioc->fw_events_off || ioc->remove_host) {
4980 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
4981 _scsih_fw_event_free(ioc, fw_event);
4982 return;
4983 }
4984 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
4985
4986 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
4987 if (ioc->shost_recovery) {
4988 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
4989 _scsih_fw_event_requeue(ioc, fw_event, 1000);
4990 return;
4991 }
4992 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
4993
4994 switch (fw_event->event) {
4995 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
4996 _scsih_sas_topology_change_event(ioc, fw_event->VF_ID,
4997 fw_event->event_data, fw_event);
4998 break;
4999 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5000 _scsih_sas_device_status_change_event(ioc, fw_event->VF_ID,
5001 fw_event->event_data);
5002 break;
5003 case MPI2_EVENT_SAS_DISCOVERY:
5004 _scsih_sas_discovery_event(ioc, fw_event->VF_ID,
5005 fw_event->event_data);
5006 break;
5007 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
5008 _scsih_sas_broadcast_primative_event(ioc, fw_event->VF_ID,
5009 fw_event->event_data);
5010 break;
5011 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5012 _scsih_sas_enclosure_dev_status_change_event(ioc,
5013 fw_event->VF_ID, fw_event->event_data);
5014 break;
5015 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5016 _scsih_sas_ir_config_change_event(ioc, fw_event->VF_ID,
5017 fw_event->event_data);
5018 break;
5019 case MPI2_EVENT_IR_VOLUME:
5020 _scsih_sas_ir_volume_event(ioc, fw_event->VF_ID,
5021 fw_event->event_data);
5022 break;
5023 case MPI2_EVENT_IR_PHYSICAL_DISK:
5024 _scsih_sas_ir_physical_disk_event(ioc, fw_event->VF_ID,
5025 fw_event->event_data);
5026 break;
5027 case MPI2_EVENT_IR_OPERATION_STATUS:
5028 _scsih_sas_ir_operation_status_event(ioc, fw_event->VF_ID,
5029 fw_event->event_data);
5030 break;
5031 case MPI2_EVENT_TASK_SET_FULL:
5032 _scsih_task_set_full(ioc, fw_event->VF_ID,
5033 fw_event->event_data);
5034 break;
5035 }
5036 _scsih_fw_event_free(ioc, fw_event);
5037}
5038
5039/**
5040 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time)
5041 * @ioc: per adapter object
5042 * @VF_ID: virtual function id
5043 * @reply: reply message frame(lower 32bit addr)
5044 * Context: interrupt.
5045 *
5046 * This function merely adds a new work task into ioc->firmware_event_thread.
5047 * The tasks are worked from _firmware_event_work in user context.
5048 *
5049 * Return nothing.
5050 */
5051void
5052mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5053{
5054 struct fw_event_work *fw_event;
5055 Mpi2EventNotificationReply_t *mpi_reply;
5056 unsigned long flags;
5057 u16 event;
5058
5059 /* events turned off due to host reset or driver unloading */
5060 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5061 if (ioc->fw_events_off || ioc->remove_host) {
5062 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5063 return;
5064 }
5065 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5066
5067 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
5068 event = le16_to_cpu(mpi_reply->Event);
5069
5070 switch (event) {
5071 /* handle these */
5072 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
5073 {
5074 Mpi2EventDataSasBroadcastPrimitive_t *baen_data =
5075 (Mpi2EventDataSasBroadcastPrimitive_t *)
5076 mpi_reply->EventData;
5077
5078 if (baen_data->Primitive !=
5079 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT ||
5080 ioc->broadcast_aen_busy)
5081 return;
5082 ioc->broadcast_aen_busy = 1;
5083 break;
5084 }
5085
5086 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
5087 _scsih_check_topo_delete_events(ioc,
5088 (Mpi2EventDataSasTopologyChangeList_t *)
5089 mpi_reply->EventData);
5090 break;
5091
5092 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5093 case MPI2_EVENT_IR_OPERATION_STATUS:
5094 case MPI2_EVENT_SAS_DISCOVERY:
5095 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5096 case MPI2_EVENT_IR_VOLUME:
5097 case MPI2_EVENT_IR_PHYSICAL_DISK:
5098 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5099 case MPI2_EVENT_TASK_SET_FULL:
5100 break;
5101
5102 default: /* ignore the rest */
5103 return;
5104 }
5105
5106 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
5107 if (!fw_event) {
5108 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5109 ioc->name, __FILE__, __LINE__, __func__);
5110 return;
5111 }
5112 fw_event->event_data =
5113 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC);
5114 if (!fw_event->event_data) {
5115 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5116 ioc->name, __FILE__, __LINE__, __func__);
5117 kfree(fw_event);
5118 return;
5119 }
5120
5121 memcpy(fw_event->event_data, mpi_reply->EventData,
5122 mpi_reply->EventDataLength*4);
5123 fw_event->ioc = ioc;
5124 fw_event->VF_ID = VF_ID;
5125 fw_event->event = event;
5126 _scsih_fw_event_add(ioc, fw_event);
5127}
5128
5129/* shost template */
5130static struct scsi_host_template scsih_driver_template = {
5131 .module = THIS_MODULE,
5132 .name = "Fusion MPT SAS Host",
5133 .proc_name = MPT2SAS_DRIVER_NAME,
5134 .queuecommand = scsih_qcmd,
5135 .target_alloc = scsih_target_alloc,
5136 .slave_alloc = scsih_slave_alloc,
5137 .slave_configure = scsih_slave_configure,
5138 .target_destroy = scsih_target_destroy,
5139 .slave_destroy = scsih_slave_destroy,
5140 .change_queue_depth = scsih_change_queue_depth,
5141 .change_queue_type = scsih_change_queue_type,
5142 .eh_abort_handler = scsih_abort,
5143 .eh_device_reset_handler = scsih_dev_reset,
5144 .eh_host_reset_handler = scsih_host_reset,
5145 .bios_param = scsih_bios_param,
5146 .can_queue = 1,
5147 .this_id = -1,
5148 .sg_tablesize = MPT2SAS_SG_DEPTH,
5149 .max_sectors = 8192,
5150 .cmd_per_lun = 7,
5151 .use_clustering = ENABLE_CLUSTERING,
5152 .shost_attrs = mpt2sas_host_attrs,
5153 .sdev_attrs = mpt2sas_dev_attrs,
5154};
5155
5156/**
5157 * _scsih_expander_node_remove - removing expander device from list.
5158 * @ioc: per adapter object
5159 * @sas_expander: the sas_device object
5160 * Context: Calling function should acquire ioc->sas_node_lock.
5161 *
5162 * Removing object and freeing associated memory from the
5163 * ioc->sas_expander_list.
5164 *
5165 * Return nothing.
5166 */
5167static void
5168_scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
5169 struct _sas_node *sas_expander)
5170{
5171 struct _sas_port *mpt2sas_port;
5172 struct _sas_device *sas_device;
5173 struct _sas_node *expander_sibling;
5174 unsigned long flags;
5175
5176 if (!sas_expander)
5177 return;
5178
5179 /* remove sibling ports attached to this expander */
5180 retry_device_search:
5181 list_for_each_entry(mpt2sas_port,
5182 &sas_expander->sas_port_list, port_list) {
5183 if (mpt2sas_port->remote_identify.device_type ==
5184 SAS_END_DEVICE) {
5185 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5186 sas_device =
5187 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5188 mpt2sas_port->remote_identify.sas_address);
5189 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5190 if (!sas_device)
5191 continue;
5192 _scsih_remove_device(ioc, sas_device->handle);
5193 goto retry_device_search;
5194 }
5195 }
5196
5197 retry_expander_search:
5198 list_for_each_entry(mpt2sas_port,
5199 &sas_expander->sas_port_list, port_list) {
5200
5201 if (mpt2sas_port->remote_identify.device_type ==
5202 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
5203 mpt2sas_port->remote_identify.device_type ==
5204 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
5205
5206 spin_lock_irqsave(&ioc->sas_node_lock, flags);
5207 expander_sibling =
5208 mpt2sas_scsih_expander_find_by_sas_address(
5209 ioc, mpt2sas_port->remote_identify.sas_address);
5210 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
5211 if (!expander_sibling)
5212 continue;
5213 _scsih_expander_remove(ioc, expander_sibling->handle);
5214 goto retry_expander_search;
5215 }
5216 }
5217
5218 mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
5219 sas_expander->parent_handle);
5220
5221 printk(MPT2SAS_INFO_FMT "expander_remove: handle"
5222 "(0x%04x), sas_addr(0x%016llx)\n", ioc->name,
5223 sas_expander->handle, (unsigned long long)
5224 sas_expander->sas_address);
5225
5226 list_del(&sas_expander->list);
5227 kfree(sas_expander->phy);
5228 kfree(sas_expander);
5229}
5230
5231/**
5232 * scsih_remove - detach and remove add host
5233 * @pdev: PCI device struct
5234 *
5235 * Return nothing.
5236 */
5237static void __devexit
5238scsih_remove(struct pci_dev *pdev)
5239{
5240 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5241 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5242 struct _sas_port *mpt2sas_port;
5243 struct _sas_device *sas_device;
5244 struct _sas_node *expander_sibling;
5245 struct workqueue_struct *wq;
5246 unsigned long flags;
5247
5248 ioc->remove_host = 1;
5249 _scsih_fw_event_off(ioc);
5250
5251 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5252 wq = ioc->firmware_event_thread;
5253 ioc->firmware_event_thread = NULL;
5254 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5255 if (wq)
5256 destroy_workqueue(wq);
5257
5258 /* free ports attached to the sas_host */
5259 retry_again:
5260 list_for_each_entry(mpt2sas_port,
5261 &ioc->sas_hba.sas_port_list, port_list) {
5262 if (mpt2sas_port->remote_identify.device_type ==
5263 SAS_END_DEVICE) {
5264 sas_device =
5265 mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
5266 mpt2sas_port->remote_identify.sas_address);
5267 if (sas_device) {
5268 _scsih_remove_device(ioc, sas_device->handle);
5269 goto retry_again;
5270 }
5271 } else {
5272 expander_sibling =
5273 mpt2sas_scsih_expander_find_by_sas_address(ioc,
5274 mpt2sas_port->remote_identify.sas_address);
5275 if (expander_sibling) {
5276 _scsih_expander_remove(ioc,
5277 expander_sibling->handle);
5278 goto retry_again;
5279 }
5280 }
5281 }
5282
5283 /* free phys attached to the sas_host */
5284 if (ioc->sas_hba.num_phys) {
5285 kfree(ioc->sas_hba.phy);
5286 ioc->sas_hba.phy = NULL;
5287 ioc->sas_hba.num_phys = 0;
5288 }
5289
5290 sas_remove_host(shost);
5291 mpt2sas_base_detach(ioc);
5292 list_del(&ioc->list);
5293 scsi_remove_host(shost);
5294 scsi_host_put(shost);
5295}
5296
5297/**
5298 * _scsih_probe_boot_devices - reports 1st device
5299 * @ioc: per adapter object
5300 *
5301 * If specified in bios page 2, this routine reports the 1st
5302 * device scsi-ml or sas transport for persistent boot device
5303 * purposes. Please refer to function _scsih_determine_boot_device()
5304 */
5305static void
5306_scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
5307{
5308 u8 is_raid;
5309 void *device;
5310 struct _sas_device *sas_device;
5311 struct _raid_device *raid_device;
5312 u16 handle, parent_handle;
5313 u64 sas_address;
5314 unsigned long flags;
5315 int rc;
5316
5317 device = NULL;
5318 if (ioc->req_boot_device.device) {
5319 device = ioc->req_boot_device.device;
5320 is_raid = ioc->req_boot_device.is_raid;
5321 } else if (ioc->req_alt_boot_device.device) {
5322 device = ioc->req_alt_boot_device.device;
5323 is_raid = ioc->req_alt_boot_device.is_raid;
5324 } else if (ioc->current_boot_device.device) {
5325 device = ioc->current_boot_device.device;
5326 is_raid = ioc->current_boot_device.is_raid;
5327 }
5328
5329 if (!device)
5330 return;
5331
5332 if (is_raid) {
5333 raid_device = device;
5334 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5335 raid_device->id, 0);
5336 if (rc)
5337 _scsih_raid_device_remove(ioc, raid_device);
5338 } else {
5339 sas_device = device;
5340 handle = sas_device->handle;
5341 parent_handle = sas_device->parent_handle;
5342 sas_address = sas_device->sas_address;
5343 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5344 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5345 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5346 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
5347 sas_device->parent_handle)) {
5348 _scsih_sas_device_remove(ioc, sas_device);
5349 } else if (!sas_device->starget) {
5350 mpt2sas_transport_port_remove(ioc, sas_address,
5351 parent_handle);
5352 _scsih_sas_device_remove(ioc, sas_device);
5353 }
5354 }
5355}
5356
5357/**
5358 * _scsih_probe_raid - reporting raid volumes to scsi-ml
5359 * @ioc: per adapter object
5360 *
5361 * Called during initial loading of the driver.
5362 */
5363static void
5364_scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
5365{
5366 struct _raid_device *raid_device, *raid_next;
5367 int rc;
5368
5369 list_for_each_entry_safe(raid_device, raid_next,
5370 &ioc->raid_device_list, list) {
5371 if (raid_device->starget)
5372 continue;
5373 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5374 raid_device->id, 0);
5375 if (rc)
5376 _scsih_raid_device_remove(ioc, raid_device);
5377 }
5378}
5379
5380/**
5381 * _scsih_probe_sas - reporting raid volumes to sas transport
5382 * @ioc: per adapter object
5383 *
5384 * Called during initial loading of the driver.
5385 */
5386static void
5387_scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
5388{
5389 struct _sas_device *sas_device, *next;
5390 unsigned long flags;
5391 u16 handle, parent_handle;
5392 u64 sas_address;
5393
5394 /* SAS Device List */
5395 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
5396 list) {
5397 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5398 list_move_tail(&sas_device->list, &ioc->sas_device_list);
5399 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5400
5401 handle = sas_device->handle;
5402 parent_handle = sas_device->parent_handle;
5403 sas_address = sas_device->sas_address;
5404 if (!mpt2sas_transport_port_add(ioc, handle, parent_handle)) {
5405 _scsih_sas_device_remove(ioc, sas_device);
5406 } else if (!sas_device->starget) {
5407 mpt2sas_transport_port_remove(ioc, sas_address,
5408 parent_handle);
5409 _scsih_sas_device_remove(ioc, sas_device);
5410 }
5411 }
5412}
5413
5414/**
5415 * _scsih_probe_devices - probing for devices
5416 * @ioc: per adapter object
5417 *
5418 * Called during initial loading of the driver.
5419 */
5420static void
5421_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
5422{
5423 u16 volume_mapping_flags =
5424 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
5425 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
5426
5427 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
5428 return; /* return when IOC doesn't support initiator mode */
5429
5430 _scsih_probe_boot_devices(ioc);
5431
5432 if (ioc->ir_firmware) {
5433 if ((volume_mapping_flags &
5434 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) {
5435 _scsih_probe_sas(ioc);
5436 _scsih_probe_raid(ioc);
5437 } else {
5438 _scsih_probe_raid(ioc);
5439 _scsih_probe_sas(ioc);
5440 }
5441 } else
5442 _scsih_probe_sas(ioc);
5443}
5444
5445/**
5446 * scsih_probe - attach and add scsi host
5447 * @pdev: PCI device struct
5448 * @id: pci device id
5449 *
5450 * Returns 0 success, anything else error.
5451 */
5452static int
5453scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5454{
5455 struct MPT2SAS_ADAPTER *ioc;
5456 struct Scsi_Host *shost;
5457
5458 shost = scsi_host_alloc(&scsih_driver_template,
5459 sizeof(struct MPT2SAS_ADAPTER));
5460 if (!shost)
5461 return -ENODEV;
5462
5463 /* init local params */
5464 ioc = shost_priv(shost);
5465 memset(ioc, 0, sizeof(struct MPT2SAS_ADAPTER));
5466 INIT_LIST_HEAD(&ioc->list);
5467 list_add_tail(&ioc->list, &mpt2sas_ioc_list);
5468 ioc->shost = shost;
5469 ioc->id = mpt_ids++;
5470 sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
5471 ioc->pdev = pdev;
5472 ioc->scsi_io_cb_idx = scsi_io_cb_idx;
5473 ioc->tm_cb_idx = tm_cb_idx;
5474 ioc->ctl_cb_idx = ctl_cb_idx;
5475 ioc->base_cb_idx = base_cb_idx;
5476 ioc->transport_cb_idx = transport_cb_idx;
5477 ioc->config_cb_idx = config_cb_idx;
5478 ioc->logging_level = logging_level;
5479 /* misc semaphores and spin locks */
5480 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
5481 spin_lock_init(&ioc->scsi_lookup_lock);
5482 spin_lock_init(&ioc->sas_device_lock);
5483 spin_lock_init(&ioc->sas_node_lock);
5484 spin_lock_init(&ioc->fw_event_lock);
5485 spin_lock_init(&ioc->raid_device_lock);
5486
5487 INIT_LIST_HEAD(&ioc->sas_device_list);
5488 INIT_LIST_HEAD(&ioc->sas_device_init_list);
5489 INIT_LIST_HEAD(&ioc->sas_expander_list);
5490 INIT_LIST_HEAD(&ioc->fw_event_list);
5491 INIT_LIST_HEAD(&ioc->raid_device_list);
5492 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
5493
5494 /* init shost parameters */
5495 shost->max_cmd_len = 16;
5496 shost->max_lun = max_lun;
5497 shost->transportt = mpt2sas_transport_template;
5498 shost->unique_id = ioc->id;
5499
5500 if ((scsi_add_host(shost, &pdev->dev))) {
5501 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5502 ioc->name, __FILE__, __LINE__, __func__);
5503 list_del(&ioc->list);
5504 goto out_add_shost_fail;
5505 }
5506
5507 /* event thread */
5508 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
5509 "fw_event%d", ioc->id);
5510 ioc->firmware_event_thread = create_singlethread_workqueue(
5511 ioc->firmware_event_name);
5512 if (!ioc->firmware_event_thread) {
5513 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5514 ioc->name, __FILE__, __LINE__, __func__);
5515 goto out_thread_fail;
5516 }
5517
5518 ioc->wait_for_port_enable_to_complete = 1;
5519 if ((mpt2sas_base_attach(ioc))) {
5520 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5521 ioc->name, __FILE__, __LINE__, __func__);
5522 goto out_attach_fail;
5523 }
5524
5525 ioc->wait_for_port_enable_to_complete = 0;
5526 _scsih_probe_devices(ioc);
5527 return 0;
5528
5529 out_attach_fail:
5530 destroy_workqueue(ioc->firmware_event_thread);
5531 out_thread_fail:
5532 list_del(&ioc->list);
5533 scsi_remove_host(shost);
5534 out_add_shost_fail:
5535 return -ENODEV;
5536}
5537
5538#ifdef CONFIG_PM
5539/**
5540 * scsih_suspend - power management suspend main entry point
5541 * @pdev: PCI device struct
5542 * @state: PM state change to (usually PCI_D3)
5543 *
5544 * Returns 0 success, anything else error.
5545 */
5546static int
5547scsih_suspend(struct pci_dev *pdev, pm_message_t state)
5548{
5549 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5550 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5551 u32 device_state;
5552
5553 flush_scheduled_work();
5554 scsi_block_requests(shost);
5555 device_state = pci_choose_state(pdev, state);
5556 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering "
5557 "operating state [D%d]\n", ioc->name, pdev,
5558 pci_name(pdev), device_state);
5559
5560 mpt2sas_base_free_resources(ioc);
5561 pci_save_state(pdev);
5562 pci_disable_device(pdev);
5563 pci_set_power_state(pdev, device_state);
5564 return 0;
5565}
5566
5567/**
5568 * scsih_resume - power management resume main entry point
5569 * @pdev: PCI device struct
5570 *
5571 * Returns 0 success, anything else error.
5572 */
5573static int
5574scsih_resume(struct pci_dev *pdev)
5575{
5576 struct Scsi_Host *shost = pci_get_drvdata(pdev);
5577 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
5578 u32 device_state = pdev->current_state;
5579 int r;
5580
5581 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous "
5582 "operating state [D%d]\n", ioc->name, pdev,
5583 pci_name(pdev), device_state);
5584
5585 pci_set_power_state(pdev, PCI_D0);
5586 pci_enable_wake(pdev, PCI_D0, 0);
5587 pci_restore_state(pdev);
5588 ioc->pdev = pdev;
5589 r = mpt2sas_base_map_resources(ioc);
5590 if (r)
5591 return r;
5592
5593 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
5594 scsi_unblock_requests(shost);
5595 return 0;
5596}
5597#endif /* CONFIG_PM */
5598
5599
5600static struct pci_driver scsih_driver = {
5601 .name = MPT2SAS_DRIVER_NAME,
5602 .id_table = scsih_pci_table,
5603 .probe = scsih_probe,
5604 .remove = __devexit_p(scsih_remove),
5605#ifdef CONFIG_PM
5606 .suspend = scsih_suspend,
5607 .resume = scsih_resume,
5608#endif
5609};
5610
5611
5612/**
5613 * scsih_init - main entry point for this driver.
5614 *
5615 * Returns 0 success, anything else error.
5616 */
5617static int __init
5618scsih_init(void)
5619{
5620 int error;
5621
5622 mpt_ids = 0;
5623 printk(KERN_INFO "%s version %s loaded\n", MPT2SAS_DRIVER_NAME,
5624 MPT2SAS_DRIVER_VERSION);
5625
5626 mpt2sas_transport_template =
5627 sas_attach_transport(&mpt2sas_transport_functions);
5628 if (!mpt2sas_transport_template)
5629 return -ENODEV;
5630
5631 mpt2sas_base_initialize_callback_handler();
5632
5633 /* queuecommand callback hander */
5634 scsi_io_cb_idx = mpt2sas_base_register_callback_handler(scsih_io_done);
5635
5636 /* task managment callback handler */
5637 tm_cb_idx = mpt2sas_base_register_callback_handler(scsih_tm_done);
5638
5639 /* base internal commands callback handler */
5640 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
5641
5642 /* transport internal commands callback handler */
5643 transport_cb_idx = mpt2sas_base_register_callback_handler(
5644 mpt2sas_transport_done);
5645
5646 /* configuration page API internal commands callback handler */
5647 config_cb_idx = mpt2sas_base_register_callback_handler(
5648 mpt2sas_config_done);
5649
5650 /* ctl module callback handler */
5651 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
5652
5653 mpt2sas_ctl_init();
5654
5655 error = pci_register_driver(&scsih_driver);
5656 if (error)
5657 sas_release_transport(mpt2sas_transport_template);
5658
5659 return error;
5660}
5661
5662/**
5663 * scsih_exit - exit point for this driver (when it is a module).
5664 *
5665 * Returns 0 success, anything else error.
5666 */
5667static void __exit
5668scsih_exit(void)
5669{
5670 printk(KERN_INFO "mpt2sas version %s unloading\n",
5671 MPT2SAS_DRIVER_VERSION);
5672
5673 pci_unregister_driver(&scsih_driver);
5674
5675 sas_release_transport(mpt2sas_transport_template);
5676 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
5677 mpt2sas_base_release_callback_handler(tm_cb_idx);
5678 mpt2sas_base_release_callback_handler(base_cb_idx);
5679 mpt2sas_base_release_callback_handler(transport_cb_idx);
5680 mpt2sas_base_release_callback_handler(config_cb_idx);
5681 mpt2sas_base_release_callback_handler(ctl_cb_idx);
5682
5683 mpt2sas_ctl_exit();
5684}
5685
5686module_init(scsih_init);
5687module_exit(scsih_exit);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
new file mode 100644
index 000000000000..e03dc0b1e1a0
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -0,0 +1,1211 @@
1/*
2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * NO WARRANTY
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
28
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 * USA.
42 */
43
44#include <linux/module.h>
45#include <linux/kernel.h>
46#include <linux/init.h>
47#include <linux/errno.h>
48#include <linux/sched.h>
49#include <linux/workqueue.h>
50#include <linux/delay.h>
51#include <linux/pci.h>
52
53#include <scsi/scsi.h>
54#include <scsi/scsi_cmnd.h>
55#include <scsi/scsi_device.h>
56#include <scsi/scsi_host.h>
57#include <scsi/scsi_transport_sas.h>
58#include <scsi/scsi_dbg.h>
59
60#include "mpt2sas_base.h"
61/**
62 * _transport_sas_node_find_by_handle - sas node search
63 * @ioc: per adapter object
64 * @handle: expander or hba handle (assigned by firmware)
65 * Context: Calling function should acquire ioc->sas_node_lock.
66 *
67 * Search for either hba phys or expander device based on handle, then returns
68 * the sas_node object.
69 */
70static struct _sas_node *
71_transport_sas_node_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
72{
73 int i;
74
75 for (i = 0; i < ioc->sas_hba.num_phys; i++)
76 if (ioc->sas_hba.phy[i].handle == handle)
77 return &ioc->sas_hba;
78
79 return mpt2sas_scsih_expander_find_by_handle(ioc, handle);
80}
81
82/**
83 * _transport_convert_phy_link_rate -
84 * @link_rate: link rate returned from mpt firmware
85 *
86 * Convert link_rate from mpi fusion into sas_transport form.
87 */
88static enum sas_linkrate
89_transport_convert_phy_link_rate(u8 link_rate)
90{
91 enum sas_linkrate rc;
92
93 switch (link_rate) {
94 case MPI2_SAS_NEG_LINK_RATE_1_5:
95 rc = SAS_LINK_RATE_1_5_GBPS;
96 break;
97 case MPI2_SAS_NEG_LINK_RATE_3_0:
98 rc = SAS_LINK_RATE_3_0_GBPS;
99 break;
100 case MPI2_SAS_NEG_LINK_RATE_6_0:
101 rc = SAS_LINK_RATE_6_0_GBPS;
102 break;
103 case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
104 rc = SAS_PHY_DISABLED;
105 break;
106 case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
107 rc = SAS_LINK_RATE_FAILED;
108 break;
109 case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
110 rc = SAS_SATA_PORT_SELECTOR;
111 break;
112 case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
113 rc = SAS_PHY_RESET_IN_PROGRESS;
114 break;
115 default:
116 case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
117 case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
118 rc = SAS_LINK_RATE_UNKNOWN;
119 break;
120 }
121 return rc;
122}
123
124/**
125 * _transport_set_identify - set identify for phys and end devices
126 * @ioc: per adapter object
127 * @handle: device handle
128 * @identify: sas identify info
129 *
130 * Populates sas identify info.
131 *
132 * Returns 0 for success, non-zero for failure.
133 */
134static int
135_transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
136 struct sas_identify *identify)
137{
138 Mpi2SasDevicePage0_t sas_device_pg0;
139 Mpi2ConfigReply_t mpi_reply;
140 u32 device_info;
141 u32 ioc_status;
142
143 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
144 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
145 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
146 ioc->name, __FILE__, __LINE__, __func__);
147 return -1;
148 }
149
150 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
151 MPI2_IOCSTATUS_MASK;
152 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
153 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
154 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
155 __FILE__, __LINE__, __func__);
156 return -1;
157 }
158
159 memset(identify, 0, sizeof(identify));
160 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
161
162 /* sas_address */
163 identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
164
165 /* device_type */
166 switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
167 case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
168 identify->device_type = SAS_PHY_UNUSED;
169 break;
170 case MPI2_SAS_DEVICE_INFO_END_DEVICE:
171 identify->device_type = SAS_END_DEVICE;
172 break;
173 case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
174 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
175 break;
176 case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
177 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
178 break;
179 }
180
181 /* initiator_port_protocols */
182 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
183 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
184 if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
185 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
186 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
187 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
188 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
189 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
190
191 /* target_port_protocols */
192 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
193 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
194 if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
195 identify->target_port_protocols |= SAS_PROTOCOL_STP;
196 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
197 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
198 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
199 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
200
201 return 0;
202}
203
204/**
205 * mpt2sas_transport_done - internal transport layer callback handler.
206 * @ioc: per adapter object
207 * @smid: system request message index
208 * @VF_ID: virtual function id
209 * @reply: reply message frame(lower 32bit addr)
210 *
211 * Callback handler when sending internal generated transport cmds.
212 * The callback index passed is `ioc->transport_cb_idx`
213 *
214 * Return nothing.
215 */
216void
217mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
218 u32 reply)
219{
220 MPI2DefaultReply_t *mpi_reply;
221
222 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
223 if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
224 return;
225 if (ioc->transport_cmds.smid != smid)
226 return;
227 ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
228 if (mpi_reply) {
229 memcpy(ioc->transport_cmds.reply, mpi_reply,
230 mpi_reply->MsgLength*4);
231 ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID;
232 }
233 ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
234 complete(&ioc->transport_cmds.done);
235}
236
237/* report manufacture request structure */
238struct rep_manu_request{
239 u8 smp_frame_type;
240 u8 function;
241 u8 reserved;
242 u8 request_length;
243};
244
245/* report manufacture reply structure */
246struct rep_manu_reply{
247 u8 smp_frame_type; /* 0x41 */
248 u8 function; /* 0x01 */
249 u8 function_result;
250 u8 response_length;
251 u16 expander_change_count;
252 u8 reserved0[2];
253 u8 sas_format:1;
254 u8 reserved1:7;
255 u8 reserved2[3];
256 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
257 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
258 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
259 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
260 u16 component_id;
261 u8 component_revision_id;
262 u8 reserved3;
263 u8 vendor_specific[8];
264};
265
266/**
267 * transport_expander_report_manufacture - obtain SMP report_manufacture
268 * @ioc: per adapter object
269 * @sas_address: expander sas address
270 * @edev: the sas_expander_device object
271 *
272 * Fills in the sas_expander_device object when SMP port is created.
273 *
274 * Returns 0 for success, non-zero for failure.
275 */
276static int
277transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
278 u64 sas_address, struct sas_expander_device *edev)
279{
280 Mpi2SmpPassthroughRequest_t *mpi_request;
281 Mpi2SmpPassthroughReply_t *mpi_reply;
282 struct rep_manu_reply *manufacture_reply;
283 struct rep_manu_request *manufacture_request;
284 int rc;
285 u16 smid;
286 u32 ioc_state;
287 unsigned long timeleft;
288 void *psge;
289 u32 sgl_flags;
290 u8 issue_reset = 0;
291 unsigned long flags;
292 void *data_out = NULL;
293 dma_addr_t data_out_dma;
294 u32 sz;
295 u64 *sas_address_le;
296 u16 wait_state_count;
297
298 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
299 if (ioc->ioc_reset_in_progress) {
300 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
301 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
302 __func__, ioc->name);
303 return -EFAULT;
304 }
305 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
306
307 mutex_lock(&ioc->transport_cmds.mutex);
308
309 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
310 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
311 ioc->name, __func__);
312 rc = -EAGAIN;
313 goto out;
314 }
315 ioc->transport_cmds.status = MPT2_CMD_PENDING;
316
317 wait_state_count = 0;
318 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
319 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
320 if (wait_state_count++ == 10) {
321 printk(MPT2SAS_ERR_FMT
322 "%s: failed due to ioc not operational\n",
323 ioc->name, __func__);
324 rc = -EFAULT;
325 goto out;
326 }
327 ssleep(1);
328 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
329 printk(MPT2SAS_INFO_FMT "%s: waiting for "
330 "operational state(count=%d)\n", ioc->name,
331 __func__, wait_state_count);
332 }
333 if (wait_state_count)
334 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
335 ioc->name, __func__);
336
337 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
338 if (!smid) {
339 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
340 ioc->name, __func__);
341 rc = -EAGAIN;
342 goto out;
343 }
344
345 rc = 0;
346 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
347 ioc->transport_cmds.smid = smid;
348
349 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
350 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
351
352 if (!data_out) {
353 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
354 __LINE__, __func__);
355 rc = -ENOMEM;
356 mpt2sas_base_free_smid(ioc, smid);
357 goto out;
358 }
359
360 manufacture_request = data_out;
361 manufacture_request->smp_frame_type = 0x40;
362 manufacture_request->function = 1;
363 manufacture_request->reserved = 0;
364 manufacture_request->request_length = 0;
365
366 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
367 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
368 mpi_request->PhysicalPort = 0xFF;
369 sas_address_le = (u64 *)&mpi_request->SASAddress;
370 *sas_address_le = cpu_to_le64(sas_address);
371 mpi_request->RequestDataLength = sizeof(struct rep_manu_request);
372 psge = &mpi_request->SGL;
373
374 /* WRITE sgel first */
375 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
376 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
377 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
378 ioc->base_add_sg_single(psge, sgl_flags |
379 sizeof(struct rep_manu_request), data_out_dma);
380
381 /* incr sgel */
382 psge += ioc->sge_size;
383
384 /* READ sgel last */
385 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
386 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
387 MPI2_SGE_FLAGS_END_OF_LIST);
388 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
389 ioc->base_add_sg_single(psge, sgl_flags |
390 sizeof(struct rep_manu_reply), data_out_dma +
391 sizeof(struct rep_manu_request));
392
393 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - "
394 "send to sas_addr(0x%016llx)\n", ioc->name,
395 (unsigned long long)sas_address));
396 mpt2sas_base_put_smid_default(ioc, smid, 0 /* VF_ID */);
397 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
398 10*HZ);
399
400 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
401 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
402 ioc->name, __func__);
403 _debug_dump_mf(mpi_request,
404 sizeof(Mpi2SmpPassthroughRequest_t)/4);
405 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
406 issue_reset = 1;
407 goto issue_host_reset;
408 }
409
410 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - "
411 "complete\n", ioc->name));
412
413 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
414 u8 *tmp;
415
416 mpi_reply = ioc->transport_cmds.reply;
417
418 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
419 "report_manufacture - reply data transfer size(%d)\n",
420 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
421
422 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
423 sizeof(struct rep_manu_reply))
424 goto out;
425
426 manufacture_reply = data_out + sizeof(struct rep_manu_request);
427 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
428 SAS_EXPANDER_VENDOR_ID_LEN);
429 strncpy(edev->product_id, manufacture_reply->product_id,
430 SAS_EXPANDER_PRODUCT_ID_LEN);
431 strncpy(edev->product_rev, manufacture_reply->product_rev,
432 SAS_EXPANDER_PRODUCT_REV_LEN);
433 edev->level = manufacture_reply->sas_format;
434 if (manufacture_reply->sas_format) {
435 strncpy(edev->component_vendor_id,
436 manufacture_reply->component_vendor_id,
437 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
438 tmp = (u8 *)&manufacture_reply->component_id;
439 edev->component_id = tmp[0] << 8 | tmp[1];
440 edev->component_revision_id =
441 manufacture_reply->component_revision_id;
442 }
443 } else
444 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
445 "report_manufacture - no reply\n", ioc->name));
446
447 issue_host_reset:
448 if (issue_reset)
449 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
450 FORCE_BIG_HAMMER);
451 out:
452 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
453 if (data_out)
454 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
455
456 mutex_unlock(&ioc->transport_cmds.mutex);
457 return rc;
458}
459
460/**
461 * mpt2sas_transport_port_add - insert port to the list
462 * @ioc: per adapter object
463 * @handle: handle of attached device
464 * @parent_handle: parent handle(either hba or expander)
465 * Context: This function will acquire ioc->sas_node_lock.
466 *
467 * Adding new port object to the sas_node->sas_port_list.
468 *
469 * Returns mpt2sas_port.
470 */
471struct _sas_port *
472mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
473 u16 parent_handle)
474{
475 struct _sas_phy *mpt2sas_phy, *next;
476 struct _sas_port *mpt2sas_port;
477 unsigned long flags;
478 struct _sas_node *sas_node;
479 struct sas_rphy *rphy;
480 int i;
481 struct sas_port *port;
482
483 if (!parent_handle)
484 return NULL;
485
486 mpt2sas_port = kzalloc(sizeof(struct _sas_port),
487 GFP_KERNEL);
488 if (!mpt2sas_port) {
489 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
490 ioc->name, __FILE__, __LINE__, __func__);
491 return NULL;
492 }
493
494 INIT_LIST_HEAD(&mpt2sas_port->port_list);
495 INIT_LIST_HEAD(&mpt2sas_port->phy_list);
496 spin_lock_irqsave(&ioc->sas_node_lock, flags);
497 sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
498 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
499
500 if (!sas_node) {
501 printk(MPT2SAS_ERR_FMT "%s: Could not find parent(0x%04x)!\n",
502 ioc->name, __func__, parent_handle);
503 goto out_fail;
504 }
505
506 mpt2sas_port->handle = parent_handle;
507 mpt2sas_port->sas_address = sas_node->sas_address;
508 if ((_transport_set_identify(ioc, handle,
509 &mpt2sas_port->remote_identify))) {
510 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
511 ioc->name, __FILE__, __LINE__, __func__);
512 goto out_fail;
513 }
514
515 if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
516 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
517 ioc->name, __FILE__, __LINE__, __func__);
518 goto out_fail;
519 }
520
521 for (i = 0; i < sas_node->num_phys; i++) {
522 if (sas_node->phy[i].remote_identify.sas_address !=
523 mpt2sas_port->remote_identify.sas_address)
524 continue;
525 list_add_tail(&sas_node->phy[i].port_siblings,
526 &mpt2sas_port->phy_list);
527 mpt2sas_port->num_phys++;
528 }
529
530 if (!mpt2sas_port->num_phys) {
531 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
532 ioc->name, __FILE__, __LINE__, __func__);
533 goto out_fail;
534 }
535
536 port = sas_port_alloc_num(sas_node->parent_dev);
537 if ((sas_port_add(port))) {
538 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
539 ioc->name, __FILE__, __LINE__, __func__);
540 goto out_fail;
541 }
542
543 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
544 port_siblings) {
545 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
546 dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)"
547 ", sas_addr(0x%016llx), phy(%d)\n", handle,
548 (unsigned long long)
549 mpt2sas_port->remote_identify.sas_address,
550 mpt2sas_phy->phy_id);
551 sas_port_add_phy(port, mpt2sas_phy->phy);
552 }
553
554 mpt2sas_port->port = port;
555 if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE)
556 rphy = sas_end_device_alloc(port);
557 else
558 rphy = sas_expander_alloc(port,
559 mpt2sas_port->remote_identify.device_type);
560
561 rphy->identify = mpt2sas_port->remote_identify;
562 if ((sas_rphy_add(rphy))) {
563 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
564 ioc->name, __FILE__, __LINE__, __func__);
565 }
566 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
567 dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
568 "sas_addr(0x%016llx)\n", handle,
569 (unsigned long long)
570 mpt2sas_port->remote_identify.sas_address);
571 mpt2sas_port->rphy = rphy;
572 spin_lock_irqsave(&ioc->sas_node_lock, flags);
573 list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list);
574 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
575
576 /* fill in report manufacture */
577 if (mpt2sas_port->remote_identify.device_type ==
578 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
579 mpt2sas_port->remote_identify.device_type ==
580 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
581 transport_expander_report_manufacture(ioc,
582 mpt2sas_port->remote_identify.sas_address,
583 rphy_to_expander_device(rphy));
584
585 return mpt2sas_port;
586
587 out_fail:
588 list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list,
589 port_siblings)
590 list_del(&mpt2sas_phy->port_siblings);
591 kfree(mpt2sas_port);
592 return NULL;
593}
594
595/**
596 * mpt2sas_transport_port_remove - remove port from the list
597 * @ioc: per adapter object
598 * @sas_address: sas address of attached device
599 * @parent_handle: handle to the upstream parent(either hba or expander)
600 * Context: This function will acquire ioc->sas_node_lock.
601 *
602 * Removing object and freeing associated memory from the
603 * ioc->sas_port_list.
604 *
605 * Return nothing.
606 */
607void
608mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
609 u16 parent_handle)
610{
611 int i;
612 unsigned long flags;
613 struct _sas_port *mpt2sas_port, *next;
614 struct _sas_node *sas_node;
615 u8 found = 0;
616 struct _sas_phy *mpt2sas_phy, *next_phy;
617
618 spin_lock_irqsave(&ioc->sas_node_lock, flags);
619 sas_node = _transport_sas_node_find_by_handle(ioc, parent_handle);
620 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
621 if (!sas_node)
622 return;
623 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
624 port_list) {
625 if (mpt2sas_port->remote_identify.sas_address != sas_address)
626 continue;
627 found = 1;
628 list_del(&mpt2sas_port->port_list);
629 goto out;
630 }
631 out:
632 if (!found)
633 return;
634
635 for (i = 0; i < sas_node->num_phys; i++) {
636 if (sas_node->phy[i].remote_identify.sas_address == sas_address)
637 memset(&sas_node->phy[i].remote_identify, 0 ,
638 sizeof(struct sas_identify));
639 }
640
641 list_for_each_entry_safe(mpt2sas_phy, next_phy,
642 &mpt2sas_port->phy_list, port_siblings) {
643 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
644 dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
645 "remove: parent_handle(0x%04x), "
646 "sas_addr(0x%016llx), phy(%d)\n", parent_handle,
647 (unsigned long long)
648 mpt2sas_port->remote_identify.sas_address,
649 mpt2sas_phy->phy_id);
650 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
651 list_del(&mpt2sas_phy->port_siblings);
652 }
653 sas_port_delete(mpt2sas_port->port);
654 kfree(mpt2sas_port);
655}
656
657/**
658 * mpt2sas_transport_add_host_phy - report sas_host phy to transport
659 * @ioc: per adapter object
660 * @mpt2sas_phy: mpt2sas per phy object
661 * @phy_pg0: sas phy page 0
662 * @parent_dev: parent device class object
663 *
664 * Returns 0 for success, non-zero for failure.
665 */
666int
667mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
668 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
669{
670 struct sas_phy *phy;
671 int phy_index = mpt2sas_phy->phy_id;
672
673
674 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
675 phy = sas_phy_alloc(parent_dev, phy_index);
676 if (!phy) {
677 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
678 ioc->name, __FILE__, __LINE__, __func__);
679 return -1;
680 }
681 if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
682 &mpt2sas_phy->identify))) {
683 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
684 ioc->name, __FILE__, __LINE__, __func__);
685 return -1;
686 }
687 phy->identify = mpt2sas_phy->identify;
688 mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
689 if (mpt2sas_phy->attached_handle)
690 _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
691 &mpt2sas_phy->remote_identify);
692 phy->identify.phy_identifier = mpt2sas_phy->phy_id;
693 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
694 phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
695 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
696 phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
697 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
698 phy_pg0.HwLinkRate >> 4);
699 phy->minimum_linkrate = _transport_convert_phy_link_rate(
700 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
701 phy->maximum_linkrate = _transport_convert_phy_link_rate(
702 phy_pg0.ProgrammedLinkRate >> 4);
703
704 if ((sas_phy_add(phy))) {
705 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
706 ioc->name, __FILE__, __LINE__, __func__);
707 sas_phy_free(phy);
708 return -1;
709 }
710 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
711 dev_printk(KERN_INFO, &phy->dev,
712 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
713 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
714 mpt2sas_phy->handle, (unsigned long long)
715 mpt2sas_phy->identify.sas_address,
716 mpt2sas_phy->attached_handle,
717 (unsigned long long)
718 mpt2sas_phy->remote_identify.sas_address);
719 mpt2sas_phy->phy = phy;
720 return 0;
721}
722
723
724/**
725 * mpt2sas_transport_add_expander_phy - report expander phy to transport
726 * @ioc: per adapter object
727 * @mpt2sas_phy: mpt2sas per phy object
728 * @expander_pg1: expander page 1
729 * @parent_dev: parent device class object
730 *
731 * Returns 0 for success, non-zero for failure.
732 */
733int
734mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
735 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev)
736{
737 struct sas_phy *phy;
738 int phy_index = mpt2sas_phy->phy_id;
739
740 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
741 phy = sas_phy_alloc(parent_dev, phy_index);
742 if (!phy) {
743 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
744 ioc->name, __FILE__, __LINE__, __func__);
745 return -1;
746 }
747 if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
748 &mpt2sas_phy->identify))) {
749 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
750 ioc->name, __FILE__, __LINE__, __func__);
751 return -1;
752 }
753 phy->identify = mpt2sas_phy->identify;
754 mpt2sas_phy->attached_handle =
755 le16_to_cpu(expander_pg1.AttachedDevHandle);
756 if (mpt2sas_phy->attached_handle)
757 _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
758 &mpt2sas_phy->remote_identify);
759 phy->identify.phy_identifier = mpt2sas_phy->phy_id;
760 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
761 expander_pg1.NegotiatedLinkRate &
762 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
763 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
764 expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
765 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
766 expander_pg1.HwLinkRate >> 4);
767 phy->minimum_linkrate = _transport_convert_phy_link_rate(
768 expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
769 phy->maximum_linkrate = _transport_convert_phy_link_rate(
770 expander_pg1.ProgrammedLinkRate >> 4);
771
772 if ((sas_phy_add(phy))) {
773 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
774 ioc->name, __FILE__, __LINE__, __func__);
775 sas_phy_free(phy);
776 return -1;
777 }
778 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
779 dev_printk(KERN_INFO, &phy->dev,
780 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
781 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
782 mpt2sas_phy->handle, (unsigned long long)
783 mpt2sas_phy->identify.sas_address,
784 mpt2sas_phy->attached_handle,
785 (unsigned long long)
786 mpt2sas_phy->remote_identify.sas_address);
787 mpt2sas_phy->phy = phy;
788 return 0;
789}
790
791/**
792 * mpt2sas_transport_update_phy_link_change - refreshing phy link changes and attached devices
793 * @ioc: per adapter object
794 * @handle: handle to sas_host or expander
795 * @attached_handle: attached device handle
796 * @phy_numberv: phy number
797 * @link_rate: new link rate
798 *
799 * Returns nothing.
800 */
801void
802mpt2sas_transport_update_phy_link_change(struct MPT2SAS_ADAPTER *ioc,
803 u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate)
804{
805 unsigned long flags;
806 struct _sas_node *sas_node;
807 struct _sas_phy *mpt2sas_phy;
808
809 spin_lock_irqsave(&ioc->sas_node_lock, flags);
810 sas_node = _transport_sas_node_find_by_handle(ioc, handle);
811 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
812 if (!sas_node)
813 return;
814
815 mpt2sas_phy = &sas_node->phy[phy_number];
816 mpt2sas_phy->attached_handle = attached_handle;
817 if (attached_handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5))
818 _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
819 &mpt2sas_phy->remote_identify);
820 else
821 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
822 sas_identify));
823
824 if (mpt2sas_phy->phy)
825 mpt2sas_phy->phy->negotiated_linkrate =
826 _transport_convert_phy_link_rate(link_rate);
827
828 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
829 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
830 "refresh: handle(0x%04x), sas_addr(0x%016llx),\n"
831 "\tlink_rate(0x%02x), phy(%d)\n"
832 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
833 handle, (unsigned long long)
834 mpt2sas_phy->identify.sas_address, link_rate,
835 phy_number, attached_handle,
836 (unsigned long long)
837 mpt2sas_phy->remote_identify.sas_address);
838}
839
840static inline void *
841phy_to_ioc(struct sas_phy *phy)
842{
843 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
844 return shost_priv(shost);
845}
846
847static inline void *
848rphy_to_ioc(struct sas_rphy *rphy)
849{
850 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
851 return shost_priv(shost);
852}
853
854/**
855 * transport_get_linkerrors -
856 * @phy: The sas phy object
857 *
858 * Only support sas_host direct attached phys.
859 * Returns 0 for success, non-zero for failure.
860 *
861 */
862static int
863transport_get_linkerrors(struct sas_phy *phy)
864{
865 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
866 struct _sas_phy *mpt2sas_phy;
867 Mpi2ConfigReply_t mpi_reply;
868 Mpi2SasPhyPage1_t phy_pg1;
869 int i;
870
871 for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys &&
872 !mpt2sas_phy; i++) {
873 if (ioc->sas_hba.phy[i].phy != phy)
874 continue;
875 mpt2sas_phy = &ioc->sas_hba.phy[i];
876 }
877
878 if (!mpt2sas_phy) /* this phy not on sas_host */
879 return -EINVAL;
880
881 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
882 mpt2sas_phy->phy_id))) {
883 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
884 ioc->name, __FILE__, __LINE__, __func__);
885 return -ENXIO;
886 }
887
888 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
889 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
890 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
891 mpt2sas_phy->phy_id,
892 le16_to_cpu(mpi_reply.IOCStatus),
893 le32_to_cpu(mpi_reply.IOCLogInfo));
894
895 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
896 phy->running_disparity_error_count =
897 le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
898 phy->loss_of_dword_sync_count =
899 le32_to_cpu(phy_pg1.LossDwordSynchCount);
900 phy->phy_reset_problem_count =
901 le32_to_cpu(phy_pg1.PhyResetProblemCount);
902 return 0;
903}
904
905/**
906 * transport_get_enclosure_identifier -
907 * @phy: The sas phy object
908 *
909 * Obtain the enclosure logical id for an expander.
910 * Returns 0 for success, non-zero for failure.
911 */
912static int
913transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
914{
915 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
916 struct _sas_node *sas_expander;
917 unsigned long flags;
918
919 spin_lock_irqsave(&ioc->sas_node_lock, flags);
920 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
921 rphy->identify.sas_address);
922 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
923
924 if (!sas_expander)
925 return -ENXIO;
926
927 *identifier = sas_expander->enclosure_logical_id;
928 return 0;
929}
930
931/**
932 * transport_get_bay_identifier -
933 * @phy: The sas phy object
934 *
935 * Returns the slot id for a device that resides inside an enclosure.
936 */
937static int
938transport_get_bay_identifier(struct sas_rphy *rphy)
939{
940 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
941 struct _sas_device *sas_device;
942 unsigned long flags;
943
944 spin_lock_irqsave(&ioc->sas_device_lock, flags);
945 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
946 rphy->identify.sas_address);
947 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
948
949 if (!sas_device)
950 return -ENXIO;
951
952 return sas_device->slot;
953}
954
955/**
956 * transport_phy_reset -
957 * @phy: The sas phy object
958 * @hard_reset:
959 *
960 * Only support sas_host direct attached phys.
961 * Returns 0 for success, non-zero for failure.
962 */
963static int
964transport_phy_reset(struct sas_phy *phy, int hard_reset)
965{
966 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
967 struct _sas_phy *mpt2sas_phy;
968 Mpi2SasIoUnitControlReply_t mpi_reply;
969 Mpi2SasIoUnitControlRequest_t mpi_request;
970 int i;
971
972 for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys &&
973 !mpt2sas_phy; i++) {
974 if (ioc->sas_hba.phy[i].phy != phy)
975 continue;
976 mpt2sas_phy = &ioc->sas_hba.phy[i];
977 }
978
979 if (!mpt2sas_phy) /* this phy not on sas_host */
980 return -EINVAL;
981
982 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
983 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
984 mpi_request.Operation = hard_reset ?
985 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
986 mpi_request.PhyNum = mpt2sas_phy->phy_id;
987
988 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
989 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
990 ioc->name, __FILE__, __LINE__, __func__);
991 return -ENXIO;
992 }
993
994 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
995 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
996 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
997 mpt2sas_phy->phy_id,
998 le16_to_cpu(mpi_reply.IOCStatus),
999 le32_to_cpu(mpi_reply.IOCLogInfo));
1000
1001 return 0;
1002}
1003
1004/**
1005 * transport_smp_handler - transport portal for smp passthru
1006 * @shost: shost object
1007 * @rphy: sas transport rphy object
1008 * @req:
1009 *
1010 * This used primarily for smp_utils.
1011 * Example:
1012 * smp_rep_general /sys/class/bsg/expander-5:0
1013 */
1014static int
1015transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1016 struct request *req)
1017{
1018 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1019 Mpi2SmpPassthroughRequest_t *mpi_request;
1020 Mpi2SmpPassthroughReply_t *mpi_reply;
1021 int rc;
1022 u16 smid;
1023 u32 ioc_state;
1024 unsigned long timeleft;
1025 void *psge;
1026 u32 sgl_flags;
1027 u8 issue_reset = 0;
1028 unsigned long flags;
1029 dma_addr_t dma_addr_in = 0;
1030 dma_addr_t dma_addr_out = 0;
1031 u16 wait_state_count;
1032 struct request *rsp = req->next_rq;
1033
1034 if (!rsp) {
1035 printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
1036 "missing\n", ioc->name, __func__);
1037 return -EINVAL;
1038 }
1039
1040 /* do we need to support multiple segments? */
1041 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1042 printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, "
1043 "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt,
1044 req->data_len, rsp->bio->bi_vcnt, rsp->data_len);
1045 return -EINVAL;
1046 }
1047
1048 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
1049 if (ioc->ioc_reset_in_progress) {
1050 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1051 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1052 __func__, ioc->name);
1053 return -EFAULT;
1054 }
1055 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
1056
1057 rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1058 if (rc)
1059 return rc;
1060
1061 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1062 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
1063 __func__);
1064 rc = -EAGAIN;
1065 goto out;
1066 }
1067 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1068
1069 wait_state_count = 0;
1070 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1071 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1072 if (wait_state_count++ == 10) {
1073 printk(MPT2SAS_ERR_FMT
1074 "%s: failed due to ioc not operational\n",
1075 ioc->name, __func__);
1076 rc = -EFAULT;
1077 goto out;
1078 }
1079 ssleep(1);
1080 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1081 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1082 "operational state(count=%d)\n", ioc->name,
1083 __func__, wait_state_count);
1084 }
1085 if (wait_state_count)
1086 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1087 ioc->name, __func__);
1088
1089 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1090 if (!smid) {
1091 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1092 ioc->name, __func__);
1093 rc = -EAGAIN;
1094 goto out;
1095 }
1096
1097 rc = 0;
1098 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1099 ioc->transport_cmds.smid = smid;
1100
1101 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1102 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1103 mpi_request->PhysicalPort = 0xFF;
1104 *((u64 *)&mpi_request->SASAddress) = (rphy) ?
1105 cpu_to_le64(rphy->identify.sas_address) :
1106 cpu_to_le64(ioc->sas_hba.sas_address);
1107 mpi_request->RequestDataLength = cpu_to_le16(req->data_len - 4);
1108 psge = &mpi_request->SGL;
1109
1110 /* WRITE sgel first */
1111 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1112 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1113 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1114 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1115 req->data_len, PCI_DMA_BIDIRECTIONAL);
1116 if (!dma_addr_out) {
1117 mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
1118 goto unmap;
1119 }
1120
1121 ioc->base_add_sg_single(psge, sgl_flags | (req->data_len - 4),
1122 dma_addr_out);
1123
1124 /* incr sgel */
1125 psge += ioc->sge_size;
1126
1127 /* READ sgel last */
1128 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1129 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1130 MPI2_SGE_FLAGS_END_OF_LIST);
1131 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1132 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
1133 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1134 if (!dma_addr_in) {
1135 mpt2sas_base_free_smid(ioc, le16_to_cpu(smid));
1136 goto unmap;
1137 }
1138
1139 ioc->base_add_sg_single(psge, sgl_flags | (rsp->data_len + 4),
1140 dma_addr_in);
1141
1142 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
1143 "sending smp request\n", ioc->name, __func__));
1144
1145 mpt2sas_base_put_smid_default(ioc, smid, 0 /* VF_ID */);
1146 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1147 10*HZ);
1148
1149 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1150 printk(MPT2SAS_ERR_FMT "%s : timeout\n",
1151 __func__, ioc->name);
1152 _debug_dump_mf(mpi_request,
1153 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1154 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1155 issue_reset = 1;
1156 goto issue_host_reset;
1157 }
1158
1159 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
1160 "complete\n", ioc->name, __func__));
1161
1162 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1163
1164 mpi_reply = ioc->transport_cmds.reply;
1165
1166 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
1167 "%s - reply data transfer size(%d)\n",
1168 ioc->name, __func__,
1169 le16_to_cpu(mpi_reply->ResponseDataLength)));
1170
1171 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
1172 req->sense_len = sizeof(*mpi_reply);
1173 req->data_len = 0;
1174 rsp->data_len -= mpi_reply->ResponseDataLength;
1175
1176 } else {
1177 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT
1178 "%s - no reply\n", ioc->name, __func__));
1179 rc = -ENXIO;
1180 }
1181
1182 issue_host_reset:
1183 if (issue_reset) {
1184 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1185 FORCE_BIG_HAMMER);
1186 rc = -ETIMEDOUT;
1187 }
1188
1189 unmap:
1190 if (dma_addr_out)
1191 pci_unmap_single(ioc->pdev, dma_addr_out, req->data_len,
1192 PCI_DMA_BIDIRECTIONAL);
1193 if (dma_addr_in)
1194 pci_unmap_single(ioc->pdev, dma_addr_in, rsp->data_len,
1195 PCI_DMA_BIDIRECTIONAL);
1196
1197 out:
1198 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1199 mutex_unlock(&ioc->transport_cmds.mutex);
1200 return rc;
1201}
1202
1203struct sas_function_template mpt2sas_transport_functions = {
1204 .get_linkerrors = transport_get_linkerrors,
1205 .get_enclosure_identifier = transport_get_enclosure_identifier,
1206 .get_bay_identifier = transport_get_bay_identifier,
1207 .phy_reset = transport_phy_reset,
1208 .smp_handler = transport_smp_handler,
1209};
1210
1211struct scsi_transport_template *mpt2sas_transport_template;
diff --git a/drivers/scsi/osd/Kbuild b/drivers/scsi/osd/Kbuild
new file mode 100644
index 000000000000..0e207aa67d16
--- /dev/null
+++ b/drivers/scsi/osd/Kbuild
@@ -0,0 +1,45 @@
1#
2# Kbuild for the OSD modules
3#
4# Copyright (C) 2008 Panasas Inc. All rights reserved.
5#
6# Authors:
7# Boaz Harrosh <bharrosh@panasas.com>
8# Benny Halevy <bhalevy@panasas.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2
12#
13
14ifneq ($(OSD_INC),)
15# we are built out-of-tree Kconfigure everything as on
16
17CONFIG_SCSI_OSD_INITIATOR=m
18ccflags-y += -DCONFIG_SCSI_OSD_INITIATOR -DCONFIG_SCSI_OSD_INITIATOR_MODULE
19
20CONFIG_SCSI_OSD_ULD=m
21ccflags-y += -DCONFIG_SCSI_OSD_ULD -DCONFIG_SCSI_OSD_ULD_MODULE
22
23# CONFIG_SCSI_OSD_DPRINT_SENSE =
24# 0 - no print of errors
25# 1 - print errors
26# 2 - errors + warrnings
27ccflags-y += -DCONFIG_SCSI_OSD_DPRINT_SENSE=1
28
29# Uncomment to turn debug on
30# ccflags-y += -DCONFIG_SCSI_OSD_DEBUG
31
32# if we are built out-of-tree and the hosting kernel has OSD headers
33# then "ccflags-y +=" will not pick the out-off-tree headers. Only by doing
34# this it will work. This might break in future kernels
35LINUXINCLUDE := -I$(OSD_INC) $(LINUXINCLUDE)
36
37endif
38
39# libosd.ko - osd-initiator library
40libosd-y := osd_initiator.o
41obj-$(CONFIG_SCSI_OSD_INITIATOR) += libosd.o
42
43# osd.ko - SCSI ULD and char-device
44osd-y := osd_uld.o
45obj-$(CONFIG_SCSI_OSD_ULD) += osd.o
diff --git a/drivers/scsi/osd/Kconfig b/drivers/scsi/osd/Kconfig
new file mode 100644
index 000000000000..861b5cebaeae
--- /dev/null
+++ b/drivers/scsi/osd/Kconfig
@@ -0,0 +1,53 @@
1#
2# Kernel configuration file for the OSD scsi protocol
3#
4# Copyright (C) 2008 Panasas Inc. All rights reserved.
5#
6# Authors:
7# Boaz Harrosh <bharrosh@panasas.com>
8# Benny Halevy <bhalevy@panasas.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public version 2 License as
12# published by the Free Software Foundation
13#
14# FIXME: SCSI_OSD_INITIATOR should select CONFIG (HMAC) SHA1 somehow.
15# How is it done properly?
16#
17
18config SCSI_OSD_INITIATOR
19 tristate "OSD-Initiator library"
20 depends on SCSI
21 help
22 Enable the OSD-Initiator library (libosd.ko).
23 NOTE: You must also select CRYPTO_SHA1 + CRYPTO_HMAC and their
24 dependencies
25
26config SCSI_OSD_ULD
27 tristate "OSD Upper Level driver"
28 depends on SCSI_OSD_INITIATOR
29 help
30 Build a SCSI upper layer driver that exports /dev/osdX devices
31 to user-mode for testing and controlling OSD devices. It is also
32 needed by exofs, for mounting an OSD based file system.
33
34config SCSI_OSD_DPRINT_SENSE
35 int "(0-2) When sense is returned, DEBUG print all sense descriptors"
36 default 1
37 depends on SCSI_OSD_INITIATOR
38 help
39 When a CHECK_CONDITION status is returned from a target, and a
40 sense-buffer is retrieved, turning this on will dump a full
41 sense-decoding message. Setting to 2 will also print recoverable
42 errors that might be regularly returned for some filesystem
43 operations.
44
45config SCSI_OSD_DEBUG
46 bool "Compile All OSD modules with lots of DEBUG prints"
47 default n
48 depends on SCSI_OSD_INITIATOR
49 help
50 OSD Code is populated with lots of OSD_DEBUG(..) printouts to
51 dmesg. Enable this if you found a bug and you want to help us
52 track the problem (see also MAINTAINERS). Setting this will also
53 force SCSI_OSD_DPRINT_SENSE=2.
diff --git a/drivers/scsi/osd/Makefile b/drivers/scsi/osd/Makefile
new file mode 100755
index 000000000000..d905344f83ba
--- /dev/null
+++ b/drivers/scsi/osd/Makefile
@@ -0,0 +1,37 @@
1#
2# Makefile for the OSD modules (out of tree)
3#
4# Copyright (C) 2008 Panasas Inc. All rights reserved.
5#
6# Authors:
7# Boaz Harrosh <bharrosh@panasas.com>
8# Benny Halevy <bhalevy@panasas.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2
12#
13# This Makefile is used to call the kernel Makefile in case of an out-of-tree
14# build.
15# $KSRC should point to a Kernel source tree otherwise host's default is
16# used. (eg. /lib/modules/`uname -r`/build)
17
18# include path for out-of-tree Headers
19OSD_INC ?= `pwd`/../../../include
20
21# allow users to override these
22# e.g. to compile for a kernel that you aren't currently running
23KSRC ?= /lib/modules/$(shell uname -r)/build
24KBUILD_OUTPUT ?=
25ARCH ?=
26V ?= 0
27
28# this is the basic Kbuild out-of-tree invocation, with the M= option
29KBUILD_BASE = +$(MAKE) -C $(KSRC) M=`pwd` KBUILD_OUTPUT=$(KBUILD_OUTPUT) ARCH=$(ARCH) V=$(V)
30
31all: libosd
32
33libosd: ;
34 $(KBUILD_BASE) OSD_INC=$(OSD_INC) modules
35
36clean:
37 $(KBUILD_BASE) clean
diff --git a/drivers/scsi/osd/osd_debug.h b/drivers/scsi/osd/osd_debug.h
new file mode 100644
index 000000000000..579e491f11df
--- /dev/null
+++ b/drivers/scsi/osd/osd_debug.h
@@ -0,0 +1,30 @@
1/*
2 * osd_debug.h - Some kprintf macros
3 *
4 * Copyright (C) 2008 Panasas Inc. All rights reserved.
5 *
6 * Authors:
7 * Boaz Harrosh <bharrosh@panasas.com>
8 * Benny Halevy <bhalevy@panasas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 *
13 */
14#ifndef __OSD_DEBUG_H__
15#define __OSD_DEBUG_H__
16
17#define OSD_ERR(fmt, a...) printk(KERN_ERR "osd: " fmt, ##a)
18#define OSD_INFO(fmt, a...) printk(KERN_NOTICE "osd: " fmt, ##a)
19
20#ifdef CONFIG_SCSI_OSD_DEBUG
21#define OSD_DEBUG(fmt, a...) \
22 printk(KERN_NOTICE "osd @%s:%d: " fmt, __func__, __LINE__, ##a)
23#else
24#define OSD_DEBUG(fmt, a...) do {} while (0)
25#endif
26
27/* u64 has problems with printk this will cast it to unsigned long long */
28#define _LLU(x) (unsigned long long)(x)
29
30#endif /* ndef __OSD_DEBUG_H__ */
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
new file mode 100644
index 000000000000..552f58b655d1
--- /dev/null
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -0,0 +1,1657 @@
1/*
2 * osd_initiator - Main body of the osd initiator library.
3 *
4 * Note: The file does not contain the advanced security functionality which
5 * is only needed by the security_manager's initiators.
6 *
7 * Copyright (C) 2008 Panasas Inc. All rights reserved.
8 *
9 * Authors:
10 * Boaz Harrosh <bharrosh@panasas.com>
11 * Benny Halevy <bhalevy@panasas.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the Panasas company nor the names of its
26 * contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include <scsi/osd_initiator.h>
43#include <scsi/osd_sec.h>
44#include <scsi/osd_attributes.h>
45#include <scsi/osd_sense.h>
46
47#include <scsi/scsi_device.h>
48
49#include "osd_debug.h"
50
51#ifndef __unused
52# define __unused __attribute__((unused))
53#endif
54
55enum { OSD_REQ_RETRIES = 1 };
56
57MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
58MODULE_DESCRIPTION("open-osd initiator library libosd.ko");
59MODULE_LICENSE("GPL");
60
61static inline void build_test(void)
62{
63 /* structures were not packed */
64 BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN);
65 BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
66 BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
67}
68
69static const char *_osd_ver_desc(struct osd_request *or)
70{
71 return osd_req_is_ver1(or) ? "OSD1" : "OSD2";
72}
73
74#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
75
76static int _osd_print_system_info(struct osd_dev *od, void *caps)
77{
78 struct osd_request *or;
79 struct osd_attr get_attrs[] = {
80 ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8),
81 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16),
82 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32),
83 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4),
84 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/),
85 ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/),
86 ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8),
87 ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8),
88 ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8),
89 ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6),
90 /* IBM-OSD-SIM Has a bug with this one put it last */
91 ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20),
92 };
93 void *iter = NULL, *pFirst;
94 int nelem = ARRAY_SIZE(get_attrs), a = 0;
95 int ret;
96
97 or = osd_start_request(od, GFP_KERNEL);
98 if (!or)
99 return -ENOMEM;
100
101 /* get attrs */
102 osd_req_get_attributes(or, &osd_root_object);
103 osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs));
104
105 ret = osd_finalize_request(or, 0, caps, NULL);
106 if (ret)
107 goto out;
108
109 ret = osd_execute_request(or);
110 if (ret) {
111 OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret);
112 goto out;
113 }
114
115 osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter);
116
117 OSD_INFO("Detected %s device\n",
118 _osd_ver_desc(or));
119
120 pFirst = get_attrs[a++].val_ptr;
121 OSD_INFO("OSD_ATTR_RI_VENDOR_IDENTIFICATION [%s]\n",
122 (char *)pFirst);
123
124 pFirst = get_attrs[a++].val_ptr;
125 OSD_INFO("OSD_ATTR_RI_PRODUCT_IDENTIFICATION [%s]\n",
126 (char *)pFirst);
127
128 pFirst = get_attrs[a++].val_ptr;
129 OSD_INFO("OSD_ATTR_RI_PRODUCT_MODEL [%s]\n",
130 (char *)pFirst);
131
132 pFirst = get_attrs[a++].val_ptr;
133 OSD_INFO("OSD_ATTR_RI_PRODUCT_REVISION_LEVEL [%u]\n",
134 pFirst ? get_unaligned_be32(pFirst) : ~0U);
135
136 pFirst = get_attrs[a++].val_ptr;
137 OSD_INFO("OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER [%s]\n",
138 (char *)pFirst);
139
140 pFirst = get_attrs[a].val_ptr;
141 OSD_INFO("OSD_ATTR_RI_OSD_NAME [%s]\n", (char *)pFirst);
142 a++;
143
144 pFirst = get_attrs[a++].val_ptr;
145 OSD_INFO("OSD_ATTR_RI_TOTAL_CAPACITY [0x%llx]\n",
146 pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
147
148 pFirst = get_attrs[a++].val_ptr;
149 OSD_INFO("OSD_ATTR_RI_USED_CAPACITY [0x%llx]\n",
150 pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
151
152 pFirst = get_attrs[a++].val_ptr;
153 OSD_INFO("OSD_ATTR_RI_NUMBER_OF_PARTITIONS [%llu]\n",
154 pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
155
156 if (a >= nelem)
157 goto out;
158
159 /* FIXME: Where are the time utilities */
160 pFirst = get_attrs[a++].val_ptr;
161 OSD_INFO("OSD_ATTR_RI_CLOCK [0x%02x%02x%02x%02x%02x%02x]\n",
162 ((char *)pFirst)[0], ((char *)pFirst)[1],
163 ((char *)pFirst)[2], ((char *)pFirst)[3],
164 ((char *)pFirst)[4], ((char *)pFirst)[5]);
165
166 if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */
167 unsigned len = get_attrs[a].len;
168 char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */
169
170 hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1,
171 sid_dump, sizeof(sid_dump), true);
172 OSD_INFO("OSD_ATTR_RI_OSD_SYSTEM_ID(%d) [%s]\n", len, sid_dump);
173 a++;
174 }
175out:
176 osd_end_request(or);
177 return ret;
178}
179
180int osd_auto_detect_ver(struct osd_dev *od, void *caps)
181{
182 int ret;
183
184 /* Auto-detect the osd version */
185 ret = _osd_print_system_info(od, caps);
186 if (ret) {
187 osd_dev_set_ver(od, OSD_VER1);
188 OSD_DEBUG("converting to OSD1\n");
189 ret = _osd_print_system_info(od, caps);
190 }
191
192 return ret;
193}
194EXPORT_SYMBOL(osd_auto_detect_ver);
195
196static unsigned _osd_req_cdb_len(struct osd_request *or)
197{
198 return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN;
199}
200
201static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len)
202{
203 return osd_req_is_ver1(or) ?
204 osdv1_attr_list_elem_size(len) :
205 osdv2_attr_list_elem_size(len);
206}
207
208static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
209{
210 return osd_req_is_ver1(or) ?
211 osdv1_list_size(list_head) :
212 osdv2_list_size(list_head);
213}
214
215static unsigned _osd_req_sizeof_alist_header(struct osd_request *or)
216{
217 return osd_req_is_ver1(or) ?
218 sizeof(struct osdv1_attributes_list_header) :
219 sizeof(struct osdv2_attributes_list_header);
220}
221
222static void _osd_req_set_alist_type(struct osd_request *or,
223 void *list, int list_type)
224{
225 if (osd_req_is_ver1(or)) {
226 struct osdv1_attributes_list_header *attr_list = list;
227
228 memset(attr_list, 0, sizeof(*attr_list));
229 attr_list->type = list_type;
230 } else {
231 struct osdv2_attributes_list_header *attr_list = list;
232
233 memset(attr_list, 0, sizeof(*attr_list));
234 attr_list->type = list_type;
235 }
236}
237
238static bool _osd_req_is_alist_type(struct osd_request *or,
239 void *list, int list_type)
240{
241 if (!list)
242 return false;
243
244 if (osd_req_is_ver1(or)) {
245 struct osdv1_attributes_list_header *attr_list = list;
246
247 return attr_list->type == list_type;
248 } else {
249 struct osdv2_attributes_list_header *attr_list = list;
250
251 return attr_list->type == list_type;
252 }
253}
254
255/* This is for List-objects not Attributes-Lists */
256static void _osd_req_encode_olist(struct osd_request *or,
257 struct osd_obj_id_list *list)
258{
259 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
260
261 if (osd_req_is_ver1(or)) {
262 cdbh->v1.list_identifier = list->list_identifier;
263 cdbh->v1.start_address = list->continuation_id;
264 } else {
265 cdbh->v2.list_identifier = list->list_identifier;
266 cdbh->v2.start_address = list->continuation_id;
267 }
268}
269
270static osd_cdb_offset osd_req_encode_offset(struct osd_request *or,
271 u64 offset, unsigned *padding)
272{
273 return __osd_encode_offset(offset, padding,
274 osd_req_is_ver1(or) ?
275 OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT,
276 OSD_OFFSET_MAX_SHIFT);
277}
278
279static struct osd_security_parameters *
280_osd_req_sec_params(struct osd_request *or)
281{
282 struct osd_cdb *ocdb = &or->cdb;
283
284 if (osd_req_is_ver1(or))
285 return &ocdb->v1.sec_params;
286 else
287 return &ocdb->v2.sec_params;
288}
289
290void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
291{
292 memset(osdd, 0, sizeof(*osdd));
293 osdd->scsi_device = scsi_device;
294 osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT;
295#ifdef OSD_VER1_SUPPORT
296 osdd->version = OSD_VER2;
297#endif
298 /* TODO: Allocate pools for osd_request attributes ... */
299}
300EXPORT_SYMBOL(osd_dev_init);
301
302void osd_dev_fini(struct osd_dev *osdd)
303{
304 /* TODO: De-allocate pools */
305
306 osdd->scsi_device = NULL;
307}
308EXPORT_SYMBOL(osd_dev_fini);
309
310static struct osd_request *_osd_request_alloc(gfp_t gfp)
311{
312 struct osd_request *or;
313
314 /* TODO: Use mempool with one saved request */
315 or = kzalloc(sizeof(*or), gfp);
316 return or;
317}
318
319static void _osd_request_free(struct osd_request *or)
320{
321 kfree(or);
322}
323
324struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
325{
326 struct osd_request *or;
327
328 or = _osd_request_alloc(gfp);
329 if (!or)
330 return NULL;
331
332 or->osd_dev = dev;
333 or->alloc_flags = gfp;
334 or->timeout = dev->def_timeout;
335 or->retries = OSD_REQ_RETRIES;
336
337 return or;
338}
339EXPORT_SYMBOL(osd_start_request);
340
341/*
342 * If osd_finalize_request() was called but the request was not executed through
343 * the block layer, then we must release BIOs.
344 */
345static void _abort_unexecuted_bios(struct request *rq)
346{
347 struct bio *bio;
348
349 while ((bio = rq->bio) != NULL) {
350 rq->bio = bio->bi_next;
351 bio_endio(bio, 0);
352 }
353}
354
355static void _osd_free_seg(struct osd_request *or __unused,
356 struct _osd_req_data_segment *seg)
357{
358 if (!seg->buff || !seg->alloc_size)
359 return;
360
361 kfree(seg->buff);
362 seg->buff = NULL;
363 seg->alloc_size = 0;
364}
365
366void osd_end_request(struct osd_request *or)
367{
368 struct request *rq = or->request;
369
370 _osd_free_seg(or, &or->set_attr);
371 _osd_free_seg(or, &or->enc_get_attr);
372 _osd_free_seg(or, &or->get_attr);
373
374 if (rq) {
375 if (rq->next_rq) {
376 _abort_unexecuted_bios(rq->next_rq);
377 blk_put_request(rq->next_rq);
378 }
379
380 _abort_unexecuted_bios(rq);
381 blk_put_request(rq);
382 }
383 _osd_request_free(or);
384}
385EXPORT_SYMBOL(osd_end_request);
386
387int osd_execute_request(struct osd_request *or)
388{
389 return blk_execute_rq(or->request->q, NULL, or->request, 0);
390}
391EXPORT_SYMBOL(osd_execute_request);
392
393static void osd_request_async_done(struct request *req, int error)
394{
395 struct osd_request *or = req->end_io_data;
396
397 or->async_error = error;
398
399 if (error)
400 OSD_DEBUG("osd_request_async_done error recieved %d\n", error);
401
402 if (or->async_done)
403 or->async_done(or, or->async_private);
404 else
405 osd_end_request(or);
406}
407
408int osd_execute_request_async(struct osd_request *or,
409 osd_req_done_fn *done, void *private)
410{
411 or->request->end_io_data = or;
412 or->async_private = private;
413 or->async_done = done;
414
415 blk_execute_rq_nowait(or->request->q, NULL, or->request, 0,
416 osd_request_async_done);
417 return 0;
418}
419EXPORT_SYMBOL(osd_execute_request_async);
420
421u8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
422u8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
423
424static int _osd_realloc_seg(struct osd_request *or,
425 struct _osd_req_data_segment *seg, unsigned max_bytes)
426{
427 void *buff;
428
429 if (seg->alloc_size >= max_bytes)
430 return 0;
431
432 buff = krealloc(seg->buff, max_bytes, or->alloc_flags);
433 if (!buff) {
434 OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes,
435 seg->alloc_size);
436 return -ENOMEM;
437 }
438
439 memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size);
440 seg->buff = buff;
441 seg->alloc_size = max_bytes;
442 return 0;
443}
444
445static int _alloc_set_attr_list(struct osd_request *or,
446 const struct osd_attr *oa, unsigned nelem, unsigned add_bytes)
447{
448 unsigned total_bytes = add_bytes;
449
450 for (; nelem; --nelem, ++oa)
451 total_bytes += _osd_req_alist_elem_size(or, oa->len);
452
453 OSD_DEBUG("total_bytes=%d\n", total_bytes);
454 return _osd_realloc_seg(or, &or->set_attr, total_bytes);
455}
456
457static int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes)
458{
459 OSD_DEBUG("total_bytes=%d\n", max_bytes);
460 return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes);
461}
462
463static int _alloc_get_attr_list(struct osd_request *or)
464{
465 OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes);
466 return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes);
467}
468
469/*
470 * Common to all OSD commands
471 */
472
473static void _osdv1_req_encode_common(struct osd_request *or,
474 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
475{
476 struct osdv1_cdb *ocdb = &or->cdb.v1;
477
478 /*
479 * For speed, the commands
480 * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C
481 * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D
482 * are not supported here. Should pass zero and set after the call
483 */
484 act &= cpu_to_be16(~0x0080); /* V1 action code */
485
486 OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act));
487
488 ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
489 ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
490 ocdb->h.varlen_cdb.service_action = act;
491
492 ocdb->h.partition = cpu_to_be64(obj->partition);
493 ocdb->h.object = cpu_to_be64(obj->id);
494 ocdb->h.v1.length = cpu_to_be64(len);
495 ocdb->h.v1.start_address = cpu_to_be64(offset);
496}
497
498static void _osdv2_req_encode_common(struct osd_request *or,
499 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
500{
501 struct osdv2_cdb *ocdb = &or->cdb.v2;
502
503 OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act));
504
505 ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
506 ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
507 ocdb->h.varlen_cdb.service_action = act;
508
509 ocdb->h.partition = cpu_to_be64(obj->partition);
510 ocdb->h.object = cpu_to_be64(obj->id);
511 ocdb->h.v2.length = cpu_to_be64(len);
512 ocdb->h.v2.start_address = cpu_to_be64(offset);
513}
514
515static void _osd_req_encode_common(struct osd_request *or,
516 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
517{
518 if (osd_req_is_ver1(or))
519 _osdv1_req_encode_common(or, act, obj, offset, len);
520 else
521 _osdv2_req_encode_common(or, act, obj, offset, len);
522}
523
524/*
525 * Device commands
526 */
527/*TODO: void osd_req_set_master_seed_xchg(struct osd_request *, ...); */
528/*TODO: void osd_req_set_master_key(struct osd_request *, ...); */
529
530void osd_req_format(struct osd_request *or, u64 tot_capacity)
531{
532 _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0,
533 tot_capacity);
534}
535EXPORT_SYMBOL(osd_req_format);
536
537int osd_req_list_dev_partitions(struct osd_request *or,
538 osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem)
539{
540 return osd_req_list_partition_objects(or, 0, initial_id, list, nelem);
541}
542EXPORT_SYMBOL(osd_req_list_dev_partitions);
543
544static void _osd_req_encode_flush(struct osd_request *or,
545 enum osd_options_flush_scope_values op)
546{
547 struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb);
548
549 ocdb->command_specific_options = op;
550}
551
552void osd_req_flush_obsd(struct osd_request *or,
553 enum osd_options_flush_scope_values op)
554{
555 _osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0);
556 _osd_req_encode_flush(or, op);
557}
558EXPORT_SYMBOL(osd_req_flush_obsd);
559
560/*TODO: void osd_req_perform_scsi_command(struct osd_request *,
561 const u8 *cdb, ...); */
562/*TODO: void osd_req_task_management(struct osd_request *, ...); */
563
564/*
565 * Partition commands
566 */
567static void _osd_req_encode_partition(struct osd_request *or,
568 __be16 act, osd_id partition)
569{
570 struct osd_obj_id par = {
571 .partition = partition,
572 .id = 0,
573 };
574
575 _osd_req_encode_common(or, act, &par, 0, 0);
576}
577
578void osd_req_create_partition(struct osd_request *or, osd_id partition)
579{
580 _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition);
581}
582EXPORT_SYMBOL(osd_req_create_partition);
583
584void osd_req_remove_partition(struct osd_request *or, osd_id partition)
585{
586 _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition);
587}
588EXPORT_SYMBOL(osd_req_remove_partition);
589
590/*TODO: void osd_req_set_partition_key(struct osd_request *,
591 osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
592 u8 seed[OSD_CRYPTO_SEED_SIZE]); */
593
594static int _osd_req_list_objects(struct osd_request *or,
595 __be16 action, const struct osd_obj_id *obj, osd_id initial_id,
596 struct osd_obj_id_list *list, unsigned nelem)
597{
598 struct request_queue *q = or->osd_dev->scsi_device->request_queue;
599 u64 len = nelem * sizeof(osd_id) + sizeof(*list);
600 struct bio *bio;
601
602 _osd_req_encode_common(or, action, obj, (u64)initial_id, len);
603
604 if (list->list_identifier)
605 _osd_req_encode_olist(or, list);
606
607 WARN_ON(or->in.bio);
608 bio = bio_map_kern(q, list, len, or->alloc_flags);
609 if (!bio) {
610 OSD_ERR("!!! Failed to allocate list_objects BIO\n");
611 return -ENOMEM;
612 }
613
614 bio->bi_rw &= ~(1 << BIO_RW);
615 or->in.bio = bio;
616 or->in.total_bytes = bio->bi_size;
617 return 0;
618}
619
620int osd_req_list_partition_collections(struct osd_request *or,
621 osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
622 unsigned nelem)
623{
624 struct osd_obj_id par = {
625 .partition = partition,
626 .id = 0,
627 };
628
629 return osd_req_list_collection_objects(or, &par, initial_id, list,
630 nelem);
631}
632EXPORT_SYMBOL(osd_req_list_partition_collections);
633
634int osd_req_list_partition_objects(struct osd_request *or,
635 osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
636 unsigned nelem)
637{
638 struct osd_obj_id par = {
639 .partition = partition,
640 .id = 0,
641 };
642
643 return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list,
644 nelem);
645}
646EXPORT_SYMBOL(osd_req_list_partition_objects);
647
648void osd_req_flush_partition(struct osd_request *or,
649 osd_id partition, enum osd_options_flush_scope_values op)
650{
651 _osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition);
652 _osd_req_encode_flush(or, op);
653}
654EXPORT_SYMBOL(osd_req_flush_partition);
655
656/*
657 * Collection commands
658 */
659/*TODO: void osd_req_create_collection(struct osd_request *,
660 const struct osd_obj_id *); */
661/*TODO: void osd_req_remove_collection(struct osd_request *,
662 const struct osd_obj_id *); */
663
664int osd_req_list_collection_objects(struct osd_request *or,
665 const struct osd_obj_id *obj, osd_id initial_id,
666 struct osd_obj_id_list *list, unsigned nelem)
667{
668 return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj,
669 initial_id, list, nelem);
670}
671EXPORT_SYMBOL(osd_req_list_collection_objects);
672
673/*TODO: void query(struct osd_request *, ...); V2 */
674
675void osd_req_flush_collection(struct osd_request *or,
676 const struct osd_obj_id *obj, enum osd_options_flush_scope_values op)
677{
678 _osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0);
679 _osd_req_encode_flush(or, op);
680}
681EXPORT_SYMBOL(osd_req_flush_collection);
682
683/*TODO: void get_member_attrs(struct osd_request *, ...); V2 */
684/*TODO: void set_member_attrs(struct osd_request *, ...); V2 */
685
686/*
687 * Object commands
688 */
689void osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj)
690{
691 _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0);
692}
693EXPORT_SYMBOL(osd_req_create_object);
694
695void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj)
696{
697 _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0);
698}
699EXPORT_SYMBOL(osd_req_remove_object);
700
701
702/*TODO: void osd_req_create_multi(struct osd_request *or,
703 struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem);
704*/
705
706void osd_req_write(struct osd_request *or,
707 const struct osd_obj_id *obj, struct bio *bio, u64 offset)
708{
709 _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, bio->bi_size);
710 WARN_ON(or->out.bio || or->out.total_bytes);
711 bio->bi_rw |= (1 << BIO_RW);
712 or->out.bio = bio;
713 or->out.total_bytes = bio->bi_size;
714}
715EXPORT_SYMBOL(osd_req_write);
716
717/*TODO: void osd_req_append(struct osd_request *,
718 const struct osd_obj_id *, struct bio *data_out); */
719/*TODO: void osd_req_create_write(struct osd_request *,
720 const struct osd_obj_id *, struct bio *data_out, u64 offset); */
721/*TODO: void osd_req_clear(struct osd_request *,
722 const struct osd_obj_id *, u64 offset, u64 len); */
723/*TODO: void osd_req_punch(struct osd_request *,
724 const struct osd_obj_id *, u64 offset, u64 len); V2 */
725
726void osd_req_flush_object(struct osd_request *or,
727 const struct osd_obj_id *obj, enum osd_options_flush_scope_values op,
728 /*V2*/ u64 offset, /*V2*/ u64 len)
729{
730 if (unlikely(osd_req_is_ver1(or) && (offset || len))) {
731 OSD_DEBUG("OSD Ver1 flush on specific range ignored\n");
732 offset = 0;
733 len = 0;
734 }
735
736 _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len);
737 _osd_req_encode_flush(or, op);
738}
739EXPORT_SYMBOL(osd_req_flush_object);
740
741void osd_req_read(struct osd_request *or,
742 const struct osd_obj_id *obj, struct bio *bio, u64 offset)
743{
744 _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, bio->bi_size);
745 WARN_ON(or->in.bio || or->in.total_bytes);
746 bio->bi_rw &= ~(1 << BIO_RW);
747 or->in.bio = bio;
748 or->in.total_bytes = bio->bi_size;
749}
750EXPORT_SYMBOL(osd_req_read);
751
752void osd_req_get_attributes(struct osd_request *or,
753 const struct osd_obj_id *obj)
754{
755 _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0);
756}
757EXPORT_SYMBOL(osd_req_get_attributes);
758
759void osd_req_set_attributes(struct osd_request *or,
760 const struct osd_obj_id *obj)
761{
762 _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0);
763}
764EXPORT_SYMBOL(osd_req_set_attributes);
765
766/*
767 * Attributes List-mode
768 */
769
770int osd_req_add_set_attr_list(struct osd_request *or,
771 const struct osd_attr *oa, unsigned nelem)
772{
773 unsigned total_bytes = or->set_attr.total_bytes;
774 void *attr_last;
775 int ret;
776
777 if (or->attributes_mode &&
778 or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
779 WARN_ON(1);
780 return -EINVAL;
781 }
782 or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
783
784 if (!total_bytes) { /* first-time: allocate and put list header */
785 total_bytes = _osd_req_sizeof_alist_header(or);
786 ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
787 if (ret)
788 return ret;
789 _osd_req_set_alist_type(or, or->set_attr.buff,
790 OSD_ATTR_LIST_SET_RETRIEVE);
791 }
792 attr_last = or->set_attr.buff + total_bytes;
793
794 for (; nelem; --nelem) {
795 struct osd_attributes_list_element *attr;
796 unsigned elem_size = _osd_req_alist_elem_size(or, oa->len);
797
798 total_bytes += elem_size;
799 if (unlikely(or->set_attr.alloc_size < total_bytes)) {
800 or->set_attr.total_bytes = total_bytes - elem_size;
801 ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
802 if (ret)
803 return ret;
804 attr_last =
805 or->set_attr.buff + or->set_attr.total_bytes;
806 }
807
808 attr = attr_last;
809 attr->attr_page = cpu_to_be32(oa->attr_page);
810 attr->attr_id = cpu_to_be32(oa->attr_id);
811 attr->attr_bytes = cpu_to_be16(oa->len);
812 memcpy(attr->attr_val, oa->val_ptr, oa->len);
813
814 attr_last += elem_size;
815 ++oa;
816 }
817
818 or->set_attr.total_bytes = total_bytes;
819 return 0;
820}
821EXPORT_SYMBOL(osd_req_add_set_attr_list);
822
823static int _append_map_kern(struct request *req,
824 void *buff, unsigned len, gfp_t flags)
825{
826 struct bio *bio;
827 int ret;
828
829 bio = bio_map_kern(req->q, buff, len, flags);
830 if (IS_ERR(bio)) {
831 OSD_ERR("Failed bio_map_kern(%p, %d) => %ld\n", buff, len,
832 PTR_ERR(bio));
833 return PTR_ERR(bio);
834 }
835 ret = blk_rq_append_bio(req->q, req, bio);
836 if (ret) {
837 OSD_ERR("Failed blk_rq_append_bio(%p) => %d\n", bio, ret);
838 bio_put(bio);
839 }
840 return ret;
841}
842
843static int _req_append_segment(struct osd_request *or,
844 unsigned padding, struct _osd_req_data_segment *seg,
845 struct _osd_req_data_segment *last_seg, struct _osd_io_info *io)
846{
847 void *pad_buff;
848 int ret;
849
850 if (padding) {
851 /* check if we can just add it to last buffer */
852 if (last_seg &&
853 (padding <= last_seg->alloc_size - last_seg->total_bytes))
854 pad_buff = last_seg->buff + last_seg->total_bytes;
855 else
856 pad_buff = io->pad_buff;
857
858 ret = _append_map_kern(io->req, pad_buff, padding,
859 or->alloc_flags);
860 if (ret)
861 return ret;
862 io->total_bytes += padding;
863 }
864
865 ret = _append_map_kern(io->req, seg->buff, seg->total_bytes,
866 or->alloc_flags);
867 if (ret)
868 return ret;
869
870 io->total_bytes += seg->total_bytes;
871 OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff,
872 seg->total_bytes);
873 return 0;
874}
875
876static int _osd_req_finalize_set_attr_list(struct osd_request *or)
877{
878 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
879 unsigned padding;
880 int ret;
881
882 if (!or->set_attr.total_bytes) {
883 cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED;
884 return 0;
885 }
886
887 cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes);
888 cdbh->attrs_list.set_attr_offset =
889 osd_req_encode_offset(or, or->out.total_bytes, &padding);
890
891 ret = _req_append_segment(or, padding, &or->set_attr,
892 or->out.last_seg, &or->out);
893 if (ret)
894 return ret;
895
896 or->out.last_seg = &or->set_attr;
897 return 0;
898}
899
900int osd_req_add_get_attr_list(struct osd_request *or,
901 const struct osd_attr *oa, unsigned nelem)
902{
903 unsigned total_bytes = or->enc_get_attr.total_bytes;
904 void *attr_last;
905 int ret;
906
907 if (or->attributes_mode &&
908 or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
909 WARN_ON(1);
910 return -EINVAL;
911 }
912 or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
913
914 /* first time calc data-in list header size */
915 if (!or->get_attr.total_bytes)
916 or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or);
917
918 /* calc data-out info */
919 if (!total_bytes) { /* first-time: allocate and put list header */
920 unsigned max_bytes;
921
922 total_bytes = _osd_req_sizeof_alist_header(or);
923 max_bytes = total_bytes +
924 nelem * sizeof(struct osd_attributes_list_attrid);
925 ret = _alloc_get_attr_desc(or, max_bytes);
926 if (ret)
927 return ret;
928
929 _osd_req_set_alist_type(or, or->enc_get_attr.buff,
930 OSD_ATTR_LIST_GET);
931 }
932 attr_last = or->enc_get_attr.buff + total_bytes;
933
934 for (; nelem; --nelem) {
935 struct osd_attributes_list_attrid *attrid;
936 const unsigned cur_size = sizeof(*attrid);
937
938 total_bytes += cur_size;
939 if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) {
940 or->enc_get_attr.total_bytes = total_bytes - cur_size;
941 ret = _alloc_get_attr_desc(or,
942 total_bytes + nelem * sizeof(*attrid));
943 if (ret)
944 return ret;
945 attr_last = or->enc_get_attr.buff +
946 or->enc_get_attr.total_bytes;
947 }
948
949 attrid = attr_last;
950 attrid->attr_page = cpu_to_be32(oa->attr_page);
951 attrid->attr_id = cpu_to_be32(oa->attr_id);
952
953 attr_last += cur_size;
954
955 /* calc data-in size */
956 or->get_attr.total_bytes +=
957 _osd_req_alist_elem_size(or, oa->len);
958 ++oa;
959 }
960
961 or->enc_get_attr.total_bytes = total_bytes;
962
963 OSD_DEBUG(
964 "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n",
965 or->get_attr.total_bytes,
966 or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or),
967 or->enc_get_attr.total_bytes,
968 (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or))
969 / sizeof(struct osd_attributes_list_attrid));
970
971 return 0;
972}
973EXPORT_SYMBOL(osd_req_add_get_attr_list);
974
975static int _osd_req_finalize_get_attr_list(struct osd_request *or)
976{
977 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
978 unsigned out_padding;
979 unsigned in_padding;
980 int ret;
981
982 if (!or->enc_get_attr.total_bytes) {
983 cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED;
984 cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED;
985 return 0;
986 }
987
988 ret = _alloc_get_attr_list(or);
989 if (ret)
990 return ret;
991
992 /* The out-going buffer info update */
993 OSD_DEBUG("out-going\n");
994 cdbh->attrs_list.get_attr_desc_bytes =
995 cpu_to_be32(or->enc_get_attr.total_bytes);
996
997 cdbh->attrs_list.get_attr_desc_offset =
998 osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
999
1000 ret = _req_append_segment(or, out_padding, &or->enc_get_attr,
1001 or->out.last_seg, &or->out);
1002 if (ret)
1003 return ret;
1004 or->out.last_seg = &or->enc_get_attr;
1005
1006 /* The incoming buffer info update */
1007 OSD_DEBUG("in-coming\n");
1008 cdbh->attrs_list.get_attr_alloc_length =
1009 cpu_to_be32(or->get_attr.total_bytes);
1010
1011 cdbh->attrs_list.get_attr_offset =
1012 osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
1013
1014 ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
1015 &or->in);
1016 if (ret)
1017 return ret;
1018 or->in.last_seg = &or->get_attr;
1019
1020 return 0;
1021}
1022
1023int osd_req_decode_get_attr_list(struct osd_request *or,
1024 struct osd_attr *oa, int *nelem, void **iterator)
1025{
1026 unsigned cur_bytes, returned_bytes;
1027 int n;
1028 const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or);
1029 void *cur_p;
1030
1031 if (!_osd_req_is_alist_type(or, or->get_attr.buff,
1032 OSD_ATTR_LIST_SET_RETRIEVE)) {
1033 oa->attr_page = 0;
1034 oa->attr_id = 0;
1035 oa->val_ptr = NULL;
1036 oa->len = 0;
1037 *iterator = NULL;
1038 return 0;
1039 }
1040
1041 if (*iterator) {
1042 BUG_ON((*iterator < or->get_attr.buff) ||
1043 (or->get_attr.buff + or->get_attr.alloc_size < *iterator));
1044 cur_p = *iterator;
1045 cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list;
1046 returned_bytes = or->get_attr.total_bytes;
1047 } else { /* first time decode the list header */
1048 cur_bytes = sizeof_attr_list;
1049 returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) +
1050 sizeof_attr_list;
1051
1052 cur_p = or->get_attr.buff + sizeof_attr_list;
1053
1054 if (returned_bytes > or->get_attr.alloc_size) {
1055 OSD_DEBUG("target report: space was not big enough! "
1056 "Allocate=%u Needed=%u\n",
1057 or->get_attr.alloc_size,
1058 returned_bytes + sizeof_attr_list);
1059
1060 returned_bytes =
1061 or->get_attr.alloc_size - sizeof_attr_list;
1062 }
1063 or->get_attr.total_bytes = returned_bytes;
1064 }
1065
1066 for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) {
1067 struct osd_attributes_list_element *attr = cur_p;
1068 unsigned inc;
1069
1070 oa->len = be16_to_cpu(attr->attr_bytes);
1071 inc = _osd_req_alist_elem_size(or, oa->len);
1072 OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n",
1073 oa->len, inc, cur_bytes);
1074 cur_bytes += inc;
1075 if (cur_bytes > returned_bytes) {
1076 OSD_ERR("BAD FOOD from target. list not valid!"
1077 "c=%d r=%d n=%d\n",
1078 cur_bytes, returned_bytes, n);
1079 oa->val_ptr = NULL;
1080 break;
1081 }
1082
1083 oa->attr_page = be32_to_cpu(attr->attr_page);
1084 oa->attr_id = be32_to_cpu(attr->attr_id);
1085 oa->val_ptr = attr->attr_val;
1086
1087 cur_p += inc;
1088 ++oa;
1089 }
1090
1091 *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL;
1092 *nelem = n;
1093 return returned_bytes - cur_bytes;
1094}
1095EXPORT_SYMBOL(osd_req_decode_get_attr_list);
1096
1097/*
1098 * Attributes Page-mode
1099 */
1100
1101int osd_req_add_get_attr_page(struct osd_request *or,
1102 u32 page_id, void *attar_page, unsigned max_page_len,
1103 const struct osd_attr *set_one_attr)
1104{
1105 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
1106
1107 if (or->attributes_mode &&
1108 or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
1109 WARN_ON(1);
1110 return -EINVAL;
1111 }
1112 or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE;
1113
1114 or->get_attr.buff = attar_page;
1115 or->get_attr.total_bytes = max_page_len;
1116
1117 or->set_attr.buff = set_one_attr->val_ptr;
1118 or->set_attr.total_bytes = set_one_attr->len;
1119
1120 cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id);
1121 cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len);
1122 /* ocdb->attrs_page.get_attr_offset; */
1123
1124 cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page);
1125 cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id);
1126 cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len);
1127 /* ocdb->attrs_page.set_attr_offset; */
1128 return 0;
1129}
1130EXPORT_SYMBOL(osd_req_add_get_attr_page);
1131
1132static int _osd_req_finalize_attr_page(struct osd_request *or)
1133{
1134 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
1135 unsigned in_padding, out_padding;
1136 int ret;
1137
1138 /* returned page */
1139 cdbh->attrs_page.get_attr_offset =
1140 osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
1141
1142 ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
1143 &or->in);
1144 if (ret)
1145 return ret;
1146
1147 /* set one value */
1148 cdbh->attrs_page.set_attr_offset =
1149 osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
1150
1151 ret = _req_append_segment(or, out_padding, &or->enc_get_attr, NULL,
1152 &or->out);
1153 return ret;
1154}
1155
1156static int _osd_req_finalize_data_integrity(struct osd_request *or,
1157 bool has_in, bool has_out, const u8 *cap_key)
1158{
1159 struct osd_security_parameters *sec_parms = _osd_req_sec_params(or);
1160 int ret;
1161
1162 if (!osd_is_sec_alldata(sec_parms))
1163 return 0;
1164
1165 if (has_out) {
1166 struct _osd_req_data_segment seg = {
1167 .buff = &or->out_data_integ,
1168 .total_bytes = sizeof(or->out_data_integ),
1169 };
1170 unsigned pad;
1171
1172 or->out_data_integ.data_bytes = cpu_to_be64(
1173 or->out.bio ? or->out.bio->bi_size : 0);
1174 or->out_data_integ.set_attributes_bytes = cpu_to_be64(
1175 or->set_attr.total_bytes);
1176 or->out_data_integ.get_attributes_bytes = cpu_to_be64(
1177 or->enc_get_attr.total_bytes);
1178
1179 sec_parms->data_out_integrity_check_offset =
1180 osd_req_encode_offset(or, or->out.total_bytes, &pad);
1181
1182 ret = _req_append_segment(or, pad, &seg, or->out.last_seg,
1183 &or->out);
1184 if (ret)
1185 return ret;
1186 or->out.last_seg = NULL;
1187
1188 /* they are now all chained to request sign them all together */
1189 osd_sec_sign_data(&or->out_data_integ, or->out.req->bio,
1190 cap_key);
1191 }
1192
1193 if (has_in) {
1194 struct _osd_req_data_segment seg = {
1195 .buff = &or->in_data_integ,
1196 .total_bytes = sizeof(or->in_data_integ),
1197 };
1198 unsigned pad;
1199
1200 sec_parms->data_in_integrity_check_offset =
1201 osd_req_encode_offset(or, or->in.total_bytes, &pad);
1202
1203 ret = _req_append_segment(or, pad, &seg, or->in.last_seg,
1204 &or->in);
1205 if (ret)
1206 return ret;
1207
1208 or->in.last_seg = NULL;
1209 }
1210
1211 return 0;
1212}
1213
1214/*
1215 * osd_finalize_request and helpers
1216 */
1217
1218static int _init_blk_request(struct osd_request *or,
1219 bool has_in, bool has_out)
1220{
1221 gfp_t flags = or->alloc_flags;
1222 struct scsi_device *scsi_device = or->osd_dev->scsi_device;
1223 struct request_queue *q = scsi_device->request_queue;
1224 struct request *req;
1225 int ret = -ENOMEM;
1226
1227 req = blk_get_request(q, has_out, flags);
1228 if (!req)
1229 goto out;
1230
1231 or->request = req;
1232 req->cmd_type = REQ_TYPE_BLOCK_PC;
1233 req->timeout = or->timeout;
1234 req->retries = or->retries;
1235 req->sense = or->sense;
1236 req->sense_len = 0;
1237
1238 if (has_out) {
1239 or->out.req = req;
1240 if (has_in) {
1241 /* allocate bidi request */
1242 req = blk_get_request(q, READ, flags);
1243 if (!req) {
1244 OSD_DEBUG("blk_get_request for bidi failed\n");
1245 goto out;
1246 }
1247 req->cmd_type = REQ_TYPE_BLOCK_PC;
1248 or->in.req = or->request->next_rq = req;
1249 }
1250 } else if (has_in)
1251 or->in.req = req;
1252
1253 ret = 0;
1254out:
1255 OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n",
1256 or, has_in, has_out, ret, or->request);
1257 return ret;
1258}
1259
1260int osd_finalize_request(struct osd_request *or,
1261 u8 options, const void *cap, const u8 *cap_key)
1262{
1263 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
1264 bool has_in, has_out;
1265 int ret;
1266
1267 if (options & OSD_REQ_FUA)
1268 cdbh->options |= OSD_CDB_FUA;
1269
1270 if (options & OSD_REQ_DPO)
1271 cdbh->options |= OSD_CDB_DPO;
1272
1273 if (options & OSD_REQ_BYPASS_TIMESTAMPS)
1274 cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS;
1275
1276 osd_set_caps(&or->cdb, cap);
1277
1278 has_in = or->in.bio || or->get_attr.total_bytes;
1279 has_out = or->out.bio || or->set_attr.total_bytes ||
1280 or->enc_get_attr.total_bytes;
1281
1282 ret = _init_blk_request(or, has_in, has_out);
1283 if (ret) {
1284 OSD_DEBUG("_init_blk_request failed\n");
1285 return ret;
1286 }
1287
1288 if (or->out.bio) {
1289 ret = blk_rq_append_bio(or->request->q, or->out.req,
1290 or->out.bio);
1291 if (ret) {
1292 OSD_DEBUG("blk_rq_append_bio out failed\n");
1293 return ret;
1294 }
1295 OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n",
1296 _LLU(or->out.total_bytes), or->out.req->data_len);
1297 }
1298 if (or->in.bio) {
1299 ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio);
1300 if (ret) {
1301 OSD_DEBUG("blk_rq_append_bio in failed\n");
1302 return ret;
1303 }
1304 OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n",
1305 _LLU(or->in.total_bytes), or->in.req->data_len);
1306 }
1307
1308 or->out.pad_buff = sg_out_pad_buffer;
1309 or->in.pad_buff = sg_in_pad_buffer;
1310
1311 if (!or->attributes_mode)
1312 or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
1313 cdbh->command_specific_options |= or->attributes_mode;
1314 if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
1315 ret = _osd_req_finalize_attr_page(or);
1316 } else {
1317 /* TODO: I think that for the GET_ATTR command these 2 should
1318 * be reversed to keep them in execution order (for embeded
1319 * targets with low memory footprint)
1320 */
1321 ret = _osd_req_finalize_set_attr_list(or);
1322 if (ret) {
1323 OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n");
1324 return ret;
1325 }
1326
1327 ret = _osd_req_finalize_get_attr_list(or);
1328 if (ret) {
1329 OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n");
1330 return ret;
1331 }
1332 }
1333
1334 ret = _osd_req_finalize_data_integrity(or, has_in, has_out, cap_key);
1335 if (ret)
1336 return ret;
1337
1338 osd_sec_sign_cdb(&or->cdb, cap_key);
1339
1340 or->request->cmd = or->cdb.buff;
1341 or->request->cmd_len = _osd_req_cdb_len(or);
1342
1343 return 0;
1344}
1345EXPORT_SYMBOL(osd_finalize_request);
1346
1347#define OSD_SENSE_PRINT1(fmt, a...) \
1348 do { \
1349 if (__cur_sense_need_output) \
1350 OSD_ERR(fmt, ##a); \
1351 } while (0)
1352
1353#define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1(" " fmt, ##a)
1354
1355int osd_req_decode_sense_full(struct osd_request *or,
1356 struct osd_sense_info *osi, bool silent,
1357 struct osd_obj_id *bad_obj_list __unused, int max_obj __unused,
1358 struct osd_attr *bad_attr_list, int max_attr)
1359{
1360 int sense_len, original_sense_len;
1361 struct osd_sense_info local_osi;
1362 struct scsi_sense_descriptor_based *ssdb;
1363 void *cur_descriptor;
1364#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0)
1365 const bool __cur_sense_need_output = false;
1366#else
1367 bool __cur_sense_need_output = !silent;
1368#endif
1369
1370 if (!or->request->errors)
1371 return 0;
1372
1373 ssdb = or->request->sense;
1374 sense_len = or->request->sense_len;
1375 if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) {
1376 OSD_ERR("Block-layer returned error(0x%x) but "
1377 "sense_len(%u) || key(%d) is empty\n",
1378 or->request->errors, sense_len, ssdb->sense_key);
1379 return -EIO;
1380 }
1381
1382 if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) {
1383 OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n",
1384 ssdb->response_code, sense_len);
1385 return -EIO;
1386 }
1387
1388 osi = osi ? : &local_osi;
1389 memset(osi, 0, sizeof(*osi));
1390 osi->key = ssdb->sense_key;
1391 osi->additional_code = be16_to_cpu(ssdb->additional_sense_code);
1392 original_sense_len = ssdb->additional_sense_length + 8;
1393
1394#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1)
1395 if (__cur_sense_need_output)
1396 __cur_sense_need_output = (osi->key > scsi_sk_recovered_error);
1397#endif
1398 OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) "
1399 "additional_code=0x%x\n",
1400 osi->key, original_sense_len, sense_len,
1401 osi->additional_code);
1402
1403 if (original_sense_len < sense_len)
1404 sense_len = original_sense_len;
1405
1406 cur_descriptor = ssdb->ssd;
1407 sense_len -= sizeof(*ssdb);
1408 while (sense_len > 0) {
1409 struct scsi_sense_descriptor *ssd = cur_descriptor;
1410 int cur_len = ssd->additional_length + 2;
1411
1412 sense_len -= cur_len;
1413
1414 if (sense_len < 0)
1415 break; /* sense was truncated */
1416
1417 switch (ssd->descriptor_type) {
1418 case scsi_sense_information:
1419 case scsi_sense_command_specific_information:
1420 {
1421 struct scsi_sense_command_specific_data_descriptor
1422 *sscd = cur_descriptor;
1423
1424 osi->command_info =
1425 get_unaligned_be64(&sscd->information) ;
1426 OSD_SENSE_PRINT2(
1427 "command_specific_information 0x%llx \n",
1428 _LLU(osi->command_info));
1429 break;
1430 }
1431 case scsi_sense_key_specific:
1432 {
1433 struct scsi_sense_key_specific_data_descriptor
1434 *ssks = cur_descriptor;
1435
1436 osi->sense_info = get_unaligned_be16(&ssks->value);
1437 OSD_SENSE_PRINT2(
1438 "sense_key_specific_information %u"
1439 "sksv_cd_bpv_bp (0x%x)\n",
1440 osi->sense_info, ssks->sksv_cd_bpv_bp);
1441 break;
1442 }
1443 case osd_sense_object_identification:
1444 { /*FIXME: Keep first not last, Store in array*/
1445 struct osd_sense_identification_data_descriptor
1446 *osidd = cur_descriptor;
1447
1448 osi->not_initiated_command_functions =
1449 le32_to_cpu(osidd->not_initiated_functions);
1450 osi->completed_command_functions =
1451 le32_to_cpu(osidd->completed_functions);
1452 osi->obj.partition = be64_to_cpu(osidd->partition_id);
1453 osi->obj.id = be64_to_cpu(osidd->object_id);
1454 OSD_SENSE_PRINT2(
1455 "object_identification pid=0x%llx oid=0x%llx\n",
1456 _LLU(osi->obj.partition), _LLU(osi->obj.id));
1457 OSD_SENSE_PRINT2(
1458 "not_initiated_bits(%x) "
1459 "completed_command_bits(%x)\n",
1460 osi->not_initiated_command_functions,
1461 osi->completed_command_functions);
1462 break;
1463 }
1464 case osd_sense_response_integrity_check:
1465 {
1466 struct osd_sense_response_integrity_check_descriptor
1467 *osricd = cur_descriptor;
1468 const unsigned len =
1469 sizeof(osricd->integrity_check_value);
1470 char key_dump[len*4 + 2]; /* 2nibbles+space+ASCII */
1471
1472 hex_dump_to_buffer(osricd->integrity_check_value, len,
1473 32, 1, key_dump, sizeof(key_dump), true);
1474 OSD_SENSE_PRINT2("response_integrity [%s]\n", key_dump);
1475 }
1476 case osd_sense_attribute_identification:
1477 {
1478 struct osd_sense_attributes_data_descriptor
1479 *osadd = cur_descriptor;
1480 int len = min(cur_len, sense_len);
1481 int i = 0;
1482 struct osd_sense_attr *pattr = osadd->sense_attrs;
1483
1484 while (len < 0) {
1485 u32 attr_page = be32_to_cpu(pattr->attr_page);
1486 u32 attr_id = be32_to_cpu(pattr->attr_id);
1487
1488 if (i++ == 0) {
1489 osi->attr.attr_page = attr_page;
1490 osi->attr.attr_id = attr_id;
1491 }
1492
1493 if (bad_attr_list && max_attr) {
1494 bad_attr_list->attr_page = attr_page;
1495 bad_attr_list->attr_id = attr_id;
1496 bad_attr_list++;
1497 max_attr--;
1498 }
1499 OSD_SENSE_PRINT2(
1500 "osd_sense_attribute_identification"
1501 "attr_page=0x%x attr_id=0x%x\n",
1502 attr_page, attr_id);
1503 }
1504 }
1505 /*These are not legal for OSD*/
1506 case scsi_sense_field_replaceable_unit:
1507 OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n");
1508 break;
1509 case scsi_sense_stream_commands:
1510 OSD_SENSE_PRINT2("scsi_sense_stream_commands\n");
1511 break;
1512 case scsi_sense_block_commands:
1513 OSD_SENSE_PRINT2("scsi_sense_block_commands\n");
1514 break;
1515 case scsi_sense_ata_return:
1516 OSD_SENSE_PRINT2("scsi_sense_ata_return\n");
1517 break;
1518 default:
1519 if (ssd->descriptor_type <= scsi_sense_Reserved_last)
1520 OSD_SENSE_PRINT2(
1521 "scsi_sense Reserved descriptor (0x%x)",
1522 ssd->descriptor_type);
1523 else
1524 OSD_SENSE_PRINT2(
1525 "scsi_sense Vendor descriptor (0x%x)",
1526 ssd->descriptor_type);
1527 }
1528
1529 cur_descriptor += cur_len;
1530 }
1531
1532 return (osi->key > scsi_sk_recovered_error) ? -EIO : 0;
1533}
1534EXPORT_SYMBOL(osd_req_decode_sense_full);
1535
1536/*
1537 * Implementation of osd_sec.h API
1538 * TODO: Move to a separate osd_sec.c file at a later stage.
1539 */
1540
1541enum { OSD_SEC_CAP_V1_ALL_CAPS =
1542 OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE |
1543 OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR |
1544 OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC |
1545 OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT
1546};
1547
1548enum { OSD_SEC_CAP_V2_ALL_CAPS =
1549 OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT
1550};
1551
1552void osd_sec_init_nosec_doall_caps(void *caps,
1553 const struct osd_obj_id *obj, bool is_collection, const bool is_v1)
1554{
1555 struct osd_capability *cap = caps;
1556 u8 type;
1557 u8 descriptor_type;
1558
1559 if (likely(obj->id)) {
1560 if (unlikely(is_collection)) {
1561 type = OSD_SEC_OBJ_COLLECTION;
1562 descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ :
1563 OSD_SEC_OBJ_DESC_COL;
1564 } else {
1565 type = OSD_SEC_OBJ_USER;
1566 descriptor_type = OSD_SEC_OBJ_DESC_OBJ;
1567 }
1568 WARN_ON(!obj->partition);
1569 } else {
1570 type = obj->partition ? OSD_SEC_OBJ_PARTITION :
1571 OSD_SEC_OBJ_ROOT;
1572 descriptor_type = OSD_SEC_OBJ_DESC_PAR;
1573 }
1574
1575 memset(cap, 0, sizeof(*cap));
1576
1577 cap->h.format = OSD_SEC_CAP_FORMAT_VER1;
1578 cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */
1579 cap->h.security_method = OSD_SEC_NOSEC;
1580/* cap->expiration_time;
1581 cap->AUDIT[30-10];
1582 cap->discriminator[42-30];
1583 cap->object_created_time; */
1584 cap->h.object_type = type;
1585 osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS);
1586 cap->h.object_descriptor_type = descriptor_type;
1587 cap->od.obj_desc.policy_access_tag = 0;
1588 cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition);
1589 cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id);
1590}
1591EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps);
1592
1593/* FIXME: Extract version from caps pointer.
1594 * Also Pete's target only supports caps from OSDv1 for now
1595 */
1596void osd_set_caps(struct osd_cdb *cdb, const void *caps)
1597{
1598 bool is_ver1 = true;
1599 /* NOTE: They start at same address */
1600 memcpy(&cdb->v1.caps, caps, is_ver1 ? OSDv1_CAP_LEN : OSD_CAP_LEN);
1601}
1602
1603bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused)
1604{
1605 return false;
1606}
1607
1608void osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused)
1609{
1610}
1611
1612void osd_sec_sign_data(void *data_integ __unused,
1613 struct bio *bio __unused, const u8 *cap_key __unused)
1614{
1615}
1616
1617/*
1618 * Declared in osd_protocol.h
1619 * 4.12.5 Data-In and Data-Out buffer offsets
1620 * byte offset = mantissa * (2^(exponent+8))
1621 * Returns the smallest allowed encoded offset that contains given @offset
1622 * The actual encoded offset returned is @offset + *@padding.
1623 */
1624osd_cdb_offset __osd_encode_offset(
1625 u64 offset, unsigned *padding, int min_shift, int max_shift)
1626{
1627 u64 try_offset = -1, mod, align;
1628 osd_cdb_offset be32_offset;
1629 int shift;
1630
1631 *padding = 0;
1632 if (!offset)
1633 return 0;
1634
1635 for (shift = min_shift; shift < max_shift; ++shift) {
1636 try_offset = offset >> shift;
1637 if (try_offset < (1 << OSD_OFFSET_MAX_BITS))
1638 break;
1639 }
1640
1641 BUG_ON(shift == max_shift);
1642
1643 align = 1 << shift;
1644 mod = offset & (align - 1);
1645 if (mod) {
1646 *padding = align - mod;
1647 try_offset += 1;
1648 }
1649
1650 try_offset |= ((shift - 8) & 0xf) << 28;
1651 be32_offset = cpu_to_be32((u32)try_offset);
1652
1653 OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n",
1654 _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift,
1655 be32_offset, *padding);
1656 return be32_offset;
1657}
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
new file mode 100644
index 000000000000..f8b1a749958b
--- /dev/null
+++ b/drivers/scsi/osd/osd_uld.c
@@ -0,0 +1,487 @@
1/*
2 * osd_uld.c - OSD Upper Layer Driver
3 *
4 * A Linux driver module that registers as a SCSI ULD and probes
5 * for OSD type SCSI devices.
6 * It's main function is to export osd devices to in-kernel users like
7 * osdfs and pNFS-objects-LD. It also provides one ioctl for running
8 * in Kernel tests.
9 *
10 * Copyright (C) 2008 Panasas Inc. All rights reserved.
11 *
12 * Authors:
13 * Boaz Harrosh <bharrosh@panasas.com>
14 * Benny Halevy <bhalevy@panasas.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. Neither the name of the Panasas company nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
33 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
34 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
40 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44
45#include <linux/namei.h>
46#include <linux/cdev.h>
47#include <linux/fs.h>
48#include <linux/module.h>
49#include <linux/device.h>
50#include <linux/idr.h>
51#include <linux/major.h>
52
53#include <scsi/scsi.h>
54#include <scsi/scsi_driver.h>
55#include <scsi/scsi_device.h>
56#include <scsi/scsi_ioctl.h>
57
58#include <scsi/osd_initiator.h>
59#include <scsi/osd_sec.h>
60
61#include "osd_debug.h"
62
63#ifndef TYPE_OSD
64# define TYPE_OSD 0x11
65#endif
66
67#ifndef SCSI_OSD_MAJOR
68# define SCSI_OSD_MAJOR 260
69#endif
70#define SCSI_OSD_MAX_MINOR 64
71
72static const char osd_name[] = "osd";
73static const char *osd_version_string = "open-osd 0.1.0";
74const char osd_symlink[] = "scsi_osd";
75
76MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
77MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
78MODULE_LICENSE("GPL");
79MODULE_ALIAS_CHARDEV_MAJOR(SCSI_OSD_MAJOR);
80MODULE_ALIAS_SCSI_DEVICE(TYPE_OSD);
81
82struct osd_uld_device {
83 int minor;
84 struct kref kref;
85 struct cdev cdev;
86 struct osd_dev od;
87 struct gendisk *disk;
88 struct device *class_member;
89};
90
91static void __uld_get(struct osd_uld_device *oud);
92static void __uld_put(struct osd_uld_device *oud);
93
94/*
95 * Char Device operations
96 */
97
98static int osd_uld_open(struct inode *inode, struct file *file)
99{
100 struct osd_uld_device *oud = container_of(inode->i_cdev,
101 struct osd_uld_device, cdev);
102
103 __uld_get(oud);
104 /* cache osd_uld_device on file handle */
105 file->private_data = oud;
106 OSD_DEBUG("osd_uld_open %p\n", oud);
107 return 0;
108}
109
110static int osd_uld_release(struct inode *inode, struct file *file)
111{
112 struct osd_uld_device *oud = file->private_data;
113
114 OSD_DEBUG("osd_uld_release %p\n", file->private_data);
115 file->private_data = NULL;
116 __uld_put(oud);
117 return 0;
118}
119
120/* FIXME: Only one vector for now */
121unsigned g_test_ioctl;
122do_test_fn *g_do_test;
123
124int osduld_register_test(unsigned ioctl, do_test_fn *do_test)
125{
126 if (g_test_ioctl)
127 return -EINVAL;
128
129 g_test_ioctl = ioctl;
130 g_do_test = do_test;
131 return 0;
132}
133EXPORT_SYMBOL(osduld_register_test);
134
135void osduld_unregister_test(unsigned ioctl)
136{
137 if (ioctl == g_test_ioctl) {
138 g_test_ioctl = 0;
139 g_do_test = NULL;
140 }
141}
142EXPORT_SYMBOL(osduld_unregister_test);
143
144static do_test_fn *_find_ioctl(unsigned cmd)
145{
146 if (g_test_ioctl == cmd)
147 return g_do_test;
148 else
149 return NULL;
150}
151
152static long osd_uld_ioctl(struct file *file, unsigned int cmd,
153 unsigned long arg)
154{
155 struct osd_uld_device *oud = file->private_data;
156 int ret;
157 do_test_fn *do_test;
158
159 do_test = _find_ioctl(cmd);
160 if (do_test)
161 ret = do_test(&oud->od, cmd, arg);
162 else {
163 OSD_ERR("Unknown ioctl %d: osd_uld_device=%p\n", cmd, oud);
164 ret = -ENOIOCTLCMD;
165 }
166 return ret;
167}
168
169static const struct file_operations osd_fops = {
170 .owner = THIS_MODULE,
171 .open = osd_uld_open,
172 .release = osd_uld_release,
173 .unlocked_ioctl = osd_uld_ioctl,
174};
175
176struct osd_dev *osduld_path_lookup(const char *path)
177{
178 struct nameidata nd;
179 struct inode *inode;
180 struct cdev *cdev;
181 struct osd_uld_device *uninitialized_var(oud);
182 int error;
183
184 if (!path || !*path) {
185 OSD_ERR("Mount with !path || !*path\n");
186 return ERR_PTR(-EINVAL);
187 }
188
189 error = path_lookup(path, LOOKUP_FOLLOW, &nd);
190 if (error) {
191 OSD_ERR("path_lookup of %s faild=>%d\n", path, error);
192 return ERR_PTR(error);
193 }
194
195 inode = nd.path.dentry->d_inode;
196 error = -EINVAL; /* Not the right device e.g osd_uld_device */
197 if (!S_ISCHR(inode->i_mode)) {
198 OSD_DEBUG("!S_ISCHR()\n");
199 goto out;
200 }
201
202 cdev = inode->i_cdev;
203 if (!cdev) {
204 OSD_ERR("Before mounting an OSD Based filesystem\n");
205 OSD_ERR(" user-mode must open+close the %s device\n", path);
206 OSD_ERR(" Example: bash: echo < %s\n", path);
207 goto out;
208 }
209
210 /* The Magic wand. Is it our char-dev */
211 /* TODO: Support sg devices */
212 if (cdev->owner != THIS_MODULE) {
213 OSD_ERR("Error mounting %s - is not an OSD device\n", path);
214 goto out;
215 }
216
217 oud = container_of(cdev, struct osd_uld_device, cdev);
218
219 __uld_get(oud);
220 error = 0;
221
222out:
223 path_put(&nd.path);
224 return error ? ERR_PTR(error) : &oud->od;
225}
226EXPORT_SYMBOL(osduld_path_lookup);
227
228void osduld_put_device(struct osd_dev *od)
229{
230 if (od) {
231 struct osd_uld_device *oud = container_of(od,
232 struct osd_uld_device, od);
233
234 __uld_put(oud);
235 }
236}
237EXPORT_SYMBOL(osduld_put_device);
238
239/*
240 * Scsi Device operations
241 */
242
243static int __detect_osd(struct osd_uld_device *oud)
244{
245 struct scsi_device *scsi_device = oud->od.scsi_device;
246 char caps[OSD_CAP_LEN];
247 int error;
248
249 /* sending a test_unit_ready as first command seems to be needed
250 * by some targets
251 */
252 OSD_DEBUG("start scsi_test_unit_ready %p %p %p\n",
253 oud, scsi_device, scsi_device->request_queue);
254 error = scsi_test_unit_ready(scsi_device, 10*HZ, 5, NULL);
255 if (error)
256 OSD_ERR("warning: scsi_test_unit_ready failed\n");
257
258 osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
259 if (osd_auto_detect_ver(&oud->od, caps))
260 return -ENODEV;
261
262 return 0;
263}
264
265static struct class *osd_sysfs_class;
266static DEFINE_IDA(osd_minor_ida);
267
268static int osd_probe(struct device *dev)
269{
270 struct scsi_device *scsi_device = to_scsi_device(dev);
271 struct gendisk *disk;
272 struct osd_uld_device *oud;
273 int minor;
274 int error;
275
276 if (scsi_device->type != TYPE_OSD)
277 return -ENODEV;
278
279 do {
280 if (!ida_pre_get(&osd_minor_ida, GFP_KERNEL))
281 return -ENODEV;
282
283 error = ida_get_new(&osd_minor_ida, &minor);
284 } while (error == -EAGAIN);
285
286 if (error)
287 return error;
288 if (minor >= SCSI_OSD_MAX_MINOR) {
289 error = -EBUSY;
290 goto err_retract_minor;
291 }
292
293 error = -ENOMEM;
294 oud = kzalloc(sizeof(*oud), GFP_KERNEL);
295 if (NULL == oud)
296 goto err_retract_minor;
297
298 kref_init(&oud->kref);
299 dev_set_drvdata(dev, oud);
300 oud->minor = minor;
301
302 /* allocate a disk and set it up */
303 /* FIXME: do we need this since sg has already done that */
304 disk = alloc_disk(1);
305 if (!disk) {
306 OSD_ERR("alloc_disk failed\n");
307 goto err_free_osd;
308 }
309 disk->major = SCSI_OSD_MAJOR;
310 disk->first_minor = oud->minor;
311 sprintf(disk->disk_name, "osd%d", oud->minor);
312 oud->disk = disk;
313
314 /* hold one more reference to the scsi_device that will get released
315 * in __release, in case a logout is happening while fs is mounted
316 */
317 scsi_device_get(scsi_device);
318 osd_dev_init(&oud->od, scsi_device);
319
320 /* Detect the OSD Version */
321 error = __detect_osd(oud);
322 if (error) {
323 OSD_ERR("osd detection failed, non-compatible OSD device\n");
324 goto err_put_disk;
325 }
326
327 /* init the char-device for communication with user-mode */
328 cdev_init(&oud->cdev, &osd_fops);
329 oud->cdev.owner = THIS_MODULE;
330 error = cdev_add(&oud->cdev,
331 MKDEV(SCSI_OSD_MAJOR, oud->minor), 1);
332 if (error) {
333 OSD_ERR("cdev_add failed\n");
334 goto err_put_disk;
335 }
336 kobject_get(&oud->cdev.kobj); /* 2nd ref see osd_remove() */
337
338 /* class_member */
339 oud->class_member = device_create(osd_sysfs_class, dev,
340 MKDEV(SCSI_OSD_MAJOR, oud->minor), "%s", disk->disk_name);
341 if (IS_ERR(oud->class_member)) {
342 OSD_ERR("class_device_create failed\n");
343 error = PTR_ERR(oud->class_member);
344 goto err_put_cdev;
345 }
346
347 dev_set_drvdata(oud->class_member, oud);
348 error = sysfs_create_link(&scsi_device->sdev_gendev.kobj,
349 &oud->class_member->kobj, osd_symlink);
350 if (error)
351 OSD_ERR("warning: unable to make symlink\n");
352
353 OSD_INFO("osd_probe %s\n", disk->disk_name);
354 return 0;
355
356err_put_cdev:
357 cdev_del(&oud->cdev);
358err_put_disk:
359 scsi_device_put(scsi_device);
360 put_disk(disk);
361err_free_osd:
362 dev_set_drvdata(dev, NULL);
363 kfree(oud);
364err_retract_minor:
365 ida_remove(&osd_minor_ida, minor);
366 return error;
367}
368
369static int osd_remove(struct device *dev)
370{
371 struct scsi_device *scsi_device = to_scsi_device(dev);
372 struct osd_uld_device *oud = dev_get_drvdata(dev);
373
374 if (!oud || (oud->od.scsi_device != scsi_device)) {
375 OSD_ERR("Half cooked osd-device %p,%p || %p!=%p",
376 dev, oud, oud ? oud->od.scsi_device : NULL,
377 scsi_device);
378 }
379
380 sysfs_remove_link(&oud->od.scsi_device->sdev_gendev.kobj, osd_symlink);
381
382 if (oud->class_member)
383 device_destroy(osd_sysfs_class,
384 MKDEV(SCSI_OSD_MAJOR, oud->minor));
385
386 /* We have 2 references to the cdev. One is released here
387 * and also takes down the /dev/osdX mapping. The second
388 * Will be released in __remove() after all users have released
389 * the osd_uld_device.
390 */
391 if (oud->cdev.owner)
392 cdev_del(&oud->cdev);
393
394 __uld_put(oud);
395 return 0;
396}
397
398static void __remove(struct kref *kref)
399{
400 struct osd_uld_device *oud = container_of(kref,
401 struct osd_uld_device, kref);
402 struct scsi_device *scsi_device = oud->od.scsi_device;
403
404 /* now let delete the char_dev */
405 kobject_put(&oud->cdev.kobj);
406
407 osd_dev_fini(&oud->od);
408 scsi_device_put(scsi_device);
409
410 OSD_INFO("osd_remove %s\n",
411 oud->disk ? oud->disk->disk_name : NULL);
412
413 if (oud->disk)
414 put_disk(oud->disk);
415
416 ida_remove(&osd_minor_ida, oud->minor);
417 kfree(oud);
418}
419
420static void __uld_get(struct osd_uld_device *oud)
421{
422 kref_get(&oud->kref);
423}
424
425static void __uld_put(struct osd_uld_device *oud)
426{
427 kref_put(&oud->kref, __remove);
428}
429
430/*
431 * Global driver and scsi registration
432 */
433
434static struct scsi_driver osd_driver = {
435 .owner = THIS_MODULE,
436 .gendrv = {
437 .name = osd_name,
438 .probe = osd_probe,
439 .remove = osd_remove,
440 }
441};
442
443static int __init osd_uld_init(void)
444{
445 int err;
446
447 osd_sysfs_class = class_create(THIS_MODULE, osd_symlink);
448 if (IS_ERR(osd_sysfs_class)) {
449 OSD_ERR("Unable to register sysfs class => %ld\n",
450 PTR_ERR(osd_sysfs_class));
451 return PTR_ERR(osd_sysfs_class);
452 }
453
454 err = register_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0),
455 SCSI_OSD_MAX_MINOR, osd_name);
456 if (err) {
457 OSD_ERR("Unable to register major %d for osd ULD => %d\n",
458 SCSI_OSD_MAJOR, err);
459 goto err_out;
460 }
461
462 err = scsi_register_driver(&osd_driver.gendrv);
463 if (err) {
464 OSD_ERR("scsi_register_driver failed => %d\n", err);
465 goto err_out_chrdev;
466 }
467
468 OSD_INFO("LOADED %s\n", osd_version_string);
469 return 0;
470
471err_out_chrdev:
472 unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
473err_out:
474 class_destroy(osd_sysfs_class);
475 return err;
476}
477
478static void __exit osd_uld_exit(void)
479{
480 scsi_unregister_driver(&osd_driver.gendrv);
481 unregister_chrdev_region(MKDEV(SCSI_OSD_MAJOR, 0), SCSI_OSD_MAX_MINOR);
482 class_destroy(osd_sysfs_class);
483 OSD_INFO("UNLOADED %s\n", osd_version_string);
484}
485
486module_init(osd_uld_init);
487module_exit(osd_uld_exit);
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 0ea78d9a37db..acb835837eec 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -280,8 +280,8 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
280 static int notyetprinted = 1; 280 static int notyetprinted = 1;
281 281
282 printk(KERN_WARNING 282 printk(KERN_WARNING
283 "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n", 283 "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
284 name, result, suggestion(result), driver_byte(result) & DRIVER_MASK, 284 name, result, driver_byte(result),
285 host_byte(result)); 285 host_byte(result));
286 if (notyetprinted) { 286 if (notyetprinted) {
287 notyetprinted = 0; 287 notyetprinted = 0;
@@ -317,18 +317,25 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
317 317
318 318
319/* Wakeup from interrupt */ 319/* Wakeup from interrupt */
320static void osst_sleep_done(void *data, char *sense, int result, int resid) 320static void osst_end_async(struct request *req, int update)
321{ 321{
322 struct osst_request *SRpnt = data; 322 struct osst_request *SRpnt = req->end_io_data;
323 struct osst_tape *STp = SRpnt->stp; 323 struct osst_tape *STp = SRpnt->stp;
324 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
324 325
325 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); 326 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
326 STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
327#if DEBUG 327#if DEBUG
328 STp->write_pending = 0; 328 STp->write_pending = 0;
329#endif 329#endif
330 if (SRpnt->waiting) 330 if (SRpnt->waiting)
331 complete(SRpnt->waiting); 331 complete(SRpnt->waiting);
332
333 if (SRpnt->bio) {
334 kfree(mdata->pages);
335 blk_rq_unmap_user(SRpnt->bio);
336 }
337
338 __blk_put_request(req->q, req);
332} 339}
333 340
334/* osst_request memory management */ 341/* osst_request memory management */
@@ -342,6 +349,74 @@ static void osst_release_request(struct osst_request *streq)
342 kfree(streq); 349 kfree(streq);
343} 350}
344 351
352static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
353 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
354 int use_sg, int timeout, int retries)
355{
356 struct request *req;
357 struct page **pages = NULL;
358 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
359
360 int err = 0;
361 int write = (data_direction == DMA_TO_DEVICE);
362
363 req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
364 if (!req)
365 return DRIVER_ERROR << 24;
366
367 req->cmd_type = REQ_TYPE_BLOCK_PC;
368 req->cmd_flags |= REQ_QUIET;
369
370 SRpnt->bio = NULL;
371
372 if (use_sg) {
373 struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
374 int i;
375
376 pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
377 if (!pages)
378 goto free_req;
379
380 for_each_sg(sgl, sg, use_sg, i)
381 pages[i] = sg_page(sg);
382
383 mdata->null_mapped = 1;
384
385 mdata->page_order = get_order(sgl[0].length);
386 mdata->nr_entries =
387 DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
388 mdata->offset = 0;
389
390 err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
391 if (err) {
392 kfree(pages);
393 goto free_req;
394 }
395 SRpnt->bio = req->bio;
396 mdata->pages = pages;
397
398 } else if (bufflen) {
399 err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
400 if (err)
401 goto free_req;
402 }
403
404 req->cmd_len = cmd_len;
405 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
406 memcpy(req->cmd, cmd, req->cmd_len);
407 req->sense = SRpnt->sense;
408 req->sense_len = 0;
409 req->timeout = timeout;
410 req->retries = retries;
411 req->end_io_data = SRpnt;
412
413 blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
414 return 0;
415free_req:
416 blk_put_request(req);
417 return DRIVER_ERROR << 24;
418}
419
345/* Do the scsi command. Waits until command performed if do_wait is true. 420/* Do the scsi command. Waits until command performed if do_wait is true.
346 Otherwise osst_write_behind_check() is used to check that the command 421 Otherwise osst_write_behind_check() is used to check that the command
347 has finished. */ 422 has finished. */
@@ -403,8 +478,8 @@ static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct oss
403 STp->buffer->cmdstat.have_sense = 0; 478 STp->buffer->cmdstat.have_sense = 0;
404 STp->buffer->syscall_result = 0; 479 STp->buffer->syscall_result = 0;
405 480
406 if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes, 481 if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
407 use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL)) 482 use_sg, timeout, retries))
408 /* could not allocate the buffer or request was too large */ 483 /* could not allocate the buffer or request was too large */
409 (STp->buffer)->syscall_result = (-EBUSY); 484 (STp->buffer)->syscall_result = (-EBUSY);
410 else if (do_wait) { 485 else if (do_wait) {
@@ -5286,11 +5361,6 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
5286 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order); 5361 struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
5287 STbuffer->sg[segs].offset = 0; 5362 STbuffer->sg[segs].offset = 0;
5288 if (page == NULL) { 5363 if (page == NULL) {
5289 if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
5290 b_size /= 2; /* Large enough for the rest of the buffers */
5291 order--;
5292 continue;
5293 }
5294 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", 5364 printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
5295 OS_FRAME_SIZE); 5365 OS_FRAME_SIZE);
5296#if DEBUG 5366#if DEBUG
diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h
index 5aa22740b5df..11d26c57f3f8 100644
--- a/drivers/scsi/osst.h
+++ b/drivers/scsi/osst.h
@@ -520,6 +520,7 @@ struct osst_buffer {
520 int syscall_result; 520 int syscall_result;
521 struct osst_request *last_SRpnt; 521 struct osst_request *last_SRpnt;
522 struct st_cmdstatus cmdstat; 522 struct st_cmdstatus cmdstat;
523 struct rq_map_data map_data;
523 unsigned char *b_data; 524 unsigned char *b_data;
524 os_aux_t *aux; /* onstream AUX structure at end of each block */ 525 os_aux_t *aux; /* onstream AUX structure at end of each block */
525 unsigned short use_sg; /* zero or number of s/g segments for this adapter */ 526 unsigned short use_sg; /* zero or number of s/g segments for this adapter */
@@ -634,6 +635,7 @@ struct osst_request {
634 int result; 635 int result;
635 struct osst_tape *stp; 636 struct osst_tape *stp;
636 struct completion *waiting; 637 struct completion *waiting;
638 struct bio *bio;
637}; 639};
638 640
639/* Values of write_type */ 641/* Values of write_type */
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index cbcd3f681b62..a2ef03243a2c 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -967,6 +967,110 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
967EXPORT_SYMBOL(scsi_track_queue_full); 967EXPORT_SYMBOL(scsi_track_queue_full);
968 968
969/** 969/**
970 * scsi_vpd_inquiry - Request a device provide us with a VPD page
971 * @sdev: The device to ask
972 * @buffer: Where to put the result
973 * @page: Which Vital Product Data to return
974 * @len: The length of the buffer
975 *
976 * This is an internal helper function. You probably want to use
977 * scsi_get_vpd_page instead.
978 *
979 * Returns 0 on success or a negative error number.
980 */
981static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
982 u8 page, unsigned len)
983{
984 int result;
985 unsigned char cmd[16];
986
987 cmd[0] = INQUIRY;
988 cmd[1] = 1; /* EVPD */
989 cmd[2] = page;
990 cmd[3] = len >> 8;
991 cmd[4] = len & 0xff;
992 cmd[5] = 0; /* Control byte */
993
994 /*
995 * I'm not convinced we need to try quite this hard to get VPD, but
996 * all the existing users tried this hard.
997 */
998 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
999 len + 4, NULL, 30 * HZ, 3, NULL);
1000 if (result)
1001 return result;
1002
1003 /* Sanity check that we got the page back that we asked for */
1004 if (buffer[1] != page)
1005 return -EIO;
1006
1007 return 0;
1008}
1009
1010/**
1011 * scsi_get_vpd_page - Get Vital Product Data from a SCSI device
1012 * @sdev: The device to ask
1013 * @page: Which Vital Product Data to return
1014 *
1015 * SCSI devices may optionally supply Vital Product Data. Each 'page'
1016 * of VPD is defined in the appropriate SCSI document (eg SPC, SBC).
1017 * If the device supports this VPD page, this routine returns a pointer
1018 * to a buffer containing the data from that page. The caller is
1019 * responsible for calling kfree() on this pointer when it is no longer
1020 * needed. If we cannot retrieve the VPD page this routine returns %NULL.
1021 */
1022unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
1023{
1024 int i, result;
1025 unsigned int len;
1026 unsigned char *buf = kmalloc(259, GFP_KERNEL);
1027
1028 if (!buf)
1029 return NULL;
1030
1031 /* Ask for all the pages supported by this device */
1032 result = scsi_vpd_inquiry(sdev, buf, 0, 255);
1033 if (result)
1034 goto fail;
1035
1036 /* If the user actually wanted this page, we can skip the rest */
1037 if (page == 0)
1038 return buf;
1039
1040 for (i = 0; i < buf[3]; i++)
1041 if (buf[i + 4] == page)
1042 goto found;
1043 /* The device claims it doesn't support the requested page */
1044 goto fail;
1045
1046 found:
1047 result = scsi_vpd_inquiry(sdev, buf, page, 255);
1048 if (result)
1049 goto fail;
1050
1051 /*
1052 * Some pages are longer than 255 bytes. The actual length of
1053 * the page is returned in the header.
1054 */
1055 len = (buf[2] << 8) | buf[3];
1056 if (len <= 255)
1057 return buf;
1058
1059 kfree(buf);
1060 buf = kmalloc(len + 4, GFP_KERNEL);
1061 result = scsi_vpd_inquiry(sdev, buf, page, len);
1062 if (result)
1063 goto fail;
1064
1065 return buf;
1066
1067 fail:
1068 kfree(buf);
1069 return NULL;
1070}
1071EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
1072
1073/**
970 * scsi_device_get - get an additional reference to a scsi_device 1074 * scsi_device_get - get an additional reference to a scsi_device
971 * @sdev: device to get a reference to 1075 * @sdev: device to get a reference to
972 * 1076 *
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6eebd0bbe8a8..213123b0486b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -40,6 +40,9 @@
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/scatterlist.h> 41#include <linux/scatterlist.h>
42#include <linux/blkdev.h> 42#include <linux/blkdev.h>
43#include <linux/crc-t10dif.h>
44
45#include <net/checksum.h>
43 46
44#include <scsi/scsi.h> 47#include <scsi/scsi.h>
45#include <scsi/scsi_cmnd.h> 48#include <scsi/scsi_cmnd.h>
@@ -48,8 +51,7 @@
48#include <scsi/scsicam.h> 51#include <scsi/scsicam.h>
49#include <scsi/scsi_eh.h> 52#include <scsi/scsi_eh.h>
50 53
51#include <linux/stat.h> 54#include "sd.h"
52
53#include "scsi_logging.h" 55#include "scsi_logging.h"
54 56
55#define SCSI_DEBUG_VERSION "1.81" 57#define SCSI_DEBUG_VERSION "1.81"
@@ -95,6 +97,10 @@ static const char * scsi_debug_version_date = "20070104";
95#define DEF_FAKE_RW 0 97#define DEF_FAKE_RW 0
96#define DEF_VPD_USE_HOSTNO 1 98#define DEF_VPD_USE_HOSTNO 1
97#define DEF_SECTOR_SIZE 512 99#define DEF_SECTOR_SIZE 512
100#define DEF_DIX 0
101#define DEF_DIF 0
102#define DEF_GUARD 0
103#define DEF_ATO 1
98 104
99/* bit mask values for scsi_debug_opts */ 105/* bit mask values for scsi_debug_opts */
100#define SCSI_DEBUG_OPT_NOISE 1 106#define SCSI_DEBUG_OPT_NOISE 1
@@ -102,6 +108,8 @@ static const char * scsi_debug_version_date = "20070104";
102#define SCSI_DEBUG_OPT_TIMEOUT 4 108#define SCSI_DEBUG_OPT_TIMEOUT 4
103#define SCSI_DEBUG_OPT_RECOVERED_ERR 8 109#define SCSI_DEBUG_OPT_RECOVERED_ERR 8
104#define SCSI_DEBUG_OPT_TRANSPORT_ERR 16 110#define SCSI_DEBUG_OPT_TRANSPORT_ERR 16
111#define SCSI_DEBUG_OPT_DIF_ERR 32
112#define SCSI_DEBUG_OPT_DIX_ERR 64
105/* When "every_nth" > 0 then modulo "every_nth" commands: 113/* When "every_nth" > 0 then modulo "every_nth" commands:
106 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set 114 * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
107 * - a RECOVERED_ERROR is simulated on successful read and write 115 * - a RECOVERED_ERROR is simulated on successful read and write
@@ -144,6 +152,10 @@ static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB;
144static int scsi_debug_fake_rw = DEF_FAKE_RW; 152static int scsi_debug_fake_rw = DEF_FAKE_RW;
145static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO; 153static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
146static int scsi_debug_sector_size = DEF_SECTOR_SIZE; 154static int scsi_debug_sector_size = DEF_SECTOR_SIZE;
155static int scsi_debug_dix = DEF_DIX;
156static int scsi_debug_dif = DEF_DIF;
157static int scsi_debug_guard = DEF_GUARD;
158static int scsi_debug_ato = DEF_ATO;
147 159
148static int scsi_debug_cmnd_count = 0; 160static int scsi_debug_cmnd_count = 0;
149 161
@@ -204,11 +216,15 @@ struct sdebug_queued_cmd {
204static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; 216static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
205 217
206static unsigned char * fake_storep; /* ramdisk storage */ 218static unsigned char * fake_storep; /* ramdisk storage */
219static unsigned char *dif_storep; /* protection info */
207 220
208static int num_aborts = 0; 221static int num_aborts = 0;
209static int num_dev_resets = 0; 222static int num_dev_resets = 0;
210static int num_bus_resets = 0; 223static int num_bus_resets = 0;
211static int num_host_resets = 0; 224static int num_host_resets = 0;
225static int dix_writes;
226static int dix_reads;
227static int dif_errors;
212 228
213static DEFINE_SPINLOCK(queued_arr_lock); 229static DEFINE_SPINLOCK(queued_arr_lock);
214static DEFINE_RWLOCK(atomic_rw); 230static DEFINE_RWLOCK(atomic_rw);
@@ -217,6 +233,11 @@ static char sdebug_proc_name[] = "scsi_debug";
217 233
218static struct bus_type pseudo_lld_bus; 234static struct bus_type pseudo_lld_bus;
219 235
236static inline sector_t dif_offset(sector_t sector)
237{
238 return sector << 3;
239}
240
220static struct device_driver sdebug_driverfs_driver = { 241static struct device_driver sdebug_driverfs_driver = {
221 .name = sdebug_proc_name, 242 .name = sdebug_proc_name,
222 .bus = &pseudo_lld_bus, 243 .bus = &pseudo_lld_bus,
@@ -225,6 +246,9 @@ static struct device_driver sdebug_driverfs_driver = {
225static const int check_condition_result = 246static const int check_condition_result =
226 (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; 247 (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
227 248
249static const int illegal_condition_result =
250 (DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
251
228static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, 252static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
229 0, 0, 0x2, 0x4b}; 253 0, 0, 0x2, 0x4b};
230static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, 254static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
@@ -726,7 +750,12 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
726 } else if (0x86 == cmd[2]) { /* extended inquiry */ 750 } else if (0x86 == cmd[2]) { /* extended inquiry */
727 arr[1] = cmd[2]; /*sanity */ 751 arr[1] = cmd[2]; /*sanity */
728 arr[3] = 0x3c; /* number of following entries */ 752 arr[3] = 0x3c; /* number of following entries */
729 arr[4] = 0x0; /* no protection stuff */ 753 if (scsi_debug_dif == SD_DIF_TYPE3_PROTECTION)
754 arr[4] = 0x4; /* SPT: GRD_CHK:1 */
755 else if (scsi_debug_dif)
756 arr[4] = 0x5; /* SPT: GRD_CHK:1, REF_CHK:1 */
757 else
758 arr[4] = 0x0; /* no protection stuff */
730 arr[5] = 0x7; /* head of q, ordered + simple q's */ 759 arr[5] = 0x7; /* head of q, ordered + simple q's */
731 } else if (0x87 == cmd[2]) { /* mode page policy */ 760 } else if (0x87 == cmd[2]) { /* mode page policy */
732 arr[1] = cmd[2]; /*sanity */ 761 arr[1] = cmd[2]; /*sanity */
@@ -767,6 +796,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
767 arr[2] = scsi_debug_scsi_level; 796 arr[2] = scsi_debug_scsi_level;
768 arr[3] = 2; /* response_data_format==2 */ 797 arr[3] = 2; /* response_data_format==2 */
769 arr[4] = SDEBUG_LONG_INQ_SZ - 5; 798 arr[4] = SDEBUG_LONG_INQ_SZ - 5;
799 arr[5] = scsi_debug_dif ? 1 : 0; /* PROTECT bit */
770 if (0 == scsi_debug_vpd_use_hostno) 800 if (0 == scsi_debug_vpd_use_hostno)
771 arr[5] = 0x10; /* claim: implicit TGPS */ 801 arr[5] = 0x10; /* claim: implicit TGPS */
772 arr[6] = 0x10; /* claim: MultiP */ 802 arr[6] = 0x10; /* claim: MultiP */
@@ -915,6 +945,12 @@ static int resp_readcap16(struct scsi_cmnd * scp,
915 arr[9] = (scsi_debug_sector_size >> 16) & 0xff; 945 arr[9] = (scsi_debug_sector_size >> 16) & 0xff;
916 arr[10] = (scsi_debug_sector_size >> 8) & 0xff; 946 arr[10] = (scsi_debug_sector_size >> 8) & 0xff;
917 arr[11] = scsi_debug_sector_size & 0xff; 947 arr[11] = scsi_debug_sector_size & 0xff;
948
949 if (scsi_debug_dif) {
950 arr[12] = (scsi_debug_dif - 1) << 1; /* P_TYPE */
951 arr[12] |= 1; /* PROT_EN */
952 }
953
918 return fill_from_dev_buffer(scp, arr, 954 return fill_from_dev_buffer(scp, arr,
919 min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); 955 min(alloc_len, SDEBUG_READCAP16_ARR_SZ));
920} 956}
@@ -1066,6 +1102,10 @@ static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target)
1066 ctrl_m_pg[2] |= 0x4; 1102 ctrl_m_pg[2] |= 0x4;
1067 else 1103 else
1068 ctrl_m_pg[2] &= ~0x4; 1104 ctrl_m_pg[2] &= ~0x4;
1105
1106 if (scsi_debug_ato)
1107 ctrl_m_pg[5] |= 0x80; /* ATO=1 */
1108
1069 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); 1109 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1070 if (1 == pcontrol) 1110 if (1 == pcontrol)
1071 memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg)); 1111 memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg));
@@ -1536,6 +1576,87 @@ static int do_device_access(struct scsi_cmnd *scmd,
1536 return ret; 1576 return ret;
1537} 1577}
1538 1578
1579static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1580 unsigned int sectors)
1581{
1582 unsigned int i, resid;
1583 struct scatterlist *psgl;
1584 struct sd_dif_tuple *sdt;
1585 sector_t sector;
1586 sector_t tmp_sec = start_sec;
1587 void *paddr;
1588
1589 start_sec = do_div(tmp_sec, sdebug_store_sectors);
1590
1591 sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec));
1592
1593 for (i = 0 ; i < sectors ; i++) {
1594 u16 csum;
1595
1596 if (sdt[i].app_tag == 0xffff)
1597 continue;
1598
1599 sector = start_sec + i;
1600
1601 switch (scsi_debug_guard) {
1602 case 1:
1603 csum = ip_compute_csum(fake_storep +
1604 sector * scsi_debug_sector_size,
1605 scsi_debug_sector_size);
1606 break;
1607 case 0:
1608 csum = crc_t10dif(fake_storep +
1609 sector * scsi_debug_sector_size,
1610 scsi_debug_sector_size);
1611 csum = cpu_to_be16(csum);
1612 break;
1613 default:
1614 BUG();
1615 }
1616
1617 if (sdt[i].guard_tag != csum) {
1618 printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
1619 " rcvd 0x%04x, data 0x%04x\n", __func__,
1620 (unsigned long)sector,
1621 be16_to_cpu(sdt[i].guard_tag),
1622 be16_to_cpu(csum));
1623 dif_errors++;
1624 return 0x01;
1625 }
1626
1627 if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION &&
1628 be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
1629 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1630 __func__, (unsigned long)sector);
1631 dif_errors++;
1632 return 0x03;
1633 }
1634 }
1635
1636 resid = sectors * 8; /* Bytes of protection data to copy into sgl */
1637 sector = start_sec;
1638
1639 scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
1640 int len = min(psgl->length, resid);
1641
1642 paddr = kmap_atomic(sg_page(psgl), KM_IRQ0) + psgl->offset;
1643 memcpy(paddr, dif_storep + dif_offset(sector), len);
1644
1645 sector += len >> 3;
1646 if (sector >= sdebug_store_sectors) {
1647 /* Force wrap */
1648 tmp_sec = sector;
1649 sector = do_div(tmp_sec, sdebug_store_sectors);
1650 }
1651 resid -= len;
1652 kunmap_atomic(paddr, KM_IRQ0);
1653 }
1654
1655 dix_reads++;
1656
1657 return 0;
1658}
1659
1539static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, 1660static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1540 unsigned int num, struct sdebug_dev_info *devip) 1661 unsigned int num, struct sdebug_dev_info *devip)
1541{ 1662{
@@ -1563,12 +1684,162 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1563 } 1684 }
1564 return check_condition_result; 1685 return check_condition_result;
1565 } 1686 }
1687
1688 /* DIX + T10 DIF */
1689 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
1690 int prot_ret = prot_verify_read(SCpnt, lba, num);
1691
1692 if (prot_ret) {
1693 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret);
1694 return illegal_condition_result;
1695 }
1696 }
1697
1566 read_lock_irqsave(&atomic_rw, iflags); 1698 read_lock_irqsave(&atomic_rw, iflags);
1567 ret = do_device_access(SCpnt, devip, lba, num, 0); 1699 ret = do_device_access(SCpnt, devip, lba, num, 0);
1568 read_unlock_irqrestore(&atomic_rw, iflags); 1700 read_unlock_irqrestore(&atomic_rw, iflags);
1569 return ret; 1701 return ret;
1570} 1702}
1571 1703
1704void dump_sector(unsigned char *buf, int len)
1705{
1706 int i, j;
1707
1708 printk(KERN_ERR ">>> Sector Dump <<<\n");
1709
1710 for (i = 0 ; i < len ; i += 16) {
1711 printk(KERN_ERR "%04d: ", i);
1712
1713 for (j = 0 ; j < 16 ; j++) {
1714 unsigned char c = buf[i+j];
1715 if (c >= 0x20 && c < 0x7e)
1716 printk(" %c ", buf[i+j]);
1717 else
1718 printk("%02x ", buf[i+j]);
1719 }
1720
1721 printk("\n");
1722 }
1723}
1724
1725static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1726 unsigned int sectors)
1727{
1728 int i, j, ret;
1729 struct sd_dif_tuple *sdt;
1730 struct scatterlist *dsgl = scsi_sglist(SCpnt);
1731 struct scatterlist *psgl = scsi_prot_sglist(SCpnt);
1732 void *daddr, *paddr;
1733 sector_t tmp_sec = start_sec;
1734 sector_t sector;
1735 int ppage_offset;
1736 unsigned short csum;
1737
1738 sector = do_div(tmp_sec, sdebug_store_sectors);
1739
1740 if (((SCpnt->cmnd[1] >> 5) & 7) != 1) {
1741 printk(KERN_WARNING "scsi_debug: WRPROTECT != 1\n");
1742 return 0;
1743 }
1744
1745 BUG_ON(scsi_sg_count(SCpnt) == 0);
1746 BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
1747
1748 paddr = kmap_atomic(sg_page(psgl), KM_IRQ1) + psgl->offset;
1749 ppage_offset = 0;
1750
1751 /* For each data page */
1752 scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
1753 daddr = kmap_atomic(sg_page(dsgl), KM_IRQ0) + dsgl->offset;
1754
1755 /* For each sector-sized chunk in data page */
1756 for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) {
1757
1758 /* If we're at the end of the current
1759 * protection page advance to the next one
1760 */
1761 if (ppage_offset >= psgl->length) {
1762 kunmap_atomic(paddr, KM_IRQ1);
1763 psgl = sg_next(psgl);
1764 BUG_ON(psgl == NULL);
1765 paddr = kmap_atomic(sg_page(psgl), KM_IRQ1)
1766 + psgl->offset;
1767 ppage_offset = 0;
1768 }
1769
1770 sdt = paddr + ppage_offset;
1771
1772 switch (scsi_debug_guard) {
1773 case 1:
1774 csum = ip_compute_csum(daddr,
1775 scsi_debug_sector_size);
1776 break;
1777 case 0:
1778 csum = cpu_to_be16(crc_t10dif(daddr,
1779 scsi_debug_sector_size));
1780 break;
1781 default:
1782 BUG();
1783 ret = 0;
1784 goto out;
1785 }
1786
1787 if (sdt->guard_tag != csum) {
1788 printk(KERN_ERR
1789 "%s: GUARD check failed on sector %lu " \
1790 "rcvd 0x%04x, calculated 0x%04x\n",
1791 __func__, (unsigned long)sector,
1792 be16_to_cpu(sdt->guard_tag),
1793 be16_to_cpu(csum));
1794 ret = 0x01;
1795 dump_sector(daddr, scsi_debug_sector_size);
1796 goto out;
1797 }
1798
1799 if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION &&
1800 be32_to_cpu(sdt->ref_tag)
1801 != (start_sec & 0xffffffff)) {
1802 printk(KERN_ERR
1803 "%s: REF check failed on sector %lu\n",
1804 __func__, (unsigned long)sector);
1805 ret = 0x03;
1806 dump_sector(daddr, scsi_debug_sector_size);
1807 goto out;
1808 }
1809
1810 /* Would be great to copy this in bigger
1811 * chunks. However, for the sake of
1812 * correctness we need to verify each sector
1813 * before writing it to "stable" storage
1814 */
1815 memcpy(dif_storep + dif_offset(sector), sdt, 8);
1816
1817 sector++;
1818
1819 if (sector == sdebug_store_sectors)
1820 sector = 0; /* Force wrap */
1821
1822 start_sec++;
1823 daddr += scsi_debug_sector_size;
1824 ppage_offset += sizeof(struct sd_dif_tuple);
1825 }
1826
1827 kunmap_atomic(daddr, KM_IRQ0);
1828 }
1829
1830 kunmap_atomic(paddr, KM_IRQ1);
1831
1832 dix_writes++;
1833
1834 return 0;
1835
1836out:
1837 dif_errors++;
1838 kunmap_atomic(daddr, KM_IRQ0);
1839 kunmap_atomic(paddr, KM_IRQ1);
1840 return ret;
1841}
1842
1572static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, 1843static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
1573 unsigned int num, struct sdebug_dev_info *devip) 1844 unsigned int num, struct sdebug_dev_info *devip)
1574{ 1845{
@@ -1579,6 +1850,16 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
1579 if (ret) 1850 if (ret)
1580 return ret; 1851 return ret;
1581 1852
1853 /* DIX + T10 DIF */
1854 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
1855 int prot_ret = prot_verify_write(SCpnt, lba, num);
1856
1857 if (prot_ret) {
1858 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret);
1859 return illegal_condition_result;
1860 }
1861 }
1862
1582 write_lock_irqsave(&atomic_rw, iflags); 1863 write_lock_irqsave(&atomic_rw, iflags);
1583 ret = do_device_access(SCpnt, devip, lba, num, 1); 1864 ret = do_device_access(SCpnt, devip, lba, num, 1);
1584 write_unlock_irqrestore(&atomic_rw, iflags); 1865 write_unlock_irqrestore(&atomic_rw, iflags);
@@ -2095,6 +2376,10 @@ module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR);
2095module_param_named(vpd_use_hostno, scsi_debug_vpd_use_hostno, int, 2376module_param_named(vpd_use_hostno, scsi_debug_vpd_use_hostno, int,
2096 S_IRUGO | S_IWUSR); 2377 S_IRUGO | S_IWUSR);
2097module_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO); 2378module_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO);
2379module_param_named(dix, scsi_debug_dix, int, S_IRUGO);
2380module_param_named(dif, scsi_debug_dif, int, S_IRUGO);
2381module_param_named(guard, scsi_debug_guard, int, S_IRUGO);
2382module_param_named(ato, scsi_debug_ato, int, S_IRUGO);
2098 2383
2099MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); 2384MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
2100MODULE_DESCRIPTION("SCSI debug adapter driver"); 2385MODULE_DESCRIPTION("SCSI debug adapter driver");
@@ -2117,7 +2402,10 @@ MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
2117MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); 2402MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
2118MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)"); 2403MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)");
2119MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)"); 2404MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)");
2120 2405MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)");
2406MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
2407MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
2408MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)");
2121 2409
2122static char sdebug_info[256]; 2410static char sdebug_info[256];
2123 2411
@@ -2164,14 +2452,14 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta
2164 "delay=%d, max_luns=%d, scsi_level=%d\n" 2452 "delay=%d, max_luns=%d, scsi_level=%d\n"
2165 "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n" 2453 "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
2166 "number of aborts=%d, device_reset=%d, bus_resets=%d, " 2454 "number of aborts=%d, device_reset=%d, bus_resets=%d, "
2167 "host_resets=%d\n", 2455 "host_resets=%d\ndix_reads=%d dix_writes=%d dif_errors=%d\n",
2168 SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts, 2456 SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts,
2169 scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, 2457 scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
2170 scsi_debug_cmnd_count, scsi_debug_delay, 2458 scsi_debug_cmnd_count, scsi_debug_delay,
2171 scsi_debug_max_luns, scsi_debug_scsi_level, 2459 scsi_debug_max_luns, scsi_debug_scsi_level,
2172 scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads, 2460 scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads,
2173 sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets, 2461 sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets,
2174 num_host_resets); 2462 num_host_resets, dix_reads, dix_writes, dif_errors);
2175 if (pos < offset) { 2463 if (pos < offset) {
2176 len = 0; 2464 len = 0;
2177 begin = pos; 2465 begin = pos;
@@ -2452,6 +2740,31 @@ static ssize_t sdebug_sector_size_show(struct device_driver * ddp, char * buf)
2452} 2740}
2453DRIVER_ATTR(sector_size, S_IRUGO, sdebug_sector_size_show, NULL); 2741DRIVER_ATTR(sector_size, S_IRUGO, sdebug_sector_size_show, NULL);
2454 2742
2743static ssize_t sdebug_dix_show(struct device_driver *ddp, char *buf)
2744{
2745 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dix);
2746}
2747DRIVER_ATTR(dix, S_IRUGO, sdebug_dix_show, NULL);
2748
2749static ssize_t sdebug_dif_show(struct device_driver *ddp, char *buf)
2750{
2751 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dif);
2752}
2753DRIVER_ATTR(dif, S_IRUGO, sdebug_dif_show, NULL);
2754
2755static ssize_t sdebug_guard_show(struct device_driver *ddp, char *buf)
2756{
2757 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_guard);
2758}
2759DRIVER_ATTR(guard, S_IRUGO, sdebug_guard_show, NULL);
2760
2761static ssize_t sdebug_ato_show(struct device_driver *ddp, char *buf)
2762{
2763 return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ato);
2764}
2765DRIVER_ATTR(ato, S_IRUGO, sdebug_ato_show, NULL);
2766
2767
2455/* Note: The following function creates attribute files in the 2768/* Note: The following function creates attribute files in the
2456 /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these 2769 /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
2457 files (over those found in the /sys/module/scsi_debug/parameters 2770 files (over those found in the /sys/module/scsi_debug/parameters
@@ -2478,11 +2791,19 @@ static int do_create_driverfs_files(void)
2478 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb); 2791 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
2479 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno); 2792 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
2480 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_sector_size); 2793 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
2794 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dix);
2795 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dif);
2796 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_guard);
2797 ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ato);
2481 return ret; 2798 return ret;
2482} 2799}
2483 2800
2484static void do_remove_driverfs_files(void) 2801static void do_remove_driverfs_files(void)
2485{ 2802{
2803 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ato);
2804 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_guard);
2805 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dif);
2806 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dix);
2486 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_sector_size); 2807 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
2487 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno); 2808 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
2488 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb); 2809 driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
@@ -2526,11 +2847,33 @@ static int __init scsi_debug_init(void)
2526 case 4096: 2847 case 4096:
2527 break; 2848 break;
2528 default: 2849 default:
2529 printk(KERN_ERR "scsi_debug_init: invalid sector_size %u\n", 2850 printk(KERN_ERR "scsi_debug_init: invalid sector_size %d\n",
2530 scsi_debug_sector_size); 2851 scsi_debug_sector_size);
2531 return -EINVAL; 2852 return -EINVAL;
2532 } 2853 }
2533 2854
2855 switch (scsi_debug_dif) {
2856
2857 case SD_DIF_TYPE0_PROTECTION:
2858 case SD_DIF_TYPE1_PROTECTION:
2859 case SD_DIF_TYPE3_PROTECTION:
2860 break;
2861
2862 default:
2863 printk(KERN_ERR "scsi_debug_init: dif must be 0, 1 or 3\n");
2864 return -EINVAL;
2865 }
2866
2867 if (scsi_debug_guard > 1) {
2868 printk(KERN_ERR "scsi_debug_init: guard must be 0 or 1\n");
2869 return -EINVAL;
2870 }
2871
2872 if (scsi_debug_ato > 1) {
2873 printk(KERN_ERR "scsi_debug_init: ato must be 0 or 1\n");
2874 return -EINVAL;
2875 }
2876
2534 if (scsi_debug_dev_size_mb < 1) 2877 if (scsi_debug_dev_size_mb < 1)
2535 scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ 2878 scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
2536 sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; 2879 sz = (unsigned long)scsi_debug_dev_size_mb * 1048576;
@@ -2563,6 +2906,24 @@ static int __init scsi_debug_init(void)
2563 if (scsi_debug_num_parts > 0) 2906 if (scsi_debug_num_parts > 0)
2564 sdebug_build_parts(fake_storep, sz); 2907 sdebug_build_parts(fake_storep, sz);
2565 2908
2909 if (scsi_debug_dif) {
2910 int dif_size;
2911
2912 dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);
2913 dif_storep = vmalloc(dif_size);
2914
2915 printk(KERN_ERR "scsi_debug_init: dif_storep %u bytes @ %p\n",
2916 dif_size, dif_storep);
2917
2918 if (dif_storep == NULL) {
2919 printk(KERN_ERR "scsi_debug_init: out of mem. (DIX)\n");
2920 ret = -ENOMEM;
2921 goto free_vm;
2922 }
2923
2924 memset(dif_storep, 0xff, dif_size);
2925 }
2926
2566 ret = device_register(&pseudo_primary); 2927 ret = device_register(&pseudo_primary);
2567 if (ret < 0) { 2928 if (ret < 0) {
2568 printk(KERN_WARNING "scsi_debug: device_register error: %d\n", 2929 printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
@@ -2615,6 +2976,8 @@ bus_unreg:
2615dev_unreg: 2976dev_unreg:
2616 device_unregister(&pseudo_primary); 2977 device_unregister(&pseudo_primary);
2617free_vm: 2978free_vm:
2979 if (dif_storep)
2980 vfree(dif_storep);
2618 vfree(fake_storep); 2981 vfree(fake_storep);
2619 2982
2620 return ret; 2983 return ret;
@@ -2632,6 +2995,9 @@ static void __exit scsi_debug_exit(void)
2632 bus_unregister(&pseudo_lld_bus); 2995 bus_unregister(&pseudo_lld_bus);
2633 device_unregister(&pseudo_primary); 2996 device_unregister(&pseudo_primary);
2634 2997
2998 if (dif_storep)
2999 vfree(dif_storep);
3000
2635 vfree(fake_storep); 3001 vfree(fake_storep);
2636} 3002}
2637 3003
@@ -2732,6 +3098,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
2732 struct sdebug_dev_info *devip = NULL; 3098 struct sdebug_dev_info *devip = NULL;
2733 int inj_recovered = 0; 3099 int inj_recovered = 0;
2734 int inj_transport = 0; 3100 int inj_transport = 0;
3101 int inj_dif = 0;
3102 int inj_dix = 0;
2735 int delay_override = 0; 3103 int delay_override = 0;
2736 3104
2737 scsi_set_resid(SCpnt, 0); 3105 scsi_set_resid(SCpnt, 0);
@@ -2769,6 +3137,10 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
2769 inj_recovered = 1; /* to reads and writes below */ 3137 inj_recovered = 1; /* to reads and writes below */
2770 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) 3138 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
2771 inj_transport = 1; /* to reads and writes below */ 3139 inj_transport = 1; /* to reads and writes below */
3140 else if (SCSI_DEBUG_OPT_DIF_ERR & scsi_debug_opts)
3141 inj_dif = 1; /* to reads and writes below */
3142 else if (SCSI_DEBUG_OPT_DIX_ERR & scsi_debug_opts)
3143 inj_dix = 1; /* to reads and writes below */
2772 } 3144 }
2773 3145
2774 if (devip->wlun) { 3146 if (devip->wlun) {
@@ -2870,6 +3242,12 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
2870 mk_sense_buffer(devip, ABORTED_COMMAND, 3242 mk_sense_buffer(devip, ABORTED_COMMAND,
2871 TRANSPORT_PROBLEM, ACK_NAK_TO); 3243 TRANSPORT_PROBLEM, ACK_NAK_TO);
2872 errsts = check_condition_result; 3244 errsts = check_condition_result;
3245 } else if (inj_dif && (0 == errsts)) {
3246 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1);
3247 errsts = illegal_condition_result;
3248 } else if (inj_dix && (0 == errsts)) {
3249 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1);
3250 errsts = illegal_condition_result;
2873 } 3251 }
2874 break; 3252 break;
2875 case REPORT_LUNS: /* mandatory, ignore unit attention */ 3253 case REPORT_LUNS: /* mandatory, ignore unit attention */
@@ -2894,6 +3272,12 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
2894 mk_sense_buffer(devip, RECOVERED_ERROR, 3272 mk_sense_buffer(devip, RECOVERED_ERROR,
2895 THRESHOLD_EXCEEDED, 0); 3273 THRESHOLD_EXCEEDED, 0);
2896 errsts = check_condition_result; 3274 errsts = check_condition_result;
3275 } else if (inj_dif && (0 == errsts)) {
3276 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1);
3277 errsts = illegal_condition_result;
3278 } else if (inj_dix && (0 == errsts)) {
3279 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1);
3280 errsts = illegal_condition_result;
2897 } 3281 }
2898 break; 3282 break;
2899 case MODE_SENSE: 3283 case MODE_SENSE:
@@ -2982,6 +3366,7 @@ static int sdebug_driver_probe(struct device * dev)
2982 int error = 0; 3366 int error = 0;
2983 struct sdebug_host_info *sdbg_host; 3367 struct sdebug_host_info *sdbg_host;
2984 struct Scsi_Host *hpnt; 3368 struct Scsi_Host *hpnt;
3369 int host_prot;
2985 3370
2986 sdbg_host = to_sdebug_host(dev); 3371 sdbg_host = to_sdebug_host(dev);
2987 3372
@@ -3000,6 +3385,50 @@ static int sdebug_driver_probe(struct device * dev)
3000 hpnt->max_id = scsi_debug_num_tgts; 3385 hpnt->max_id = scsi_debug_num_tgts;
3001 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ 3386 hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */
3002 3387
3388 host_prot = 0;
3389
3390 switch (scsi_debug_dif) {
3391
3392 case SD_DIF_TYPE1_PROTECTION:
3393 host_prot = SHOST_DIF_TYPE1_PROTECTION;
3394 if (scsi_debug_dix)
3395 host_prot |= SHOST_DIX_TYPE1_PROTECTION;
3396 break;
3397
3398 case SD_DIF_TYPE2_PROTECTION:
3399 host_prot = SHOST_DIF_TYPE2_PROTECTION;
3400 if (scsi_debug_dix)
3401 host_prot |= SHOST_DIX_TYPE2_PROTECTION;
3402 break;
3403
3404 case SD_DIF_TYPE3_PROTECTION:
3405 host_prot = SHOST_DIF_TYPE3_PROTECTION;
3406 if (scsi_debug_dix)
3407 host_prot |= SHOST_DIX_TYPE3_PROTECTION;
3408 break;
3409
3410 default:
3411 if (scsi_debug_dix)
3412 host_prot |= SHOST_DIX_TYPE0_PROTECTION;
3413 break;
3414 }
3415
3416 scsi_host_set_prot(hpnt, host_prot);
3417
3418 printk(KERN_INFO "scsi_debug: host protection%s%s%s%s%s%s%s\n",
3419 (host_prot & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "",
3420 (host_prot & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "",
3421 (host_prot & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "",
3422 (host_prot & SHOST_DIX_TYPE0_PROTECTION) ? " DIX0" : "",
3423 (host_prot & SHOST_DIX_TYPE1_PROTECTION) ? " DIX1" : "",
3424 (host_prot & SHOST_DIX_TYPE2_PROTECTION) ? " DIX2" : "",
3425 (host_prot & SHOST_DIX_TYPE3_PROTECTION) ? " DIX3" : "");
3426
3427 if (scsi_debug_guard == 1)
3428 scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_IP);
3429 else
3430 scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC);
3431
3003 error = scsi_add_host(hpnt, &sdbg_host->dev); 3432 error = scsi_add_host(hpnt, &sdbg_host->dev);
3004 if (error) { 3433 if (error) {
3005 printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); 3434 printk(KERN_ERR "%s: scsi_add_host failed\n", __func__);
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index ad6a1370761e..0c2c73be1974 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1441,6 +1441,11 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1441 } 1441 }
1442} 1442}
1443 1443
1444static void eh_lock_door_done(struct request *req, int uptodate)
1445{
1446 __blk_put_request(req->q, req);
1447}
1448
1444/** 1449/**
1445 * scsi_eh_lock_door - Prevent medium removal for the specified device 1450 * scsi_eh_lock_door - Prevent medium removal for the specified device
1446 * @sdev: SCSI device to prevent medium removal 1451 * @sdev: SCSI device to prevent medium removal
@@ -1463,19 +1468,28 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1463 */ 1468 */
1464static void scsi_eh_lock_door(struct scsi_device *sdev) 1469static void scsi_eh_lock_door(struct scsi_device *sdev)
1465{ 1470{
1466 unsigned char cmnd[MAX_COMMAND_SIZE]; 1471 struct request *req;
1467 1472
1468 cmnd[0] = ALLOW_MEDIUM_REMOVAL; 1473 req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
1469 cmnd[1] = 0; 1474 if (!req)
1470 cmnd[2] = 0; 1475 return;
1471 cmnd[3] = 0;
1472 cmnd[4] = SCSI_REMOVAL_PREVENT;
1473 cmnd[5] = 0;
1474 1476
1475 scsi_execute_async(sdev, cmnd, 6, DMA_NONE, NULL, 0, 0, 10 * HZ, 1477 req->cmd[0] = ALLOW_MEDIUM_REMOVAL;
1476 5, NULL, NULL, GFP_KERNEL); 1478 req->cmd[1] = 0;
1477} 1479 req->cmd[2] = 0;
1480 req->cmd[3] = 0;
1481 req->cmd[4] = SCSI_REMOVAL_PREVENT;
1482 req->cmd[5] = 0;
1478 1483
1484 req->cmd_len = COMMAND_SIZE(req->cmd[0]);
1485
1486 req->cmd_type = REQ_TYPE_BLOCK_PC;
1487 req->cmd_flags |= REQ_QUIET;
1488 req->timeout = 10 * HZ;
1489 req->retries = 5;
1490
1491 blk_execute_rq_nowait(req->q, NULL, req, 1, eh_lock_door_done);
1492}
1479 1493
1480/** 1494/**
1481 * scsi_restart_operations - restart io operations to the specified host. 1495 * scsi_restart_operations - restart io operations to the specified host.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index b82ffd90632e..4b13e36d3aa0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -277,196 +277,6 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
277} 277}
278EXPORT_SYMBOL(scsi_execute_req); 278EXPORT_SYMBOL(scsi_execute_req);
279 279
280struct scsi_io_context {
281 void *data;
282 void (*done)(void *data, char *sense, int result, int resid);
283 char sense[SCSI_SENSE_BUFFERSIZE];
284};
285
286static struct kmem_cache *scsi_io_context_cache;
287
288static void scsi_end_async(struct request *req, int uptodate)
289{
290 struct scsi_io_context *sioc = req->end_io_data;
291
292 if (sioc->done)
293 sioc->done(sioc->data, sioc->sense, req->errors, req->data_len);
294
295 kmem_cache_free(scsi_io_context_cache, sioc);
296 __blk_put_request(req->q, req);
297}
298
299static int scsi_merge_bio(struct request *rq, struct bio *bio)
300{
301 struct request_queue *q = rq->q;
302
303 bio->bi_flags &= ~(1 << BIO_SEG_VALID);
304 if (rq_data_dir(rq) == WRITE)
305 bio->bi_rw |= (1 << BIO_RW);
306 blk_queue_bounce(q, &bio);
307
308 return blk_rq_append_bio(q, rq, bio);
309}
310
311static void scsi_bi_endio(struct bio *bio, int error)
312{
313 bio_put(bio);
314}
315
316/**
317 * scsi_req_map_sg - map a scatterlist into a request
318 * @rq: request to fill
319 * @sgl: scatterlist
320 * @nsegs: number of elements
321 * @bufflen: len of buffer
322 * @gfp: memory allocation flags
323 *
324 * scsi_req_map_sg maps a scatterlist into a request so that the
325 * request can be sent to the block layer. We do not trust the scatterlist
326 * sent to use, as some ULDs use that struct to only organize the pages.
327 */
328static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
329 int nsegs, unsigned bufflen, gfp_t gfp)
330{
331 struct request_queue *q = rq->q;
332 int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
333 unsigned int data_len = bufflen, len, bytes, off;
334 struct scatterlist *sg;
335 struct page *page;
336 struct bio *bio = NULL;
337 int i, err, nr_vecs = 0;
338
339 for_each_sg(sgl, sg, nsegs, i) {
340 page = sg_page(sg);
341 off = sg->offset;
342 len = sg->length;
343
344 while (len > 0 && data_len > 0) {
345 /*
346 * sg sends a scatterlist that is larger than
347 * the data_len it wants transferred for certain
348 * IO sizes
349 */
350 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
351 bytes = min(bytes, data_len);
352
353 if (!bio) {
354 nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
355 nr_pages -= nr_vecs;
356
357 bio = bio_alloc(gfp, nr_vecs);
358 if (!bio) {
359 err = -ENOMEM;
360 goto free_bios;
361 }
362 bio->bi_end_io = scsi_bi_endio;
363 }
364
365 if (bio_add_pc_page(q, bio, page, bytes, off) !=
366 bytes) {
367 bio_put(bio);
368 err = -EINVAL;
369 goto free_bios;
370 }
371
372 if (bio->bi_vcnt >= nr_vecs) {
373 err = scsi_merge_bio(rq, bio);
374 if (err) {
375 bio_endio(bio, 0);
376 goto free_bios;
377 }
378 bio = NULL;
379 }
380
381 page++;
382 len -= bytes;
383 data_len -=bytes;
384 off = 0;
385 }
386 }
387
388 rq->buffer = rq->data = NULL;
389 rq->data_len = bufflen;
390 return 0;
391
392free_bios:
393 while ((bio = rq->bio) != NULL) {
394 rq->bio = bio->bi_next;
395 /*
396 * call endio instead of bio_put incase it was bounced
397 */
398 bio_endio(bio, 0);
399 }
400
401 return err;
402}
403
404/**
405 * scsi_execute_async - insert request
406 * @sdev: scsi device
407 * @cmd: scsi command
408 * @cmd_len: length of scsi cdb
409 * @data_direction: DMA_TO_DEVICE, DMA_FROM_DEVICE, or DMA_NONE
410 * @buffer: data buffer (this can be a kernel buffer or scatterlist)
411 * @bufflen: len of buffer
412 * @use_sg: if buffer is a scatterlist this is the number of elements
413 * @timeout: request timeout in seconds
414 * @retries: number of times to retry request
415 * @privdata: data passed to done()
416 * @done: callback function when done
417 * @gfp: memory allocation flags
418 */
419int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
420 int cmd_len, int data_direction, void *buffer, unsigned bufflen,
421 int use_sg, int timeout, int retries, void *privdata,
422 void (*done)(void *, char *, int, int), gfp_t gfp)
423{
424 struct request *req;
425 struct scsi_io_context *sioc;
426 int err = 0;
427 int write = (data_direction == DMA_TO_DEVICE);
428
429 sioc = kmem_cache_zalloc(scsi_io_context_cache, gfp);
430 if (!sioc)
431 return DRIVER_ERROR << 24;
432
433 req = blk_get_request(sdev->request_queue, write, gfp);
434 if (!req)
435 goto free_sense;
436 req->cmd_type = REQ_TYPE_BLOCK_PC;
437 req->cmd_flags |= REQ_QUIET;
438
439 if (use_sg)
440 err = scsi_req_map_sg(req, buffer, use_sg, bufflen, gfp);
441 else if (bufflen)
442 err = blk_rq_map_kern(req->q, req, buffer, bufflen, gfp);
443
444 if (err)
445 goto free_req;
446
447 req->cmd_len = cmd_len;
448 memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
449 memcpy(req->cmd, cmd, req->cmd_len);
450 req->sense = sioc->sense;
451 req->sense_len = 0;
452 req->timeout = timeout;
453 req->retries = retries;
454 req->end_io_data = sioc;
455
456 sioc->data = privdata;
457 sioc->done = done;
458
459 blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async);
460 return 0;
461
462free_req:
463 blk_put_request(req);
464free_sense:
465 kmem_cache_free(scsi_io_context_cache, sioc);
466 return DRIVER_ERROR << 24;
467}
468EXPORT_SYMBOL_GPL(scsi_execute_async);
469
470/* 280/*
471 * Function: scsi_init_cmd_errh() 281 * Function: scsi_init_cmd_errh()
472 * 282 *
@@ -1920,20 +1730,12 @@ int __init scsi_init_queue(void)
1920{ 1730{
1921 int i; 1731 int i;
1922 1732
1923 scsi_io_context_cache = kmem_cache_create("scsi_io_context",
1924 sizeof(struct scsi_io_context),
1925 0, 0, NULL);
1926 if (!scsi_io_context_cache) {
1927 printk(KERN_ERR "SCSI: can't init scsi io context cache\n");
1928 return -ENOMEM;
1929 }
1930
1931 scsi_sdb_cache = kmem_cache_create("scsi_data_buffer", 1733 scsi_sdb_cache = kmem_cache_create("scsi_data_buffer",
1932 sizeof(struct scsi_data_buffer), 1734 sizeof(struct scsi_data_buffer),
1933 0, 0, NULL); 1735 0, 0, NULL);
1934 if (!scsi_sdb_cache) { 1736 if (!scsi_sdb_cache) {
1935 printk(KERN_ERR "SCSI: can't init scsi sdb cache\n"); 1737 printk(KERN_ERR "SCSI: can't init scsi sdb cache\n");
1936 goto cleanup_io_context; 1738 return -ENOMEM;
1937 } 1739 }
1938 1740
1939 for (i = 0; i < SG_MEMPOOL_NR; i++) { 1741 for (i = 0; i < SG_MEMPOOL_NR; i++) {
@@ -1968,8 +1770,6 @@ cleanup_sdb:
1968 kmem_cache_destroy(sgp->slab); 1770 kmem_cache_destroy(sgp->slab);
1969 } 1771 }
1970 kmem_cache_destroy(scsi_sdb_cache); 1772 kmem_cache_destroy(scsi_sdb_cache);
1971cleanup_io_context:
1972 kmem_cache_destroy(scsi_io_context_cache);
1973 1773
1974 return -ENOMEM; 1774 return -ENOMEM;
1975} 1775}
@@ -1978,7 +1778,6 @@ void scsi_exit_queue(void)
1978{ 1778{
1979 int i; 1779 int i;
1980 1780
1981 kmem_cache_destroy(scsi_io_context_cache);
1982 kmem_cache_destroy(scsi_sdb_cache); 1781 kmem_cache_destroy(scsi_sdb_cache);
1983 1782
1984 for (i = 0; i < SG_MEMPOOL_NR; i++) { 1783 for (i = 0; i < SG_MEMPOOL_NR; i++) {
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 8f4de20c9deb..a14d245a66b8 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -797,6 +797,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
797 case TYPE_ENCLOSURE: 797 case TYPE_ENCLOSURE:
798 case TYPE_COMM: 798 case TYPE_COMM:
799 case TYPE_RAID: 799 case TYPE_RAID:
800 case TYPE_OSD:
800 sdev->writeable = 1; 801 sdev->writeable = 1;
801 break; 802 break;
802 case TYPE_ROM: 803 case TYPE_ROM:
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index da63802cbf9d..fa4711d12744 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1043,7 +1043,6 @@ EXPORT_SYMBOL(scsi_register_interface);
1043/** 1043/**
1044 * scsi_sysfs_add_host - add scsi host to subsystem 1044 * scsi_sysfs_add_host - add scsi host to subsystem
1045 * @shost: scsi host struct to add to subsystem 1045 * @shost: scsi host struct to add to subsystem
1046 * @dev: parent struct device pointer
1047 **/ 1046 **/
1048int scsi_sysfs_add_host(struct Scsi_Host *shost) 1047int scsi_sysfs_add_host(struct Scsi_Host *shost)
1049{ 1048{
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 3ee4eb40abcf..a152f89ae51c 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -95,7 +95,7 @@ static struct {
95 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" }, 95 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" },
96 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" }, 96 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" },
97 { FC_PORTTYPE_LPORT, "LPort (private loop)" }, 97 { FC_PORTTYPE_LPORT, "LPort (private loop)" },
98 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection" }, 98 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection)" },
99 { FC_PORTTYPE_NPIV, "NPIV VPORT" }, 99 { FC_PORTTYPE_NPIV, "NPIV VPORT" },
100}; 100};
101fc_enum_name_search(port_type, fc_port_type, fc_port_type_names) 101fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 2adfab8c11c1..094795455293 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -246,30 +246,13 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
246 memset(ihost, 0, sizeof(*ihost)); 246 memset(ihost, 0, sizeof(*ihost));
247 atomic_set(&ihost->nr_scans, 0); 247 atomic_set(&ihost->nr_scans, 0);
248 mutex_init(&ihost->mutex); 248 mutex_init(&ihost->mutex);
249
250 snprintf(ihost->scan_workq_name, sizeof(ihost->scan_workq_name),
251 "iscsi_scan_%d", shost->host_no);
252 ihost->scan_workq = create_singlethread_workqueue(
253 ihost->scan_workq_name);
254 if (!ihost->scan_workq)
255 return -ENOMEM;
256 return 0;
257}
258
259static int iscsi_remove_host(struct transport_container *tc, struct device *dev,
260 struct device *cdev)
261{
262 struct Scsi_Host *shost = dev_to_shost(dev);
263 struct iscsi_cls_host *ihost = shost->shost_data;
264
265 destroy_workqueue(ihost->scan_workq);
266 return 0; 249 return 0;
267} 250}
268 251
269static DECLARE_TRANSPORT_CLASS(iscsi_host_class, 252static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
270 "iscsi_host", 253 "iscsi_host",
271 iscsi_setup_host, 254 iscsi_setup_host,
272 iscsi_remove_host, 255 NULL,
273 NULL); 256 NULL);
274 257
275static DECLARE_TRANSPORT_CLASS(iscsi_session_class, 258static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
@@ -568,7 +551,7 @@ static void __iscsi_unblock_session(struct work_struct *work)
568 * scanning from userspace). 551 * scanning from userspace).
569 */ 552 */
570 if (shost->hostt->scan_finished) { 553 if (shost->hostt->scan_finished) {
571 if (queue_work(ihost->scan_workq, &session->scan_work)) 554 if (scsi_queue_work(shost, &session->scan_work))
572 atomic_inc(&ihost->nr_scans); 555 atomic_inc(&ihost->nr_scans);
573 } 556 }
574} 557}
@@ -636,14 +619,6 @@ static void __iscsi_unbind_session(struct work_struct *work)
636 iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); 619 iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
637} 620}
638 621
639static int iscsi_unbind_session(struct iscsi_cls_session *session)
640{
641 struct Scsi_Host *shost = iscsi_session_to_shost(session);
642 struct iscsi_cls_host *ihost = shost->shost_data;
643
644 return queue_work(ihost->scan_workq, &session->unbind_work);
645}
646
647struct iscsi_cls_session * 622struct iscsi_cls_session *
648iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, 623iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
649 int dd_size) 624 int dd_size)
@@ -796,7 +771,6 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data)
796void iscsi_remove_session(struct iscsi_cls_session *session) 771void iscsi_remove_session(struct iscsi_cls_session *session)
797{ 772{
798 struct Scsi_Host *shost = iscsi_session_to_shost(session); 773 struct Scsi_Host *shost = iscsi_session_to_shost(session);
799 struct iscsi_cls_host *ihost = shost->shost_data;
800 unsigned long flags; 774 unsigned long flags;
801 int err; 775 int err;
802 776
@@ -821,7 +795,7 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
821 795
822 scsi_target_unblock(&session->dev); 796 scsi_target_unblock(&session->dev);
823 /* flush running scans then delete devices */ 797 /* flush running scans then delete devices */
824 flush_workqueue(ihost->scan_workq); 798 scsi_flush_work(shost);
825 __iscsi_unbind_session(&session->unbind_work); 799 __iscsi_unbind_session(&session->unbind_work);
826 800
827 /* hw iscsi may not have removed all connections from session */ 801 /* hw iscsi may not have removed all connections from session */
@@ -1215,14 +1189,15 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
1215{ 1189{
1216 struct iscsi_transport *transport = priv->iscsi_transport; 1190 struct iscsi_transport *transport = priv->iscsi_transport;
1217 struct iscsi_cls_session *session; 1191 struct iscsi_cls_session *session;
1218 uint32_t host_no; 1192 struct Scsi_Host *shost;
1219 1193
1220 session = transport->create_session(ep, cmds_max, queue_depth, 1194 session = transport->create_session(ep, cmds_max, queue_depth,
1221 initial_cmdsn, &host_no); 1195 initial_cmdsn);
1222 if (!session) 1196 if (!session)
1223 return -ENOMEM; 1197 return -ENOMEM;
1224 1198
1225 ev->r.c_session_ret.host_no = host_no; 1199 shost = iscsi_session_to_shost(session);
1200 ev->r.c_session_ret.host_no = shost->host_no;
1226 ev->r.c_session_ret.sid = session->sid; 1201 ev->r.c_session_ret.sid = session->sid;
1227 return 0; 1202 return 0;
1228} 1203}
@@ -1439,7 +1414,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1439 case ISCSI_UEVENT_UNBIND_SESSION: 1414 case ISCSI_UEVENT_UNBIND_SESSION:
1440 session = iscsi_session_lookup(ev->u.d_session.sid); 1415 session = iscsi_session_lookup(ev->u.d_session.sid);
1441 if (session) 1416 if (session)
1442 iscsi_unbind_session(session); 1417 scsi_queue_work(iscsi_session_to_shost(session),
1418 &session->unbind_work);
1443 else 1419 else
1444 err = -EINVAL; 1420 err = -EINVAL;
1445 break; 1421 break;
@@ -1801,8 +1777,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
1801 priv->daemon_pid = -1; 1777 priv->daemon_pid = -1;
1802 priv->iscsi_transport = tt; 1778 priv->iscsi_transport = tt;
1803 priv->t.user_scan = iscsi_user_scan; 1779 priv->t.user_scan = iscsi_user_scan;
1804 if (!(tt->caps & CAP_DATA_PATH_OFFLOAD)) 1780 priv->t.create_work_queue = 1;
1805 priv->t.create_work_queue = 1;
1806 1781
1807 priv->dev.class = &iscsi_transport_class; 1782 priv->dev.class = &iscsi_transport_class;
1808 dev_set_name(&priv->dev, "%s", tt->name); 1783 dev_set_name(&priv->dev, "%s", tt->name);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 4970ae4a62d6..aeab5d9dff27 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1273,42 +1273,126 @@ disable:
1273 sdkp->capacity = 0; 1273 sdkp->capacity = 0;
1274} 1274}
1275 1275
1276/* 1276static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
1277 * read disk capacity 1277 struct scsi_sense_hdr *sshdr, int sense_valid,
1278 */ 1278 int the_result)
1279static void 1279{
1280sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) 1280 sd_print_result(sdkp, the_result);
1281 if (driver_byte(the_result) & DRIVER_SENSE)
1282 sd_print_sense_hdr(sdkp, sshdr);
1283 else
1284 sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n");
1285
1286 /*
1287 * Set dirty bit for removable devices if not ready -
1288 * sometimes drives will not report this properly.
1289 */
1290 if (sdp->removable &&
1291 sense_valid && sshdr->sense_key == NOT_READY)
1292 sdp->changed = 1;
1293
1294 /*
1295 * We used to set media_present to 0 here to indicate no media
1296 * in the drive, but some drives fail read capacity even with
1297 * media present, so we can't do that.
1298 */
1299 sdkp->capacity = 0; /* unknown mapped to zero - as usual */
1300}
1301
1302#define RC16_LEN 32
1303#if RC16_LEN > SD_BUF_SIZE
1304#error RC16_LEN must not be more than SD_BUF_SIZE
1305#endif
1306
1307static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
1308 unsigned char *buffer)
1281{ 1309{
1282 unsigned char cmd[16]; 1310 unsigned char cmd[16];
1283 int the_result, retries;
1284 int sector_size = 0;
1285 /* Force READ CAPACITY(16) when PROTECT=1 */
1286 int longrc = scsi_device_protection(sdkp->device) ? 1 : 0;
1287 struct scsi_sense_hdr sshdr; 1311 struct scsi_sense_hdr sshdr;
1288 int sense_valid = 0; 1312 int sense_valid = 0;
1289 struct scsi_device *sdp = sdkp->device; 1313 int the_result;
1314 int retries = 3;
1315 unsigned long long lba;
1316 unsigned sector_size;
1290 1317
1291repeat:
1292 retries = 3;
1293 do { 1318 do {
1294 if (longrc) { 1319 memset(cmd, 0, 16);
1295 memset((void *) cmd, 0, 16); 1320 cmd[0] = SERVICE_ACTION_IN;
1296 cmd[0] = SERVICE_ACTION_IN; 1321 cmd[1] = SAI_READ_CAPACITY_16;
1297 cmd[1] = SAI_READ_CAPACITY_16; 1322 cmd[13] = RC16_LEN;
1298 cmd[13] = 13; 1323 memset(buffer, 0, RC16_LEN);
1299 memset((void *) buffer, 0, 13); 1324
1300 } else { 1325 the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
1301 cmd[0] = READ_CAPACITY; 1326 buffer, RC16_LEN, &sshdr,
1302 memset((void *) &cmd[1], 0, 9); 1327 SD_TIMEOUT, SD_MAX_RETRIES, NULL);
1303 memset((void *) buffer, 0, 8); 1328
1329 if (media_not_present(sdkp, &sshdr))
1330 return -ENODEV;
1331
1332 if (the_result) {
1333 sense_valid = scsi_sense_valid(&sshdr);
1334 if (sense_valid &&
1335 sshdr.sense_key == ILLEGAL_REQUEST &&
1336 (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
1337 sshdr.ascq == 0x00)
1338 /* Invalid Command Operation Code or
1339 * Invalid Field in CDB, just retry
1340 * silently with RC10 */
1341 return -EINVAL;
1304 } 1342 }
1305 1343 retries--;
1344
1345 } while (the_result && retries);
1346
1347 if (the_result) {
1348 sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n");
1349 read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result);
1350 return -EINVAL;
1351 }
1352
1353 sector_size = (buffer[8] << 24) | (buffer[9] << 16) |
1354 (buffer[10] << 8) | buffer[11];
1355 lba = (((u64)buffer[0] << 56) | ((u64)buffer[1] << 48) |
1356 ((u64)buffer[2] << 40) | ((u64)buffer[3] << 32) |
1357 ((u64)buffer[4] << 24) | ((u64)buffer[5] << 16) |
1358 ((u64)buffer[6] << 8) | (u64)buffer[7]);
1359
1360 sd_read_protection_type(sdkp, buffer);
1361
1362 if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
1363 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
1364 "kernel compiled with support for large block "
1365 "devices.\n");
1366 sdkp->capacity = 0;
1367 return -EOVERFLOW;
1368 }
1369
1370 sdkp->capacity = lba + 1;
1371 return sector_size;
1372}
1373
1374static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
1375 unsigned char *buffer)
1376{
1377 unsigned char cmd[16];
1378 struct scsi_sense_hdr sshdr;
1379 int sense_valid = 0;
1380 int the_result;
1381 int retries = 3;
1382 sector_t lba;
1383 unsigned sector_size;
1384
1385 do {
1386 cmd[0] = READ_CAPACITY;
1387 memset(&cmd[1], 0, 9);
1388 memset(buffer, 0, 8);
1389
1306 the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, 1390 the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
1307 buffer, longrc ? 13 : 8, &sshdr, 1391 buffer, 8, &sshdr,
1308 SD_TIMEOUT, SD_MAX_RETRIES, NULL); 1392 SD_TIMEOUT, SD_MAX_RETRIES, NULL);
1309 1393
1310 if (media_not_present(sdkp, &sshdr)) 1394 if (media_not_present(sdkp, &sshdr))
1311 return; 1395 return -ENODEV;
1312 1396
1313 if (the_result) 1397 if (the_result)
1314 sense_valid = scsi_sense_valid(&sshdr); 1398 sense_valid = scsi_sense_valid(&sshdr);
@@ -1316,85 +1400,96 @@ repeat:
1316 1400
1317 } while (the_result && retries); 1401 } while (the_result && retries);
1318 1402
1319 if (the_result && !longrc) { 1403 if (the_result) {
1320 sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n"); 1404 sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n");
1321 sd_print_result(sdkp, the_result); 1405 read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result);
1322 if (driver_byte(the_result) & DRIVER_SENSE) 1406 return -EINVAL;
1323 sd_print_sense_hdr(sdkp, &sshdr); 1407 }
1324 else
1325 sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n");
1326 1408
1327 /* Set dirty bit for removable devices if not ready - 1409 sector_size = (buffer[4] << 24) | (buffer[5] << 16) |
1328 * sometimes drives will not report this properly. */ 1410 (buffer[6] << 8) | buffer[7];
1329 if (sdp->removable && 1411 lba = (buffer[0] << 24) | (buffer[1] << 16) |
1330 sense_valid && sshdr.sense_key == NOT_READY) 1412 (buffer[2] << 8) | buffer[3];
1331 sdp->changed = 1;
1332 1413
1333 /* Either no media are present but the drive didn't tell us, 1414 if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
1334 or they are present but the read capacity command fails */ 1415 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
1335 /* sdkp->media_present = 0; -- not always correct */ 1416 "kernel compiled with support for large block "
1336 sdkp->capacity = 0; /* unknown mapped to zero - as usual */ 1417 "devices.\n");
1418 sdkp->capacity = 0;
1419 return -EOVERFLOW;
1420 }
1337 1421
1338 return; 1422 sdkp->capacity = lba + 1;
1339 } else if (the_result && longrc) { 1423 return sector_size;
1340 /* READ CAPACITY(16) has been failed */ 1424}
1341 sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n");
1342 sd_print_result(sdkp, the_result);
1343 sd_printk(KERN_NOTICE, sdkp, "Use 0xffffffff as device size\n");
1344 1425
1345 sdkp->capacity = 1 + (sector_t) 0xffffffff; 1426static int sd_try_rc16_first(struct scsi_device *sdp)
1346 goto got_data; 1427{
1347 } 1428 if (sdp->scsi_level > SCSI_SPC_2)
1348 1429 return 1;
1349 if (!longrc) { 1430 if (scsi_device_protection(sdp))
1350 sector_size = (buffer[4] << 24) | 1431 return 1;
1351 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; 1432 return 0;
1352 if (buffer[0] == 0xff && buffer[1] == 0xff && 1433}
1353 buffer[2] == 0xff && buffer[3] == 0xff) { 1434
1354 if(sizeof(sdkp->capacity) > 4) { 1435/*
1355 sd_printk(KERN_NOTICE, sdkp, "Very big device. " 1436 * read disk capacity
1356 "Trying to use READ CAPACITY(16).\n"); 1437 */
1357 longrc = 1; 1438static void
1358 goto repeat; 1439sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
1359 } 1440{
1360 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use " 1441 int sector_size;
1361 "a kernel compiled with support for large " 1442 struct scsi_device *sdp = sdkp->device;
1362 "block devices.\n"); 1443 sector_t old_capacity = sdkp->capacity;
1363 sdkp->capacity = 0; 1444
1445 if (sd_try_rc16_first(sdp)) {
1446 sector_size = read_capacity_16(sdkp, sdp, buffer);
1447 if (sector_size == -EOVERFLOW)
1364 goto got_data; 1448 goto got_data;
1365 } 1449 if (sector_size == -ENODEV)
1366 sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) | 1450 return;
1367 (buffer[1] << 16) | 1451 if (sector_size < 0)
1368 (buffer[2] << 8) | 1452 sector_size = read_capacity_10(sdkp, sdp, buffer);
1369 buffer[3]); 1453 if (sector_size < 0)
1454 return;
1370 } else { 1455 } else {
1371 sdkp->capacity = 1 + (((u64)buffer[0] << 56) | 1456 sector_size = read_capacity_10(sdkp, sdp, buffer);
1372 ((u64)buffer[1] << 48) | 1457 if (sector_size == -EOVERFLOW)
1373 ((u64)buffer[2] << 40) | 1458 goto got_data;
1374 ((u64)buffer[3] << 32) | 1459 if (sector_size < 0)
1375 ((sector_t)buffer[4] << 24) | 1460 return;
1376 ((sector_t)buffer[5] << 16) | 1461 if ((sizeof(sdkp->capacity) > 4) &&
1377 ((sector_t)buffer[6] << 8) | 1462 (sdkp->capacity > 0xffffffffULL)) {
1378 (sector_t)buffer[7]); 1463 int old_sector_size = sector_size;
1379 1464 sd_printk(KERN_NOTICE, sdkp, "Very big device. "
1380 sector_size = (buffer[8] << 24) | 1465 "Trying to use READ CAPACITY(16).\n");
1381 (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; 1466 sector_size = read_capacity_16(sdkp, sdp, buffer);
1382 1467 if (sector_size < 0) {
1383 sd_read_protection_type(sdkp, buffer); 1468 sd_printk(KERN_NOTICE, sdkp,
1384 } 1469 "Using 0xffffffff as device size\n");
1385 1470 sdkp->capacity = 1 + (sector_t) 0xffffffff;
1386 /* Some devices return the total number of sectors, not the 1471 sector_size = old_sector_size;
1387 * highest sector number. Make the necessary adjustment. */ 1472 goto got_data;
1388 if (sdp->fix_capacity) { 1473 }
1389 --sdkp->capacity; 1474 }
1475 }
1390 1476
1391 /* Some devices have version which report the correct sizes 1477 /* Some devices are known to return the total number of blocks,
1392 * and others which do not. We guess size according to a heuristic 1478 * not the highest block number. Some devices have versions
1393 * and err on the side of lowering the capacity. */ 1479 * which do this and others which do not. Some devices we might
1394 } else { 1480 * suspect of doing this but we don't know for certain.
1395 if (sdp->guess_capacity) 1481 *
1396 if (sdkp->capacity & 0x01) /* odd sizes are odd */ 1482 * If we know the reported capacity is wrong, decrement it. If
1397 --sdkp->capacity; 1483 * we can only guess, then assume the number of blocks is even
1484 * (usually true but not always) and err on the side of lowering
1485 * the capacity.
1486 */
1487 if (sdp->fix_capacity ||
1488 (sdp->guess_capacity && (sdkp->capacity & 0x01))) {
1489 sd_printk(KERN_INFO, sdkp, "Adjusting the sector count "
1490 "from its reported value: %llu\n",
1491 (unsigned long long) sdkp->capacity);
1492 --sdkp->capacity;
1398 } 1493 }
1399 1494
1400got_data: 1495got_data:
@@ -1437,10 +1532,11 @@ got_data:
1437 string_get_size(sz, STRING_UNITS_10, cap_str_10, 1532 string_get_size(sz, STRING_UNITS_10, cap_str_10,
1438 sizeof(cap_str_10)); 1533 sizeof(cap_str_10));
1439 1534
1440 sd_printk(KERN_NOTICE, sdkp, 1535 if (sdkp->first_scan || old_capacity != sdkp->capacity)
1441 "%llu %d-byte hardware sectors: (%s/%s)\n", 1536 sd_printk(KERN_NOTICE, sdkp,
1442 (unsigned long long)sdkp->capacity, 1537 "%llu %d-byte hardware sectors: (%s/%s)\n",
1443 sector_size, cap_str_10, cap_str_2); 1538 (unsigned long long)sdkp->capacity,
1539 sector_size, cap_str_10, cap_str_2);
1444 } 1540 }
1445 1541
1446 /* Rescale capacity to 512-byte units */ 1542 /* Rescale capacity to 512-byte units */
@@ -1477,6 +1573,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
1477 int res; 1573 int res;
1478 struct scsi_device *sdp = sdkp->device; 1574 struct scsi_device *sdp = sdkp->device;
1479 struct scsi_mode_data data; 1575 struct scsi_mode_data data;
1576 int old_wp = sdkp->write_prot;
1480 1577
1481 set_disk_ro(sdkp->disk, 0); 1578 set_disk_ro(sdkp->disk, 0);
1482 if (sdp->skip_ms_page_3f) { 1579 if (sdp->skip_ms_page_3f) {
@@ -1517,11 +1614,13 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
1517 } else { 1614 } else {
1518 sdkp->write_prot = ((data.device_specific & 0x80) != 0); 1615 sdkp->write_prot = ((data.device_specific & 0x80) != 0);
1519 set_disk_ro(sdkp->disk, sdkp->write_prot); 1616 set_disk_ro(sdkp->disk, sdkp->write_prot);
1520 sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", 1617 if (sdkp->first_scan || old_wp != sdkp->write_prot) {
1521 sdkp->write_prot ? "on" : "off"); 1618 sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n",
1522 sd_printk(KERN_DEBUG, sdkp, 1619 sdkp->write_prot ? "on" : "off");
1523 "Mode Sense: %02x %02x %02x %02x\n", 1620 sd_printk(KERN_DEBUG, sdkp,
1524 buffer[0], buffer[1], buffer[2], buffer[3]); 1621 "Mode Sense: %02x %02x %02x %02x\n",
1622 buffer[0], buffer[1], buffer[2], buffer[3]);
1623 }
1525 } 1624 }
1526} 1625}
1527 1626
@@ -1539,6 +1638,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
1539 int modepage; 1638 int modepage;
1540 struct scsi_mode_data data; 1639 struct scsi_mode_data data;
1541 struct scsi_sense_hdr sshdr; 1640 struct scsi_sense_hdr sshdr;
1641 int old_wce = sdkp->WCE;
1642 int old_rcd = sdkp->RCD;
1643 int old_dpofua = sdkp->DPOFUA;
1542 1644
1543 if (sdp->skip_ms_page_8) 1645 if (sdp->skip_ms_page_8)
1544 goto defaults; 1646 goto defaults;
@@ -1610,12 +1712,14 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
1610 sdkp->DPOFUA = 0; 1712 sdkp->DPOFUA = 0;
1611 } 1713 }
1612 1714
1613 sd_printk(KERN_NOTICE, sdkp, 1715 if (sdkp->first_scan || old_wce != sdkp->WCE ||
1614 "Write cache: %s, read cache: %s, %s\n", 1716 old_rcd != sdkp->RCD || old_dpofua != sdkp->DPOFUA)
1615 sdkp->WCE ? "enabled" : "disabled", 1717 sd_printk(KERN_NOTICE, sdkp,
1616 sdkp->RCD ? "disabled" : "enabled", 1718 "Write cache: %s, read cache: %s, %s\n",
1617 sdkp->DPOFUA ? "supports DPO and FUA" 1719 sdkp->WCE ? "enabled" : "disabled",
1618 : "doesn't support DPO or FUA"); 1720 sdkp->RCD ? "disabled" : "enabled",
1721 sdkp->DPOFUA ? "supports DPO and FUA"
1722 : "doesn't support DPO or FUA");
1619 1723
1620 return; 1724 return;
1621 } 1725 }
@@ -1711,15 +1815,6 @@ static int sd_revalidate_disk(struct gendisk *disk)
1711 goto out; 1815 goto out;
1712 } 1816 }
1713 1817
1714 /* defaults, until the device tells us otherwise */
1715 sdp->sector_size = 512;
1716 sdkp->capacity = 0;
1717 sdkp->media_present = 1;
1718 sdkp->write_prot = 0;
1719 sdkp->WCE = 0;
1720 sdkp->RCD = 0;
1721 sdkp->ATO = 0;
1722
1723 sd_spinup_disk(sdkp); 1818 sd_spinup_disk(sdkp);
1724 1819
1725 /* 1820 /*
@@ -1733,6 +1828,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
1733 sd_read_app_tag_own(sdkp, buffer); 1828 sd_read_app_tag_own(sdkp, buffer);
1734 } 1829 }
1735 1830
1831 sdkp->first_scan = 0;
1832
1736 /* 1833 /*
1737 * We now have all cache related info, determine how we deal 1834 * We now have all cache related info, determine how we deal
1738 * with ordered requests. Note that as the current SCSI 1835 * with ordered requests. Note that as the current SCSI
@@ -1843,6 +1940,16 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
1843 gd->private_data = &sdkp->driver; 1940 gd->private_data = &sdkp->driver;
1844 gd->queue = sdkp->device->request_queue; 1941 gd->queue = sdkp->device->request_queue;
1845 1942
1943 /* defaults, until the device tells us otherwise */
1944 sdp->sector_size = 512;
1945 sdkp->capacity = 0;
1946 sdkp->media_present = 1;
1947 sdkp->write_prot = 0;
1948 sdkp->WCE = 0;
1949 sdkp->RCD = 0;
1950 sdkp->ATO = 0;
1951 sdkp->first_scan = 1;
1952
1846 sd_revalidate_disk(gd); 1953 sd_revalidate_disk(gd);
1847 1954
1848 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); 1955 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 75638e7d3f66..708778cf5f06 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -53,6 +53,7 @@ struct scsi_disk {
53 unsigned WCE : 1; /* state of disk WCE bit */ 53 unsigned WCE : 1; /* state of disk WCE bit */
54 unsigned RCD : 1; /* state of disk RCD bit, unused */ 54 unsigned RCD : 1; /* state of disk RCD bit, unused */
55 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ 55 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
56 unsigned first_scan : 1;
56}; 57};
57#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) 58#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
58 59
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index e946e05db7f7..c9146d751cbf 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -345,44 +345,21 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
345 return 0; 345 return 0;
346} 346}
347 347
348#define VPD_INQUIRY_SIZE 36
349
350static void ses_match_to_enclosure(struct enclosure_device *edev, 348static void ses_match_to_enclosure(struct enclosure_device *edev,
351 struct scsi_device *sdev) 349 struct scsi_device *sdev)
352{ 350{
353 unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL); 351 unsigned char *buf;
354 unsigned char *desc; 352 unsigned char *desc;
355 u16 vpd_len; 353 unsigned int vpd_len;
356 struct efd efd = { 354 struct efd efd = {
357 .addr = 0, 355 .addr = 0,
358 }; 356 };
359 unsigned char cmd[] = {
360 INQUIRY,
361 1,
362 0x83,
363 VPD_INQUIRY_SIZE >> 8,
364 VPD_INQUIRY_SIZE & 0xff,
365 0
366 };
367 357
358 buf = scsi_get_vpd_page(sdev, 0x83);
368 if (!buf) 359 if (!buf)
369 return; 360 return;
370 361
371 if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, 362 vpd_len = ((buf[2] << 8) | buf[3]) + 4;
372 VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES,
373 NULL))
374 goto free;
375
376 vpd_len = (buf[2] << 8) + buf[3];
377 kfree(buf);
378 buf = kmalloc(vpd_len, GFP_KERNEL);
379 if (!buf)
380 return;
381 cmd[3] = vpd_len >> 8;
382 cmd[4] = vpd_len & 0xff;
383 if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf,
384 vpd_len, NULL, SES_TIMEOUT, SES_RETRIES, NULL))
385 goto free;
386 363
387 desc = buf + 4; 364 desc = buf + 4;
388 while (desc < buf + vpd_len) { 365 while (desc < buf + vpd_len) {
@@ -393,7 +370,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
393 u8 type = desc[1] & 0x0f; 370 u8 type = desc[1] & 0x0f;
394 u8 len = desc[3]; 371 u8 len = desc[3];
395 372
396 if (piv && code_set == 1 && assoc == 1 && code_set == 1 373 if (piv && code_set == 1 && assoc == 1
397 && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8) 374 && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8)
398 efd.addr = (u64)desc[4] << 56 | 375 efd.addr = (u64)desc[4] << 56 |
399 (u64)desc[5] << 48 | 376 (u64)desc[5] << 48 |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index b4ef2f84ea32..ffc87851f2e8 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -98,7 +98,6 @@ static int scatter_elem_sz = SG_SCATTER_SZ;
98static int scatter_elem_sz_prev = SG_SCATTER_SZ; 98static int scatter_elem_sz_prev = SG_SCATTER_SZ;
99 99
100#define SG_SECTOR_SZ 512 100#define SG_SECTOR_SZ 512
101#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
102 101
103static int sg_add(struct device *, struct class_interface *); 102static int sg_add(struct device *, struct class_interface *);
104static void sg_remove(struct device *, struct class_interface *); 103static void sg_remove(struct device *, struct class_interface *);
@@ -137,10 +136,11 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
137 volatile char done; /* 0->before bh, 1->before read, 2->read */ 136 volatile char done; /* 0->before bh, 1->before read, 2->read */
138 struct request *rq; 137 struct request *rq;
139 struct bio *bio; 138 struct bio *bio;
139 struct execute_work ew;
140} Sg_request; 140} Sg_request;
141 141
142typedef struct sg_fd { /* holds the state of a file descriptor */ 142typedef struct sg_fd { /* holds the state of a file descriptor */
143 struct sg_fd *nextfp; /* NULL when last opened fd on this device */ 143 struct list_head sfd_siblings;
144 struct sg_device *parentdp; /* owning device */ 144 struct sg_device *parentdp; /* owning device */
145 wait_queue_head_t read_wait; /* queue read until command done */ 145 wait_queue_head_t read_wait; /* queue read until command done */
146 rwlock_t rq_list_lock; /* protect access to list in req_arr */ 146 rwlock_t rq_list_lock; /* protect access to list in req_arr */
@@ -158,6 +158,8 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
158 char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */ 158 char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
159 char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */ 159 char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
160 char mmap_called; /* 0 -> mmap() never called on this fd */ 160 char mmap_called; /* 0 -> mmap() never called on this fd */
161 struct kref f_ref;
162 struct execute_work ew;
161} Sg_fd; 163} Sg_fd;
162 164
163typedef struct sg_device { /* holds the state of each scsi generic device */ 165typedef struct sg_device { /* holds the state of each scsi generic device */
@@ -165,27 +167,25 @@ typedef struct sg_device { /* holds the state of each scsi generic device */
165 wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ 167 wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */
166 int sg_tablesize; /* adapter's max scatter-gather table size */ 168 int sg_tablesize; /* adapter's max scatter-gather table size */
167 u32 index; /* device index number */ 169 u32 index; /* device index number */
168 Sg_fd *headfp; /* first open fd belonging to this device */ 170 struct list_head sfds;
169 volatile char detached; /* 0->attached, 1->detached pending removal */ 171 volatile char detached; /* 0->attached, 1->detached pending removal */
170 volatile char exclude; /* opened for exclusive access */ 172 volatile char exclude; /* opened for exclusive access */
171 char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */ 173 char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
172 struct gendisk *disk; 174 struct gendisk *disk;
173 struct cdev * cdev; /* char_dev [sysfs: /sys/cdev/major/sg<n>] */ 175 struct cdev * cdev; /* char_dev [sysfs: /sys/cdev/major/sg<n>] */
176 struct kref d_ref;
174} Sg_device; 177} Sg_device;
175 178
176static int sg_fasync(int fd, struct file *filp, int mode);
177/* tasklet or soft irq callback */ 179/* tasklet or soft irq callback */
178static void sg_rq_end_io(struct request *rq, int uptodate); 180static void sg_rq_end_io(struct request *rq, int uptodate);
179static int sg_start_req(Sg_request *srp, unsigned char *cmd); 181static int sg_start_req(Sg_request *srp, unsigned char *cmd);
180static void sg_finish_rem_req(Sg_request * srp); 182static void sg_finish_rem_req(Sg_request * srp);
181static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size); 183static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
182static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
183 int tablesize);
184static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, 184static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
185 Sg_request * srp); 185 Sg_request * srp);
186static ssize_t sg_new_write(Sg_fd *sfp, struct file *file, 186static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
187 const char __user *buf, size_t count, int blocking, 187 const char __user *buf, size_t count, int blocking,
188 int read_only, Sg_request **o_srp); 188 int read_only, int sg_io_owned, Sg_request **o_srp);
189static int sg_common_write(Sg_fd * sfp, Sg_request * srp, 189static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
190 unsigned char *cmnd, int timeout, int blocking); 190 unsigned char *cmnd, int timeout, int blocking);
191static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer); 191static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
@@ -194,16 +194,13 @@ static void sg_build_reserve(Sg_fd * sfp, int req_size);
194static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size); 194static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
195static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp); 195static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
196static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev); 196static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
197static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp); 197static void sg_remove_sfp(struct kref *);
198static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
199static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); 198static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
200static Sg_request *sg_add_request(Sg_fd * sfp); 199static Sg_request *sg_add_request(Sg_fd * sfp);
201static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); 200static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
202static int sg_res_in_use(Sg_fd * sfp); 201static int sg_res_in_use(Sg_fd * sfp);
203static Sg_device *sg_get_dev(int dev); 202static Sg_device *sg_get_dev(int dev);
204#ifdef CONFIG_SCSI_PROC_FS 203static void sg_put_dev(Sg_device *sdp);
205static int sg_last_dev(void);
206#endif
207 204
208#define SZ_SG_HEADER sizeof(struct sg_header) 205#define SZ_SG_HEADER sizeof(struct sg_header)
209#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t) 206#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t)
@@ -237,22 +234,17 @@ sg_open(struct inode *inode, struct file *filp)
237 nonseekable_open(inode, filp); 234 nonseekable_open(inode, filp);
238 SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags)); 235 SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
239 sdp = sg_get_dev(dev); 236 sdp = sg_get_dev(dev);
240 if ((!sdp) || (!sdp->device)) { 237 if (IS_ERR(sdp)) {
241 unlock_kernel(); 238 retval = PTR_ERR(sdp);
242 return -ENXIO; 239 sdp = NULL;
243 } 240 goto sg_put;
244 if (sdp->detached) {
245 unlock_kernel();
246 return -ENODEV;
247 } 241 }
248 242
249 /* This driver's module count bumped by fops_get in <linux/fs.h> */ 243 /* This driver's module count bumped by fops_get in <linux/fs.h> */
250 /* Prevent the device driver from vanishing while we sleep */ 244 /* Prevent the device driver from vanishing while we sleep */
251 retval = scsi_device_get(sdp->device); 245 retval = scsi_device_get(sdp->device);
252 if (retval) { 246 if (retval)
253 unlock_kernel(); 247 goto sg_put;
254 return retval;
255 }
256 248
257 if (!((flags & O_NONBLOCK) || 249 if (!((flags & O_NONBLOCK) ||
258 scsi_block_when_processing_errors(sdp->device))) { 250 scsi_block_when_processing_errors(sdp->device))) {
@@ -266,13 +258,13 @@ sg_open(struct inode *inode, struct file *filp)
266 retval = -EPERM; /* Can't lock it with read only access */ 258 retval = -EPERM; /* Can't lock it with read only access */
267 goto error_out; 259 goto error_out;
268 } 260 }
269 if (sdp->headfp && (flags & O_NONBLOCK)) { 261 if (!list_empty(&sdp->sfds) && (flags & O_NONBLOCK)) {
270 retval = -EBUSY; 262 retval = -EBUSY;
271 goto error_out; 263 goto error_out;
272 } 264 }
273 res = 0; 265 res = 0;
274 __wait_event_interruptible(sdp->o_excl_wait, 266 __wait_event_interruptible(sdp->o_excl_wait,
275 ((sdp->headfp || sdp->exclude) ? 0 : (sdp->exclude = 1)), res); 267 ((!list_empty(&sdp->sfds) || sdp->exclude) ? 0 : (sdp->exclude = 1)), res);
276 if (res) { 268 if (res) {
277 retval = res; /* -ERESTARTSYS because signal hit process */ 269 retval = res; /* -ERESTARTSYS because signal hit process */
278 goto error_out; 270 goto error_out;
@@ -294,7 +286,7 @@ sg_open(struct inode *inode, struct file *filp)
294 retval = -ENODEV; 286 retval = -ENODEV;
295 goto error_out; 287 goto error_out;
296 } 288 }
297 if (!sdp->headfp) { /* no existing opens on this device */ 289 if (list_empty(&sdp->sfds)) { /* no existing opens on this device */
298 sdp->sgdebug = 0; 290 sdp->sgdebug = 0;
299 q = sdp->device->request_queue; 291 q = sdp->device->request_queue;
300 sdp->sg_tablesize = min(q->max_hw_segments, 292 sdp->sg_tablesize = min(q->max_hw_segments,
@@ -303,16 +295,20 @@ sg_open(struct inode *inode, struct file *filp)
303 if ((sfp = sg_add_sfp(sdp, dev))) 295 if ((sfp = sg_add_sfp(sdp, dev)))
304 filp->private_data = sfp; 296 filp->private_data = sfp;
305 else { 297 else {
306 if (flags & O_EXCL) 298 if (flags & O_EXCL) {
307 sdp->exclude = 0; /* undo if error */ 299 sdp->exclude = 0; /* undo if error */
300 wake_up_interruptible(&sdp->o_excl_wait);
301 }
308 retval = -ENOMEM; 302 retval = -ENOMEM;
309 goto error_out; 303 goto error_out;
310 } 304 }
311 unlock_kernel(); 305 retval = 0;
312 return 0; 306error_out:
313 307 if (retval)
314 error_out: 308 scsi_device_put(sdp->device);
315 scsi_device_put(sdp->device); 309sg_put:
310 if (sdp)
311 sg_put_dev(sdp);
316 unlock_kernel(); 312 unlock_kernel();
317 return retval; 313 return retval;
318} 314}
@@ -327,13 +323,13 @@ sg_release(struct inode *inode, struct file *filp)
327 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) 323 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
328 return -ENXIO; 324 return -ENXIO;
329 SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name)); 325 SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name));
330 if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */ 326
331 if (!sdp->detached) { 327 sfp->closed = 1;
332 scsi_device_put(sdp->device); 328
333 } 329 sdp->exclude = 0;
334 sdp->exclude = 0; 330 wake_up_interruptible(&sdp->o_excl_wait);
335 wake_up_interruptible(&sdp->o_excl_wait); 331
336 } 332 kref_put(&sfp->f_ref, sg_remove_sfp);
337 return 0; 333 return 0;
338} 334}
339 335
@@ -557,7 +553,8 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
557 return -EFAULT; 553 return -EFAULT;
558 blocking = !(filp->f_flags & O_NONBLOCK); 554 blocking = !(filp->f_flags & O_NONBLOCK);
559 if (old_hdr.reply_len < 0) 555 if (old_hdr.reply_len < 0)
560 return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL); 556 return sg_new_write(sfp, filp, buf, count,
557 blocking, 0, 0, NULL);
561 if (count < (SZ_SG_HEADER + 6)) 558 if (count < (SZ_SG_HEADER + 6))
562 return -EIO; /* The minimum scsi command length is 6 bytes. */ 559 return -EIO; /* The minimum scsi command length is 6 bytes. */
563 560
@@ -638,7 +635,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
638 635
639static ssize_t 636static ssize_t
640sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, 637sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
641 size_t count, int blocking, int read_only, 638 size_t count, int blocking, int read_only, int sg_io_owned,
642 Sg_request **o_srp) 639 Sg_request **o_srp)
643{ 640{
644 int k; 641 int k;
@@ -658,6 +655,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
658 SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n")); 655 SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n"));
659 return -EDOM; 656 return -EDOM;
660 } 657 }
658 srp->sg_io_owned = sg_io_owned;
661 hp = &srp->header; 659 hp = &srp->header;
662 if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) { 660 if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) {
663 sg_remove_request(sfp, srp); 661 sg_remove_request(sfp, srp);
@@ -755,24 +753,13 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
755 hp->duration = jiffies_to_msecs(jiffies); 753 hp->duration = jiffies_to_msecs(jiffies);
756 754
757 srp->rq->timeout = timeout; 755 srp->rq->timeout = timeout;
756 kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
758 blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk, 757 blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
759 srp->rq, 1, sg_rq_end_io); 758 srp->rq, 1, sg_rq_end_io);
760 return 0; 759 return 0;
761} 760}
762 761
763static int 762static int
764sg_srp_done(Sg_request *srp, Sg_fd *sfp)
765{
766 unsigned long iflags;
767 int done;
768
769 read_lock_irqsave(&sfp->rq_list_lock, iflags);
770 done = srp->done;
771 read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
772 return done;
773}
774
775static int
776sg_ioctl(struct inode *inode, struct file *filp, 763sg_ioctl(struct inode *inode, struct file *filp,
777 unsigned int cmd_in, unsigned long arg) 764 unsigned int cmd_in, unsigned long arg)
778{ 765{
@@ -804,27 +791,26 @@ sg_ioctl(struct inode *inode, struct file *filp,
804 return -EFAULT; 791 return -EFAULT;
805 result = 792 result =
806 sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, 793 sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
807 blocking, read_only, &srp); 794 blocking, read_only, 1, &srp);
808 if (result < 0) 795 if (result < 0)
809 return result; 796 return result;
810 srp->sg_io_owned = 1;
811 while (1) { 797 while (1) {
812 result = 0; /* following macro to beat race condition */ 798 result = 0; /* following macro to beat race condition */
813 __wait_event_interruptible(sfp->read_wait, 799 __wait_event_interruptible(sfp->read_wait,
814 (sdp->detached || sfp->closed || sg_srp_done(srp, sfp)), 800 (srp->done || sdp->detached),
815 result); 801 result);
816 if (sdp->detached) 802 if (sdp->detached)
817 return -ENODEV; 803 return -ENODEV;
818 if (sfp->closed) 804 write_lock_irq(&sfp->rq_list_lock);
819 return 0; /* request packet dropped already */ 805 if (srp->done) {
820 if (0 == result) 806 srp->done = 2;
807 write_unlock_irq(&sfp->rq_list_lock);
821 break; 808 break;
809 }
822 srp->orphan = 1; 810 srp->orphan = 1;
811 write_unlock_irq(&sfp->rq_list_lock);
823 return result; /* -ERESTARTSYS because signal hit process */ 812 return result; /* -ERESTARTSYS because signal hit process */
824 } 813 }
825 write_lock_irqsave(&sfp->rq_list_lock, iflags);
826 srp->done = 2;
827 write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
828 result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); 814 result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
829 return (result < 0) ? result : 0; 815 return (result < 0) ? result : 0;
830 } 816 }
@@ -1238,6 +1224,15 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
1238 return 0; 1224 return 0;
1239} 1225}
1240 1226
1227static void sg_rq_end_io_usercontext(struct work_struct *work)
1228{
1229 struct sg_request *srp = container_of(work, struct sg_request, ew.work);
1230 struct sg_fd *sfp = srp->parentfp;
1231
1232 sg_finish_rem_req(srp);
1233 kref_put(&sfp->f_ref, sg_remove_sfp);
1234}
1235
1241/* 1236/*
1242 * This function is a "bottom half" handler that is called by the mid 1237 * This function is a "bottom half" handler that is called by the mid
1243 * level when a command is completed (or has failed). 1238 * level when a command is completed (or has failed).
@@ -1245,24 +1240,23 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
1245static void sg_rq_end_io(struct request *rq, int uptodate) 1240static void sg_rq_end_io(struct request *rq, int uptodate)
1246{ 1241{
1247 struct sg_request *srp = rq->end_io_data; 1242 struct sg_request *srp = rq->end_io_data;
1248 Sg_device *sdp = NULL; 1243 Sg_device *sdp;
1249 Sg_fd *sfp; 1244 Sg_fd *sfp;
1250 unsigned long iflags; 1245 unsigned long iflags;
1251 unsigned int ms; 1246 unsigned int ms;
1252 char *sense; 1247 char *sense;
1253 int result, resid; 1248 int result, resid, done = 1;
1254 1249
1255 if (NULL == srp) { 1250 if (WARN_ON(srp->done != 0))
1256 printk(KERN_ERR "sg_cmd_done: NULL request\n");
1257 return; 1251 return;
1258 } 1252
1259 sfp = srp->parentfp; 1253 sfp = srp->parentfp;
1260 if (sfp) 1254 if (WARN_ON(sfp == NULL))
1261 sdp = sfp->parentdp;
1262 if ((NULL == sdp) || sdp->detached) {
1263 printk(KERN_INFO "sg_cmd_done: device detached\n");
1264 return; 1255 return;
1265 } 1256
1257 sdp = sfp->parentdp;
1258 if (unlikely(sdp->detached))
1259 printk(KERN_INFO "sg_rq_end_io: device detached\n");
1266 1260
1267 sense = rq->sense; 1261 sense = rq->sense;
1268 result = rq->errors; 1262 result = rq->errors;
@@ -1301,33 +1295,25 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
1301 } 1295 }
1302 /* Rely on write phase to clean out srp status values, so no "else" */ 1296 /* Rely on write phase to clean out srp status values, so no "else" */
1303 1297
1304 if (sfp->closed) { /* whoops this fd already released, cleanup */ 1298 write_lock_irqsave(&sfp->rq_list_lock, iflags);
1305 SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n")); 1299 if (unlikely(srp->orphan)) {
1306 sg_finish_rem_req(srp);
1307 srp = NULL;
1308 if (NULL == sfp->headrp) {
1309 SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n"));
1310 if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
1311 scsi_device_put(sdp->device);
1312 }
1313 sfp = NULL;
1314 }
1315 } else if (srp && srp->orphan) {
1316 if (sfp->keep_orphan) 1300 if (sfp->keep_orphan)
1317 srp->sg_io_owned = 0; 1301 srp->sg_io_owned = 0;
1318 else { 1302 else
1319 sg_finish_rem_req(srp); 1303 done = 0;
1320 srp = NULL;
1321 }
1322 } 1304 }
1323 if (sfp && srp) { 1305 srp->done = done;
1324 /* Now wake up any sg_read() that is waiting for this packet. */ 1306 write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
1325 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); 1307
1326 write_lock_irqsave(&sfp->rq_list_lock, iflags); 1308 if (likely(done)) {
1327 srp->done = 1; 1309 /* Now wake up any sg_read() that is waiting for this
1310 * packet.
1311 */
1328 wake_up_interruptible(&sfp->read_wait); 1312 wake_up_interruptible(&sfp->read_wait);
1329 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); 1313 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
1330 } 1314 kref_put(&sfp->f_ref, sg_remove_sfp);
1315 } else
1316 execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew);
1331} 1317}
1332 1318
1333static struct file_operations sg_fops = { 1319static struct file_operations sg_fops = {
@@ -1362,17 +1348,18 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1362 printk(KERN_WARNING "kmalloc Sg_device failure\n"); 1348 printk(KERN_WARNING "kmalloc Sg_device failure\n");
1363 return ERR_PTR(-ENOMEM); 1349 return ERR_PTR(-ENOMEM);
1364 } 1350 }
1365 error = -ENOMEM; 1351
1366 if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) { 1352 if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) {
1367 printk(KERN_WARNING "idr expansion Sg_device failure\n"); 1353 printk(KERN_WARNING "idr expansion Sg_device failure\n");
1354 error = -ENOMEM;
1368 goto out; 1355 goto out;
1369 } 1356 }
1370 1357
1371 write_lock_irqsave(&sg_index_lock, iflags); 1358 write_lock_irqsave(&sg_index_lock, iflags);
1372 error = idr_get_new(&sg_index_idr, sdp, &k);
1373 write_unlock_irqrestore(&sg_index_lock, iflags);
1374 1359
1360 error = idr_get_new(&sg_index_idr, sdp, &k);
1375 if (error) { 1361 if (error) {
1362 write_unlock_irqrestore(&sg_index_lock, iflags);
1376 printk(KERN_WARNING "idr allocation Sg_device failure: %d\n", 1363 printk(KERN_WARNING "idr allocation Sg_device failure: %d\n",
1377 error); 1364 error);
1378 goto out; 1365 goto out;
@@ -1386,9 +1373,13 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1386 disk->first_minor = k; 1373 disk->first_minor = k;
1387 sdp->disk = disk; 1374 sdp->disk = disk;
1388 sdp->device = scsidp; 1375 sdp->device = scsidp;
1376 INIT_LIST_HEAD(&sdp->sfds);
1389 init_waitqueue_head(&sdp->o_excl_wait); 1377 init_waitqueue_head(&sdp->o_excl_wait);
1390 sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); 1378 sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
1391 sdp->index = k; 1379 sdp->index = k;
1380 kref_init(&sdp->d_ref);
1381
1382 write_unlock_irqrestore(&sg_index_lock, iflags);
1392 1383
1393 error = 0; 1384 error = 0;
1394 out: 1385 out:
@@ -1399,6 +1390,8 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1399 return sdp; 1390 return sdp;
1400 1391
1401 overflow: 1392 overflow:
1393 idr_remove(&sg_index_idr, k);
1394 write_unlock_irqrestore(&sg_index_lock, iflags);
1402 sdev_printk(KERN_WARNING, scsidp, 1395 sdev_printk(KERN_WARNING, scsidp,
1403 "Unable to attach sg device type=%d, minor " 1396 "Unable to attach sg device type=%d, minor "
1404 "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); 1397 "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1);
@@ -1486,49 +1479,46 @@ out:
1486 return error; 1479 return error;
1487} 1480}
1488 1481
1489static void 1482static void sg_device_destroy(struct kref *kref)
1490sg_remove(struct device *cl_dev, struct class_interface *cl_intf) 1483{
1484 struct sg_device *sdp = container_of(kref, struct sg_device, d_ref);
1485 unsigned long flags;
1486
1487 /* CAUTION! Note that the device can still be found via idr_find()
1488 * even though the refcount is 0. Therefore, do idr_remove() BEFORE
1489 * any other cleanup.
1490 */
1491
1492 write_lock_irqsave(&sg_index_lock, flags);
1493 idr_remove(&sg_index_idr, sdp->index);
1494 write_unlock_irqrestore(&sg_index_lock, flags);
1495
1496 SCSI_LOG_TIMEOUT(3,
1497 printk("sg_device_destroy: %s\n",
1498 sdp->disk->disk_name));
1499
1500 put_disk(sdp->disk);
1501 kfree(sdp);
1502}
1503
1504static void sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
1491{ 1505{
1492 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); 1506 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent);
1493 Sg_device *sdp = dev_get_drvdata(cl_dev); 1507 Sg_device *sdp = dev_get_drvdata(cl_dev);
1494 unsigned long iflags; 1508 unsigned long iflags;
1495 Sg_fd *sfp; 1509 Sg_fd *sfp;
1496 Sg_fd *tsfp;
1497 Sg_request *srp;
1498 Sg_request *tsrp;
1499 int delay;
1500 1510
1501 if (!sdp) 1511 if (!sdp || sdp->detached)
1502 return; 1512 return;
1503 1513
1504 delay = 0; 1514 SCSI_LOG_TIMEOUT(3, printk("sg_remove: %s\n", sdp->disk->disk_name));
1515
1516 /* Need a write lock to set sdp->detached. */
1505 write_lock_irqsave(&sg_index_lock, iflags); 1517 write_lock_irqsave(&sg_index_lock, iflags);
1506 if (sdp->headfp) { 1518 sdp->detached = 1;
1507 sdp->detached = 1; 1519 list_for_each_entry(sfp, &sdp->sfds, sfd_siblings) {
1508 for (sfp = sdp->headfp; sfp; sfp = tsfp) { 1520 wake_up_interruptible(&sfp->read_wait);
1509 tsfp = sfp->nextfp; 1521 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP);
1510 for (srp = sfp->headrp; srp; srp = tsrp) {
1511 tsrp = srp->nextrp;
1512 if (sfp->closed || (0 == sg_srp_done(srp, sfp)))
1513 sg_finish_rem_req(srp);
1514 }
1515 if (sfp->closed) {
1516 scsi_device_put(sdp->device);
1517 __sg_remove_sfp(sdp, sfp);
1518 } else {
1519 delay = 1;
1520 wake_up_interruptible(&sfp->read_wait);
1521 kill_fasync(&sfp->async_qp, SIGPOLL,
1522 POLL_HUP);
1523 }
1524 }
1525 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index));
1526 if (NULL == sdp->headfp) {
1527 idr_remove(&sg_index_idr, sdp->index);
1528 }
1529 } else { /* nothing active, simple case */
1530 SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index));
1531 idr_remove(&sg_index_idr, sdp->index);
1532 } 1522 }
1533 write_unlock_irqrestore(&sg_index_lock, iflags); 1523 write_unlock_irqrestore(&sg_index_lock, iflags);
1534 1524
@@ -1536,13 +1526,8 @@ sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
1536 device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); 1526 device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index));
1537 cdev_del(sdp->cdev); 1527 cdev_del(sdp->cdev);
1538 sdp->cdev = NULL; 1528 sdp->cdev = NULL;
1539 put_disk(sdp->disk);
1540 sdp->disk = NULL;
1541 if (NULL == sdp->headfp)
1542 kfree(sdp);
1543 1529
1544 if (delay) 1530 sg_put_dev(sdp);
1545 msleep(10); /* dirty detach so delay device destruction */
1546} 1531}
1547 1532
1548module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR); 1533module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
@@ -1736,8 +1721,8 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
1736 return -EFAULT; 1721 return -EFAULT;
1737 if (0 == blk_size) 1722 if (0 == blk_size)
1738 ++blk_size; /* don't know why */ 1723 ++blk_size; /* don't know why */
1739/* round request up to next highest SG_SECTOR_SZ byte boundary */ 1724 /* round request up to next highest SG_SECTOR_SZ byte boundary */
1740 blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK); 1725 blk_size = ALIGN(blk_size, SG_SECTOR_SZ);
1741 SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n", 1726 SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
1742 buff_size, blk_size)); 1727 buff_size, blk_size));
1743 1728
@@ -1939,22 +1924,6 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
1939 return resp; 1924 return resp;
1940} 1925}
1941 1926
1942#ifdef CONFIG_SCSI_PROC_FS
1943static Sg_request *
1944sg_get_nth_request(Sg_fd * sfp, int nth)
1945{
1946 Sg_request *resp;
1947 unsigned long iflags;
1948 int k;
1949
1950 read_lock_irqsave(&sfp->rq_list_lock, iflags);
1951 for (k = 0, resp = sfp->headrp; resp && (k < nth);
1952 ++k, resp = resp->nextrp) ;
1953 read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
1954 return resp;
1955}
1956#endif
1957
1958/* always adds to end of list */ 1927/* always adds to end of list */
1959static Sg_request * 1928static Sg_request *
1960sg_add_request(Sg_fd * sfp) 1929sg_add_request(Sg_fd * sfp)
@@ -2030,22 +1999,6 @@ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
2030 return res; 1999 return res;
2031} 2000}
2032 2001
2033#ifdef CONFIG_SCSI_PROC_FS
2034static Sg_fd *
2035sg_get_nth_sfp(Sg_device * sdp, int nth)
2036{
2037 Sg_fd *resp;
2038 unsigned long iflags;
2039 int k;
2040
2041 read_lock_irqsave(&sg_index_lock, iflags);
2042 for (k = 0, resp = sdp->headfp; resp && (k < nth);
2043 ++k, resp = resp->nextfp) ;
2044 read_unlock_irqrestore(&sg_index_lock, iflags);
2045 return resp;
2046}
2047#endif
2048
2049static Sg_fd * 2002static Sg_fd *
2050sg_add_sfp(Sg_device * sdp, int dev) 2003sg_add_sfp(Sg_device * sdp, int dev)
2051{ 2004{
@@ -2060,6 +2013,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
2060 init_waitqueue_head(&sfp->read_wait); 2013 init_waitqueue_head(&sfp->read_wait);
2061 rwlock_init(&sfp->rq_list_lock); 2014 rwlock_init(&sfp->rq_list_lock);
2062 2015
2016 kref_init(&sfp->f_ref);
2063 sfp->timeout = SG_DEFAULT_TIMEOUT; 2017 sfp->timeout = SG_DEFAULT_TIMEOUT;
2064 sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER; 2018 sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER;
2065 sfp->force_packid = SG_DEF_FORCE_PACK_ID; 2019 sfp->force_packid = SG_DEF_FORCE_PACK_ID;
@@ -2069,14 +2023,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
2069 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; 2023 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
2070 sfp->parentdp = sdp; 2024 sfp->parentdp = sdp;
2071 write_lock_irqsave(&sg_index_lock, iflags); 2025 write_lock_irqsave(&sg_index_lock, iflags);
2072 if (!sdp->headfp) 2026 list_add_tail(&sfp->sfd_siblings, &sdp->sfds);
2073 sdp->headfp = sfp;
2074 else { /* add to tail of existing list */
2075 Sg_fd *pfp = sdp->headfp;
2076 while (pfp->nextfp)
2077 pfp = pfp->nextfp;
2078 pfp->nextfp = sfp;
2079 }
2080 write_unlock_irqrestore(&sg_index_lock, iflags); 2027 write_unlock_irqrestore(&sg_index_lock, iflags);
2081 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); 2028 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
2082 if (unlikely(sg_big_buff != def_reserved_size)) 2029 if (unlikely(sg_big_buff != def_reserved_size))
@@ -2087,75 +2034,52 @@ sg_add_sfp(Sg_device * sdp, int dev)
2087 sg_build_reserve(sfp, bufflen); 2034 sg_build_reserve(sfp, bufflen);
2088 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", 2035 SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n",
2089 sfp->reserve.bufflen, sfp->reserve.k_use_sg)); 2036 sfp->reserve.bufflen, sfp->reserve.k_use_sg));
2037
2038 kref_get(&sdp->d_ref);
2039 __module_get(THIS_MODULE);
2090 return sfp; 2040 return sfp;
2091} 2041}
2092 2042
2093static void 2043static void sg_remove_sfp_usercontext(struct work_struct *work)
2094__sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
2095{ 2044{
2096 Sg_fd *fp; 2045 struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
2097 Sg_fd *prev_fp; 2046 struct sg_device *sdp = sfp->parentdp;
2047
2048 /* Cleanup any responses which were never read(). */
2049 while (sfp->headrp)
2050 sg_finish_rem_req(sfp->headrp);
2098 2051
2099 prev_fp = sdp->headfp;
2100 if (sfp == prev_fp)
2101 sdp->headfp = prev_fp->nextfp;
2102 else {
2103 while ((fp = prev_fp->nextfp)) {
2104 if (sfp == fp) {
2105 prev_fp->nextfp = fp->nextfp;
2106 break;
2107 }
2108 prev_fp = fp;
2109 }
2110 }
2111 if (sfp->reserve.bufflen > 0) { 2052 if (sfp->reserve.bufflen > 0) {
2112 SCSI_LOG_TIMEOUT(6, 2053 SCSI_LOG_TIMEOUT(6,
2113 printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", 2054 printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
2114 (int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg)); 2055 (int) sfp->reserve.bufflen,
2056 (int) sfp->reserve.k_use_sg));
2115 sg_remove_scat(&sfp->reserve); 2057 sg_remove_scat(&sfp->reserve);
2116 } 2058 }
2117 sfp->parentdp = NULL; 2059
2118 SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp: sfp=0x%p\n", sfp)); 2060 SCSI_LOG_TIMEOUT(6,
2061 printk("sg_remove_sfp: %s, sfp=0x%p\n",
2062 sdp->disk->disk_name,
2063 sfp));
2119 kfree(sfp); 2064 kfree(sfp);
2065
2066 scsi_device_put(sdp->device);
2067 sg_put_dev(sdp);
2068 module_put(THIS_MODULE);
2120} 2069}
2121 2070
2122/* Returns 0 in normal case, 1 when detached and sdp object removed */ 2071static void sg_remove_sfp(struct kref *kref)
2123static int
2124sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
2125{ 2072{
2126 Sg_request *srp; 2073 struct sg_fd *sfp = container_of(kref, struct sg_fd, f_ref);
2127 Sg_request *tsrp; 2074 struct sg_device *sdp = sfp->parentdp;
2128 int dirty = 0; 2075 unsigned long iflags;
2129 int res = 0;
2130 2076
2131 for (srp = sfp->headrp; srp; srp = tsrp) { 2077 write_lock_irqsave(&sg_index_lock, iflags);
2132 tsrp = srp->nextrp; 2078 list_del(&sfp->sfd_siblings);
2133 if (sg_srp_done(srp, sfp)) 2079 write_unlock_irqrestore(&sg_index_lock, iflags);
2134 sg_finish_rem_req(srp); 2080 wake_up_interruptible(&sdp->o_excl_wait);
2135 else 2081
2136 ++dirty; 2082 execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew);
2137 }
2138 if (0 == dirty) {
2139 unsigned long iflags;
2140
2141 write_lock_irqsave(&sg_index_lock, iflags);
2142 __sg_remove_sfp(sdp, sfp);
2143 if (sdp->detached && (NULL == sdp->headfp)) {
2144 idr_remove(&sg_index_idr, sdp->index);
2145 kfree(sdp);
2146 res = 1;
2147 }
2148 write_unlock_irqrestore(&sg_index_lock, iflags);
2149 } else {
2150 /* MOD_INC's to inhibit unloading sg and associated adapter driver */
2151 /* only bump the access_count if we actually succeeded in
2152 * throwing another counter on the host module */
2153 scsi_device_get(sdp->device); /* XXX: retval ignored? */
2154 sfp->closed = 1; /* flag dirty state on this fd */
2155 SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
2156 dirty));
2157 }
2158 return res;
2159} 2083}
2160 2084
2161static int 2085static int
@@ -2197,19 +2121,38 @@ sg_last_dev(void)
2197} 2121}
2198#endif 2122#endif
2199 2123
2200static Sg_device * 2124/* must be called with sg_index_lock held */
2201sg_get_dev(int dev) 2125static Sg_device *sg_lookup_dev(int dev)
2202{ 2126{
2203 Sg_device *sdp; 2127 return idr_find(&sg_index_idr, dev);
2204 unsigned long iflags; 2128}
2205 2129
2206 read_lock_irqsave(&sg_index_lock, iflags); 2130static Sg_device *sg_get_dev(int dev)
2207 sdp = idr_find(&sg_index_idr, dev); 2131{
2208 read_unlock_irqrestore(&sg_index_lock, iflags); 2132 struct sg_device *sdp;
2133 unsigned long flags;
2134
2135 read_lock_irqsave(&sg_index_lock, flags);
2136 sdp = sg_lookup_dev(dev);
2137 if (!sdp)
2138 sdp = ERR_PTR(-ENXIO);
2139 else if (sdp->detached) {
2140 /* If sdp->detached, then the refcount may already be 0, in
2141 * which case it would be a bug to do kref_get().
2142 */
2143 sdp = ERR_PTR(-ENODEV);
2144 } else
2145 kref_get(&sdp->d_ref);
2146 read_unlock_irqrestore(&sg_index_lock, flags);
2209 2147
2210 return sdp; 2148 return sdp;
2211} 2149}
2212 2150
2151static void sg_put_dev(struct sg_device *sdp)
2152{
2153 kref_put(&sdp->d_ref, sg_device_destroy);
2154}
2155
2213#ifdef CONFIG_SCSI_PROC_FS 2156#ifdef CONFIG_SCSI_PROC_FS
2214 2157
2215static struct proc_dir_entry *sg_proc_sgp = NULL; 2158static struct proc_dir_entry *sg_proc_sgp = NULL;
@@ -2466,8 +2409,10 @@ static int sg_proc_seq_show_dev(struct seq_file *s, void *v)
2466 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; 2409 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
2467 Sg_device *sdp; 2410 Sg_device *sdp;
2468 struct scsi_device *scsidp; 2411 struct scsi_device *scsidp;
2412 unsigned long iflags;
2469 2413
2470 sdp = it ? sg_get_dev(it->index) : NULL; 2414 read_lock_irqsave(&sg_index_lock, iflags);
2415 sdp = it ? sg_lookup_dev(it->index) : NULL;
2471 if (sdp && (scsidp = sdp->device) && (!sdp->detached)) 2416 if (sdp && (scsidp = sdp->device) && (!sdp->detached))
2472 seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", 2417 seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
2473 scsidp->host->host_no, scsidp->channel, 2418 scsidp->host->host_no, scsidp->channel,
@@ -2478,6 +2423,7 @@ static int sg_proc_seq_show_dev(struct seq_file *s, void *v)
2478 (int) scsi_device_online(scsidp)); 2423 (int) scsi_device_online(scsidp));
2479 else 2424 else
2480 seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n"); 2425 seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
2426 read_unlock_irqrestore(&sg_index_lock, iflags);
2481 return 0; 2427 return 0;
2482} 2428}
2483 2429
@@ -2491,16 +2437,20 @@ static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v)
2491 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; 2437 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
2492 Sg_device *sdp; 2438 Sg_device *sdp;
2493 struct scsi_device *scsidp; 2439 struct scsi_device *scsidp;
2440 unsigned long iflags;
2494 2441
2495 sdp = it ? sg_get_dev(it->index) : NULL; 2442 read_lock_irqsave(&sg_index_lock, iflags);
2443 sdp = it ? sg_lookup_dev(it->index) : NULL;
2496 if (sdp && (scsidp = sdp->device) && (!sdp->detached)) 2444 if (sdp && (scsidp = sdp->device) && (!sdp->detached))
2497 seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n", 2445 seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n",
2498 scsidp->vendor, scsidp->model, scsidp->rev); 2446 scsidp->vendor, scsidp->model, scsidp->rev);
2499 else 2447 else
2500 seq_printf(s, "<no active device>\n"); 2448 seq_printf(s, "<no active device>\n");
2449 read_unlock_irqrestore(&sg_index_lock, iflags);
2501 return 0; 2450 return 0;
2502} 2451}
2503 2452
2453/* must be called while holding sg_index_lock */
2504static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) 2454static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
2505{ 2455{
2506 int k, m, new_interface, blen, usg; 2456 int k, m, new_interface, blen, usg;
@@ -2510,9 +2460,12 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
2510 const char * cp; 2460 const char * cp;
2511 unsigned int ms; 2461 unsigned int ms;
2512 2462
2513 for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) { 2463 k = 0;
2464 list_for_each_entry(fp, &sdp->sfds, sfd_siblings) {
2465 k++;
2466 read_lock(&fp->rq_list_lock); /* irqs already disabled */
2514 seq_printf(s, " FD(%d): timeout=%dms bufflen=%d " 2467 seq_printf(s, " FD(%d): timeout=%dms bufflen=%d "
2515 "(res)sgat=%d low_dma=%d\n", k + 1, 2468 "(res)sgat=%d low_dma=%d\n", k,
2516 jiffies_to_msecs(fp->timeout), 2469 jiffies_to_msecs(fp->timeout),
2517 fp->reserve.bufflen, 2470 fp->reserve.bufflen,
2518 (int) fp->reserve.k_use_sg, 2471 (int) fp->reserve.k_use_sg,
@@ -2520,7 +2473,9 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
2520 seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n", 2473 seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n",
2521 (int) fp->cmd_q, (int) fp->force_packid, 2474 (int) fp->cmd_q, (int) fp->force_packid,
2522 (int) fp->keep_orphan, (int) fp->closed); 2475 (int) fp->keep_orphan, (int) fp->closed);
2523 for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) { 2476 for (m = 0, srp = fp->headrp;
2477 srp != NULL;
2478 ++m, srp = srp->nextrp) {
2524 hp = &srp->header; 2479 hp = &srp->header;
2525 new_interface = (hp->interface_id == '\0') ? 0 : 1; 2480 new_interface = (hp->interface_id == '\0') ? 0 : 1;
2526 if (srp->res_used) { 2481 if (srp->res_used) {
@@ -2557,6 +2512,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
2557 } 2512 }
2558 if (0 == m) 2513 if (0 == m)
2559 seq_printf(s, " No requests active\n"); 2514 seq_printf(s, " No requests active\n");
2515 read_unlock(&fp->rq_list_lock);
2560 } 2516 }
2561} 2517}
2562 2518
@@ -2569,39 +2525,34 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v)
2569{ 2525{
2570 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; 2526 struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
2571 Sg_device *sdp; 2527 Sg_device *sdp;
2528 unsigned long iflags;
2572 2529
2573 if (it && (0 == it->index)) { 2530 if (it && (0 == it->index)) {
2574 seq_printf(s, "max_active_device=%d(origin 1)\n", 2531 seq_printf(s, "max_active_device=%d(origin 1)\n",
2575 (int)it->max); 2532 (int)it->max);
2576 seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); 2533 seq_printf(s, " def_reserved_size=%d\n", sg_big_buff);
2577 } 2534 }
2578 sdp = it ? sg_get_dev(it->index) : NULL;
2579 if (sdp) {
2580 struct scsi_device *scsidp = sdp->device;
2581 2535
2582 if (NULL == scsidp) { 2536 read_lock_irqsave(&sg_index_lock, iflags);
2583 seq_printf(s, "device %d detached ??\n", 2537 sdp = it ? sg_lookup_dev(it->index) : NULL;
2584 (int)it->index); 2538 if (sdp && !list_empty(&sdp->sfds)) {
2585 return 0; 2539 struct scsi_device *scsidp = sdp->device;
2586 }
2587 2540
2588 if (sg_get_nth_sfp(sdp, 0)) { 2541 seq_printf(s, " >>> device=%s ", sdp->disk->disk_name);
2589 seq_printf(s, " >>> device=%s ", 2542 if (sdp->detached)
2590 sdp->disk->disk_name); 2543 seq_printf(s, "detached pending close ");
2591 if (sdp->detached) 2544 else
2592 seq_printf(s, "detached pending close "); 2545 seq_printf
2593 else 2546 (s, "scsi%d chan=%d id=%d lun=%d em=%d",
2594 seq_printf 2547 scsidp->host->host_no,
2595 (s, "scsi%d chan=%d id=%d lun=%d em=%d", 2548 scsidp->channel, scsidp->id,
2596 scsidp->host->host_no, 2549 scsidp->lun,
2597 scsidp->channel, scsidp->id, 2550 scsidp->host->hostt->emulated);
2598 scsidp->lun, 2551 seq_printf(s, " sg_tablesize=%d excl=%d\n",
2599 scsidp->host->hostt->emulated); 2552 sdp->sg_tablesize, sdp->exclude);
2600 seq_printf(s, " sg_tablesize=%d excl=%d\n",
2601 sdp->sg_tablesize, sdp->exclude);
2602 }
2603 sg_proc_debug_helper(s, sdp); 2553 sg_proc_debug_helper(s, sdp);
2604 } 2554 }
2555 read_unlock_irqrestore(&sg_index_lock, iflags);
2605 return 0; 2556 return 0;
2606} 2557}
2607 2558
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index c6f19ee8f2cb..eb24efea8f14 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -374,9 +374,9 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
374 if (!debugging) { /* Abnormal conditions for tape */ 374 if (!debugging) { /* Abnormal conditions for tape */
375 if (!cmdstatp->have_sense) 375 if (!cmdstatp->have_sense)
376 printk(KERN_WARNING 376 printk(KERN_WARNING
377 "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n", 377 "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
378 name, result, suggestion(result), 378 name, result, driver_byte(result),
379 driver_byte(result) & DRIVER_MASK, host_byte(result)); 379 host_byte(result));
380 else if (cmdstatp->have_sense && 380 else if (cmdstatp->have_sense &&
381 scode != NO_SENSE && 381 scode != NO_SENSE &&
382 scode != RECOVERED_ERROR && 382 scode != RECOVERED_ERROR &&
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index a3a18ad73125..47b614e8580c 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SuperTrak EX Series Storage Controller driver for Linux 2 * SuperTrak EX Series Storage Controller driver for Linux
3 * 3 *
4 * Copyright (C) 2005, 2006 Promise Technology Inc. 4 * Copyright (C) 2005-2009 Promise Technology Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -36,8 +36,8 @@
36#include <scsi/scsi_eh.h> 36#include <scsi/scsi_eh.h>
37 37
38#define DRV_NAME "stex" 38#define DRV_NAME "stex"
39#define ST_DRIVER_VERSION "3.6.0000.1" 39#define ST_DRIVER_VERSION "4.6.0000.1"
40#define ST_VER_MAJOR 3 40#define ST_VER_MAJOR 4
41#define ST_VER_MINOR 6 41#define ST_VER_MINOR 6
42#define ST_OEM 0 42#define ST_OEM 0
43#define ST_BUILD_VER 1 43#define ST_BUILD_VER 1
@@ -103,7 +103,7 @@ enum {
103 MU_REQ_COUNT = (MU_MAX_REQUEST + 1), 103 MU_REQ_COUNT = (MU_MAX_REQUEST + 1),
104 MU_STATUS_COUNT = (MU_MAX_REQUEST + 1), 104 MU_STATUS_COUNT = (MU_MAX_REQUEST + 1),
105 105
106 STEX_CDB_LENGTH = MAX_COMMAND_SIZE, 106 STEX_CDB_LENGTH = 16,
107 REQ_VARIABLE_LEN = 1024, 107 REQ_VARIABLE_LEN = 1024,
108 STATUS_VAR_LEN = 128, 108 STATUS_VAR_LEN = 128,
109 ST_CAN_QUEUE = MU_MAX_REQUEST, 109 ST_CAN_QUEUE = MU_MAX_REQUEST,
@@ -114,15 +114,19 @@ enum {
114 SG_CF_EOT = 0x80, /* end of table */ 114 SG_CF_EOT = 0x80, /* end of table */
115 SG_CF_64B = 0x40, /* 64 bit item */ 115 SG_CF_64B = 0x40, /* 64 bit item */
116 SG_CF_HOST = 0x20, /* sg in host memory */ 116 SG_CF_HOST = 0x20, /* sg in host memory */
117 MSG_DATA_DIR_ND = 0,
118 MSG_DATA_DIR_IN = 1,
119 MSG_DATA_DIR_OUT = 2,
117 120
118 st_shasta = 0, 121 st_shasta = 0,
119 st_vsc = 1, 122 st_vsc = 1,
120 st_vsc1 = 2, 123 st_vsc1 = 2,
121 st_yosemite = 3, 124 st_yosemite = 3,
125 st_seq = 4,
122 126
123 PASSTHRU_REQ_TYPE = 0x00000001, 127 PASSTHRU_REQ_TYPE = 0x00000001,
124 PASSTHRU_REQ_NO_WAKEUP = 0x00000100, 128 PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
125 ST_INTERNAL_TIMEOUT = 30, 129 ST_INTERNAL_TIMEOUT = 180,
126 130
127 ST_TO_CMD = 0, 131 ST_TO_CMD = 0,
128 ST_FROM_CMD = 1, 132 ST_FROM_CMD = 1,
@@ -152,35 +156,6 @@ enum {
152 ST_ADDITIONAL_MEM = 0x200000, 156 ST_ADDITIONAL_MEM = 0x200000,
153}; 157};
154 158
155/* SCSI inquiry data */
156typedef struct st_inq {
157 u8 DeviceType :5;
158 u8 DeviceTypeQualifier :3;
159 u8 DeviceTypeModifier :7;
160 u8 RemovableMedia :1;
161 u8 Versions;
162 u8 ResponseDataFormat :4;
163 u8 HiSupport :1;
164 u8 NormACA :1;
165 u8 ReservedBit :1;
166 u8 AERC :1;
167 u8 AdditionalLength;
168 u8 Reserved[2];
169 u8 SoftReset :1;
170 u8 CommandQueue :1;
171 u8 Reserved2 :1;
172 u8 LinkedCommands :1;
173 u8 Synchronous :1;
174 u8 Wide16Bit :1;
175 u8 Wide32Bit :1;
176 u8 RelativeAddressing :1;
177 u8 VendorId[8];
178 u8 ProductId[16];
179 u8 ProductRevisionLevel[4];
180 u8 VendorSpecific[20];
181 u8 Reserved3[40];
182} ST_INQ;
183
184struct st_sgitem { 159struct st_sgitem {
185 u8 ctrl; /* SG_CF_xxx */ 160 u8 ctrl; /* SG_CF_xxx */
186 u8 reserved[3]; 161 u8 reserved[3];
@@ -222,7 +197,7 @@ struct req_msg {
222 u8 target; 197 u8 target;
223 u8 task_attr; 198 u8 task_attr;
224 u8 task_manage; 199 u8 task_manage;
225 u8 prd_entry; 200 u8 data_dir;
226 u8 payload_sz; /* payload size in 4-byte, not used */ 201 u8 payload_sz; /* payload size in 4-byte, not used */
227 u8 cdb[STEX_CDB_LENGTH]; 202 u8 cdb[STEX_CDB_LENGTH];
228 u8 variable[REQ_VARIABLE_LEN]; 203 u8 variable[REQ_VARIABLE_LEN];
@@ -284,7 +259,7 @@ struct st_drvver {
284#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) 259#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
285#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) 260#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
286#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) 261#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
287#define STEX_EXTRA_SIZE max(sizeof(struct st_frame), sizeof(ST_INQ)) 262#define STEX_EXTRA_SIZE sizeof(struct st_frame)
288#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE) 263#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
289 264
290struct st_ccb { 265struct st_ccb {
@@ -346,8 +321,8 @@ MODULE_VERSION(ST_DRIVER_VERSION);
346static void stex_gettime(__le32 *time) 321static void stex_gettime(__le32 *time)
347{ 322{
348 struct timeval tv; 323 struct timeval tv;
349 do_gettimeofday(&tv);
350 324
325 do_gettimeofday(&tv);
351 *time = cpu_to_le32(tv.tv_sec & 0xffffffff); 326 *time = cpu_to_le32(tv.tv_sec & 0xffffffff);
352 *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16); 327 *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16);
353} 328}
@@ -368,7 +343,7 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,
368{ 343{
369 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; 344 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
370 345
371 /* "Invalid field in cbd" */ 346 /* "Invalid field in cdb" */
372 scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, 347 scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24,
373 0x0); 348 0x0);
374 done(cmd); 349 done(cmd);
@@ -497,6 +472,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
497 unsigned int id,lun; 472 unsigned int id,lun;
498 struct req_msg *req; 473 struct req_msg *req;
499 u16 tag; 474 u16 tag;
475
500 host = cmd->device->host; 476 host = cmd->device->host;
501 id = cmd->device->id; 477 id = cmd->device->id;
502 lun = cmd->device->lun; 478 lun = cmd->device->lun;
@@ -508,6 +484,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
508 static char ms10_caching_page[12] = 484 static char ms10_caching_page[12] =
509 { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 }; 485 { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 };
510 unsigned char page; 486 unsigned char page;
487
511 page = cmd->cmnd[2] & 0x3f; 488 page = cmd->cmnd[2] & 0x3f;
512 if (page == 0x8 || page == 0x3f) { 489 if (page == 0x8 || page == 0x3f) {
513 scsi_sg_copy_from_buffer(cmd, ms10_caching_page, 490 scsi_sg_copy_from_buffer(cmd, ms10_caching_page,
@@ -551,6 +528,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
551 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { 528 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
552 struct st_drvver ver; 529 struct st_drvver ver;
553 size_t cp_len = sizeof(ver); 530 size_t cp_len = sizeof(ver);
531
554 ver.major = ST_VER_MAJOR; 532 ver.major = ST_VER_MAJOR;
555 ver.minor = ST_VER_MINOR; 533 ver.minor = ST_VER_MINOR;
556 ver.oem = ST_OEM; 534 ver.oem = ST_OEM;
@@ -584,6 +562,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
584 /* cdb */ 562 /* cdb */
585 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); 563 memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
586 564
565 if (cmd->sc_data_direction == DMA_FROM_DEVICE)
566 req->data_dir = MSG_DATA_DIR_IN;
567 else if (cmd->sc_data_direction == DMA_TO_DEVICE)
568 req->data_dir = MSG_DATA_DIR_OUT;
569 else
570 req->data_dir = MSG_DATA_DIR_ND;
571
587 hba->ccb[tag].cmd = cmd; 572 hba->ccb[tag].cmd = cmd;
588 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; 573 hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE;
589 hba->ccb[tag].sense_buffer = cmd->sense_buffer; 574 hba->ccb[tag].sense_buffer = cmd->sense_buffer;
@@ -642,6 +627,7 @@ static void stex_copy_data(struct st_ccb *ccb,
642 struct status_msg *resp, unsigned int variable) 627 struct status_msg *resp, unsigned int variable)
643{ 628{
644 size_t count = variable; 629 size_t count = variable;
630
645 if (resp->scsi_status != SAM_STAT_GOOD) { 631 if (resp->scsi_status != SAM_STAT_GOOD) {
646 if (ccb->sense_buffer != NULL) 632 if (ccb->sense_buffer != NULL)
647 memcpy(ccb->sense_buffer, resp->variable, 633 memcpy(ccb->sense_buffer, resp->variable,
@@ -661,24 +647,6 @@ static void stex_ys_commands(struct st_hba *hba,
661 resp->scsi_status != SAM_STAT_CHECK_CONDITION) { 647 resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
662 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - 648 scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
663 le32_to_cpu(*(__le32 *)&resp->variable[0])); 649 le32_to_cpu(*(__le32 *)&resp->variable[0]));
664 return;
665 }
666
667 if (resp->srb_status != 0)
668 return;
669
670 /* determine inquiry command status by DeviceTypeQualifier */
671 if (ccb->cmd->cmnd[0] == INQUIRY &&
672 resp->scsi_status == SAM_STAT_GOOD) {
673 ST_INQ *inq_data;
674
675 scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer,
676 STEX_EXTRA_SIZE);
677 inq_data = (ST_INQ *)hba->copy_buffer;
678 if (inq_data->DeviceTypeQualifier != 0)
679 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
680 else
681 ccb->srb_status = SRB_STATUS_SUCCESS;
682 } 650 }
683} 651}
684 652
@@ -746,6 +714,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
746 stex_copy_data(ccb, resp, size); 714 stex_copy_data(ccb, resp, size);
747 } 715 }
748 716
717 ccb->req = NULL;
749 ccb->srb_status = resp->srb_status; 718 ccb->srb_status = resp->srb_status;
750 ccb->scsi_status = resp->scsi_status; 719 ccb->scsi_status = resp->scsi_status;
751 720
@@ -983,6 +952,7 @@ static int stex_reset(struct scsi_cmnd *cmd)
983 struct st_hba *hba; 952 struct st_hba *hba;
984 unsigned long flags; 953 unsigned long flags;
985 unsigned long before; 954 unsigned long before;
955
986 hba = (struct st_hba *) &cmd->device->host->hostdata[0]; 956 hba = (struct st_hba *) &cmd->device->host->hostdata[0];
987 957
988 printk(KERN_INFO DRV_NAME 958 printk(KERN_INFO DRV_NAME
@@ -1067,6 +1037,7 @@ static struct scsi_host_template driver_template = {
1067static int stex_set_dma_mask(struct pci_dev * pdev) 1037static int stex_set_dma_mask(struct pci_dev * pdev)
1068{ 1038{
1069 int ret; 1039 int ret;
1040
1070 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) 1041 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1071 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) 1042 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1072 return 0; 1043 return 0;
@@ -1124,9 +1095,9 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1124 } 1095 }
1125 1096
1126 hba->cardtype = (unsigned int) id->driver_data; 1097 hba->cardtype = (unsigned int) id->driver_data;
1127 if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) 1098 if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))
1128 hba->cardtype = st_vsc1; 1099 hba->cardtype = st_vsc1;
1129 hba->dma_size = (hba->cardtype == st_vsc1) ? 1100 hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ?
1130 (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); 1101 (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE);
1131 hba->dma_mem = dma_alloc_coherent(&pdev->dev, 1102 hba->dma_mem = dma_alloc_coherent(&pdev->dev,
1132 hba->dma_size, &hba->dma_handle, GFP_KERNEL); 1103 hba->dma_size, &hba->dma_handle, GFP_KERNEL);
@@ -1146,10 +1117,10 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1146 host->max_lun = 8; 1117 host->max_lun = 8;
1147 host->max_id = 16 + 1; 1118 host->max_id = 16 + 1;
1148 } else if (hba->cardtype == st_yosemite) { 1119 } else if (hba->cardtype == st_yosemite) {
1149 host->max_lun = 128; 1120 host->max_lun = 256;
1150 host->max_id = 1 + 1; 1121 host->max_id = 1 + 1;
1151 } else { 1122 } else {
1152 /* st_vsc and st_vsc1 */ 1123 /* st_vsc , st_vsc1 and st_seq */
1153 host->max_lun = 1; 1124 host->max_lun = 1;
1154 host->max_id = 128 + 1; 1125 host->max_id = 128 + 1;
1155 } 1126 }
@@ -1299,18 +1270,10 @@ static struct pci_device_id stex_pci_tbl[] = {
1299 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, 1270 { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
1300 1271
1301 /* st_yosemite */ 1272 /* st_yosemite */
1302 { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0, 1273 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
1303 st_yosemite }, /* SuperTrak EX4650 */ 1274
1304 { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0, 1275 /* st_seq */
1305 st_yosemite }, /* SuperTrak EX4650o */ 1276 { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
1306 { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0,
1307 st_yosemite }, /* SuperTrak EX8650EL */
1308 { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0,
1309 st_yosemite }, /* SuperTrak EX8650 */
1310 { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0,
1311 st_yosemite }, /* SuperTrak EX8654 */
1312 { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1313 st_yosemite }, /* generic st_yosemite */
1314 { } /* terminate list */ 1277 { } /* terminate list */
1315}; 1278};
1316MODULE_DEVICE_TABLE(pci, stex_pci_tbl); 1279MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index f4e6cde1fd0d..23e782015880 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -792,9 +792,9 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev)
792 792
793 /* 793 /*
794 * Select queue depth from driver setup. 794 * Select queue depth from driver setup.
795 * Donnot use more than configured by user. 795 * Do not use more than configured by user.
796 * Use at least 2. 796 * Use at least 1.
797 * Donnot use more than our maximum. 797 * Do not use more than our maximum.
798 */ 798 */
799 reqtags = sym_driver_setup.max_tag; 799 reqtags = sym_driver_setup.max_tag;
800 if (reqtags > tp->usrtags) 800 if (reqtags > tp->usrtags)
@@ -803,7 +803,7 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev)
803 reqtags = 0; 803 reqtags = 0;
804 if (reqtags > SYM_CONF_MAX_TAG) 804 if (reqtags > SYM_CONF_MAX_TAG)
805 reqtags = SYM_CONF_MAX_TAG; 805 reqtags = SYM_CONF_MAX_TAG;
806 depth_to_use = reqtags ? reqtags : 2; 806 depth_to_use = reqtags ? reqtags : 1;
807 scsi_adjust_queue_depth(sdev, 807 scsi_adjust_queue_depth(sdev,
808 sdev->tagged_supported ? MSG_SIMPLE_TAG : 0, 808 sdev->tagged_supported ? MSG_SIMPLE_TAG : 0,
809 depth_to_use); 809 depth_to_use);
@@ -1236,14 +1236,29 @@ static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer,
1236#endif /* SYM_LINUX_PROC_INFO_SUPPORT */ 1236#endif /* SYM_LINUX_PROC_INFO_SUPPORT */
1237 1237
1238/* 1238/*
1239 * Free resources claimed by sym_iomap_device(). Note that
1240 * sym_free_resources() should be used instead of this function after calling
1241 * sym_attach().
1242 */
1243static void __devinit
1244sym_iounmap_device(struct sym_device *device)
1245{
1246 if (device->s.ioaddr)
1247 pci_iounmap(device->pdev, device->s.ioaddr);
1248 if (device->s.ramaddr)
1249 pci_iounmap(device->pdev, device->s.ramaddr);
1250}
1251
1252/*
1239 * Free controller resources. 1253 * Free controller resources.
1240 */ 1254 */
1241static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) 1255static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev,
1256 int do_free_irq)
1242{ 1257{
1243 /* 1258 /*
1244 * Free O/S specific resources. 1259 * Free O/S specific resources.
1245 */ 1260 */
1246 if (pdev->irq) 1261 if (do_free_irq)
1247 free_irq(pdev->irq, np->s.host); 1262 free_irq(pdev->irq, np->s.host);
1248 if (np->s.ioaddr) 1263 if (np->s.ioaddr)
1249 pci_iounmap(pdev, np->s.ioaddr); 1264 pci_iounmap(pdev, np->s.ioaddr);
@@ -1271,10 +1286,11 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1271{ 1286{
1272 struct sym_data *sym_data; 1287 struct sym_data *sym_data;
1273 struct sym_hcb *np = NULL; 1288 struct sym_hcb *np = NULL;
1274 struct Scsi_Host *shost; 1289 struct Scsi_Host *shost = NULL;
1275 struct pci_dev *pdev = dev->pdev; 1290 struct pci_dev *pdev = dev->pdev;
1276 unsigned long flags; 1291 unsigned long flags;
1277 struct sym_fw *fw; 1292 struct sym_fw *fw;
1293 int do_free_irq = 0;
1278 1294
1279 printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", 1295 printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n",
1280 unit, dev->chip.name, pdev->revision, pci_name(pdev), 1296 unit, dev->chip.name, pdev->revision, pci_name(pdev),
@@ -1285,11 +1301,11 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1285 */ 1301 */
1286 fw = sym_find_firmware(&dev->chip); 1302 fw = sym_find_firmware(&dev->chip);
1287 if (!fw) 1303 if (!fw)
1288 return NULL; 1304 goto attach_failed;
1289 1305
1290 shost = scsi_host_alloc(tpnt, sizeof(*sym_data)); 1306 shost = scsi_host_alloc(tpnt, sizeof(*sym_data));
1291 if (!shost) 1307 if (!shost)
1292 return NULL; 1308 goto attach_failed;
1293 sym_data = shost_priv(shost); 1309 sym_data = shost_priv(shost);
1294 1310
1295 /* 1311 /*
@@ -1319,6 +1335,10 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1319 np->maxoffs = dev->chip.offset_max; 1335 np->maxoffs = dev->chip.offset_max;
1320 np->maxburst = dev->chip.burst_max; 1336 np->maxburst = dev->chip.burst_max;
1321 np->myaddr = dev->host_id; 1337 np->myaddr = dev->host_id;
1338 np->mmio_ba = (u32)dev->mmio_base;
1339 np->ram_ba = (u32)dev->ram_base;
1340 np->s.ioaddr = dev->s.ioaddr;
1341 np->s.ramaddr = dev->s.ramaddr;
1322 1342
1323 /* 1343 /*
1324 * Edit its name. 1344 * Edit its name.
@@ -1334,22 +1354,6 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1334 goto attach_failed; 1354 goto attach_failed;
1335 } 1355 }
1336 1356
1337 /*
1338 * Try to map the controller chip to
1339 * virtual and physical memory.
1340 */
1341 np->mmio_ba = (u32)dev->mmio_base;
1342 np->s.ioaddr = dev->s.ioaddr;
1343 np->s.ramaddr = dev->s.ramaddr;
1344
1345 /*
1346 * Map on-chip RAM if present and supported.
1347 */
1348 if (!(np->features & FE_RAM))
1349 dev->ram_base = 0;
1350 if (dev->ram_base)
1351 np->ram_ba = (u32)dev->ram_base;
1352
1353 if (sym_hcb_attach(shost, fw, dev->nvram)) 1357 if (sym_hcb_attach(shost, fw, dev->nvram))
1354 goto attach_failed; 1358 goto attach_failed;
1355 1359
@@ -1364,6 +1368,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1364 sym_name(np), pdev->irq); 1368 sym_name(np), pdev->irq);
1365 goto attach_failed; 1369 goto attach_failed;
1366 } 1370 }
1371 do_free_irq = 1;
1367 1372
1368 /* 1373 /*
1369 * After SCSI devices have been opened, we cannot 1374 * After SCSI devices have been opened, we cannot
@@ -1416,12 +1421,13 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1416 "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); 1421 "TERMINATION, DEVICE POWER etc.!\n", sym_name(np));
1417 spin_unlock_irqrestore(shost->host_lock, flags); 1422 spin_unlock_irqrestore(shost->host_lock, flags);
1418 attach_failed: 1423 attach_failed:
1419 if (!shost) 1424 printf_info("sym%d: giving up ...\n", unit);
1420 return NULL;
1421 printf_info("%s: giving up ...\n", sym_name(np));
1422 if (np) 1425 if (np)
1423 sym_free_resources(np, pdev); 1426 sym_free_resources(np, pdev, do_free_irq);
1424 scsi_host_put(shost); 1427 else
1428 sym_iounmap_device(dev);
1429 if (shost)
1430 scsi_host_put(shost);
1425 1431
1426 return NULL; 1432 return NULL;
1427 } 1433 }
@@ -1550,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device)
1550} 1556}
1551 1557
1552/* 1558/*
1553 * Read and check the PCI configuration for any detected NCR 1559 * Map HBA registers and on-chip SRAM (if present).
1554 * boards and save data for attaching after all boards have
1555 * been detected.
1556 */ 1560 */
1557static void __devinit 1561static int __devinit
1558sym_init_device(struct pci_dev *pdev, struct sym_device *device) 1562sym_iomap_device(struct sym_device *device)
1559{ 1563{
1560 int i = 2; 1564 struct pci_dev *pdev = device->pdev;
1561 struct pci_bus_region bus_addr; 1565 struct pci_bus_region bus_addr;
1562 1566 int i = 2;
1563 device->host_id = SYM_SETUP_HOST_ID;
1564 device->pdev = pdev;
1565 1567
1566 pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); 1568 pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]);
1567 device->mmio_base = bus_addr.start; 1569 device->mmio_base = bus_addr.start;
1568 1570
1569 /* 1571 if (device->chip.features & FE_RAM) {
1570 * If the BAR is 64-bit, resource 2 will be occupied by the 1572 /*
1571 * upper 32 bits 1573 * If the BAR is 64-bit, resource 2 will be occupied by the
1572 */ 1574 * upper 32 bits
1573 if (!pdev->resource[i].flags) 1575 */
1574 i++; 1576 if (!pdev->resource[i].flags)
1575 pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); 1577 i++;
1576 device->ram_base = bus_addr.start; 1578 pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]);
1579 device->ram_base = bus_addr.start;
1580 }
1577 1581
1578#ifdef CONFIG_SCSI_SYM53C8XX_MMIO 1582#ifdef CONFIG_SCSI_SYM53C8XX_MMIO
1579 if (device->mmio_base) 1583 if (device->mmio_base)
@@ -1583,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device)
1583 if (!device->s.ioaddr) 1587 if (!device->s.ioaddr)
1584 device->s.ioaddr = pci_iomap(pdev, 0, 1588 device->s.ioaddr = pci_iomap(pdev, 0,
1585 pci_resource_len(pdev, 0)); 1589 pci_resource_len(pdev, 0));
1586 if (device->ram_base) 1590 if (!device->s.ioaddr) {
1591 dev_err(&pdev->dev, "could not map registers; giving up.\n");
1592 return -EIO;
1593 }
1594 if (device->ram_base) {
1587 device->s.ramaddr = pci_iomap(pdev, i, 1595 device->s.ramaddr = pci_iomap(pdev, i,
1588 pci_resource_len(pdev, i)); 1596 pci_resource_len(pdev, i));
1597 if (!device->s.ramaddr) {
1598 dev_warn(&pdev->dev,
1599 "could not map SRAM; continuing anyway.\n");
1600 device->ram_base = 0;
1601 }
1602 }
1603
1604 return 0;
1589} 1605}
1590 1606
1591/* 1607/*
@@ -1659,7 +1675,8 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev)
1659 udelay(10); 1675 udelay(10);
1660 OUTB(np, nc_istat, 0); 1676 OUTB(np, nc_istat, 0);
1661 1677
1662 sym_free_resources(np, pdev); 1678 sym_free_resources(np, pdev, 1);
1679 scsi_host_put(shost);
1663 1680
1664 return 1; 1681 return 1;
1665} 1682}
@@ -1696,9 +1713,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1696 struct sym_device sym_dev; 1713 struct sym_device sym_dev;
1697 struct sym_nvram nvram; 1714 struct sym_nvram nvram;
1698 struct Scsi_Host *shost; 1715 struct Scsi_Host *shost;
1716 int do_iounmap = 0;
1717 int do_disable_device = 1;
1699 1718
1700 memset(&sym_dev, 0, sizeof(sym_dev)); 1719 memset(&sym_dev, 0, sizeof(sym_dev));
1701 memset(&nvram, 0, sizeof(nvram)); 1720 memset(&nvram, 0, sizeof(nvram));
1721 sym_dev.pdev = pdev;
1722 sym_dev.host_id = SYM_SETUP_HOST_ID;
1702 1723
1703 if (pci_enable_device(pdev)) 1724 if (pci_enable_device(pdev))
1704 goto leave; 1725 goto leave;
@@ -1708,12 +1729,17 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1708 if (pci_request_regions(pdev, NAME53C8XX)) 1729 if (pci_request_regions(pdev, NAME53C8XX))
1709 goto disable; 1730 goto disable;
1710 1731
1711 sym_init_device(pdev, &sym_dev);
1712 if (sym_check_supported(&sym_dev)) 1732 if (sym_check_supported(&sym_dev))
1713 goto free; 1733 goto free;
1714 1734
1715 if (sym_check_raid(&sym_dev)) 1735 if (sym_iomap_device(&sym_dev))
1716 goto leave; /* Don't disable the device */ 1736 goto free;
1737 do_iounmap = 1;
1738
1739 if (sym_check_raid(&sym_dev)) {
1740 do_disable_device = 0; /* Don't disable the device */
1741 goto free;
1742 }
1717 1743
1718 if (sym_set_workarounds(&sym_dev)) 1744 if (sym_set_workarounds(&sym_dev))
1719 goto free; 1745 goto free;
@@ -1722,6 +1748,7 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1722 1748
1723 sym_get_nvram(&sym_dev, &nvram); 1749 sym_get_nvram(&sym_dev, &nvram);
1724 1750
1751 do_iounmap = 0; /* Don't sym_iounmap_device() after sym_attach(). */
1725 shost = sym_attach(&sym2_template, attach_count, &sym_dev); 1752 shost = sym_attach(&sym2_template, attach_count, &sym_dev);
1726 if (!shost) 1753 if (!shost)
1727 goto free; 1754 goto free;
@@ -1737,9 +1764,12 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1737 detach: 1764 detach:
1738 sym_detach(pci_get_drvdata(pdev), pdev); 1765 sym_detach(pci_get_drvdata(pdev), pdev);
1739 free: 1766 free:
1767 if (do_iounmap)
1768 sym_iounmap_device(&sym_dev);
1740 pci_release_regions(pdev); 1769 pci_release_regions(pdev);
1741 disable: 1770 disable:
1742 pci_disable_device(pdev); 1771 if (do_disable_device)
1772 pci_disable_device(pdev);
1743 leave: 1773 leave:
1744 return -ENODEV; 1774 return -ENODEV;
1745} 1775}
@@ -1749,7 +1779,6 @@ static void sym2_remove(struct pci_dev *pdev)
1749 struct Scsi_Host *shost = pci_get_drvdata(pdev); 1779 struct Scsi_Host *shost = pci_get_drvdata(pdev);
1750 1780
1751 scsi_remove_host(shost); 1781 scsi_remove_host(shost);
1752 scsi_host_put(shost);
1753 sym_detach(shost, pdev); 1782 sym_detach(shost, pdev);
1754 pci_release_regions(pdev); 1783 pci_release_regions(pdev);
1755 pci_disable_device(pdev); 1784 pci_disable_device(pdev);
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 98df1651404f..ccea7db59f49 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -1433,13 +1433,12 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
1433 * Many devices implement PPR in a buggy way, so only use it if we 1433 * Many devices implement PPR in a buggy way, so only use it if we
1434 * really want to. 1434 * really want to.
1435 */ 1435 */
1436 if (goal->offset && 1436 if (goal->renego == NS_PPR || (goal->offset &&
1437 (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) { 1437 (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)))) {
1438 nego = NS_PPR; 1438 nego = NS_PPR;
1439 } else if (spi_width(starget) != goal->width) { 1439 } else if (goal->renego == NS_WIDE || goal->width) {
1440 nego = NS_WIDE; 1440 nego = NS_WIDE;
1441 } else if (spi_period(starget) != goal->period || 1441 } else if (goal->renego == NS_SYNC || goal->offset) {
1442 spi_offset(starget) != goal->offset) {
1443 nego = NS_SYNC; 1442 nego = NS_SYNC;
1444 } else { 1443 } else {
1445 goal->check_nego = 0; 1444 goal->check_nego = 0;
@@ -2040,6 +2039,29 @@ static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs
2040 } 2039 }
2041} 2040}
2042 2041
2042static void sym_announce_transfer_rate(struct sym_tcb *tp)
2043{
2044 struct scsi_target *starget = tp->starget;
2045
2046 if (tp->tprint.period != spi_period(starget) ||
2047 tp->tprint.offset != spi_offset(starget) ||
2048 tp->tprint.width != spi_width(starget) ||
2049 tp->tprint.iu != spi_iu(starget) ||
2050 tp->tprint.dt != spi_dt(starget) ||
2051 tp->tprint.qas != spi_qas(starget) ||
2052 !tp->tprint.check_nego) {
2053 tp->tprint.period = spi_period(starget);
2054 tp->tprint.offset = spi_offset(starget);
2055 tp->tprint.width = spi_width(starget);
2056 tp->tprint.iu = spi_iu(starget);
2057 tp->tprint.dt = spi_dt(starget);
2058 tp->tprint.qas = spi_qas(starget);
2059 tp->tprint.check_nego = 1;
2060
2061 spi_display_xfer_agreement(starget);
2062 }
2063}
2064
2043/* 2065/*
2044 * We received a WDTR. 2066 * We received a WDTR.
2045 * Let everything be aware of the changes. 2067 * Let everything be aware of the changes.
@@ -2049,11 +2071,13 @@ static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
2049 struct sym_tcb *tp = &np->target[target]; 2071 struct sym_tcb *tp = &np->target[target];
2050 struct scsi_target *starget = tp->starget; 2072 struct scsi_target *starget = tp->starget;
2051 2073
2052 if (spi_width(starget) == wide)
2053 return;
2054
2055 sym_settrans(np, target, 0, 0, 0, wide, 0, 0); 2074 sym_settrans(np, target, 0, 0, 0, wide, 0, 0);
2056 2075
2076 if (wide)
2077 tp->tgoal.renego = NS_WIDE;
2078 else
2079 tp->tgoal.renego = 0;
2080 tp->tgoal.check_nego = 0;
2057 tp->tgoal.width = wide; 2081 tp->tgoal.width = wide;
2058 spi_offset(starget) = 0; 2082 spi_offset(starget) = 0;
2059 spi_period(starget) = 0; 2083 spi_period(starget) = 0;
@@ -2063,7 +2087,7 @@ static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
2063 spi_qas(starget) = 0; 2087 spi_qas(starget) = 0;
2064 2088
2065 if (sym_verbose >= 3) 2089 if (sym_verbose >= 3)
2066 spi_display_xfer_agreement(starget); 2090 sym_announce_transfer_rate(tp);
2067} 2091}
2068 2092
2069/* 2093/*
@@ -2080,6 +2104,12 @@ sym_setsync(struct sym_hcb *np, int target,
2080 2104
2081 sym_settrans(np, target, 0, ofs, per, wide, div, fak); 2105 sym_settrans(np, target, 0, ofs, per, wide, div, fak);
2082 2106
2107 if (wide)
2108 tp->tgoal.renego = NS_WIDE;
2109 else if (ofs)
2110 tp->tgoal.renego = NS_SYNC;
2111 else
2112 tp->tgoal.renego = 0;
2083 spi_period(starget) = per; 2113 spi_period(starget) = per;
2084 spi_offset(starget) = ofs; 2114 spi_offset(starget) = ofs;
2085 spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0; 2115 spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0;
@@ -2090,7 +2120,7 @@ sym_setsync(struct sym_hcb *np, int target,
2090 tp->tgoal.check_nego = 0; 2120 tp->tgoal.check_nego = 0;
2091 } 2121 }
2092 2122
2093 spi_display_xfer_agreement(starget); 2123 sym_announce_transfer_rate(tp);
2094} 2124}
2095 2125
2096/* 2126/*
@@ -2106,6 +2136,10 @@ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
2106 2136
2107 sym_settrans(np, target, opts, ofs, per, wide, div, fak); 2137 sym_settrans(np, target, opts, ofs, per, wide, div, fak);
2108 2138
2139 if (wide || ofs)
2140 tp->tgoal.renego = NS_PPR;
2141 else
2142 tp->tgoal.renego = 0;
2109 spi_width(starget) = tp->tgoal.width = wide; 2143 spi_width(starget) = tp->tgoal.width = wide;
2110 spi_period(starget) = tp->tgoal.period = per; 2144 spi_period(starget) = tp->tgoal.period = per;
2111 spi_offset(starget) = tp->tgoal.offset = ofs; 2145 spi_offset(starget) = tp->tgoal.offset = ofs;
@@ -2114,7 +2148,7 @@ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
2114 spi_qas(starget) = tp->tgoal.qas = !!(opts & PPR_OPT_QAS); 2148 spi_qas(starget) = tp->tgoal.qas = !!(opts & PPR_OPT_QAS);
2115 tp->tgoal.check_nego = 0; 2149 tp->tgoal.check_nego = 0;
2116 2150
2117 spi_display_xfer_agreement(starget); 2151 sym_announce_transfer_rate(tp);
2118} 2152}
2119 2153
2120/* 2154/*
@@ -3516,6 +3550,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
3516 spi_dt(starget) = 0; 3550 spi_dt(starget) = 0;
3517 spi_qas(starget) = 0; 3551 spi_qas(starget) = 0;
3518 tp->tgoal.check_nego = 1; 3552 tp->tgoal.check_nego = 1;
3553 tp->tgoal.renego = 0;
3519 } 3554 }
3520 3555
3521 /* 3556 /*
@@ -5135,9 +5170,14 @@ int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *
5135 /* 5170 /*
5136 * Build a negotiation message if needed. 5171 * Build a negotiation message if needed.
5137 * (nego_status is filled by sym_prepare_nego()) 5172 * (nego_status is filled by sym_prepare_nego())
5173 *
5174 * Always negotiate on INQUIRY and REQUEST SENSE.
5175 *
5138 */ 5176 */
5139 cp->nego_status = 0; 5177 cp->nego_status = 0;
5140 if (tp->tgoal.check_nego && !tp->nego_cp && lp) { 5178 if ((tp->tgoal.check_nego ||
5179 cmd->cmnd[0] == INQUIRY || cmd->cmnd[0] == REQUEST_SENSE) &&
5180 !tp->nego_cp && lp) {
5141 msglen += sym_prepare_nego(np, cp, msgptr + msglen); 5181 msglen += sym_prepare_nego(np, cp, msgptr + msglen);
5142 } 5182 }
5143 5183
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index ad078805e62b..61d28fcfffbf 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -354,6 +354,7 @@ struct sym_trans {
354 unsigned int dt:1; 354 unsigned int dt:1;
355 unsigned int qas:1; 355 unsigned int qas:1;
356 unsigned int check_nego:1; 356 unsigned int check_nego:1;
357 unsigned int renego:2;
357}; 358};
358 359
359/* 360/*
@@ -419,6 +420,9 @@ struct sym_tcb {
419 /* Transfer goal */ 420 /* Transfer goal */
420 struct sym_trans tgoal; 421 struct sym_trans tgoal;
421 422
423 /* Last printed transfer speed */
424 struct sym_trans tprint;
425
422 /* 426 /*
423 * Keep track of the CCB used for the negotiation in order 427 * Keep track of the CCB used for the negotiation in order
424 * to ensure that only 1 negotiation is queued at a time. 428 * to ensure that only 1 negotiation is queued at a time.