diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 14:44:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 14:44:25 -0500 |
commit | 5f0b1437e0708772b6fecae5900c01c3b5f9b512 (patch) | |
tree | bcd923e305345178bc162ed8560d56a3af197224 | |
parent | 574009c1a895aeeb85eaab29c235d75852b09eb8 (diff) | |
parent | 81b7bbd1932a04869d4c8635a75222dfc6089f96 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (97 commits)
[SCSI] zfcp: removed wrong comment
[SCSI] zfcp: use of uninitialized variable
[SCSI] zfcp: Invalid locking order
[SCSI] aic79xx: use dma_get_required_mask()
[SCSI] aic79xx: fix bracket mismatch in unused macro
[SCSI] BusLogic: Replace 'boolean' by 'bool'
[SCSI] advansys: clean up warnings
[SCSI] 53c7xx: brackets fix in uncompiled code
[SCSI] nsp_cs: remove old scsi code
[SCSI] aic79xx: make ahd_match_scb() static
[SCSI] DAC960: kmalloc->kzalloc/Casting cleanups
[SCSI] scsi_kmap_atomic_sg(): check that local irqs are disabled
[SCSI] Buslogic: local_irq_disable() is redundant after local_irq_save()
[SCSI] aic94xx: update for v28 firmware
[SCSI] scsi_error: Fix lost EH commands
[SCSI] aic94xx: Add default bus reset handler
[SCSI] aic94xx: Remove TMF result code munging
[SCSI] libsas: Add an LU reset mechanism to the error handler
[SCSI] libsas: Don't BUG when connecting two expanders via wide port
[SCSI] st: fix Tape dies if wrong block size used, bug 7919
...
104 files changed, 5827 insertions, 3135 deletions
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid index a056bbe67c7e..37796fe45bd0 100644 --- a/Documentation/scsi/ChangeLog.megaraid +++ b/Documentation/scsi/ChangeLog.megaraid | |||
@@ -1,3 +1,19 @@ | |||
1 | Release Date : Thu Nov 16 15:32:35 EST 2006 - | ||
2 | Sumant Patro <sumant.patro@lsi.com> | ||
3 | Current Version : 2.20.5.1 (scsi module), 2.20.2.6 (cmm module) | ||
4 | Older Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) | ||
5 | |||
6 | 1. Changes in Initialization to fix kdump failure. | ||
7 | Send SYNC command on loading. | ||
8 | This command clears the pending commands in the adapter | ||
9 | and re-initialize its internal RAID structure. | ||
10 | Without this change, megaraid driver either panics or fails to | ||
11 | initialize the adapter during kdump's second kernel boot | ||
12 | if there are pending commands or interrupts from other devices | ||
13 | sharing the same IRQ. | ||
14 | 2. Authors email-id domain name changed from lsil.com to lsi.com. | ||
15 | Also modified the MODULE_AUTHOR to megaraidlinux@lsi.com | ||
16 | |||
1 | Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com> | 17 | Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com> |
2 | Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) | 18 | Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) |
3 | Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) | 19 | Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6ad28dfb1469..7b2fa3d8f61c 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -1373,8 +1373,7 @@ static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T | |||
1373 | Controller->BounceBufferLimit = DAC690_V2_PciDmaMask; | 1373 | Controller->BounceBufferLimit = DAC690_V2_PciDmaMask; |
1374 | 1374 | ||
1375 | /* This is a temporary dma mapping, used only in the scope of this function */ | 1375 | /* This is a temporary dma mapping, used only in the scope of this function */ |
1376 | CommandMailbox = | 1376 | CommandMailbox = pci_alloc_consistent(PCI_Device, |
1377 | (DAC960_V2_CommandMailbox_T *)pci_alloc_consistent( PCI_Device, | ||
1378 | sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA); | 1377 | sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA); |
1379 | if (CommandMailbox == NULL) | 1378 | if (CommandMailbox == NULL) |
1380 | return false; | 1379 | return false; |
@@ -1879,8 +1878,8 @@ static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T | |||
1879 | if (NewLogicalDeviceInfo->LogicalDeviceState != | 1878 | if (NewLogicalDeviceInfo->LogicalDeviceState != |
1880 | DAC960_V2_LogicalDevice_Offline) | 1879 | DAC960_V2_LogicalDevice_Offline) |
1881 | Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true; | 1880 | Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true; |
1882 | LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *) | 1881 | LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), |
1883 | kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC); | 1882 | GFP_ATOMIC); |
1884 | if (LogicalDeviceInfo == NULL) | 1883 | if (LogicalDeviceInfo == NULL) |
1885 | return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION"); | 1884 | return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION"); |
1886 | Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = | 1885 | Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = |
@@ -2113,8 +2112,8 @@ static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T | |||
2113 | if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit)) | 2112 | if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit)) |
2114 | break; | 2113 | break; |
2115 | 2114 | ||
2116 | PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *) | 2115 | PhysicalDeviceInfo = kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), |
2117 | kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC); | 2116 | GFP_ATOMIC); |
2118 | if (PhysicalDeviceInfo == NULL) | 2117 | if (PhysicalDeviceInfo == NULL) |
2119 | return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION"); | 2118 | return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION"); |
2120 | Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] = | 2119 | Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] = |
@@ -2122,8 +2121,8 @@ static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T | |||
2122 | memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo, | 2121 | memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo, |
2123 | sizeof(DAC960_V2_PhysicalDeviceInfo_T)); | 2122 | sizeof(DAC960_V2_PhysicalDeviceInfo_T)); |
2124 | 2123 | ||
2125 | InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *) | 2124 | InquiryUnitSerialNumber = kmalloc( |
2126 | kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC); | 2125 | sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC); |
2127 | if (InquiryUnitSerialNumber == NULL) { | 2126 | if (InquiryUnitSerialNumber == NULL) { |
2128 | kfree(PhysicalDeviceInfo); | 2127 | kfree(PhysicalDeviceInfo); |
2129 | return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION"); | 2128 | return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION"); |
@@ -4949,8 +4948,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4949 | PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit; | 4948 | PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit; |
4950 | Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] = | 4949 | Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] = |
4951 | PhysicalDevice; | 4950 | PhysicalDevice; |
4952 | LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *) | 4951 | LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), |
4953 | kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC); | 4952 | GFP_ATOMIC); |
4954 | Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = | 4953 | Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] = |
4955 | LogicalDeviceInfo; | 4954 | LogicalDeviceInfo; |
4956 | DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " | 4955 | DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) " |
@@ -5709,14 +5708,14 @@ static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller, | |||
5709 | unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize; | 5708 | unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize; |
5710 | while (NewStatusBufferLength < ByteCount) | 5709 | while (NewStatusBufferLength < ByteCount) |
5711 | NewStatusBufferLength *= 2; | 5710 | NewStatusBufferLength *= 2; |
5712 | Controller->CombinedStatusBuffer = | 5711 | Controller->CombinedStatusBuffer = kmalloc(NewStatusBufferLength, |
5713 | (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC); | 5712 | GFP_ATOMIC); |
5714 | if (Controller->CombinedStatusBuffer == NULL) return false; | 5713 | if (Controller->CombinedStatusBuffer == NULL) return false; |
5715 | Controller->CombinedStatusBufferLength = NewStatusBufferLength; | 5714 | Controller->CombinedStatusBufferLength = NewStatusBufferLength; |
5716 | return true; | 5715 | return true; |
5717 | } | 5716 | } |
5718 | NewStatusBuffer = (unsigned char *) | 5717 | NewStatusBuffer = kmalloc(2 * Controller->CombinedStatusBufferLength, |
5719 | kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC); | 5718 | GFP_ATOMIC); |
5720 | if (NewStatusBuffer == NULL) | 5719 | if (NewStatusBuffer == NULL) |
5721 | { | 5720 | { |
5722 | DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n", | 5721 | DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n", |
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index ea31d8470510..71037f91c222 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig | |||
@@ -66,7 +66,7 @@ config FUSION_MAX_SGE | |||
66 | 66 | ||
67 | config FUSION_CTL | 67 | config FUSION_CTL |
68 | tristate "Fusion MPT misc device (ioctl) driver" | 68 | tristate "Fusion MPT misc device (ioctl) driver" |
69 | depends on FUSION_SPI || FUSION_FC | 69 | depends on FUSION_SPI || FUSION_FC || FUSION_SAS |
70 | ---help--- | 70 | ---help--- |
71 | The Fusion MPT misc device driver provides specialized control | 71 | The Fusion MPT misc device driver provides specialized control |
72 | of MPT adapters via system ioctl calls. Use of ioctl calls to | 72 | of MPT adapters via system ioctl calls. Use of ioctl calls to |
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 341691390e86..6003b46c8438 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -8,6 +8,9 @@ | |||
8 | #EXTRA_CFLAGS += -DMPT_DEBUG_INIT | 8 | #EXTRA_CFLAGS += -DMPT_DEBUG_INIT |
9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT | 9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT |
10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL | 10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL |
11 | #EXTRA_CFLAGS += -DMPT_DEBUG_DV | ||
12 | #EXTRA_CFLAGS += -DMPT_DEBUG_TM | ||
13 | #EXTRA_CFLAGS += -DMPT_DEBUG_REPLY | ||
11 | 14 | ||
12 | # | 15 | # |
13 | # driver/module specifics... | 16 | # driver/module specifics... |
@@ -20,11 +23,7 @@ | |||
20 | #CFLAGS_mptbase.o += -DMPT_DEBUG_RESET | 23 | #CFLAGS_mptbase.o += -DMPT_DEBUG_RESET |
21 | # | 24 | # |
22 | # For mptscsih: | 25 | # For mptscsih: |
23 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_DV | ||
24 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO | ||
25 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_TM | ||
26 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI | 26 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI |
27 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY | ||
28 | # | 27 | # |
29 | # For mptctl: | 28 | # For mptctl: |
30 | #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL | 29 | #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL |
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 81ad77622dac..75223bf24ae8 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 LSI Logic Corporation. | 2 | * Copyright (c) 2000-2006 LSI Logic Corporation. |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Name: mpi.h | 5 | * Name: mpi.h |
6 | * Title: MPI Message independent structures and definitions | 6 | * Title: MPI Message independent structures and definitions |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi.h Version: 01.05.11 | 9 | * mpi.h Version: 01.05.12 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -77,6 +77,7 @@ | |||
77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
79 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | 79 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. |
80 | * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT. | ||
80 | * -------------------------------------------------------------------------- | 81 | * -------------------------------------------------------------------------- |
81 | */ | 82 | */ |
82 | 83 | ||
@@ -107,7 +108,7 @@ | |||
107 | /* Note: The major versions of 0xe0 through 0xff are reserved */ | 108 | /* Note: The major versions of 0xe0 through 0xff are reserved */ |
108 | 109 | ||
109 | /* versioning for this MPI header set */ | 110 | /* versioning for this MPI header set */ |
110 | #define MPI_HEADER_VERSION_UNIT (0x0D) | 111 | #define MPI_HEADER_VERSION_UNIT (0x0E) |
111 | #define MPI_HEADER_VERSION_DEV (0x00) | 112 | #define MPI_HEADER_VERSION_DEV (0x00) |
112 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) | 113 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) |
113 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) | 114 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) |
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index 47e13e360c10..0e4c8e77a81d 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 LSI Logic Corporation. | 2 | * Copyright (c) 2000-2006 LSI Logic Corporation. |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Name: mpi_cnfg.h | 5 | * Name: mpi_cnfg.h |
6 | * Title: MPI Config message, structures, and Pages | 6 | * Title: MPI Config message, structures, and Pages |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi_cnfg.h Version: 01.05.12 | 9 | * mpi_cnfg.h Version: 01.05.13 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -276,6 +276,23 @@ | |||
276 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | 276 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, |
277 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | 277 | * ReportDeviceMissingDelay, and IODeviceMissingDelay |
278 | * fields to SAS IO Unit Page 1. | 278 | * fields to SAS IO Unit Page 1. |
279 | * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to | ||
280 | * Manufacturing Page 5. | ||
281 | * Added Manufacturing pages 8 through 10. | ||
282 | * Added defines for supported metadata size bits in | ||
283 | * CapabilitiesFlags field of IOC Page 6. | ||
284 | * Added defines for metadata size bits in VolumeSettings | ||
285 | * field of RAID Volume Page 0. | ||
286 | * Added SATA Link Reset settings, Enable SATA Asynchronous | ||
287 | * Notification bit, and HideNonZeroAttachedPhyIdentifiers | ||
288 | * bit to AdditionalControlFlags field of SAS IO Unit | ||
289 | * Page 1. | ||
290 | * Added defines for Enclosure Devices Unmapped and | ||
291 | * Device Limit Exceeded bits in Status field of SAS IO | ||
292 | * Unit Page 2. | ||
293 | * Added more AccessStatus values for SAS Device Page 0. | ||
294 | * Added bit for SATA Asynchronous Notification Support in | ||
295 | * Flags field of SAS Device Page 0. | ||
279 | * -------------------------------------------------------------------------- | 296 | * -------------------------------------------------------------------------- |
280 | */ | 297 | */ |
281 | 298 | ||
@@ -654,17 +671,24 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 | |||
654 | #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) | 671 | #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) |
655 | 672 | ||
656 | 673 | ||
674 | #ifndef MPI_MANPAGE5_NUM_FORCEWWID | ||
675 | #define MPI_MANPAGE5_NUM_FORCEWWID (1) | ||
676 | #endif | ||
677 | |||
657 | typedef struct _CONFIG_PAGE_MANUFACTURING_5 | 678 | typedef struct _CONFIG_PAGE_MANUFACTURING_5 |
658 | { | 679 | { |
659 | CONFIG_PAGE_HEADER Header; /* 00h */ | 680 | CONFIG_PAGE_HEADER Header; /* 00h */ |
660 | U64 BaseWWID; /* 04h */ | 681 | U64 BaseWWID; /* 04h */ |
661 | U8 Flags; /* 0Ch */ | 682 | U8 Flags; /* 0Ch */ |
662 | U8 Reserved1; /* 0Dh */ | 683 | U8 NumForceWWID; /* 0Dh */ |
663 | U16 Reserved2; /* 0Eh */ | 684 | U16 Reserved2; /* 0Eh */ |
685 | U32 Reserved3; /* 10h */ | ||
686 | U32 Reserved4; /* 14h */ | ||
687 | U64 ForceWWID[MPI_MANPAGE5_NUM_FORCEWWID]; /* 18h */ | ||
664 | } CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5, | 688 | } CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5, |
665 | ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t; | 689 | ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t; |
666 | 690 | ||
667 | #define MPI_MANUFACTURING5_PAGEVERSION (0x01) | 691 | #define MPI_MANUFACTURING5_PAGEVERSION (0x02) |
668 | 692 | ||
669 | /* defines for the Flags field */ | 693 | /* defines for the Flags field */ |
670 | #define MPI_MANPAGE5_TWO_WWID_PER_PHY (0x01) | 694 | #define MPI_MANPAGE5_TWO_WWID_PER_PHY (0x01) |
@@ -740,6 +764,36 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_7 | |||
740 | #define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) | 764 | #define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) |
741 | 765 | ||
742 | 766 | ||
767 | typedef struct _CONFIG_PAGE_MANUFACTURING_8 | ||
768 | { | ||
769 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
770 | U32 ProductSpecificInfo;/* 04h */ | ||
771 | } CONFIG_PAGE_MANUFACTURING_8, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_8, | ||
772 | ManufacturingPage8_t, MPI_POINTER pManufacturingPage8_t; | ||
773 | |||
774 | #define MPI_MANUFACTURING8_PAGEVERSION (0x00) | ||
775 | |||
776 | |||
777 | typedef struct _CONFIG_PAGE_MANUFACTURING_9 | ||
778 | { | ||
779 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
780 | U32 ProductSpecificInfo;/* 04h */ | ||
781 | } CONFIG_PAGE_MANUFACTURING_9, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_9, | ||
782 | ManufacturingPage9_t, MPI_POINTER pManufacturingPage9_t; | ||
783 | |||
784 | #define MPI_MANUFACTURING6_PAGEVERSION (0x00) | ||
785 | |||
786 | |||
787 | typedef struct _CONFIG_PAGE_MANUFACTURING_10 | ||
788 | { | ||
789 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
790 | U32 ProductSpecificInfo;/* 04h */ | ||
791 | } CONFIG_PAGE_MANUFACTURING_10, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_10, | ||
792 | ManufacturingPage10_t, MPI_POINTER pManufacturingPage10_t; | ||
793 | |||
794 | #define MPI_MANUFACTURING10_PAGEVERSION (0x00) | ||
795 | |||
796 | |||
743 | /**************************************************************************** | 797 | /**************************************************************************** |
744 | * IO Unit Config Pages | 798 | * IO Unit Config Pages |
745 | ****************************************************************************/ | 799 | ****************************************************************************/ |
@@ -1080,10 +1134,14 @@ typedef struct _CONFIG_PAGE_IOC_6 | |||
1080 | } CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, | 1134 | } CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, |
1081 | IOCPage6_t, MPI_POINTER pIOCPage6_t; | 1135 | IOCPage6_t, MPI_POINTER pIOCPage6_t; |
1082 | 1136 | ||
1083 | #define MPI_IOCPAGE6_PAGEVERSION (0x00) | 1137 | #define MPI_IOCPAGE6_PAGEVERSION (0x01) |
1084 | 1138 | ||
1085 | /* IOC Page 6 Capabilities Flags */ | 1139 | /* IOC Page 6 Capabilities Flags */ |
1086 | 1140 | ||
1141 | #define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE (0x00000006) | ||
1142 | #define MPI_IOCPAGE6_CAP_FLAGS_64MB_METADATA_SIZE (0x00000000) | ||
1143 | #define MPI_IOCPAGE6_CAP_FLAGS_512MB_METADATA_SIZE (0x00000002) | ||
1144 | |||
1087 | #define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) | 1145 | #define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) |
1088 | 1146 | ||
1089 | 1147 | ||
@@ -2160,6 +2218,11 @@ typedef struct _RAID_VOL0_SETTINGS | |||
2160 | #define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004) | 2218 | #define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004) |
2161 | #define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008) | 2219 | #define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008) |
2162 | #define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102 (0x0020) /* obsolete */ | 2220 | #define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102 (0x0020) /* obsolete */ |
2221 | |||
2222 | #define MPI_RAIDVOL0_SETTING_MASK_METADATA_SIZE (0x00C0) | ||
2223 | #define MPI_RAIDVOL0_SETTING_64MB_METADATA_SIZE (0x0000) | ||
2224 | #define MPI_RAIDVOL0_SETTING_512MB_METADATA_SIZE (0x0040) | ||
2225 | |||
2163 | #define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010) | 2226 | #define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010) |
2164 | #define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000) | 2227 | #define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000) |
2165 | 2228 | ||
@@ -2203,7 +2266,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 | |||
2203 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, | 2266 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, |
2204 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; | 2267 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; |
2205 | 2268 | ||
2206 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06) | 2269 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x07) |
2207 | 2270 | ||
2208 | /* values for RAID Volume Page 0 InactiveStatus field */ | 2271 | /* values for RAID Volume Page 0 InactiveStatus field */ |
2209 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) | 2272 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) |
@@ -2518,7 +2581,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2518 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, | 2581 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, |
2519 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; | 2582 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; |
2520 | 2583 | ||
2521 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06) | 2584 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x07) |
2522 | 2585 | ||
2523 | /* values for SAS IO Unit Page 1 ControlFlags */ | 2586 | /* values for SAS IO Unit Page 1 ControlFlags */ |
2524 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) | 2587 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) |
@@ -2544,7 +2607,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2544 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) | 2607 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) |
2545 | 2608 | ||
2546 | /* values for SAS IO Unit Page 1 AdditionalControlFlags */ | 2609 | /* values for SAS IO Unit Page 1 AdditionalControlFlags */ |
2547 | #define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) | 2610 | #define MPI_SAS_IOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040) |
2611 | #define MPI_SAS_IOUNIT1_ACONTROL_HIDE_NONZERO_ATTACHED_PHY_IDENT (0x0020) | ||
2612 | #define MPI_SAS_IOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010) | ||
2613 | #define MPI_SAS_IOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008) | ||
2614 | #define MPI_SAS_IOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004) | ||
2615 | #define MPI_SAS_IOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002) | ||
2616 | #define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) | ||
2548 | 2617 | ||
2549 | /* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ | 2618 | /* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ |
2550 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) | 2619 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) |
@@ -2585,9 +2654,11 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 | |||
2585 | } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, | 2654 | } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, |
2586 | SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; | 2655 | SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; |
2587 | 2656 | ||
2588 | #define MPI_SASIOUNITPAGE2_PAGEVERSION (0x05) | 2657 | #define MPI_SASIOUNITPAGE2_PAGEVERSION (0x06) |
2589 | 2658 | ||
2590 | /* values for SAS IO Unit Page 2 Status field */ | 2659 | /* values for SAS IO Unit Page 2 Status field */ |
2660 | #define MPI_SAS_IOUNIT2_STATUS_DEVICE_LIMIT_EXCEEDED (0x08) | ||
2661 | #define MPI_SAS_IOUNIT2_STATUS_ENCLOSURE_DEVICES_UNMAPPED (0x04) | ||
2591 | #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) | 2662 | #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) |
2592 | #define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01) | 2663 | #define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01) |
2593 | 2664 | ||
@@ -2739,24 +2810,38 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_0 | |||
2739 | } CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0, | 2810 | } CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0, |
2740 | SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t; | 2811 | SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t; |
2741 | 2812 | ||
2742 | #define MPI_SASDEVICE0_PAGEVERSION (0x04) | 2813 | #define MPI_SASDEVICE0_PAGEVERSION (0x05) |
2743 | 2814 | ||
2744 | /* values for SAS Device Page 0 AccessStatus field */ | 2815 | /* values for SAS Device Page 0 AccessStatus field */ |
2745 | #define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) | 2816 | #define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) |
2746 | #define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) | 2817 | #define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) |
2747 | #define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) | 2818 | #define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) |
2819 | #define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03) | ||
2820 | /* specific values for SATA Init failures */ | ||
2821 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10) | ||
2822 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11) | ||
2823 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12) | ||
2824 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13) | ||
2825 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14) | ||
2826 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15) | ||
2827 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16) | ||
2828 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17) | ||
2829 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18) | ||
2830 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19) | ||
2831 | #define MPI_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F) | ||
2748 | 2832 | ||
2749 | /* values for SAS Device Page 0 Flags field */ | 2833 | /* values for SAS Device Page 0 Flags field */ |
2750 | #define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) | 2834 | #define MPI_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) |
2751 | #define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) | 2835 | #define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) |
2752 | #define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080) | 2836 | #define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) |
2753 | #define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040) | 2837 | #define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080) |
2754 | #define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) | 2838 | #define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040) |
2755 | #define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) | 2839 | #define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) |
2756 | #define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) | 2840 | #define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) |
2757 | #define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004) | 2841 | #define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) |
2758 | #define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002) | 2842 | #define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004) |
2759 | #define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) | 2843 | #define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002) |
2844 | #define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) | ||
2760 | 2845 | ||
2761 | /* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */ | 2846 | /* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */ |
2762 | 2847 | ||
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 582cfe7c2aa1..d6b4c607453b 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt | |||
@@ -3,28 +3,28 @@ | |||
3 | MPI Header File Change History | 3 | MPI Header File Change History |
4 | ============================== | 4 | ============================== |
5 | 5 | ||
6 | Copyright (c) 2000-2005 LSI Logic Corporation. | 6 | Copyright (c) 2000-2006 LSI Logic Corporation. |
7 | 7 | ||
8 | --------------------------------------- | 8 | --------------------------------------- |
9 | Header Set Release Version: 01.05.13 | 9 | Header Set Release Version: 01.05.14 |
10 | Header Set Release Date: 03-27-06 | 10 | Header Set Release Date: 10-11-06 |
11 | --------------------------------------- | 11 | --------------------------------------- |
12 | 12 | ||
13 | Filename Current version Prior version | 13 | Filename Current version Prior version |
14 | ---------- --------------- ------------- | 14 | ---------- --------------- ------------- |
15 | mpi.h 01.05.11 01.05.10 | 15 | mpi.h 01.05.12 01.05.11 |
16 | mpi_ioc.h 01.05.11 01.05.10 | 16 | mpi_ioc.h 01.05.12 01.05.11 |
17 | mpi_cnfg.h 01.05.12 01.05.11 | 17 | mpi_cnfg.h 01.05.13 01.05.12 |
18 | mpi_init.h 01.05.07 01.05.06 | 18 | mpi_init.h 01.05.08 01.05.07 |
19 | mpi_targ.h 01.05.06 01.05.05 | 19 | mpi_targ.h 01.05.06 01.05.06 |
20 | mpi_fc.h 01.05.01 01.05.01 | 20 | mpi_fc.h 01.05.01 01.05.01 |
21 | mpi_lan.h 01.05.01 01.05.01 | 21 | mpi_lan.h 01.05.01 01.05.01 |
22 | mpi_raid.h 01.05.02 01.05.02 | 22 | mpi_raid.h 01.05.02 01.05.02 |
23 | mpi_tool.h 01.05.03 01.05.03 | 23 | mpi_tool.h 01.05.03 01.05.03 |
24 | mpi_inb.h 01.05.01 01.05.01 | 24 | mpi_inb.h 01.05.01 01.05.01 |
25 | mpi_sas.h 01.05.03 01.05.02 | 25 | mpi_sas.h 01.05.04 01.05.03 |
26 | mpi_type.h 01.05.02 01.05.02 | 26 | mpi_type.h 01.05.02 01.05.02 |
27 | mpi_history.txt 01.05.13 01.05.12 | 27 | mpi_history.txt 01.05.14 01.05.13 |
28 | 28 | ||
29 | 29 | ||
30 | * Date Version Description | 30 | * Date Version Description |
@@ -94,6 +94,7 @@ mpi.h | |||
94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
96 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | 96 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. |
97 | * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT. | ||
97 | * -------------------------------------------------------------------------- | 98 | * -------------------------------------------------------------------------- |
98 | 99 | ||
99 | mpi_ioc.h | 100 | mpi_ioc.h |
@@ -182,6 +183,14 @@ mpi_ioc.h | |||
182 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | 183 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event |
183 | * data structure. | 184 | * data structure. |
184 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | 185 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. |
186 | * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. | ||
187 | * Added MaxInitiators field to PortFacts reply. | ||
188 | * Added SAS Device Status Change ReasonCode for | ||
189 | * asynchronous notificaiton. | ||
190 | * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event | ||
191 | * data structure. | ||
192 | * Added new ImageType values for FWDownload and FWUpload | ||
193 | * requests. | ||
185 | * -------------------------------------------------------------------------- | 194 | * -------------------------------------------------------------------------- |
186 | 195 | ||
187 | mpi_cnfg.h | 196 | mpi_cnfg.h |
@@ -447,6 +456,23 @@ mpi_cnfg.h | |||
447 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | 456 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, |
448 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | 457 | * ReportDeviceMissingDelay, and IODeviceMissingDelay |
449 | * fields to SAS IO Unit Page 1. | 458 | * fields to SAS IO Unit Page 1. |
459 | * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to | ||
460 | * Manufacturing Page 5. | ||
461 | * Added Manufacturing pages 8 through 10. | ||
462 | * Added defines for supported metadata size bits in | ||
463 | * CapabilitiesFlags field of IOC Page 6. | ||
464 | * Added defines for metadata size bits in VolumeSettings | ||
465 | * field of RAID Volume Page 0. | ||
466 | * Added SATA Link Reset settings, Enable SATA Asynchronous | ||
467 | * Notification bit, and HideNonZeroAttachedPhyIdentifiers | ||
468 | * bit to AdditionalControlFlags field of SAS IO Unit | ||
469 | * Page 1. | ||
470 | * Added defines for Enclosure Devices Unmapped and | ||
471 | * Device Limit Exceeded bits in Status field of SAS IO | ||
472 | * Unit Page 2. | ||
473 | * Added more AccessStatus values for SAS Device Page 0. | ||
474 | * Added bit for SATA Asynchronous Notification Support in | ||
475 | * Flags field of SAS Device Page 0. | ||
450 | * -------------------------------------------------------------------------- | 476 | * -------------------------------------------------------------------------- |
451 | 477 | ||
452 | mpi_init.h | 478 | mpi_init.h |
@@ -490,6 +516,7 @@ mpi_init.h | |||
490 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 516 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
491 | * unique in the first 32 characters. | 517 | * unique in the first 32 characters. |
492 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | 518 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. |
519 | * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA. | ||
493 | * -------------------------------------------------------------------------- | 520 | * -------------------------------------------------------------------------- |
494 | 521 | ||
495 | mpi_targ.h | 522 | mpi_targ.h |
@@ -638,6 +665,8 @@ mpi_sas.h | |||
638 | * and Remove Device operations to SAS IO Unit Control. | 665 | * and Remove Device operations to SAS IO Unit Control. |
639 | * Added DevHandle field to SAS IO Unit Control request and | 666 | * Added DevHandle field to SAS IO Unit Control request and |
640 | * reply. | 667 | * reply. |
668 | * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO | ||
669 | * Unit Control request. | ||
641 | * -------------------------------------------------------------------------- | 670 | * -------------------------------------------------------------------------- |
642 | 671 | ||
643 | mpi_type.h | 672 | mpi_type.h |
@@ -653,20 +682,20 @@ mpi_type.h | |||
653 | 682 | ||
654 | mpi_history.txt Parts list history | 683 | mpi_history.txt Parts list history |
655 | 684 | ||
656 | Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 | 685 | Filename 01.05.13 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 |
657 | ---------- -------- -------- -------- -------- -------- | 686 | ---------- -------- -------- -------- -------- -------- -------- |
658 | mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07 | 687 | mpi.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07 |
659 | mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08 | 688 | mpi_ioc.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08 |
660 | mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 | 689 | mpi_cnfg.h 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 |
661 | mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04 | 690 | mpi_init.h 01.05.08 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04 |
662 | mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04 | 691 | mpi_targ.h 01.05.06 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04 |
663 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 | 692 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
664 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 | 693 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
665 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 | 694 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 |
666 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 | 695 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 |
667 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 | 696 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
668 | mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01 | 697 | mpi_sas.h 01.05.04 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01 |
669 | mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01 | 698 | mpi_type.h 01.05.02 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01 |
670 | 699 | ||
671 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 | 700 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 |
672 | ---------- -------- -------- -------- -------- -------- -------- | 701 | ---------- -------- -------- -------- -------- -------- -------- |
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index c1c678989a23..ec9dff2249a7 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 LSI Logic Corporation. | 2 | * Copyright (c) 2000-2006 LSI Logic Corporation. |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Name: mpi_init.h | 5 | * Name: mpi_init.h |
6 | * Title: MPI initiator mode messages and structures | 6 | * Title: MPI initiator mode messages and structures |
7 | * Creation Date: June 8, 2000 | 7 | * Creation Date: June 8, 2000 |
8 | * | 8 | * |
9 | * mpi_init.h Version: 01.05.07 | 9 | * mpi_init.h Version: 01.05.08 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -53,6 +53,7 @@ | |||
53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
54 | * unique in the first 32 characters. | 54 | * unique in the first 32 characters. |
55 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | 55 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. |
56 | * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA. | ||
56 | * -------------------------------------------------------------------------- | 57 | * -------------------------------------------------------------------------- |
57 | */ | 58 | */ |
58 | 59 | ||
@@ -428,7 +429,7 @@ typedef struct _MSG_SCSI_TASK_MGMT | |||
428 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) | 429 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) |
429 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) | 430 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) |
430 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) | 431 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) |
431 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) | 432 | #define MPI_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) |
432 | 433 | ||
433 | /* MsgFlags bits */ | 434 | /* MsgFlags bits */ |
434 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) | 435 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) |
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index 18ba407fd399..6c33e3353375 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 LSI Logic Corporation. | 2 | * Copyright (c) 2000-2006 LSI Logic Corporation. |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Name: mpi_ioc.h | 5 | * Name: mpi_ioc.h |
6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages | 6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages |
7 | * Creation Date: August 11, 2000 | 7 | * Creation Date: August 11, 2000 |
8 | * | 8 | * |
9 | * mpi_ioc.h Version: 01.05.11 | 9 | * mpi_ioc.h Version: 01.05.12 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -98,6 +98,14 @@ | |||
98 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | 98 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event |
99 | * data structure. | 99 | * data structure. |
100 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | 100 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. |
101 | * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. | ||
102 | * Added MaxInitiators field to PortFacts reply. | ||
103 | * Added SAS Device Status Change ReasonCode for | ||
104 | * asynchronous notificaiton. | ||
105 | * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event | ||
106 | * data structure. | ||
107 | * Added new ImageType values for FWDownload and FWUpload | ||
108 | * requests. | ||
101 | * -------------------------------------------------------------------------- | 109 | * -------------------------------------------------------------------------- |
102 | */ | 110 | */ |
103 | 111 | ||
@@ -264,6 +272,7 @@ typedef struct _MSG_IOC_FACTS_REPLY | |||
264 | #define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) | 272 | #define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) |
265 | #define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) | 273 | #define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) |
266 | #define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008) | 274 | #define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008) |
275 | #define MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010) | ||
267 | 276 | ||
268 | #define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01) | 277 | #define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01) |
269 | #define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02) | 278 | #define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02) |
@@ -328,7 +337,8 @@ typedef struct _MSG_PORT_FACTS_REPLY | |||
328 | U16 MaxPostedCmdBuffers; /* 1Ch */ | 337 | U16 MaxPostedCmdBuffers; /* 1Ch */ |
329 | U16 MaxPersistentIDs; /* 1Eh */ | 338 | U16 MaxPersistentIDs; /* 1Eh */ |
330 | U16 MaxLanBuckets; /* 20h */ | 339 | U16 MaxLanBuckets; /* 20h */ |
331 | U16 Reserved4; /* 22h */ | 340 | U8 MaxInitiators; /* 22h */ |
341 | U8 Reserved4; /* 23h */ | ||
332 | U32 Reserved5; /* 24h */ | 342 | U32 Reserved5; /* 24h */ |
333 | } MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY, | 343 | } MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY, |
334 | PortFactsReply_t, MPI_POINTER pPortFactsReply_t; | 344 | PortFactsReply_t, MPI_POINTER pPortFactsReply_t; |
@@ -487,6 +497,7 @@ typedef struct _MSG_EVENT_ACK_REPLY | |||
487 | #define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) | 497 | #define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) |
488 | #define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019) | 498 | #define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019) |
489 | #define MPI_EVENT_SAS_SMP_ERROR (0x0000001A) | 499 | #define MPI_EVENT_SAS_SMP_ERROR (0x0000001A) |
500 | #define MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE (0x0000001B) | ||
490 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) | 501 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) |
491 | 502 | ||
492 | /* AckRequired field values */ | 503 | /* AckRequired field values */ |
@@ -593,6 +604,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE | |||
593 | #define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) | 604 | #define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) |
594 | #define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) | 605 | #define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) |
595 | #define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) | 606 | #define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) |
607 | #define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) | ||
596 | 608 | ||
597 | 609 | ||
598 | /* SCSI Event data for Queue Full event */ | 610 | /* SCSI Event data for Queue Full event */ |
@@ -895,6 +907,54 @@ typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW | |||
895 | MpiEventDataSasInitTableOverflow_t, | 907 | MpiEventDataSasInitTableOverflow_t, |
896 | MPI_POINTER pMpiEventDataSasInitTableOverflow_t; | 908 | MPI_POINTER pMpiEventDataSasInitTableOverflow_t; |
897 | 909 | ||
910 | /* SAS Expander Status Change Event data */ | ||
911 | |||
912 | typedef struct _EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE | ||
913 | { | ||
914 | U8 ReasonCode; /* 00h */ | ||
915 | U8 Reserved1; /* 01h */ | ||
916 | U16 Reserved2; /* 02h */ | ||
917 | U8 PhysicalPort; /* 04h */ | ||
918 | U8 Reserved3; /* 05h */ | ||
919 | U16 EnclosureHandle; /* 06h */ | ||
920 | U64 SASAddress; /* 08h */ | ||
921 | U32 DiscoveryStatus; /* 10h */ | ||
922 | U16 DevHandle; /* 14h */ | ||
923 | U16 ParentDevHandle; /* 16h */ | ||
924 | U16 ExpanderChangeCount; /* 18h */ | ||
925 | U16 ExpanderRouteIndexes; /* 1Ah */ | ||
926 | U8 NumPhys; /* 1Ch */ | ||
927 | U8 SASLevel; /* 1Dh */ | ||
928 | U8 Flags; /* 1Eh */ | ||
929 | U8 Reserved4; /* 1Fh */ | ||
930 | } EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE, | ||
931 | MPI_POINTER PTR_EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE, | ||
932 | MpiEventDataSasExpanderStatusChange_t, | ||
933 | MPI_POINTER pMpiEventDataSasExpanderStatusChange_t; | ||
934 | |||
935 | /* values for ReasonCode field of SAS Expander Status Change Event data */ | ||
936 | #define MPI_EVENT_SAS_EXP_RC_ADDED (0x00) | ||
937 | #define MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING (0x01) | ||
938 | |||
939 | /* values for DiscoveryStatus field of SAS Expander Status Change Event data */ | ||
940 | #define MPI_EVENT_SAS_EXP_DS_LOOP_DETECTED (0x00000001) | ||
941 | #define MPI_EVENT_SAS_EXP_DS_UNADDRESSABLE_DEVICE (0x00000002) | ||
942 | #define MPI_EVENT_SAS_EXP_DS_MULTIPLE_PORTS (0x00000004) | ||
943 | #define MPI_EVENT_SAS_EXP_DS_EXPANDER_ERR (0x00000008) | ||
944 | #define MPI_EVENT_SAS_EXP_DS_SMP_TIMEOUT (0x00000010) | ||
945 | #define MPI_EVENT_SAS_EXP_DS_OUT_ROUTE_ENTRIES (0x00000020) | ||
946 | #define MPI_EVENT_SAS_EXP_DS_INDEX_NOT_EXIST (0x00000040) | ||
947 | #define MPI_EVENT_SAS_EXP_DS_SMP_FUNCTION_FAILED (0x00000080) | ||
948 | #define MPI_EVENT_SAS_EXP_DS_SMP_CRC_ERROR (0x00000100) | ||
949 | #define MPI_EVENT_SAS_EXP_DS_SUBTRACTIVE_LINK (0x00000200) | ||
950 | #define MPI_EVENT_SAS_EXP_DS_TABLE_LINK (0x00000400) | ||
951 | #define MPI_EVENT_SAS_EXP_DS_UNSUPPORTED_DEVICE (0x00000800) | ||
952 | |||
953 | /* values for Flags field of SAS Expander Status Change Event data */ | ||
954 | #define MPI_EVENT_SAS_EXP_FLAGS_ROUTE_TABLE_CONFIG (0x02) | ||
955 | #define MPI_EVENT_SAS_EXP_FLAGS_CONFIG_IN_PROGRESS (0x01) | ||
956 | |||
957 | |||
898 | 958 | ||
899 | /***************************************************************************** | 959 | /***************************************************************************** |
900 | * | 960 | * |
@@ -926,6 +986,10 @@ typedef struct _MSG_FW_DOWNLOAD | |||
926 | #define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02) | 986 | #define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02) |
927 | #define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03) | 987 | #define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03) |
928 | #define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04) | 988 | #define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04) |
989 | #define MPI_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06) | ||
990 | #define MPI_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07) | ||
991 | #define MPI_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08) | ||
992 | #define MPI_FW_DOWNLOAD_ITYPE_MEGARAID (0x09) | ||
929 | 993 | ||
930 | 994 | ||
931 | typedef struct _FWDownloadTCSGE | 995 | typedef struct _FWDownloadTCSGE |
@@ -980,6 +1044,11 @@ typedef struct _MSG_FW_UPLOAD | |||
980 | #define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03) | 1044 | #define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03) |
981 | #define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04) | 1045 | #define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04) |
982 | #define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05) | 1046 | #define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05) |
1047 | #define MPI_FW_UPLOAD_ITYPE_MANUFACTURING (0x06) | ||
1048 | #define MPI_FW_UPLOAD_ITYPE_CONFIG_1 (0x07) | ||
1049 | #define MPI_FW_UPLOAD_ITYPE_CONFIG_2 (0x08) | ||
1050 | #define MPI_FW_UPLOAD_ITYPE_MEGARAID (0x09) | ||
1051 | #define MPI_FW_UPLOAD_ITYPE_COMPLETE (0x0A) | ||
983 | 1052 | ||
984 | typedef struct _FWUploadTCSGE | 1053 | typedef struct _FWUploadTCSGE |
985 | { | 1054 | { |
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index 871ebc08b706..635bbe04513e 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /*************************************************************************** | 1 | /*************************************************************************** |
3 | * * | 2 | * * |
4 | * Copyright 2003 LSI Logic Corporation. All rights reserved. * | 3 | * Copyright 2003 LSI Logic Corporation. All rights reserved. * |
@@ -14,7 +13,7 @@ | |||
14 | #define IOPI_IOCLOGINFO_H_INCLUDED | 13 | #define IOPI_IOCLOGINFO_H_INCLUDED |
15 | 14 | ||
16 | #define SAS_LOGINFO_NEXUS_LOSS 0x31170000 | 15 | #define SAS_LOGINFO_NEXUS_LOSS 0x31170000 |
17 | #define SAS_LOGINFO_MASK 0xFFFF0000 | 16 | #define SAS_LOGINFO_MASK 0xFFFF0000 |
18 | 17 | ||
19 | /****************************************************************************/ | 18 | /****************************************************************************/ |
20 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ | 19 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ |
@@ -43,129 +42,172 @@ | |||
43 | /****************************************************************************/ | 42 | /****************************************************************************/ |
44 | /* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */ | 43 | /* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */ |
45 | /****************************************************************************/ | 44 | /****************************************************************************/ |
46 | #define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000) | 45 | #define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000) |
47 | #define IOP_LOGINFO_CODE_UNUSED2 (0x00020000) | 46 | #define IOP_LOGINFO_CODE_UNUSED2 (0x00020000) |
48 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000) | 47 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000) |
49 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */ | 48 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */ |
50 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */ | 49 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */ |
51 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */ | 50 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */ |
52 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */ | 51 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */ |
53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ | 52 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ |
54 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ | 53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ |
55 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ | 54 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ |
56 | 55 | ||
57 | #define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ | 56 | #define IOP_LOGINFO_CODE_FWUPLOAD_NO_FLASH_AVAILABLE (0x0003E000) /* Tried to upload from flash, but there is none */ |
58 | 57 | #define IOP_LOGINFO_CODE_FWUPLOAD_UNKNOWN_IMAGE_TYPE (0x0003E001) /* ImageType field contents were invalid */ | |
59 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) | 58 | #define IOP_LOGINFO_CODE_FWUPLOAD_WRONG_IMAGE_SIZE (0x0003E002) /* ImageSize field in TCSGE was bad/offset in MfgPg 4 was wrong */ |
60 | 59 | #define IOP_LOGINFO_CODE_FWUPLOAD_ENTIRE_FLASH_UPLOAD_FAILED (0x0003E003) /* Error occured while attempting to upload the entire flash */ | |
61 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ | 60 | #define IOP_LOGINFO_CODE_FWUPLOAD_REGION_UPLOAD_FAILED (0x0003E004) /* Error occured while attempting to upload single flash region */ |
62 | #define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */ | 61 | #define IOP_LOGINFO_CODE_FWUPLOAD_DMA_FAILURE (0x0003E005) /* Problem occured while DMAing FW to host memory */ |
63 | 62 | ||
64 | #define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001) | 63 | #define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ |
65 | #define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002) | 64 | |
66 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003) | 65 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) |
67 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004) | 66 | |
68 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005) | 67 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ |
68 | #define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */ | ||
69 | |||
70 | #define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001) | ||
71 | #define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002) | ||
72 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003) | ||
73 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004) | ||
74 | #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005) | ||
69 | 75 | ||
70 | /****************************************************************************/ | 76 | /****************************************************************************/ |
71 | /* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ | 77 | /* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ |
72 | /****************************************************************************/ | 78 | /****************************************************************************/ |
73 | #define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) | 79 | #define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) /* see SUB_CODE_OPEN_FAIL_ below */ |
74 | #define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001) | 80 | |
75 | #define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011) | 81 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_NO_DEST_TIME_OUT (0x00000001) |
76 | #define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013) | 82 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATHWAY_BLOCKED (0x00000002) |
77 | #define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018) | 83 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE0 (0x00000003) |
78 | #define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019) | 84 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE1 (0x00000004) |
79 | #define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A) | 85 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE0 (0x00000005) |
80 | #define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B) | 86 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE1 (0x00000006) |
81 | #define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C) | 87 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP0 (0x00000007) |
82 | #define PL_LOGINFO_CODE_INVALID_SGL (0x00020000) | 88 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP1 (0x00000008) |
83 | #define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000) | 89 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RETRY (0x00000009) |
84 | #define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000) | 90 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_BREAK (0x0000000A) |
85 | #define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000) | 91 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0B (0x0000000B) |
86 | #define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000) | 92 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_OPEN_TIMEOUT_EXP (0x0000000C) |
87 | #define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000) | 93 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0D (0x0000000D) |
88 | #define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000) | 94 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_DVTBLE_ACCSS_FAIL (0x0000000E) |
89 | #define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000) | 95 | #define PL_LOGINFO_SUB CODE_OPEN_FAIL_BAD_DEST (0x00000011) |
90 | #define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000) | 96 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RATE_NOT_SUPP (0x00000012) |
91 | #define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000) | 97 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PROT_NOT_SUPP (0x00000013) |
92 | #define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000) | 98 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON0 (0x00000014) |
93 | #define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000) | 99 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON1 (0x00000015) |
94 | #define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000) | 100 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON2 (0x00000016) |
95 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000) | 101 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON3 (0x00000017) |
96 | #define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */ | 102 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_STP_RESOURCES_BSY (0x00000018) |
97 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */ | 103 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_WRONG_DESTINATION (0x00000019) |
98 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */ | 104 | |
99 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */ | 105 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATH_BLOCKED (0x0000001B) /* Retry Timeout */ |
100 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */ | 106 | #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_AWT_MAXED (0x0000001C) /* Retry Timeout */ |
101 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */ | 107 | |
102 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */ | 108 | |
103 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */ | 109 | |
104 | #define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000) | 110 | #define PL_LOGINFO_CODE_INVALID_SGL (0x00020000) |
105 | #define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */ | 111 | #define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000) |
106 | #define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */ | 112 | #define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000) |
107 | #define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000) | 113 | #define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000) |
108 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) | 114 | #define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000) |
109 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) | 115 | #define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000) |
110 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) | 116 | #define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000) |
111 | #define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000) | 117 | #define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000) |
112 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) | 118 | #define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000) |
113 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) | 119 | #define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000) |
114 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ | 120 | #define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000) |
115 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B) | 121 | #define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000) |
116 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */ | 122 | #define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000) |
117 | 123 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000) | |
118 | #define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120) | 124 | #define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */ |
119 | #define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */ | 125 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */ |
120 | #define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */ | 126 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */ |
121 | 127 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */ | |
122 | 128 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */ | |
123 | #define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) | 129 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */ |
124 | #define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) | 130 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */ |
125 | #define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) | 131 | #define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */ |
126 | #define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500) | 132 | #define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000) |
127 | #define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600) | 133 | #define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE) */ |
128 | #define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700) | 134 | #define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE)*/ |
129 | #define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800) | 135 | #define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000) |
130 | #define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900) | 136 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) |
131 | #define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00) | 137 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) |
132 | #define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00) | 138 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) |
133 | #define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00) | 139 | #define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000) |
134 | #define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00) | 140 | #define PL_LOGINFO_CODE_IO_CANCELLED_DUE_TO_R_ERR (0x00180000) |
135 | #define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00) | 141 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) |
136 | #define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01) | 142 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) |
137 | #define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00) | 143 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_SATA_NEG_RATE_2HI (0x00000102) |
138 | #define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) | 144 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_RATE_NOT_SUPPORTED (0x00000103) |
139 | 145 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_BREAK (0x00000104) | |
140 | 146 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ZONE_VIOLATION (0x00000114) | |
141 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ | 147 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON0 (0x00000114) /* Open Reject (Zone Violation) - available on SAS-2 devices */ |
142 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ | 148 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON1 (0x00000115) |
143 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */ | 149 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON2 (0x00000116) |
144 | #define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */ | 150 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON3 (0x00000117) |
145 | #define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */ | 151 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ |
146 | #define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */ | 152 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATH_BLOCKED (0x0000011B) |
147 | #define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */ | 153 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */ |
148 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */ | 154 | |
149 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */ | 155 | #define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120) |
150 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */ | 156 | #define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */ |
151 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */ | 157 | #define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */ |
152 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */ | 158 | |
153 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */ | 159 | |
154 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */ | 160 | #define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) |
155 | 161 | #define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) | |
156 | #define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */ | 162 | #define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) /* Bits 0-3 encode Transport Status Register (offset 0x08) */ |
157 | #define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */ | 163 | /* Bit 0 is Status Bit 0: FrameXferErr */ |
158 | #define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */ | 164 | /* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */ |
159 | #define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ | 165 | /* Bit 3 is Status Bit 18 WriteDataLenghtGTDataLengthErr */ |
160 | #define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */ | 166 | |
161 | #define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */ | 167 | #define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500) |
162 | #define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */ | 168 | #define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600) |
163 | #define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */ | 169 | #define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700) |
164 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */ | 170 | #define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800) |
165 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */ | 171 | #define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900) |
166 | #define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */ | 172 | #define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00) |
167 | #define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/ | 173 | #define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00) |
168 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */ | 174 | #define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00) |
175 | #define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00) | ||
176 | #define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00) | ||
177 | #define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01) | ||
178 | #define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00) | ||
179 | #define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) | ||
180 | |||
181 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ | ||
182 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ | ||
183 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */ | ||
184 | #define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */ | ||
185 | #define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */ | ||
186 | #define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */ | ||
187 | #define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */ | ||
188 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */ | ||
189 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */ | ||
190 | #define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */ | ||
191 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */ | ||
192 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */ | ||
193 | #define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */ | ||
194 | #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */ | ||
195 | |||
196 | #define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */ | ||
197 | #define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */ | ||
198 | #define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */ | ||
199 | #define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ | ||
200 | #define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */ | ||
201 | #define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */ | ||
202 | #define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */ | ||
203 | #define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */ | ||
204 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */ | ||
205 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */ | ||
206 | #define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */ | ||
207 | #define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/ | ||
208 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode f/w location 1 */ | ||
209 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_2 (0x0020010D) /* SEP doesn't support CDB opcode f/w location 2 */ | ||
210 | #define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_3 (0x0020010E) /* SEP doesn't support CDB opcode f/w location 3 */ | ||
169 | 211 | ||
170 | 212 | ||
171 | /****************************************************************************/ | 213 | /****************************************************************************/ |
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 50b8f0a8f456..8e990a0fa7a2 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004 LSI Logic Corporation. | 2 | * Copyright (c) 2004-2006 LSI Logic Corporation. |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Name: mpi_sas.h | 5 | * Name: mpi_sas.h |
6 | * Title: MPI Serial Attached SCSI structures and definitions | 6 | * Title: MPI Serial Attached SCSI structures and definitions |
7 | * Creation Date: August 19, 2004 | 7 | * Creation Date: August 19, 2004 |
8 | * | 8 | * |
9 | * mpi_sas.h Version: 01.05.03 | 9 | * mpi_sas.h Version: 01.05.04 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -21,6 +21,8 @@ | |||
21 | * and Remove Device operations to SAS IO Unit Control. | 21 | * and Remove Device operations to SAS IO Unit Control. |
22 | * Added DevHandle field to SAS IO Unit Control request and | 22 | * Added DevHandle field to SAS IO Unit Control request and |
23 | * reply. | 23 | * reply. |
24 | * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO | ||
25 | * Unit Control request. | ||
24 | * -------------------------------------------------------------------------- | 26 | * -------------------------------------------------------------------------- |
25 | */ | 27 | */ |
26 | 28 | ||
@@ -237,7 +239,8 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST | |||
237 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) | 239 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) |
238 | #define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) | 240 | #define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) |
239 | #define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) | 241 | #define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) |
240 | #define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) | 242 | #define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) /* obsolete name */ |
243 | #define MPI_SAS_OP_REMOVE_DEVICE (0x0D) | ||
241 | 244 | ||
242 | /* values for the PrimFlags field */ | 245 | /* values for the PrimFlags field */ |
243 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) | 246 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index b3f28a03b6a9..083acfd91d8b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
7 | * | 7 | * |
8 | * Copyright (c) 1999-2007 LSI Logic Corporation | 8 | * Copyright (c) 1999-2007 LSI Logic Corporation |
9 | * (mailto:mpt_linux_developer@lsil.com) | 9 | * (mailto:mpt_linux_developer@lsi.com) |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -82,6 +82,10 @@ static int mpt_msi_enable; | |||
82 | module_param(mpt_msi_enable, int, 0); | 82 | module_param(mpt_msi_enable, int, 0); |
83 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); | 83 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); |
84 | 84 | ||
85 | static int mpt_channel_mapping; | ||
86 | module_param(mpt_channel_mapping, int, 0); | ||
87 | MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); | ||
88 | |||
85 | #ifdef MFCNT | 89 | #ifdef MFCNT |
86 | static int mfcounter = 0; | 90 | static int mfcounter = 0; |
87 | #define PRINT_MF_COUNT 20000 | 91 | #define PRINT_MF_COUNT 20000 |
@@ -173,11 +177,14 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); | |||
173 | 177 | ||
174 | //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 178 | //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
175 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); | 179 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); |
176 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | 180 | #ifdef MPT_DEBUG_REPLY |
181 | static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | ||
182 | #endif | ||
177 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); | 183 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); |
178 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); | 184 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); |
179 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); | 185 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); |
180 | static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); | 186 | static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); |
187 | static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); | ||
181 | 188 | ||
182 | /* module entry point */ | 189 | /* module entry point */ |
183 | static int __init fusion_init (void); | 190 | static int __init fusion_init (void); |
@@ -319,13 +326,11 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) | |||
319 | else if (ioc->bus_type == SAS) | 326 | else if (ioc->bus_type == SAS) |
320 | mpt_sas_log_info(ioc, log_info); | 327 | mpt_sas_log_info(ioc, log_info); |
321 | } | 328 | } |
322 | if (ioc_stat & MPI_IOCSTATUS_MASK) { | ||
323 | if (ioc->bus_type == SPI && | ||
324 | cb_idx != mpt_stm_index && | ||
325 | cb_idx != mpt_lan_index) | ||
326 | mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf); | ||
327 | } | ||
328 | 329 | ||
330 | #ifdef MPT_DEBUG_REPLY | ||
331 | if (ioc_stat & MPI_IOCSTATUS_MASK) | ||
332 | mpt_iocstatus_info(ioc, (u32)ioc_stat, mf); | ||
333 | #endif | ||
329 | 334 | ||
330 | /* Check for (valid) IO callback! */ | 335 | /* Check for (valid) IO callback! */ |
331 | if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || | 336 | if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || |
@@ -911,7 +916,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) | |||
911 | int | 916 | int |
912 | mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) | 917 | mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) |
913 | { | 918 | { |
914 | int r = 0; | 919 | int r = 0; |
915 | u8 *req_as_bytes; | 920 | u8 *req_as_bytes; |
916 | int ii; | 921 | int ii; |
917 | 922 | ||
@@ -1811,6 +1816,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1811 | * and we try GetLanConfigPages again... | 1816 | * and we try GetLanConfigPages again... |
1812 | */ | 1817 | */ |
1813 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { | 1818 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { |
1819 | |||
1820 | /* | ||
1821 | * Initalize link list for inactive raid volumes. | ||
1822 | */ | ||
1823 | init_MUTEX(&ioc->raid_data.inactive_list_mutex); | ||
1824 | INIT_LIST_HEAD(&ioc->raid_data.inactive_list); | ||
1825 | |||
1814 | if (ioc->bus_type == SAS) { | 1826 | if (ioc->bus_type == SAS) { |
1815 | 1827 | ||
1816 | /* clear persistency table */ | 1828 | /* clear persistency table */ |
@@ -2017,6 +2029,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) | |||
2017 | } | 2029 | } |
2018 | 2030 | ||
2019 | kfree(ioc->spi_data.nvram); | 2031 | kfree(ioc->spi_data.nvram); |
2032 | mpt_inactive_raid_list_free(ioc); | ||
2033 | kfree(ioc->raid_data.pIocPg2); | ||
2020 | kfree(ioc->raid_data.pIocPg3); | 2034 | kfree(ioc->raid_data.pIocPg3); |
2021 | ioc->spi_data.nvram = NULL; | 2035 | ioc->spi_data.nvram = NULL; |
2022 | ioc->raid_data.pIocPg3 = NULL; | 2036 | ioc->raid_data.pIocPg3 = NULL; |
@@ -2413,6 +2427,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) | |||
2413 | facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); | 2427 | facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); |
2414 | 2428 | ||
2415 | facts->ProductID = le16_to_cpu(facts->ProductID); | 2429 | facts->ProductID = le16_to_cpu(facts->ProductID); |
2430 | if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | ||
2431 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) | ||
2432 | ioc->ir_firmware = 1; | ||
2416 | facts->CurrentHostMfaHighAddr = | 2433 | facts->CurrentHostMfaHighAddr = |
2417 | le32_to_cpu(facts->CurrentHostMfaHighAddr); | 2434 | le32_to_cpu(facts->CurrentHostMfaHighAddr); |
2418 | facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); | 2435 | facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); |
@@ -2505,6 +2522,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2505 | int ii; | 2522 | int ii; |
2506 | int req_sz; | 2523 | int req_sz; |
2507 | int reply_sz; | 2524 | int reply_sz; |
2525 | int max_id; | ||
2508 | 2526 | ||
2509 | /* IOC *must* NOT be in RESET state! */ | 2527 | /* IOC *must* NOT be in RESET state! */ |
2510 | if (ioc->last_state == MPI_IOC_STATE_RESET) { | 2528 | if (ioc->last_state == MPI_IOC_STATE_RESET) { |
@@ -2552,6 +2570,21 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2552 | pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); | 2570 | pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); |
2553 | pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); | 2571 | pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); |
2554 | 2572 | ||
2573 | max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : | ||
2574 | pfacts->MaxDevices; | ||
2575 | ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; | ||
2576 | ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; | ||
2577 | |||
2578 | /* | ||
2579 | * Place all the devices on channels | ||
2580 | * | ||
2581 | * (for debuging) | ||
2582 | */ | ||
2583 | if (mpt_channel_mapping) { | ||
2584 | ioc->devices_per_bus = 1; | ||
2585 | ioc->number_of_buses = (max_id > 255) ? 255 : max_id; | ||
2586 | } | ||
2587 | |||
2555 | return 0; | 2588 | return 0; |
2556 | } | 2589 | } |
2557 | 2590 | ||
@@ -2592,13 +2625,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) | |||
2592 | ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", | 2625 | ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", |
2593 | ioc->name, ioc->upload_fw, ioc->facts.Flags)); | 2626 | ioc->name, ioc->upload_fw, ioc->facts.Flags)); |
2594 | 2627 | ||
2595 | if(ioc->bus_type == SAS) | 2628 | ioc_init.MaxDevices = (U8)ioc->devices_per_bus; |
2596 | ioc_init.MaxDevices = ioc->facts.MaxDevices; | 2629 | ioc_init.MaxBuses = (U8)ioc->number_of_buses; |
2597 | else if(ioc->bus_type == FC) | ||
2598 | ioc_init.MaxDevices = MPT_MAX_FC_DEVICES; | ||
2599 | else | ||
2600 | ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES; | ||
2601 | ioc_init.MaxBuses = MPT_MAX_BUS; | ||
2602 | dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", | 2630 | dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", |
2603 | ioc->name, ioc->facts.MsgVersion)); | 2631 | ioc->name, ioc->facts.MsgVersion)); |
2604 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { | 2632 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { |
@@ -2720,9 +2748,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2720 | 2748 | ||
2721 | /* RAID FW may take a long time to enable | 2749 | /* RAID FW may take a long time to enable |
2722 | */ | 2750 | */ |
2723 | if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | 2751 | if (ioc->ir_firmware || ioc->bus_type == SAS) { |
2724 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) || | ||
2725 | (ioc->bus_type == SAS)) { | ||
2726 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, | 2752 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
2727 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, | 2753 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, |
2728 | 300 /*seconds*/, sleepFlag); | 2754 | 300 /*seconds*/, sleepFlag); |
@@ -3193,6 +3219,9 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3193 | u32 diag1val = 0; | 3219 | u32 diag1val = 0; |
3194 | #endif | 3220 | #endif |
3195 | 3221 | ||
3222 | /* Clear any existing interrupts */ | ||
3223 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | ||
3224 | |||
3196 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | 3225 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { |
3197 | drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " | 3226 | drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " |
3198 | "address=%p\n", ioc->name, __FUNCTION__, | 3227 | "address=%p\n", ioc->name, __FUNCTION__, |
@@ -3212,7 +3241,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3212 | " count=%d\n", | 3241 | " count=%d\n", |
3213 | ioc->name, doorbell, count)); | 3242 | ioc->name, doorbell, count)); |
3214 | if (doorbell == MPI_IOC_STATE_READY) { | 3243 | if (doorbell == MPI_IOC_STATE_READY) { |
3215 | return 0; | 3244 | return 1; |
3216 | } | 3245 | } |
3217 | 3246 | ||
3218 | /* wait 1 sec */ | 3247 | /* wait 1 sec */ |
@@ -3224,9 +3253,6 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3224 | return -1; | 3253 | return -1; |
3225 | } | 3254 | } |
3226 | 3255 | ||
3227 | /* Clear any existing interrupts */ | ||
3228 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | ||
3229 | |||
3230 | /* Use "Diagnostic reset" method! (only thing available!) */ | 3256 | /* Use "Diagnostic reset" method! (only thing available!) */ |
3231 | diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); | 3257 | diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); |
3232 | 3258 | ||
@@ -3942,7 +3968,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) | |||
3942 | } | 3968 | } |
3943 | } else { | 3969 | } else { |
3944 | while (--cntdn) { | 3970 | while (--cntdn) { |
3945 | mdelay (1); | 3971 | udelay (1000); |
3946 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); | 3972 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); |
3947 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) | 3973 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) |
3948 | break; | 3974 | break; |
@@ -3994,7 +4020,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) | |||
3994 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); | 4020 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); |
3995 | if (intstat & MPI_HIS_DOORBELL_INTERRUPT) | 4021 | if (intstat & MPI_HIS_DOORBELL_INTERRUPT) |
3996 | break; | 4022 | break; |
3997 | mdelay(1); | 4023 | udelay (1000); |
3998 | count++; | 4024 | count++; |
3999 | } | 4025 | } |
4000 | } | 4026 | } |
@@ -4310,8 +4336,8 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc, | |||
4310 | if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && | 4336 | if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && |
4311 | reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || | 4337 | reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || |
4312 | (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { | 4338 | (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { |
4313 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", | 4339 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n", |
4314 | ioc->name, disk); | 4340 | ioc->name, disk, volume); |
4315 | } else { | 4341 | } else { |
4316 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", | 4342 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", |
4317 | ioc->name, volume); | 4343 | ioc->name, volume); |
@@ -4712,7 +4738,187 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) | |||
4712 | return 0; | 4738 | return 0; |
4713 | } | 4739 | } |
4714 | 4740 | ||
4715 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 4741 | /** |
4742 | * mpt_inactive_raid_list_free | ||
4743 | * | ||
4744 | * This clears this link list. | ||
4745 | * | ||
4746 | * @ioc - pointer to per adapter structure | ||
4747 | * | ||
4748 | **/ | ||
4749 | static void | ||
4750 | mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) | ||
4751 | { | ||
4752 | struct inactive_raid_component_info *component_info, *pNext; | ||
4753 | |||
4754 | if (list_empty(&ioc->raid_data.inactive_list)) | ||
4755 | return; | ||
4756 | |||
4757 | down(&ioc->raid_data.inactive_list_mutex); | ||
4758 | list_for_each_entry_safe(component_info, pNext, | ||
4759 | &ioc->raid_data.inactive_list, list) { | ||
4760 | list_del(&component_info->list); | ||
4761 | kfree(component_info); | ||
4762 | } | ||
4763 | up(&ioc->raid_data.inactive_list_mutex); | ||
4764 | } | ||
4765 | |||
4766 | /** | ||
4767 | * mpt_inactive_raid_volumes | ||
4768 | * | ||
4769 | * This sets up link list of phy_disk_nums for devices belonging in an inactive volume | ||
4770 | * | ||
4771 | * @ioc - pointer to per adapter structure | ||
4772 | * @channel - volume channel | ||
4773 | * @id - volume target id | ||
4774 | * | ||
4775 | * | ||
4776 | **/ | ||
4777 | static void | ||
4778 | mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
4779 | { | ||
4780 | CONFIGPARMS cfg; | ||
4781 | ConfigPageHeader_t hdr; | ||
4782 | dma_addr_t dma_handle; | ||
4783 | pRaidVolumePage0_t buffer = NULL; | ||
4784 | int i; | ||
4785 | RaidPhysDiskPage0_t phys_disk; | ||
4786 | struct inactive_raid_component_info *component_info; | ||
4787 | int handle_inactive_volumes; | ||
4788 | |||
4789 | memset(&cfg, 0 , sizeof(CONFIGPARMS)); | ||
4790 | memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); | ||
4791 | hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; | ||
4792 | cfg.pageAddr = (channel << 8) + id; | ||
4793 | cfg.cfghdr.hdr = &hdr; | ||
4794 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
4795 | |||
4796 | if (mpt_config(ioc, &cfg) != 0) | ||
4797 | goto out; | ||
4798 | |||
4799 | if (!hdr.PageLength) | ||
4800 | goto out; | ||
4801 | |||
4802 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, | ||
4803 | &dma_handle); | ||
4804 | |||
4805 | if (!buffer) | ||
4806 | goto out; | ||
4807 | |||
4808 | cfg.physAddr = dma_handle; | ||
4809 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
4810 | |||
4811 | if (mpt_config(ioc, &cfg) != 0) | ||
4812 | goto out; | ||
4813 | |||
4814 | if (!buffer->NumPhysDisks) | ||
4815 | goto out; | ||
4816 | |||
4817 | handle_inactive_volumes = | ||
4818 | (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE || | ||
4819 | (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 || | ||
4820 | buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED || | ||
4821 | buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0; | ||
4822 | |||
4823 | if (!handle_inactive_volumes) | ||
4824 | goto out; | ||
4825 | |||
4826 | down(&ioc->raid_data.inactive_list_mutex); | ||
4827 | for (i = 0; i < buffer->NumPhysDisks; i++) { | ||
4828 | if(mpt_raid_phys_disk_pg0(ioc, | ||
4829 | buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) | ||
4830 | continue; | ||
4831 | |||
4832 | if ((component_info = kmalloc(sizeof (*component_info), | ||
4833 | GFP_KERNEL)) == NULL) | ||
4834 | continue; | ||
4835 | |||
4836 | component_info->volumeID = id; | ||
4837 | component_info->volumeBus = channel; | ||
4838 | component_info->d.PhysDiskNum = phys_disk.PhysDiskNum; | ||
4839 | component_info->d.PhysDiskBus = phys_disk.PhysDiskBus; | ||
4840 | component_info->d.PhysDiskID = phys_disk.PhysDiskID; | ||
4841 | component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC; | ||
4842 | |||
4843 | list_add_tail(&component_info->list, | ||
4844 | &ioc->raid_data.inactive_list); | ||
4845 | } | ||
4846 | up(&ioc->raid_data.inactive_list_mutex); | ||
4847 | |||
4848 | out: | ||
4849 | if (buffer) | ||
4850 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, | ||
4851 | dma_handle); | ||
4852 | } | ||
4853 | |||
4854 | /** | ||
4855 | * mpt_raid_phys_disk_pg0 - returns phys disk page zero | ||
4856 | * @ioc: Pointer to a Adapter Structure | ||
4857 | * @phys_disk_num: io unit unique phys disk num generated by the ioc | ||
4858 | * @phys_disk: requested payload data returned | ||
4859 | * | ||
4860 | * Return: | ||
4861 | * 0 on success | ||
4862 | * -EFAULT if read of config page header fails or data pointer not NULL | ||
4863 | * -ENOMEM if pci_alloc failed | ||
4864 | **/ | ||
4865 | int | ||
4866 | mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk) | ||
4867 | { | ||
4868 | CONFIGPARMS cfg; | ||
4869 | ConfigPageHeader_t hdr; | ||
4870 | dma_addr_t dma_handle; | ||
4871 | pRaidPhysDiskPage0_t buffer = NULL; | ||
4872 | int rc; | ||
4873 | |||
4874 | memset(&cfg, 0 , sizeof(CONFIGPARMS)); | ||
4875 | memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); | ||
4876 | |||
4877 | hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; | ||
4878 | cfg.cfghdr.hdr = &hdr; | ||
4879 | cfg.physAddr = -1; | ||
4880 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
4881 | |||
4882 | if (mpt_config(ioc, &cfg) != 0) { | ||
4883 | rc = -EFAULT; | ||
4884 | goto out; | ||
4885 | } | ||
4886 | |||
4887 | if (!hdr.PageLength) { | ||
4888 | rc = -EFAULT; | ||
4889 | goto out; | ||
4890 | } | ||
4891 | |||
4892 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, | ||
4893 | &dma_handle); | ||
4894 | |||
4895 | if (!buffer) { | ||
4896 | rc = -ENOMEM; | ||
4897 | goto out; | ||
4898 | } | ||
4899 | |||
4900 | cfg.physAddr = dma_handle; | ||
4901 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
4902 | cfg.pageAddr = phys_disk_num; | ||
4903 | |||
4904 | if (mpt_config(ioc, &cfg) != 0) { | ||
4905 | rc = -EFAULT; | ||
4906 | goto out; | ||
4907 | } | ||
4908 | |||
4909 | rc = 0; | ||
4910 | memcpy(phys_disk, buffer, sizeof(*buffer)); | ||
4911 | phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA); | ||
4912 | |||
4913 | out: | ||
4914 | |||
4915 | if (buffer) | ||
4916 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, | ||
4917 | dma_handle); | ||
4918 | |||
4919 | return rc; | ||
4920 | } | ||
4921 | |||
4716 | /** | 4922 | /** |
4717 | * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes | 4923 | * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes |
4718 | * @ioc: Pointer to a Adapter Strucutre | 4924 | * @ioc: Pointer to a Adapter Strucutre |
@@ -4722,21 +4928,27 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) | |||
4722 | * 0 on success | 4928 | * 0 on success |
4723 | * -EFAULT if read of config page header fails or data pointer not NULL | 4929 | * -EFAULT if read of config page header fails or data pointer not NULL |
4724 | * -ENOMEM if pci_alloc failed | 4930 | * -ENOMEM if pci_alloc failed |
4725 | */ | 4931 | **/ |
4726 | int | 4932 | int |
4727 | mpt_findImVolumes(MPT_ADAPTER *ioc) | 4933 | mpt_findImVolumes(MPT_ADAPTER *ioc) |
4728 | { | 4934 | { |
4729 | IOCPage2_t *pIoc2; | 4935 | IOCPage2_t *pIoc2; |
4730 | u8 *mem; | 4936 | u8 *mem; |
4731 | ConfigPageIoc2RaidVol_t *pIocRv; | ||
4732 | dma_addr_t ioc2_dma; | 4937 | dma_addr_t ioc2_dma; |
4733 | CONFIGPARMS cfg; | 4938 | CONFIGPARMS cfg; |
4734 | ConfigPageHeader_t header; | 4939 | ConfigPageHeader_t header; |
4735 | int jj; | ||
4736 | int rc = 0; | 4940 | int rc = 0; |
4737 | int iocpage2sz; | 4941 | int iocpage2sz; |
4738 | u8 nVols, nPhys; | 4942 | int i; |
4739 | u8 vid, vbus, vioc; | 4943 | |
4944 | if (!ioc->ir_firmware) | ||
4945 | return 0; | ||
4946 | |||
4947 | /* Free the old page | ||
4948 | */ | ||
4949 | kfree(ioc->raid_data.pIocPg2); | ||
4950 | ioc->raid_data.pIocPg2 = NULL; | ||
4951 | mpt_inactive_raid_list_free(ioc); | ||
4740 | 4952 | ||
4741 | /* Read IOCP2 header then the page. | 4953 | /* Read IOCP2 header then the page. |
4742 | */ | 4954 | */ |
@@ -4764,55 +4976,23 @@ mpt_findImVolumes(MPT_ADAPTER *ioc) | |||
4764 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | 4976 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; |
4765 | cfg.physAddr = ioc2_dma; | 4977 | cfg.physAddr = ioc2_dma; |
4766 | if (mpt_config(ioc, &cfg) != 0) | 4978 | if (mpt_config(ioc, &cfg) != 0) |
4767 | goto done_and_free; | 4979 | goto out; |
4980 | |||
4981 | mem = kmalloc(iocpage2sz, GFP_KERNEL); | ||
4982 | if (!mem) | ||
4983 | goto out; | ||
4768 | 4984 | ||
4769 | if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) { | ||
4770 | mem = kmalloc(iocpage2sz, GFP_ATOMIC); | ||
4771 | if (mem) { | ||
4772 | ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; | ||
4773 | } else { | ||
4774 | goto done_and_free; | ||
4775 | } | ||
4776 | } | ||
4777 | memcpy(mem, (u8 *)pIoc2, iocpage2sz); | 4985 | memcpy(mem, (u8 *)pIoc2, iocpage2sz); |
4986 | ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; | ||
4778 | 4987 | ||
4779 | /* Identify RAID Volume Id's */ | 4988 | mpt_read_ioc_pg_3(ioc); |
4780 | nVols = pIoc2->NumActiveVolumes; | ||
4781 | if ( nVols == 0) { | ||
4782 | /* No RAID Volume. | ||
4783 | */ | ||
4784 | goto done_and_free; | ||
4785 | } else { | ||
4786 | /* At least 1 RAID Volume | ||
4787 | */ | ||
4788 | pIocRv = pIoc2->RaidVolume; | ||
4789 | ioc->raid_data.isRaid = 0; | ||
4790 | for (jj = 0; jj < nVols; jj++, pIocRv++) { | ||
4791 | vid = pIocRv->VolumeID; | ||
4792 | vbus = pIocRv->VolumeBus; | ||
4793 | vioc = pIocRv->VolumeIOC; | ||
4794 | |||
4795 | /* find the match | ||
4796 | */ | ||
4797 | if (vbus == 0) { | ||
4798 | ioc->raid_data.isRaid |= (1 << vid); | ||
4799 | } else { | ||
4800 | /* Error! Always bus 0 | ||
4801 | */ | ||
4802 | } | ||
4803 | } | ||
4804 | } | ||
4805 | 4989 | ||
4806 | /* Identify Hidden Physical Disk Id's */ | 4990 | for (i = 0; i < pIoc2->NumActiveVolumes ; i++) |
4807 | nPhys = pIoc2->NumActivePhysDisks; | 4991 | mpt_inactive_raid_volumes(ioc, |
4808 | if (nPhys == 0) { | 4992 | pIoc2->RaidVolume[i].VolumeBus, |
4809 | /* No physical disks. | 4993 | pIoc2->RaidVolume[i].VolumeID); |
4810 | */ | ||
4811 | } else { | ||
4812 | mpt_read_ioc_pg_3(ioc); | ||
4813 | } | ||
4814 | 4994 | ||
4815 | done_and_free: | 4995 | out: |
4816 | pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); | 4996 | pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); |
4817 | 4997 | ||
4818 | return rc; | 4998 | return rc; |
@@ -4865,7 +5045,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) | |||
4865 | cfg.physAddr = ioc3_dma; | 5045 | cfg.physAddr = ioc3_dma; |
4866 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | 5046 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; |
4867 | if (mpt_config(ioc, &cfg) == 0) { | 5047 | if (mpt_config(ioc, &cfg) == 0) { |
4868 | mem = kmalloc(iocpage3sz, GFP_ATOMIC); | 5048 | mem = kmalloc(iocpage3sz, GFP_KERNEL); |
4869 | if (mem) { | 5049 | if (mem) { |
4870 | memcpy(mem, (u8 *)pIoc3, iocpage3sz); | 5050 | memcpy(mem, (u8 *)pIoc3, iocpage3sz); |
4871 | ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; | 5051 | ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; |
@@ -5679,8 +5859,6 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
5679 | return rc; | 5859 | return rc; |
5680 | } | 5860 | } |
5681 | 5861 | ||
5682 | # define EVENT_DESCR_STR_SZ 100 | ||
5683 | |||
5684 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 5862 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5685 | static void | 5863 | static void |
5686 | EventDescriptionStr(u8 event, u32 evData0, char *evStr) | 5864 | EventDescriptionStr(u8 event, u32 evData0, char *evStr) |
@@ -5708,9 +5886,6 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5708 | break; | 5886 | break; |
5709 | case MPI_EVENT_RESCAN: | 5887 | case MPI_EVENT_RESCAN: |
5710 | ds = "Bus Rescan Event"; | 5888 | ds = "Bus Rescan Event"; |
5711 | /* Ok, do we need to do anything here? As far as | ||
5712 | I can tell, this is when a new device gets added | ||
5713 | to the loop. */ | ||
5714 | break; | 5889 | break; |
5715 | case MPI_EVENT_LINK_STATUS_CHANGE: | 5890 | case MPI_EVENT_LINK_STATUS_CHANGE: |
5716 | if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) | 5891 | if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) |
@@ -5787,48 +5962,63 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5787 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: | 5962 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: |
5788 | { | 5963 | { |
5789 | u8 id = (u8)(evData0); | 5964 | u8 id = (u8)(evData0); |
5965 | u8 channel = (u8)(evData0 >> 8); | ||
5790 | u8 ReasonCode = (u8)(evData0 >> 16); | 5966 | u8 ReasonCode = (u8)(evData0 >> 16); |
5791 | switch (ReasonCode) { | 5967 | switch (ReasonCode) { |
5792 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: | 5968 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: |
5793 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5969 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5794 | "SAS Device Status Change: Added: id=%d", id); | 5970 | "SAS Device Status Change: Added: " |
5971 | "id=%d channel=%d", id, channel); | ||
5795 | break; | 5972 | break; |
5796 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: | 5973 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: |
5797 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5974 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5798 | "SAS Device Status Change: Deleted: id=%d", id); | 5975 | "SAS Device Status Change: Deleted: " |
5976 | "id=%d channel=%d", id, channel); | ||
5799 | break; | 5977 | break; |
5800 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: | 5978 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: |
5801 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5979 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5802 | "SAS Device Status Change: SMART Data: id=%d", | 5980 | "SAS Device Status Change: SMART Data: " |
5803 | id); | 5981 | "id=%d channel=%d", id, channel); |
5804 | break; | 5982 | break; |
5805 | case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: | 5983 | case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: |
5806 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5984 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5807 | "SAS Device Status Change: No Persistancy: id=%d", id); | 5985 | "SAS Device Status Change: No Persistancy: " |
5986 | "id=%d channel=%d", id, channel); | ||
5987 | break; | ||
5988 | case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: | ||
5989 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5990 | "SAS Device Status Change: Unsupported Device " | ||
5991 | "Discovered : id=%d channel=%d", id, channel); | ||
5808 | break; | 5992 | break; |
5809 | case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: | 5993 | case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: |
5810 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5994 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5811 | "SAS Device Status Change: Internal Device Reset : id=%d", id); | 5995 | "SAS Device Status Change: Internal Device " |
5996 | "Reset : id=%d channel=%d", id, channel); | ||
5812 | break; | 5997 | break; |
5813 | case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: | 5998 | case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: |
5814 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5999 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5815 | "SAS Device Status Change: Internal Task Abort : id=%d", id); | 6000 | "SAS Device Status Change: Internal Task " |
6001 | "Abort : id=%d channel=%d", id, channel); | ||
5816 | break; | 6002 | break; |
5817 | case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: | 6003 | case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: |
5818 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 6004 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5819 | "SAS Device Status Change: Internal Abort Task Set : id=%d", id); | 6005 | "SAS Device Status Change: Internal Abort " |
6006 | "Task Set : id=%d channel=%d", id, channel); | ||
5820 | break; | 6007 | break; |
5821 | case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: | 6008 | case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: |
5822 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 6009 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5823 | "SAS Device Status Change: Internal Clear Task Set : id=%d", id); | 6010 | "SAS Device Status Change: Internal Clear " |
6011 | "Task Set : id=%d channel=%d", id, channel); | ||
5824 | break; | 6012 | break; |
5825 | case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: | 6013 | case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: |
5826 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 6014 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5827 | "SAS Device Status Change: Internal Query Task : id=%d", id); | 6015 | "SAS Device Status Change: Internal Query " |
6016 | "Task : id=%d channel=%d", id, channel); | ||
5828 | break; | 6017 | break; |
5829 | default: | 6018 | default: |
5830 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 6019 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5831 | "SAS Device Status Change: Unknown: id=%d", id); | 6020 | "SAS Device Status Change: Unknown: " |
6021 | "id=%d channel=%d", id, channel); | ||
5832 | break; | 6022 | break; |
5833 | } | 6023 | } |
5834 | break; | 6024 | break; |
@@ -5837,8 +6027,16 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5837 | ds = "Bus Timer Expired"; | 6027 | ds = "Bus Timer Expired"; |
5838 | break; | 6028 | break; |
5839 | case MPI_EVENT_QUEUE_FULL: | 6029 | case MPI_EVENT_QUEUE_FULL: |
5840 | ds = "Queue Full"; | 6030 | { |
6031 | u16 curr_depth = (u16)(evData0 >> 16); | ||
6032 | u8 channel = (u8)(evData0 >> 8); | ||
6033 | u8 id = (u8)(evData0); | ||
6034 | |||
6035 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6036 | "Queue Full: channel=%d id=%d depth=%d", | ||
6037 | channel, id, curr_depth); | ||
5841 | break; | 6038 | break; |
6039 | } | ||
5842 | case MPI_EVENT_SAS_SES: | 6040 | case MPI_EVENT_SAS_SES: |
5843 | ds = "SAS SES Event"; | 6041 | ds = "SAS SES Event"; |
5844 | break; | 6042 | break; |
@@ -5942,6 +6140,76 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5942 | ds = "SAS Log Entry Added"; | 6140 | ds = "SAS Log Entry Added"; |
5943 | break; | 6141 | break; |
5944 | 6142 | ||
6143 | case MPI_EVENT_SAS_BROADCAST_PRIMITIVE: | ||
6144 | { | ||
6145 | u8 phy_num = (u8)(evData0); | ||
6146 | u8 port_num = (u8)(evData0 >> 8); | ||
6147 | u8 port_width = (u8)(evData0 >> 16); | ||
6148 | u8 primative = (u8)(evData0 >> 24); | ||
6149 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6150 | "SAS Broadcase Primative: phy=%d port=%d " | ||
6151 | "width=%d primative=0x%02x", | ||
6152 | phy_num, port_num, port_width, primative); | ||
6153 | break; | ||
6154 | } | ||
6155 | |||
6156 | case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: | ||
6157 | { | ||
6158 | u8 reason = (u8)(evData0); | ||
6159 | u8 port_num = (u8)(evData0 >> 8); | ||
6160 | u16 handle = le16_to_cpu(evData0 >> 16); | ||
6161 | |||
6162 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6163 | "SAS Initiator Device Status Change: reason=0x%02x " | ||
6164 | "port=%d handle=0x%04x", | ||
6165 | reason, port_num, handle); | ||
6166 | break; | ||
6167 | } | ||
6168 | |||
6169 | case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW: | ||
6170 | { | ||
6171 | u8 max_init = (u8)(evData0); | ||
6172 | u8 current_init = (u8)(evData0 >> 8); | ||
6173 | |||
6174 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6175 | "SAS Initiator Device Table Overflow: max initiators=%02d " | ||
6176 | "current initators=%02d", | ||
6177 | max_init, current_init); | ||
6178 | break; | ||
6179 | } | ||
6180 | case MPI_EVENT_SAS_SMP_ERROR: | ||
6181 | { | ||
6182 | u8 status = (u8)(evData0); | ||
6183 | u8 port_num = (u8)(evData0 >> 8); | ||
6184 | u8 result = (u8)(evData0 >> 16); | ||
6185 | |||
6186 | if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID) | ||
6187 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6188 | "SAS SMP Error: port=%d result=0x%02x", | ||
6189 | port_num, result); | ||
6190 | else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR) | ||
6191 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6192 | "SAS SMP Error: port=%d : CRC Error", | ||
6193 | port_num); | ||
6194 | else if (status == MPI_EVENT_SAS_SMP_TIMEOUT) | ||
6195 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6196 | "SAS SMP Error: port=%d : Timeout", | ||
6197 | port_num); | ||
6198 | else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION) | ||
6199 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6200 | "SAS SMP Error: port=%d : No Destination", | ||
6201 | port_num); | ||
6202 | else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION) | ||
6203 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6204 | "SAS SMP Error: port=%d : Bad Destination", | ||
6205 | port_num); | ||
6206 | else | ||
6207 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
6208 | "SAS SMP Error: port=%d : status=0x%02x", | ||
6209 | port_num, status); | ||
6210 | break; | ||
6211 | } | ||
6212 | |||
5945 | /* | 6213 | /* |
5946 | * MPT base "custom" events may be added here... | 6214 | * MPT base "custom" events may be added here... |
5947 | */ | 6215 | */ |
@@ -6205,10 +6473,11 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6205 | "Abort", /* 12h */ | 6473 | "Abort", /* 12h */ |
6206 | "IO Not Yet Executed", /* 13h */ | 6474 | "IO Not Yet Executed", /* 13h */ |
6207 | "IO Executed", /* 14h */ | 6475 | "IO Executed", /* 14h */ |
6208 | "Persistent Reservation Out Not Affiliation Owner", /* 15h */ | 6476 | "Persistent Reservation Out Not Affiliation " |
6477 | "Owner", /* 15h */ | ||
6209 | "Open Transmit DMA Abort", /* 16h */ | 6478 | "Open Transmit DMA Abort", /* 16h */ |
6210 | "IO Device Missing Delay Retry", /* 17h */ | 6479 | "IO Device Missing Delay Retry", /* 17h */ |
6211 | NULL, /* 18h */ | 6480 | "IO Cancelled Due to Recieve Error", /* 18h */ |
6212 | NULL, /* 19h */ | 6481 | NULL, /* 19h */ |
6213 | NULL, /* 1Ah */ | 6482 | NULL, /* 1Ah */ |
6214 | NULL, /* 1Bh */ | 6483 | NULL, /* 1Bh */ |
@@ -6218,6 +6487,96 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6218 | NULL, /* 1Fh */ | 6487 | NULL, /* 1Fh */ |
6219 | "Enclosure Management" /* 20h */ | 6488 | "Enclosure Management" /* 20h */ |
6220 | }; | 6489 | }; |
6490 | static char *ir_code_str[] = { | ||
6491 | "Raid Action Error", /* 00h */ | ||
6492 | NULL, /* 00h */ | ||
6493 | NULL, /* 01h */ | ||
6494 | NULL, /* 02h */ | ||
6495 | NULL, /* 03h */ | ||
6496 | NULL, /* 04h */ | ||
6497 | NULL, /* 05h */ | ||
6498 | NULL, /* 06h */ | ||
6499 | NULL /* 07h */ | ||
6500 | }; | ||
6501 | static char *raid_sub_code_str[] = { | ||
6502 | NULL, /* 00h */ | ||
6503 | "Volume Creation Failed: Data Passed too " | ||
6504 | "Large", /* 01h */ | ||
6505 | "Volume Creation Failed: Duplicate Volumes " | ||
6506 | "Attempted", /* 02h */ | ||
6507 | "Volume Creation Failed: Max Number " | ||
6508 | "Supported Volumes Exceeded", /* 03h */ | ||
6509 | "Volume Creation Failed: DMA Error", /* 04h */ | ||
6510 | "Volume Creation Failed: Invalid Volume Type", /* 05h */ | ||
6511 | "Volume Creation Failed: Error Reading " | ||
6512 | "MFG Page 4", /* 06h */ | ||
6513 | "Volume Creation Failed: Creating Internal " | ||
6514 | "Structures", /* 07h */ | ||
6515 | NULL, /* 08h */ | ||
6516 | NULL, /* 09h */ | ||
6517 | NULL, /* 0Ah */ | ||
6518 | NULL, /* 0Bh */ | ||
6519 | NULL, /* 0Ch */ | ||
6520 | NULL, /* 0Dh */ | ||
6521 | NULL, /* 0Eh */ | ||
6522 | NULL, /* 0Fh */ | ||
6523 | "Activation failed: Already Active Volume", /* 10h */ | ||
6524 | "Activation failed: Unsupported Volume Type", /* 11h */ | ||
6525 | "Activation failed: Too Many Active Volumes", /* 12h */ | ||
6526 | "Activation failed: Volume ID in Use", /* 13h */ | ||
6527 | "Activation failed: Reported Failure", /* 14h */ | ||
6528 | "Activation failed: Importing a Volume", /* 15h */ | ||
6529 | NULL, /* 16h */ | ||
6530 | NULL, /* 17h */ | ||
6531 | NULL, /* 18h */ | ||
6532 | NULL, /* 19h */ | ||
6533 | NULL, /* 1Ah */ | ||
6534 | NULL, /* 1Bh */ | ||
6535 | NULL, /* 1Ch */ | ||
6536 | NULL, /* 1Dh */ | ||
6537 | NULL, /* 1Eh */ | ||
6538 | NULL, /* 1Fh */ | ||
6539 | "Phys Disk failed: Too Many Phys Disks", /* 20h */ | ||
6540 | "Phys Disk failed: Data Passed too Large", /* 21h */ | ||
6541 | "Phys Disk failed: DMA Error", /* 22h */ | ||
6542 | "Phys Disk failed: Invalid <channel:id>", /* 23h */ | ||
6543 | "Phys Disk failed: Creating Phys Disk Config " | ||
6544 | "Page", /* 24h */ | ||
6545 | NULL, /* 25h */ | ||
6546 | NULL, /* 26h */ | ||
6547 | NULL, /* 27h */ | ||
6548 | NULL, /* 28h */ | ||
6549 | NULL, /* 29h */ | ||
6550 | NULL, /* 2Ah */ | ||
6551 | NULL, /* 2Bh */ | ||
6552 | NULL, /* 2Ch */ | ||
6553 | NULL, /* 2Dh */ | ||
6554 | NULL, /* 2Eh */ | ||
6555 | NULL, /* 2Fh */ | ||
6556 | "Compatibility Error: IR Disabled", /* 30h */ | ||
6557 | "Compatibility Error: Inquiry Comand Failed", /* 31h */ | ||
6558 | "Compatibility Error: Device not Direct Access " | ||
6559 | "Device ", /* 32h */ | ||
6560 | "Compatibility Error: Removable Device Found", /* 33h */ | ||
6561 | "Compatibility Error: Device SCSI Version not " | ||
6562 | "2 or Higher", /* 34h */ | ||
6563 | "Compatibility Error: SATA Device, 48 BIT LBA " | ||
6564 | "not Supported", /* 35h */ | ||
6565 | "Compatibility Error: Device doesn't have " | ||
6566 | "512 Byte Block Sizes", /* 36h */ | ||
6567 | "Compatibility Error: Volume Type Check Failed", /* 37h */ | ||
6568 | "Compatibility Error: Volume Type is " | ||
6569 | "Unsupported by FW", /* 38h */ | ||
6570 | "Compatibility Error: Disk Drive too Small for " | ||
6571 | "use in Volume", /* 39h */ | ||
6572 | "Compatibility Error: Phys Disk for Create " | ||
6573 | "Volume not Found", /* 3Ah */ | ||
6574 | "Compatibility Error: Too Many or too Few " | ||
6575 | "Disks for Volume Type", /* 3Bh */ | ||
6576 | "Compatibility Error: Disk stripe Sizes " | ||
6577 | "Must be 64KB", /* 3Ch */ | ||
6578 | "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */ | ||
6579 | }; | ||
6221 | 6580 | ||
6222 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6581 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6223 | /** | 6582 | /** |
@@ -6226,7 +6585,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6226 | * @log_info: U32 LogInfo reply word from the IOC | 6585 | * @log_info: U32 LogInfo reply word from the IOC |
6227 | * | 6586 | * |
6228 | * Refer to lsi/mpi_log_sas.h. | 6587 | * Refer to lsi/mpi_log_sas.h. |
6229 | */ | 6588 | **/ |
6230 | static void | 6589 | static void |
6231 | mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) | 6590 | mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) |
6232 | { | 6591 | { |
@@ -6240,56 +6599,165 @@ union loginfo_type { | |||
6240 | }dw; | 6599 | }dw; |
6241 | }; | 6600 | }; |
6242 | union loginfo_type sas_loginfo; | 6601 | union loginfo_type sas_loginfo; |
6602 | char *originator_desc = NULL; | ||
6243 | char *code_desc = NULL; | 6603 | char *code_desc = NULL; |
6604 | char *sub_code_desc = NULL; | ||
6244 | 6605 | ||
6245 | sas_loginfo.loginfo = log_info; | 6606 | sas_loginfo.loginfo = log_info; |
6246 | if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && | 6607 | if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && |
6247 | (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*))) | 6608 | (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*))) |
6248 | return; | 6609 | return; |
6249 | if ((sas_loginfo.dw.originator == 0 /*IOP*/) && | 6610 | |
6250 | (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) { | 6611 | originator_desc = originator_str[sas_loginfo.dw.originator]; |
6251 | code_desc = iop_code_str[sas_loginfo.dw.code]; | 6612 | |
6252 | }else if ((sas_loginfo.dw.originator == 1 /*PL*/) && | 6613 | switch (sas_loginfo.dw.originator) { |
6253 | (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) { | 6614 | |
6254 | code_desc = pl_code_str[sas_loginfo.dw.code]; | 6615 | case 0: /* IOP */ |
6616 | if (sas_loginfo.dw.code < | ||
6617 | sizeof(iop_code_str)/sizeof(char*)) | ||
6618 | code_desc = iop_code_str[sas_loginfo.dw.code]; | ||
6619 | break; | ||
6620 | case 1: /* PL */ | ||
6621 | if (sas_loginfo.dw.code < | ||
6622 | sizeof(pl_code_str)/sizeof(char*)) | ||
6623 | code_desc = pl_code_str[sas_loginfo.dw.code]; | ||
6624 | break; | ||
6625 | case 2: /* IR */ | ||
6626 | if (sas_loginfo.dw.code >= | ||
6627 | sizeof(ir_code_str)/sizeof(char*)) | ||
6628 | break; | ||
6629 | code_desc = ir_code_str[sas_loginfo.dw.code]; | ||
6630 | if (sas_loginfo.dw.subcode >= | ||
6631 | sizeof(raid_sub_code_str)/sizeof(char*)) | ||
6632 | break; | ||
6633 | if (sas_loginfo.dw.code == 0) | ||
6634 | sub_code_desc = | ||
6635 | raid_sub_code_str[sas_loginfo.dw.subcode]; | ||
6636 | break; | ||
6637 | default: | ||
6638 | return; | ||
6255 | } | 6639 | } |
6256 | 6640 | ||
6257 | if (code_desc != NULL) | 6641 | if (sub_code_desc != NULL) |
6642 | printk(MYIOC_s_INFO_FMT | ||
6643 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," | ||
6644 | " SubCode={%s}\n", | ||
6645 | ioc->name, log_info, originator_desc, code_desc, | ||
6646 | sub_code_desc); | ||
6647 | else if (code_desc != NULL) | ||
6258 | printk(MYIOC_s_INFO_FMT | 6648 | printk(MYIOC_s_INFO_FMT |
6259 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," | 6649 | "LogInfo(0x%08x): Originator={%s}, Code={%s}," |
6260 | " SubCode(0x%04x)\n", | 6650 | " SubCode(0x%04x)\n", |
6261 | ioc->name, | 6651 | ioc->name, log_info, originator_desc, code_desc, |
6262 | log_info, | ||
6263 | originator_str[sas_loginfo.dw.originator], | ||
6264 | code_desc, | ||
6265 | sas_loginfo.dw.subcode); | 6652 | sas_loginfo.dw.subcode); |
6266 | else | 6653 | else |
6267 | printk(MYIOC_s_INFO_FMT | 6654 | printk(MYIOC_s_INFO_FMT |
6268 | "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," | 6655 | "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," |
6269 | " SubCode(0x%04x)\n", | 6656 | " SubCode(0x%04x)\n", |
6270 | ioc->name, | 6657 | ioc->name, log_info, originator_desc, |
6271 | log_info, | 6658 | sas_loginfo.dw.code, sas_loginfo.dw.subcode); |
6272 | originator_str[sas_loginfo.dw.originator], | ||
6273 | sas_loginfo.dw.code, | ||
6274 | sas_loginfo.dw.subcode); | ||
6275 | } | 6659 | } |
6276 | 6660 | ||
6661 | #ifdef MPT_DEBUG_REPLY | ||
6277 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6662 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6278 | /** | 6663 | /** |
6279 | * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC. | 6664 | * mpt_iocstatus_info_config - IOCSTATUS information for config pages |
6665 | * @ioc: Pointer to MPT_ADAPTER structure | ||
6666 | * ioc_status: U32 IOCStatus word from IOC | ||
6667 | * @mf: Pointer to MPT request frame | ||
6668 | * | ||
6669 | * Refer to lsi/mpi.h. | ||
6670 | **/ | ||
6671 | static void | ||
6672 | mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) | ||
6673 | { | ||
6674 | Config_t *pReq = (Config_t *)mf; | ||
6675 | char extend_desc[EVENT_DESCR_STR_SZ]; | ||
6676 | char *desc = NULL; | ||
6677 | u32 form; | ||
6678 | u8 page_type; | ||
6679 | |||
6680 | if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED) | ||
6681 | page_type = pReq->ExtPageType; | ||
6682 | else | ||
6683 | page_type = pReq->Header.PageType; | ||
6684 | |||
6685 | /* | ||
6686 | * ignore invalid page messages for GET_NEXT_HANDLE | ||
6687 | */ | ||
6688 | form = le32_to_cpu(pReq->PageAddress); | ||
6689 | if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { | ||
6690 | if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE || | ||
6691 | page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER || | ||
6692 | page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) { | ||
6693 | if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) == | ||
6694 | MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) | ||
6695 | return; | ||
6696 | } | ||
6697 | if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE) | ||
6698 | if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) == | ||
6699 | MPI_FC_DEVICE_PGAD_FORM_NEXT_DID) | ||
6700 | return; | ||
6701 | } | ||
6702 | |||
6703 | snprintf(extend_desc, EVENT_DESCR_STR_SZ, | ||
6704 | "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh", | ||
6705 | page_type, pReq->Header.PageNumber, pReq->Action, form); | ||
6706 | |||
6707 | switch (ioc_status) { | ||
6708 | |||
6709 | case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ | ||
6710 | desc = "Config Page Invalid Action"; | ||
6711 | break; | ||
6712 | |||
6713 | case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ | ||
6714 | desc = "Config Page Invalid Type"; | ||
6715 | break; | ||
6716 | |||
6717 | case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ | ||
6718 | desc = "Config Page Invalid Page"; | ||
6719 | break; | ||
6720 | |||
6721 | case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ | ||
6722 | desc = "Config Page Invalid Data"; | ||
6723 | break; | ||
6724 | |||
6725 | case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ | ||
6726 | desc = "Config Page No Defaults"; | ||
6727 | break; | ||
6728 | |||
6729 | case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ | ||
6730 | desc = "Config Page Can't Commit"; | ||
6731 | break; | ||
6732 | } | ||
6733 | |||
6734 | if (!desc) | ||
6735 | return; | ||
6736 | |||
6737 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n", | ||
6738 | ioc->name, ioc_status, desc, extend_desc); | ||
6739 | } | ||
6740 | |||
6741 | /** | ||
6742 | * mpt_iocstatus_info - IOCSTATUS information returned from IOC. | ||
6280 | * @ioc: Pointer to MPT_ADAPTER structure | 6743 | * @ioc: Pointer to MPT_ADAPTER structure |
6281 | * @ioc_status: U32 IOCStatus word from IOC | 6744 | * @ioc_status: U32 IOCStatus word from IOC |
6282 | * @mf: Pointer to MPT request frame | 6745 | * @mf: Pointer to MPT request frame |
6283 | * | 6746 | * |
6284 | * Refer to lsi/mpi.h. | 6747 | * Refer to lsi/mpi.h. |
6285 | */ | 6748 | **/ |
6286 | static void | 6749 | static void |
6287 | mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) | 6750 | mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) |
6288 | { | 6751 | { |
6289 | u32 status = ioc_status & MPI_IOCSTATUS_MASK; | 6752 | u32 status = ioc_status & MPI_IOCSTATUS_MASK; |
6290 | char *desc = NULL; | 6753 | char *desc = NULL; |
6291 | 6754 | ||
6292 | switch (status) { | 6755 | switch (status) { |
6756 | |||
6757 | /****************************************************************************/ | ||
6758 | /* Common IOCStatus values for all replies */ | ||
6759 | /****************************************************************************/ | ||
6760 | |||
6293 | case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ | 6761 | case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ |
6294 | desc = "Invalid Function"; | 6762 | desc = "Invalid Function"; |
6295 | break; | 6763 | break; |
@@ -6322,84 +6790,180 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) | |||
6322 | desc = "Invalid State"; | 6790 | desc = "Invalid State"; |
6323 | break; | 6791 | break; |
6324 | 6792 | ||
6793 | /****************************************************************************/ | ||
6794 | /* Config IOCStatus values */ | ||
6795 | /****************************************************************************/ | ||
6796 | |||
6325 | case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ | 6797 | case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ |
6326 | case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ | 6798 | case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ |
6327 | case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ | 6799 | case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ |
6328 | case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ | 6800 | case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ |
6329 | case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ | 6801 | case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ |
6330 | case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ | 6802 | case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ |
6331 | /* No message for Config IOCStatus values */ | 6803 | mpt_iocstatus_info_config(ioc, status, mf); |
6332 | break; | 6804 | break; |
6333 | 6805 | ||
6806 | /****************************************************************************/ | ||
6807 | /* SCSIIO Reply (SPI, FCP, SAS) initiator values */ | ||
6808 | /* */ | ||
6809 | /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */ | ||
6810 | /* */ | ||
6811 | /****************************************************************************/ | ||
6812 | |||
6334 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ | 6813 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ |
6335 | /* No message for recovered error | 6814 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ |
6336 | desc = "SCSI Recovered Error"; | 6815 | case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ |
6337 | */ | 6816 | case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ |
6817 | case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ | ||
6818 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | ||
6819 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ | ||
6820 | case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ | ||
6821 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | ||
6822 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | ||
6823 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ | ||
6824 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | ||
6825 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ | ||
6338 | break; | 6826 | break; |
6339 | 6827 | ||
6340 | case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ | 6828 | /****************************************************************************/ |
6341 | desc = "SCSI Invalid Bus"; | 6829 | /* SCSI Target values */ |
6830 | /****************************************************************************/ | ||
6831 | |||
6832 | case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */ | ||
6833 | desc = "Target: Priority IO"; | ||
6342 | break; | 6834 | break; |
6343 | 6835 | ||
6344 | case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ | 6836 | case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */ |
6345 | desc = "SCSI Invalid TargetID"; | 6837 | desc = "Target: Invalid Port"; |
6346 | break; | 6838 | break; |
6347 | 6839 | ||
6348 | case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ | 6840 | case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */ |
6349 | { | 6841 | desc = "Target Invalid IO Index:"; |
6350 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; | ||
6351 | U8 cdb = pScsiReq->CDB[0]; | ||
6352 | if (cdb != 0x12) { /* Inquiry is issued for device scanning */ | ||
6353 | desc = "SCSI Device Not There"; | ||
6354 | } | ||
6355 | break; | 6842 | break; |
6356 | } | ||
6357 | 6843 | ||
6358 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | 6844 | case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */ |
6359 | desc = "SCSI Data Overrun"; | 6845 | desc = "Target: Aborted"; |
6360 | break; | 6846 | break; |
6361 | 6847 | ||
6362 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ | 6848 | case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */ |
6363 | /* This error is checked in scsi_io_done(). Skip. | 6849 | desc = "Target: No Conn Retryable"; |
6364 | desc = "SCSI Data Underrun"; | ||
6365 | */ | ||
6366 | break; | 6850 | break; |
6367 | 6851 | ||
6368 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ | 6852 | case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */ |
6369 | desc = "SCSI I/O Data Error"; | 6853 | desc = "Target: No Connection"; |
6370 | break; | 6854 | break; |
6371 | 6855 | ||
6372 | case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ | 6856 | case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */ |
6373 | desc = "SCSI Protocol Error"; | 6857 | desc = "Target: Transfer Count Mismatch"; |
6374 | break; | 6858 | break; |
6375 | 6859 | ||
6376 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | 6860 | case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */ |
6377 | desc = "SCSI Task Terminated"; | 6861 | desc = "Target: STS Data not Sent"; |
6378 | break; | 6862 | break; |
6379 | 6863 | ||
6380 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | 6864 | case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */ |
6381 | desc = "SCSI Residual Mismatch"; | 6865 | desc = "Target: Data Offset Error"; |
6382 | break; | 6866 | break; |
6383 | 6867 | ||
6384 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ | 6868 | case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */ |
6385 | desc = "SCSI Task Management Failed"; | 6869 | desc = "Target: Too Much Write Data"; |
6386 | break; | 6870 | break; |
6387 | 6871 | ||
6388 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | 6872 | case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */ |
6389 | desc = "SCSI IOC Terminated"; | 6873 | desc = "Target: IU Too Short"; |
6390 | break; | 6874 | break; |
6391 | 6875 | ||
6392 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ | 6876 | case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */ |
6393 | desc = "SCSI Ext Terminated"; | 6877 | desc = "Target: ACK NAK Timeout"; |
6878 | break; | ||
6879 | |||
6880 | case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */ | ||
6881 | desc = "Target: Nak Received"; | ||
6882 | break; | ||
6883 | |||
6884 | /****************************************************************************/ | ||
6885 | /* Fibre Channel Direct Access values */ | ||
6886 | /****************************************************************************/ | ||
6887 | |||
6888 | case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */ | ||
6889 | desc = "FC: Aborted"; | ||
6890 | break; | ||
6891 | |||
6892 | case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */ | ||
6893 | desc = "FC: RX ID Invalid"; | ||
6894 | break; | ||
6895 | |||
6896 | case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */ | ||
6897 | desc = "FC: DID Invalid"; | ||
6898 | break; | ||
6899 | |||
6900 | case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */ | ||
6901 | desc = "FC: Node Logged Out"; | ||
6902 | break; | ||
6903 | |||
6904 | case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */ | ||
6905 | desc = "FC: Exchange Canceled"; | ||
6906 | break; | ||
6907 | |||
6908 | /****************************************************************************/ | ||
6909 | /* LAN values */ | ||
6910 | /****************************************************************************/ | ||
6911 | |||
6912 | case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */ | ||
6913 | desc = "LAN: Device not Found"; | ||
6914 | break; | ||
6915 | |||
6916 | case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */ | ||
6917 | desc = "LAN: Device Failure"; | ||
6918 | break; | ||
6919 | |||
6920 | case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */ | ||
6921 | desc = "LAN: Transmit Error"; | ||
6922 | break; | ||
6923 | |||
6924 | case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */ | ||
6925 | desc = "LAN: Transmit Aborted"; | ||
6926 | break; | ||
6927 | |||
6928 | case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */ | ||
6929 | desc = "LAN: Receive Error"; | ||
6930 | break; | ||
6931 | |||
6932 | case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */ | ||
6933 | desc = "LAN: Receive Aborted"; | ||
6934 | break; | ||
6935 | |||
6936 | case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */ | ||
6937 | desc = "LAN: Partial Packet"; | ||
6938 | break; | ||
6939 | |||
6940 | case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */ | ||
6941 | desc = "LAN: Canceled"; | ||
6942 | break; | ||
6943 | |||
6944 | /****************************************************************************/ | ||
6945 | /* Serial Attached SCSI values */ | ||
6946 | /****************************************************************************/ | ||
6947 | |||
6948 | case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */ | ||
6949 | desc = "SAS: SMP Request Failed"; | ||
6950 | break; | ||
6951 | |||
6952 | case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */ | ||
6953 | desc = "SAS: SMP Data Overrun"; | ||
6394 | break; | 6954 | break; |
6395 | 6955 | ||
6396 | default: | 6956 | default: |
6397 | desc = "Others"; | 6957 | desc = "Others"; |
6398 | break; | 6958 | break; |
6399 | } | 6959 | } |
6400 | if (desc != NULL) | 6960 | |
6401 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); | 6961 | if (!desc) |
6962 | return; | ||
6963 | |||
6964 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc); | ||
6402 | } | 6965 | } |
6966 | #endif | ||
6403 | 6967 | ||
6404 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6968 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6405 | EXPORT_SYMBOL(mpt_attach); | 6969 | EXPORT_SYMBOL(mpt_attach); |
@@ -6434,6 +6998,7 @@ EXPORT_SYMBOL(mpt_findImVolumes); | |||
6434 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6998 | EXPORT_SYMBOL(mpt_alloc_fw_memory); |
6435 | EXPORT_SYMBOL(mpt_free_fw_memory); | 6999 | EXPORT_SYMBOL(mpt_free_fw_memory); |
6436 | EXPORT_SYMBOL(mptbase_sas_persist_operation); | 7000 | EXPORT_SYMBOL(mptbase_sas_persist_operation); |
7001 | EXPORT_SYMBOL(mpt_raid_phys_disk_pg0); | ||
6437 | 7002 | ||
6438 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 7003 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6439 | /** | 7004 | /** |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index e316708f76bd..e3a39272aad6 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
7 | * | 7 | * |
8 | * Copyright (c) 1999-2007 LSI Logic Corporation | 8 | * Copyright (c) 1999-2007 LSI Logic Corporation |
9 | * (mailto:mpt_linux_developer@lsil.com) | 9 | * (mailto:mpt_linux_developer@lsi.com) |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -75,8 +75,8 @@ | |||
75 | #define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR | 75 | #define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define MPT_LINUX_VERSION_COMMON "3.04.03" | 78 | #define MPT_LINUX_VERSION_COMMON "3.04.04" |
79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.03" | 79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.04" |
80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
81 | 81 | ||
82 | #define show_mptmod_ver(s,ver) \ | 82 | #define show_mptmod_ver(s,ver) \ |
@@ -172,6 +172,9 @@ | |||
172 | #define MPT_SCSI_SG_DEPTH 40 | 172 | #define MPT_SCSI_SG_DEPTH 40 |
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | /* debug print string length used for events and iocstatus */ | ||
176 | # define EVENT_DESCR_STR_SZ 100 | ||
177 | |||
175 | #ifdef __KERNEL__ /* { */ | 178 | #ifdef __KERNEL__ /* { */ |
176 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 179 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
177 | 180 | ||
@@ -334,8 +337,8 @@ typedef struct _VirtTarget { | |||
334 | struct scsi_target *starget; | 337 | struct scsi_target *starget; |
335 | u8 tflags; | 338 | u8 tflags; |
336 | u8 ioc_id; | 339 | u8 ioc_id; |
337 | u8 target_id; | 340 | u8 id; |
338 | u8 bus_id; | 341 | u8 channel; |
339 | u8 minSyncFactor; /* 0xFF is async */ | 342 | u8 minSyncFactor; /* 0xFF is async */ |
340 | u8 maxOffset; /* 0 if async */ | 343 | u8 maxOffset; /* 0 if async */ |
341 | u8 maxWidth; /* 0 if narrow, 1 if wide */ | 344 | u8 maxWidth; /* 0 if narrow, 1 if wide */ |
@@ -344,13 +347,12 @@ typedef struct _VirtTarget { | |||
344 | u8 type; /* byte 0 of Inquiry data */ | 347 | u8 type; /* byte 0 of Inquiry data */ |
345 | u8 deleted; /* target in process of being removed */ | 348 | u8 deleted; /* target in process of being removed */ |
346 | u32 num_luns; | 349 | u32 num_luns; |
347 | u32 luns[8]; /* Max LUNs is 256 */ | ||
348 | } VirtTarget; | 350 | } VirtTarget; |
349 | 351 | ||
350 | typedef struct _VirtDevice { | 352 | typedef struct _VirtDevice { |
351 | VirtTarget *vtarget; | 353 | VirtTarget *vtarget; |
352 | u8 configured_lun; | 354 | u8 configured_lun; |
353 | u32 lun; | 355 | int lun; |
354 | } VirtDevice; | 356 | } VirtDevice; |
355 | 357 | ||
356 | /* | 358 | /* |
@@ -412,7 +414,7 @@ typedef struct _MPT_IOCTL { | |||
412 | u8 rsvd; | 414 | u8 rsvd; |
413 | u8 status; /* current command status */ | 415 | u8 status; /* current command status */ |
414 | u8 reset; /* 1 if bus reset allowed */ | 416 | u8 reset; /* 1 if bus reset allowed */ |
415 | u8 target; /* target for reset */ | 417 | u8 id; /* target for reset */ |
416 | struct mutex ioctl_mutex; | 418 | struct mutex ioctl_mutex; |
417 | } MPT_IOCTL; | 419 | } MPT_IOCTL; |
418 | 420 | ||
@@ -483,10 +485,24 @@ typedef struct _SasCfgData { | |||
483 | */ | 485 | */ |
484 | }SasCfgData; | 486 | }SasCfgData; |
485 | 487 | ||
488 | /* | ||
489 | * Inactive volume link list of raid component data | ||
490 | * @inactive_list | ||
491 | */ | ||
492 | struct inactive_raid_component_info { | ||
493 | struct list_head list; | ||
494 | u8 volumeID; /* volume target id */ | ||
495 | u8 volumeBus; /* volume channel */ | ||
496 | IOC_3_PHYS_DISK d; /* phys disk info */ | ||
497 | }; | ||
498 | |||
486 | typedef struct _RaidCfgData { | 499 | typedef struct _RaidCfgData { |
487 | IOCPage2_t *pIocPg2; /* table of Raid Volumes */ | 500 | IOCPage2_t *pIocPg2; /* table of Raid Volumes */ |
488 | IOCPage3_t *pIocPg3; /* table of physical disks */ | 501 | IOCPage3_t *pIocPg3; /* table of physical disks */ |
489 | int isRaid; /* bit field, 1 if RAID */ | 502 | struct semaphore inactive_list_mutex; |
503 | struct list_head inactive_list; /* link list for physical | ||
504 | disk that belong in | ||
505 | inactive volumes */ | ||
490 | }RaidCfgData; | 506 | }RaidCfgData; |
491 | 507 | ||
492 | typedef struct _FcCfgData { | 508 | typedef struct _FcCfgData { |
@@ -528,6 +544,8 @@ typedef struct _MPT_ADAPTER | |||
528 | u32 mem_phys; /* == f4020000 (mmap) */ | 544 | u32 mem_phys; /* == f4020000 (mmap) */ |
529 | u32 pio_mem_phys; /* Programmed IO (downloadboot) */ | 545 | u32 pio_mem_phys; /* Programmed IO (downloadboot) */ |
530 | int mem_size; /* mmap memory size */ | 546 | int mem_size; /* mmap memory size */ |
547 | int number_of_buses; | ||
548 | int devices_per_bus; | ||
531 | int alloc_total; | 549 | int alloc_total; |
532 | u32 last_state; | 550 | u32 last_state; |
533 | int active; | 551 | int active; |
@@ -607,6 +625,8 @@ typedef struct _MPT_ADAPTER | |||
607 | u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */ | 625 | u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */ |
608 | LANPage0_t lan_cnfg_page0; | 626 | LANPage0_t lan_cnfg_page0; |
609 | LANPage1_t lan_cnfg_page1; | 627 | LANPage1_t lan_cnfg_page1; |
628 | |||
629 | u8 ir_firmware; /* =1 if IR firmware detected */ | ||
610 | /* | 630 | /* |
611 | * Description: errata_flag_1064 | 631 | * Description: errata_flag_1064 |
612 | * If a PCIX read occurs within 1 or 2 cycles after the chip receives | 632 | * If a PCIX read occurs within 1 or 2 cycles after the chip receives |
@@ -790,12 +810,6 @@ typedef struct _mpt_sge { | |||
790 | #define ddvprintk(x) | 810 | #define ddvprintk(x) |
791 | #endif | 811 | #endif |
792 | 812 | ||
793 | #ifdef MPT_DEBUG_NEGO | ||
794 | #define dnegoprintk(x) printk x | ||
795 | #else | ||
796 | #define dnegoprintk(x) | ||
797 | #endif | ||
798 | |||
799 | #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) | 813 | #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) |
800 | #define ddvtprintk(x) printk x | 814 | #define ddvtprintk(x) printk x |
801 | #else | 815 | #else |
@@ -957,7 +971,6 @@ typedef struct _MPT_SCSI_HOST { | |||
957 | int port; | 971 | int port; |
958 | u32 pad0; | 972 | u32 pad0; |
959 | struct scsi_cmnd **ScsiLookup; | 973 | struct scsi_cmnd **ScsiLookup; |
960 | VirtTarget **Targets; | ||
961 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ | 974 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ |
962 | struct timer_list timer; | 975 | struct timer_list timer; |
963 | /* Pool of memory for holding SCpnts before doing | 976 | /* Pool of memory for holding SCpnts before doing |
@@ -981,6 +994,7 @@ typedef struct _MPT_SCSI_HOST { | |||
981 | int scandv_wait_done; | 994 | int scandv_wait_done; |
982 | long last_queue_full; | 995 | long last_queue_full; |
983 | u16 tm_iocstatus; | 996 | u16 tm_iocstatus; |
997 | struct list_head target_reset_list; | ||
984 | } MPT_SCSI_HOST; | 998 | } MPT_SCSI_HOST; |
985 | 999 | ||
986 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1000 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -1046,6 +1060,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | |||
1046 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 1060 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
1047 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 1061 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); |
1048 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); | 1062 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); |
1063 | extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk); | ||
1049 | 1064 | ||
1050 | /* | 1065 | /* |
1051 | * Public data decl's... | 1066 | * Public data decl's... |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 504632da4347..b0b80428d110 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
6 | * | 6 | * |
7 | * Copyright (c) 1999-2007 LSI Logic Corporation | 7 | * Copyright (c) 1999-2007 LSI Logic Corporation |
8 | * (mailto:mpt_linux_developer@lsil.com) | 8 | * (mailto:mpt_linux_developer@lsi.com) |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 11 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -313,7 +313,7 @@ static void mptctl_timeout_expired (MPT_IOCTL *ioctl) | |||
313 | */ | 313 | */ |
314 | dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", | 314 | dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", |
315 | ioctl->ioc->name)); | 315 | ioctl->ioc->name)); |
316 | mpt_HardResetHandler(ioctl->ioc, NO_SLEEP); | 316 | mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP); |
317 | } | 317 | } |
318 | return; | 318 | return; |
319 | 319 | ||
@@ -361,7 +361,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) | |||
361 | ioctl->ioc->name, mf)); | 361 | ioctl->ioc->name, mf)); |
362 | 362 | ||
363 | pScsiTm = (SCSITaskMgmt_t *) mf; | 363 | pScsiTm = (SCSITaskMgmt_t *) mf; |
364 | pScsiTm->TargetID = ioctl->target; | 364 | pScsiTm->TargetID = ioctl->id; |
365 | pScsiTm->Bus = hd->port; /* 0 */ | 365 | pScsiTm->Bus = hd->port; /* 0 */ |
366 | pScsiTm->ChainOffset = 0; | 366 | pScsiTm->ChainOffset = 0; |
367 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 367 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
@@ -1159,15 +1159,12 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1159 | struct mpt_ioctl_iocinfo *karg; | 1159 | struct mpt_ioctl_iocinfo *karg; |
1160 | MPT_ADAPTER *ioc; | 1160 | MPT_ADAPTER *ioc; |
1161 | struct pci_dev *pdev; | 1161 | struct pci_dev *pdev; |
1162 | struct Scsi_Host *sh; | ||
1163 | MPT_SCSI_HOST *hd; | ||
1164 | int iocnum; | 1162 | int iocnum; |
1165 | int numDevices = 0; | ||
1166 | unsigned int max_id; | ||
1167 | int ii; | ||
1168 | unsigned int port; | 1163 | unsigned int port; |
1169 | int cim_rev; | 1164 | int cim_rev; |
1170 | u8 revision; | 1165 | u8 revision; |
1166 | struct scsi_device *sdev; | ||
1167 | VirtDevice *vdev; | ||
1171 | 1168 | ||
1172 | dctlprintk((": mptctl_getiocinfo called.\n")); | 1169 | dctlprintk((": mptctl_getiocinfo called.\n")); |
1173 | /* Add of PCI INFO results in unaligned access for | 1170 | /* Add of PCI INFO results in unaligned access for |
@@ -1257,23 +1254,16 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1257 | 1254 | ||
1258 | /* Get number of devices | 1255 | /* Get number of devices |
1259 | */ | 1256 | */ |
1260 | if ((sh = ioc->sh) != NULL) { | 1257 | karg->numDevices = 0; |
1261 | /* sh->max_id = maximum target ID + 1 | 1258 | if (ioc->sh) { |
1262 | */ | 1259 | shost_for_each_device(sdev, ioc->sh) { |
1263 | max_id = sh->max_id - 1; | 1260 | vdev = sdev->hostdata; |
1264 | hd = (MPT_SCSI_HOST *) sh->hostdata; | 1261 | if (vdev->vtarget->tflags & |
1265 | 1262 | MPT_TARGET_FLAGS_RAID_COMPONENT) | |
1266 | /* Check all of the target structures and | 1263 | continue; |
1267 | * keep a counter. | 1264 | karg->numDevices++; |
1268 | */ | ||
1269 | if (hd && hd->Targets) { | ||
1270 | for (ii = 0; ii <= max_id; ii++) { | ||
1271 | if (hd->Targets[ii]) | ||
1272 | numDevices++; | ||
1273 | } | ||
1274 | } | 1265 | } |
1275 | } | 1266 | } |
1276 | karg->numDevices = numDevices; | ||
1277 | 1267 | ||
1278 | /* Set the BIOS and FW Version | 1268 | /* Set the BIOS and FW Version |
1279 | */ | 1269 | */ |
@@ -1319,21 +1309,16 @@ mptctl_gettargetinfo (unsigned long arg) | |||
1319 | struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; | 1309 | struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; |
1320 | struct mpt_ioctl_targetinfo karg; | 1310 | struct mpt_ioctl_targetinfo karg; |
1321 | MPT_ADAPTER *ioc; | 1311 | MPT_ADAPTER *ioc; |
1322 | struct Scsi_Host *sh; | 1312 | VirtDevice *vdev; |
1323 | MPT_SCSI_HOST *hd; | ||
1324 | VirtTarget *vdev; | ||
1325 | char *pmem; | 1313 | char *pmem; |
1326 | int *pdata; | 1314 | int *pdata; |
1327 | IOCPage2_t *pIoc2; | ||
1328 | IOCPage3_t *pIoc3; | ||
1329 | int iocnum; | 1315 | int iocnum; |
1330 | int numDevices = 0; | 1316 | int numDevices = 0; |
1331 | unsigned int max_id; | 1317 | int lun; |
1332 | int id, jj, indexed_lun, lun_index; | ||
1333 | u32 lun; | ||
1334 | int maxWordsLeft; | 1318 | int maxWordsLeft; |
1335 | int numBytes; | 1319 | int numBytes; |
1336 | u8 port, devType, bus_id; | 1320 | u8 port; |
1321 | struct scsi_device *sdev; | ||
1337 | 1322 | ||
1338 | dctlprintk(("mptctl_gettargetinfo called.\n")); | 1323 | dctlprintk(("mptctl_gettargetinfo called.\n")); |
1339 | if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { | 1324 | if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { |
@@ -1389,74 +1374,22 @@ mptctl_gettargetinfo (unsigned long arg) | |||
1389 | 1374 | ||
1390 | /* Get number of devices | 1375 | /* Get number of devices |
1391 | */ | 1376 | */ |
1392 | if ((sh = ioc->sh) != NULL) { | 1377 | if (ioc->sh){ |
1393 | 1378 | shost_for_each_device(sdev, ioc->sh) { | |
1394 | max_id = sh->max_id - 1; | 1379 | if (!maxWordsLeft) |
1395 | hd = (MPT_SCSI_HOST *) sh->hostdata; | 1380 | continue; |
1396 | 1381 | vdev = sdev->hostdata; | |
1397 | /* Check all of the target structures. | 1382 | if (vdev->vtarget->tflags & |
1398 | * Save the Id and increment the counter, | 1383 | MPT_TARGET_FLAGS_RAID_COMPONENT) |
1399 | * if ptr non-null. | 1384 | continue; |
1400 | * sh->max_id = maximum target ID + 1 | 1385 | lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun; |
1401 | */ | 1386 | *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) + |
1402 | if (hd && hd->Targets) { | 1387 | (vdev->vtarget->id )); |
1403 | mpt_findImVolumes(ioc); | 1388 | pdata++; |
1404 | pIoc2 = ioc->raid_data.pIocPg2; | 1389 | numDevices++; |
1405 | for ( id = 0; id <= max_id; ) { | 1390 | --maxWordsLeft; |
1406 | if ( pIoc2 && pIoc2->NumActiveVolumes ) { | ||
1407 | if ( id == pIoc2->RaidVolume[0].VolumeID ) { | ||
1408 | if (maxWordsLeft <= 0) { | ||
1409 | printk(KERN_ERR "mptctl_gettargetinfo - " | ||
1410 | "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices); | ||
1411 | goto data_space_full; | ||
1412 | } | ||
1413 | if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 ) | ||
1414 | devType = 0x80; | ||
1415 | else | ||
1416 | devType = 0xC0; | ||
1417 | bus_id = pIoc2->RaidVolume[0].VolumeBus; | ||
1418 | numDevices++; | ||
1419 | *pdata = ( (devType << 24) | (bus_id << 8) | id ); | ||
1420 | dctlprintk((KERN_ERR "mptctl_gettargetinfo - " | ||
1421 | "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); | ||
1422 | pdata++; | ||
1423 | --maxWordsLeft; | ||
1424 | goto next_id; | ||
1425 | } else { | ||
1426 | pIoc3 = ioc->raid_data.pIocPg3; | ||
1427 | for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) { | ||
1428 | if ( pIoc3->PhysDisk[jj].PhysDiskID == id ) | ||
1429 | goto next_id; | ||
1430 | } | ||
1431 | } | ||
1432 | } | ||
1433 | if ( (vdev = hd->Targets[id]) ) { | ||
1434 | for (jj = 0; jj <= MPT_LAST_LUN; jj++) { | ||
1435 | lun_index = (jj >> 5); | ||
1436 | indexed_lun = (jj % 32); | ||
1437 | lun = (1 << indexed_lun); | ||
1438 | if (vdev->luns[lun_index] & lun) { | ||
1439 | if (maxWordsLeft <= 0) { | ||
1440 | printk(KERN_ERR "mptctl_gettargetinfo - " | ||
1441 | "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices); | ||
1442 | goto data_space_full; | ||
1443 | } | ||
1444 | bus_id = vdev->bus_id; | ||
1445 | numDevices++; | ||
1446 | *pdata = ( (jj << 16) | (bus_id << 8) | id ); | ||
1447 | dctlprintk((KERN_ERR "mptctl_gettargetinfo - " | ||
1448 | "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); | ||
1449 | pdata++; | ||
1450 | --maxWordsLeft; | ||
1451 | } | ||
1452 | } | ||
1453 | } | ||
1454 | next_id: | ||
1455 | id++; | ||
1456 | } | ||
1457 | } | 1391 | } |
1458 | } | 1392 | } |
1459 | data_space_full: | ||
1460 | karg.numDevices = numDevices; | 1393 | karg.numDevices = numDevices; |
1461 | 1394 | ||
1462 | /* Copy part of the data from kernel memory to user memory | 1395 | /* Copy part of the data from kernel memory to user memory |
@@ -1821,6 +1754,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1821 | int msgContext; | 1754 | int msgContext; |
1822 | u16 req_idx; | 1755 | u16 req_idx; |
1823 | ulong timeout; | 1756 | ulong timeout; |
1757 | struct scsi_device *sdev; | ||
1824 | 1758 | ||
1825 | dctlprintk(("mptctl_do_mpt_command called.\n")); | 1759 | dctlprintk(("mptctl_do_mpt_command called.\n")); |
1826 | bufIn.kptr = bufOut.kptr = NULL; | 1760 | bufIn.kptr = bufOut.kptr = NULL; |
@@ -1902,14 +1836,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1902 | case MPI_FUNCTION_SCSI_IO_REQUEST: | 1836 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
1903 | if (ioc->sh) { | 1837 | if (ioc->sh) { |
1904 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; | 1838 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; |
1905 | VirtTarget *pTarget = NULL; | ||
1906 | MPT_SCSI_HOST *hd = NULL; | ||
1907 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; | 1839 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; |
1908 | int scsidir = 0; | 1840 | int scsidir = 0; |
1909 | int target = (int) pScsiReq->TargetID; | ||
1910 | int dataSize; | 1841 | int dataSize; |
1842 | u32 id; | ||
1911 | 1843 | ||
1912 | if ((target < 0) || (target >= ioc->sh->max_id)) { | 1844 | id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; |
1845 | if (pScsiReq->TargetID > id) { | ||
1913 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1846 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
1914 | "Target ID out of bounds. \n", | 1847 | "Target ID out of bounds. \n", |
1915 | __FILE__, __LINE__); | 1848 | __FILE__, __LINE__); |
@@ -1917,6 +1850,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1917 | goto done_free_mem; | 1850 | goto done_free_mem; |
1918 | } | 1851 | } |
1919 | 1852 | ||
1853 | if (pScsiReq->Bus >= ioc->number_of_buses) { | ||
1854 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | ||
1855 | "Target Bus out of bounds. \n", | ||
1856 | __FILE__, __LINE__); | ||
1857 | rc = -ENODEV; | ||
1858 | goto done_free_mem; | ||
1859 | } | ||
1860 | |||
1920 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; | 1861 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
1921 | pScsiReq->MsgFlags |= mpt_msg_flags(); | 1862 | pScsiReq->MsgFlags |= mpt_msg_flags(); |
1922 | 1863 | ||
@@ -1936,13 +1877,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1936 | cpu_to_le32(ioc->sense_buf_low_dma | 1877 | cpu_to_le32(ioc->sense_buf_low_dma |
1937 | + (req_idx * MPT_SENSE_BUFFER_ALLOC)); | 1878 | + (req_idx * MPT_SENSE_BUFFER_ALLOC)); |
1938 | 1879 | ||
1939 | if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { | 1880 | shost_for_each_device(sdev, ioc->sh) { |
1940 | if (hd->Targets) | 1881 | struct scsi_target *starget = scsi_target(sdev); |
1941 | pTarget = hd->Targets[target]; | 1882 | VirtTarget *vtarget = starget->hostdata; |
1942 | } | ||
1943 | 1883 | ||
1944 | if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | 1884 | if ((pScsiReq->TargetID == vtarget->id) && |
1945 | qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; | 1885 | (pScsiReq->Bus == vtarget->channel) && |
1886 | (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | ||
1887 | qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; | ||
1888 | } | ||
1946 | 1889 | ||
1947 | /* Have the IOCTL driver set the direction based | 1890 | /* Have the IOCTL driver set the direction based |
1948 | * on the dataOutSize (ordering issue with Sparc). | 1891 | * on the dataOutSize (ordering issue with Sparc). |
@@ -1959,7 +1902,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1959 | pScsiReq->DataLength = cpu_to_le32(dataSize); | 1902 | pScsiReq->DataLength = cpu_to_le32(dataSize); |
1960 | 1903 | ||
1961 | ioc->ioctl->reset = MPTCTL_RESET_OK; | 1904 | ioc->ioctl->reset = MPTCTL_RESET_OK; |
1962 | ioc->ioctl->target = target; | 1905 | ioc->ioctl->id = pScsiReq->TargetID; |
1963 | 1906 | ||
1964 | } else { | 1907 | } else { |
1965 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1908 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
@@ -2038,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
2038 | pScsiReq->DataLength = cpu_to_le32(dataSize); | 1981 | pScsiReq->DataLength = cpu_to_le32(dataSize); |
2039 | 1982 | ||
2040 | ioc->ioctl->reset = MPTCTL_RESET_OK; | 1983 | ioc->ioctl->reset = MPTCTL_RESET_OK; |
2041 | ioc->ioctl->target = pScsiReq->TargetID; | 1984 | ioc->ioctl->id = pScsiReq->TargetID; |
2042 | } else { | 1985 | } else { |
2043 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1986 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
2044 | "SCSI driver is not loaded. \n", | 1987 | "SCSI driver is not loaded. \n", |
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index e65a1cf5eb0b..f7e72c5e47de 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
7 | * | 7 | * |
8 | * Copyright (c) 1999-2007 LSI Logic Corporation | 8 | * Copyright (c) 1999-2007 LSI Logic Corporation |
9 | * (mailto:mpt_linux_developer@lsil.com) | 9 | * (mailto:mpt_linux_developer@lsi.com) |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index c819c23b55b1..b7d4c7265ec6 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
5 | * | 5 | * |
6 | * Copyright (c) 1999-2007 LSI Logic Corporation | 6 | * Copyright (c) 1999-2007 LSI Logic Corporation |
7 | * (mailto:mpt_linux_developer@lsil.com) | 7 | * (mailto:mpt_linux_developer@lsi.com) |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -86,6 +86,12 @@ MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the " | |||
86 | " return following a device loss event." | 86 | " return following a device loss event." |
87 | " Default=60."); | 87 | " Default=60."); |
88 | 88 | ||
89 | /* scsi-mid layer global parmeter is max_report_luns, which is 511 */ | ||
90 | #define MPTFC_MAX_LUN (16895) | ||
91 | static int max_lun = MPTFC_MAX_LUN; | ||
92 | module_param(max_lun, int, 0); | ||
93 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | ||
94 | |||
89 | static int mptfcDoneCtx = -1; | 95 | static int mptfcDoneCtx = -1; |
90 | static int mptfcTaskCtx = -1; | 96 | static int mptfcTaskCtx = -1; |
91 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ | 97 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ |
@@ -292,10 +298,9 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, | |||
292 | U32 port_id = 0xffffff; | 298 | U32 port_id = 0xffffff; |
293 | int num_targ = 0; | 299 | int num_targ = 0; |
294 | int max_bus = ioc->facts.MaxBuses; | 300 | int max_bus = ioc->facts.MaxBuses; |
295 | int max_targ = ioc->facts.MaxDevices; | 301 | int max_targ; |
296 | 302 | ||
297 | if (max_bus == 0 || max_targ == 0) | 303 | max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices; |
298 | goto out; | ||
299 | 304 | ||
300 | data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; | 305 | data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; |
301 | p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); | 306 | p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); |
@@ -467,8 +472,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
467 | if (ri->starget) { | 472 | if (ri->starget) { |
468 | vtarget = ri->starget->hostdata; | 473 | vtarget = ri->starget->hostdata; |
469 | if (vtarget) { | 474 | if (vtarget) { |
470 | vtarget->target_id = pg0->CurrentTargetID; | 475 | vtarget->id = pg0->CurrentTargetID; |
471 | vtarget->bus_id = pg0->CurrentBus; | 476 | vtarget->channel = pg0->CurrentBus; |
472 | } | 477 | } |
473 | } | 478 | } |
474 | *((struct mptfc_rport_info **)rport->dd_data) = ri; | 479 | *((struct mptfc_rport_info **)rport->dd_data) = ri; |
@@ -540,8 +545,8 @@ mptfc_target_alloc(struct scsi_target *starget) | |||
540 | if (rport) { | 545 | if (rport) { |
541 | ri = *((struct mptfc_rport_info **)rport->dd_data); | 546 | ri = *((struct mptfc_rport_info **)rport->dd_data); |
542 | if (ri) { /* better be! */ | 547 | if (ri) { /* better be! */ |
543 | vtarget->target_id = ri->pg0.CurrentTargetID; | 548 | vtarget->id = ri->pg0.CurrentTargetID; |
544 | vtarget->bus_id = ri->pg0.CurrentBus; | 549 | vtarget->channel = ri->pg0.CurrentBus; |
545 | ri->starget = starget; | 550 | ri->starget = starget; |
546 | rc = 0; | 551 | rc = 0; |
547 | } | 552 | } |
@@ -592,7 +597,6 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
592 | if (vtarget->num_luns == 0) { | 597 | if (vtarget->num_luns == 0) { |
593 | vtarget->ioc_id = hd->ioc->id; | 598 | vtarget->ioc_id = hd->ioc->id; |
594 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | 599 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; |
595 | hd->Targets[sdev->id] = vtarget; | ||
596 | } | 600 | } |
597 | 601 | ||
598 | vdev->vtarget = vtarget; | 602 | vdev->vtarget = vtarget; |
@@ -630,16 +634,17 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
630 | struct mptfc_rport_info *ri; | 634 | struct mptfc_rport_info *ri; |
631 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); | 635 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); |
632 | int err; | 636 | int err; |
637 | VirtDevice *vdev = SCpnt->device->hostdata; | ||
633 | 638 | ||
634 | err = fc_remote_port_chkready(rport); | 639 | if (!vdev || !vdev->vtarget) { |
635 | if (unlikely(err)) { | 640 | SCpnt->result = DID_NO_CONNECT << 16; |
636 | SCpnt->result = err; | ||
637 | done(SCpnt); | 641 | done(SCpnt); |
638 | return 0; | 642 | return 0; |
639 | } | 643 | } |
640 | 644 | ||
641 | if (!SCpnt->device->hostdata) { /* vdev */ | 645 | err = fc_remote_port_chkready(rport); |
642 | SCpnt->result = DID_NO_CONNECT << 16; | 646 | if (unlikely(err)) { |
647 | SCpnt->result = err; | ||
643 | done(SCpnt); | 648 | done(SCpnt); |
644 | return 0; | 649 | return 0; |
645 | } | 650 | } |
@@ -1143,7 +1148,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1143 | printk(MYIOC_s_WARN_FMT | 1148 | printk(MYIOC_s_WARN_FMT |
1144 | "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", | 1149 | "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", |
1145 | ioc->name, ioc); | 1150 | ioc->name, ioc); |
1146 | return -ENODEV; | 1151 | return 0; |
1147 | } | 1152 | } |
1148 | 1153 | ||
1149 | sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); | 1154 | sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); |
@@ -1173,10 +1178,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1173 | /* set 16 byte cdb's */ | 1178 | /* set 16 byte cdb's */ |
1174 | sh->max_cmd_len = 16; | 1179 | sh->max_cmd_len = 16; |
1175 | 1180 | ||
1176 | sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; | 1181 | sh->max_id = ioc->pfacts->MaxDevices; |
1182 | sh->max_lun = max_lun; | ||
1177 | 1183 | ||
1178 | sh->max_lun = MPT_LAST_LUN + 1; | ||
1179 | sh->max_channel = 0; | ||
1180 | sh->this_id = ioc->pfacts[0].PortSCSIID; | 1184 | sh->this_id = ioc->pfacts[0].PortSCSIID; |
1181 | 1185 | ||
1182 | /* Required entry. | 1186 | /* Required entry. |
@@ -1230,19 +1234,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1230 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 1234 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
1231 | ioc->name, hd->ScsiLookup)); | 1235 | ioc->name, hd->ScsiLookup)); |
1232 | 1236 | ||
1233 | /* Allocate memory for the device structures. | ||
1234 | * A non-Null pointer at an offset | ||
1235 | * indicates a device exists. | ||
1236 | * max_id = 1 + maximum id (hosts.h) | ||
1237 | */ | ||
1238 | hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); | ||
1239 | if (!hd->Targets) { | ||
1240 | error = -ENOMEM; | ||
1241 | goto out_mptfc_probe; | ||
1242 | } | ||
1243 | |||
1244 | dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); | ||
1245 | |||
1246 | /* Clear the TM flags | 1237 | /* Clear the TM flags |
1247 | */ | 1238 | */ |
1248 | hd->tmPending = 0; | 1239 | hd->tmPending = 0; |
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 2936204d8ad6..b691292ff599 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
6 | * | 6 | * |
7 | * Copyright (c) 2000-2007 LSI Logic Corporation | 7 | * Copyright (c) 2000-2007 LSI Logic Corporation |
8 | * (mailto:mpt_linux_developer@lsi.com) | ||
8 | * | 9 | * |
9 | */ | 10 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 11 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h index 70ab75e7c263..fe438bf119f6 100644 --- a/drivers/message/fusion/mptlan.h +++ b/drivers/message/fusion/mptlan.h | |||
@@ -5,6 +5,7 @@ | |||
5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 5 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
6 | * | 6 | * |
7 | * Copyright (c) 2000-2007 LSI Logic Corporation | 7 | * Copyright (c) 2000-2007 LSI Logic Corporation |
8 | * (mailto:mpt_linux_developer@lsi.com) | ||
8 | * | 9 | * |
9 | */ | 10 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 11 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 09e9a9d96410..84b8b485e95b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
5 | * | 5 | * |
6 | * Copyright (c) 1999-2007 LSI Logic Corporation | 6 | * Copyright (c) 1999-2007 LSI Logic Corporation |
7 | * (mailto:mpt_linux_developer@lsil.com) | 7 | * (mailto:mpt_linux_developer@lsi.com) |
8 | * Copyright (c) 2005-2007 Dell | 8 | * Copyright (c) 2005-2007 Dell |
9 | */ | 9 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -83,17 +83,31 @@ MODULE_PARM_DESC(mpt_pt_clear, | |||
83 | " Clear persistency table: enable=1 " | 83 | " Clear persistency table: enable=1 " |
84 | "(default=MPTSCSIH_PT_CLEAR=0)"); | 84 | "(default=MPTSCSIH_PT_CLEAR=0)"); |
85 | 85 | ||
86 | /* scsi-mid layer global parmeter is max_report_luns, which is 511 */ | ||
87 | #define MPTSAS_MAX_LUN (16895) | ||
88 | static int max_lun = MPTSAS_MAX_LUN; | ||
89 | module_param(max_lun, int, 0); | ||
90 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | ||
91 | |||
86 | static int mptsasDoneCtx = -1; | 92 | static int mptsasDoneCtx = -1; |
87 | static int mptsasTaskCtx = -1; | 93 | static int mptsasTaskCtx = -1; |
88 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ | 94 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ |
89 | static int mptsasMgmtCtx = -1; | 95 | static int mptsasMgmtCtx = -1; |
90 | 96 | ||
97 | static void mptsas_hotplug_work(struct work_struct *work); | ||
98 | |||
99 | struct mptsas_target_reset_event { | ||
100 | struct list_head list; | ||
101 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data; | ||
102 | u8 target_reset_issued; | ||
103 | }; | ||
91 | 104 | ||
92 | enum mptsas_hotplug_action { | 105 | enum mptsas_hotplug_action { |
93 | MPTSAS_ADD_DEVICE, | 106 | MPTSAS_ADD_DEVICE, |
94 | MPTSAS_DEL_DEVICE, | 107 | MPTSAS_DEL_DEVICE, |
95 | MPTSAS_ADD_RAID, | 108 | MPTSAS_ADD_RAID, |
96 | MPTSAS_DEL_RAID, | 109 | MPTSAS_DEL_RAID, |
110 | MPTSAS_ADD_INACTIVE_VOLUME, | ||
97 | MPTSAS_IGNORE_EVENT, | 111 | MPTSAS_IGNORE_EVENT, |
98 | }; | 112 | }; |
99 | 113 | ||
@@ -102,14 +116,15 @@ struct mptsas_hotplug_event { | |||
102 | MPT_ADAPTER *ioc; | 116 | MPT_ADAPTER *ioc; |
103 | enum mptsas_hotplug_action event_type; | 117 | enum mptsas_hotplug_action event_type; |
104 | u64 sas_address; | 118 | u64 sas_address; |
105 | u32 channel; | 119 | u8 channel; |
106 | u32 id; | 120 | u8 id; |
107 | u32 device_info; | 121 | u32 device_info; |
108 | u16 handle; | 122 | u16 handle; |
109 | u16 parent_handle; | 123 | u16 parent_handle; |
110 | u8 phy_id; | 124 | u8 phy_id; |
111 | u8 phys_disk_num; | 125 | u8 phys_disk_num_valid; /* hrc (hidden raid component) */ |
112 | u8 phys_disk_num_valid; | 126 | u8 phys_disk_num; /* hrc - unique index*/ |
127 | u8 hidden_raid_component; /* hrc - don't expose*/ | ||
113 | }; | 128 | }; |
114 | 129 | ||
115 | struct mptsas_discovery_event { | 130 | struct mptsas_discovery_event { |
@@ -134,6 +149,7 @@ struct mptsas_devinfo { | |||
134 | u8 port_id; /* sas physical port this device | 149 | u8 port_id; /* sas physical port this device |
135 | is assoc'd with */ | 150 | is assoc'd with */ |
136 | u8 id; /* logical target id of this device */ | 151 | u8 id; /* logical target id of this device */ |
152 | u32 phys_disk_num; /* phys disk id, for csmi-ioctls */ | ||
137 | u8 channel; /* logical bus number of this device */ | 153 | u8 channel; /* logical bus number of this device */ |
138 | u64 sas_address; /* WWN of this device, | 154 | u64 sas_address; /* WWN of this device, |
139 | SATA is assigned by HBA,expander */ | 155 | SATA is assigned by HBA,expander */ |
@@ -153,6 +169,7 @@ struct mptsas_portinfo_details{ | |||
153 | }; | 169 | }; |
154 | 170 | ||
155 | struct mptsas_phyinfo { | 171 | struct mptsas_phyinfo { |
172 | u16 handle; /* unique id to address this */ | ||
156 | u8 phy_id; /* phy index */ | 173 | u8 phy_id; /* phy index */ |
157 | u8 port_id; /* firmware port identifier */ | 174 | u8 port_id; /* firmware port identifier */ |
158 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ | 175 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ |
@@ -168,7 +185,6 @@ struct mptsas_phyinfo { | |||
168 | 185 | ||
169 | struct mptsas_portinfo { | 186 | struct mptsas_portinfo { |
170 | struct list_head list; | 187 | struct list_head list; |
171 | u16 handle; /* unique id to address this */ | ||
172 | u16 num_phys; /* number of phys */ | 188 | u16 num_phys; /* number of phys */ |
173 | struct mptsas_phyinfo *phy_info; | 189 | struct mptsas_phyinfo *phy_info; |
174 | }; | 190 | }; |
@@ -561,22 +577,273 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
561 | mutex_unlock(&ioc->sas_topology_mutex); | 577 | mutex_unlock(&ioc->sas_topology_mutex); |
562 | } | 578 | } |
563 | 579 | ||
580 | /** | ||
581 | * csmisas_find_vtarget | ||
582 | * | ||
583 | * @ioc | ||
584 | * @volume_id | ||
585 | * @volume_bus | ||
586 | * | ||
587 | **/ | ||
588 | static VirtTarget * | ||
589 | mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
590 | { | ||
591 | struct scsi_device *sdev; | ||
592 | VirtDevice *vdev; | ||
593 | VirtTarget *vtarget = NULL; | ||
594 | |||
595 | shost_for_each_device(sdev, ioc->sh) { | ||
596 | if ((vdev = sdev->hostdata) == NULL) | ||
597 | continue; | ||
598 | if (vdev->vtarget->id == id && | ||
599 | vdev->vtarget->channel == channel) | ||
600 | vtarget = vdev->vtarget; | ||
601 | } | ||
602 | return vtarget; | ||
603 | } | ||
604 | |||
605 | /** | ||
606 | * mptsas_target_reset | ||
607 | * | ||
608 | * Issues TARGET_RESET to end device using handshaking method | ||
609 | * | ||
610 | * @ioc | ||
611 | * @channel | ||
612 | * @id | ||
613 | * | ||
614 | * Returns (1) success | ||
615 | * (0) failure | ||
616 | * | ||
617 | **/ | ||
618 | static int | ||
619 | mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
620 | { | ||
621 | MPT_FRAME_HDR *mf; | ||
622 | SCSITaskMgmt_t *pScsiTm; | ||
623 | |||
624 | if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) { | ||
625 | dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n", | ||
626 | ioc->name,__FUNCTION__, __LINE__)); | ||
627 | return 0; | ||
628 | } | ||
629 | |||
630 | /* Format the Request | ||
631 | */ | ||
632 | pScsiTm = (SCSITaskMgmt_t *) mf; | ||
633 | memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t)); | ||
634 | pScsiTm->TargetID = id; | ||
635 | pScsiTm->Bus = channel; | ||
636 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | ||
637 | pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | ||
638 | pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION; | ||
639 | |||
640 | DBG_DUMP_TM_REQUEST_FRAME(mf); | ||
641 | |||
642 | if (mpt_send_handshake_request(ioc->TaskCtx, ioc, | ||
643 | sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) { | ||
644 | mpt_free_msg_frame(ioc, mf); | ||
645 | dfailprintk((MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n", | ||
646 | ioc->name,__FUNCTION__, __LINE__)); | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | return 1; | ||
651 | } | ||
652 | |||
653 | /** | ||
654 | * mptsas_target_reset_queue | ||
655 | * | ||
656 | * Receive request for TARGET_RESET after recieving an firmware | ||
657 | * event NOT_RESPONDING_EVENT, then put command in link list | ||
658 | * and queue if task_queue already in use. | ||
659 | * | ||
660 | * @ioc | ||
661 | * @sas_event_data | ||
662 | * | ||
663 | **/ | ||
564 | static void | 664 | static void |
565 | mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) | 665 | mptsas_target_reset_queue(MPT_ADAPTER *ioc, |
666 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) | ||
566 | { | 667 | { |
567 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | 668 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; |
669 | VirtTarget *vtarget = NULL; | ||
670 | struct mptsas_target_reset_event *target_reset_list; | ||
671 | u8 id, channel; | ||
568 | 672 | ||
569 | if (mptscsih_TMHandler(hd, | 673 | id = sas_event_data->TargetID; |
570 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 674 | channel = sas_event_data->Bus; |
571 | vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { | 675 | |
572 | hd->tmPending = 0; | 676 | if (!(vtarget = mptsas_find_vtarget(ioc, channel, id))) |
573 | hd->tmState = TM_STATE_NONE; | 677 | return; |
574 | printk(MYIOC_s_WARN_FMT | 678 | |
575 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | 679 | vtarget->deleted = 1; /* block IO */ |
576 | ioc->name, vtarget->target_id); | 680 | |
681 | target_reset_list = kzalloc(sizeof(*target_reset_list), | ||
682 | GFP_ATOMIC); | ||
683 | if (!target_reset_list) { | ||
684 | dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", | ||
685 | ioc->name,__FUNCTION__, __LINE__)); | ||
686 | return; | ||
687 | } | ||
688 | |||
689 | memcpy(&target_reset_list->sas_event_data, sas_event_data, | ||
690 | sizeof(*sas_event_data)); | ||
691 | list_add_tail(&target_reset_list->list, &hd->target_reset_list); | ||
692 | |||
693 | if (hd->resetPending) | ||
694 | return; | ||
695 | |||
696 | if (mptsas_target_reset(ioc, channel, id)) { | ||
697 | target_reset_list->target_reset_issued = 1; | ||
698 | hd->resetPending = 1; | ||
577 | } | 699 | } |
578 | } | 700 | } |
579 | 701 | ||
702 | /** | ||
703 | * mptsas_dev_reset_complete | ||
704 | * | ||
705 | * Completion for TARGET_RESET after NOT_RESPONDING_EVENT, | ||
706 | * enable work queue to finish off removing device from upper layers. | ||
707 | * then send next TARGET_RESET in the queue. | ||
708 | * | ||
709 | * @ioc | ||
710 | * | ||
711 | **/ | ||
712 | static void | ||
713 | mptsas_dev_reset_complete(MPT_ADAPTER *ioc) | ||
714 | { | ||
715 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
716 | struct list_head *head = &hd->target_reset_list; | ||
717 | struct mptsas_target_reset_event *target_reset_list; | ||
718 | struct mptsas_hotplug_event *ev; | ||
719 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data; | ||
720 | u8 id, channel; | ||
721 | __le64 sas_address; | ||
722 | |||
723 | if (list_empty(head)) | ||
724 | return; | ||
725 | |||
726 | target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list); | ||
727 | |||
728 | sas_event_data = &target_reset_list->sas_event_data; | ||
729 | id = sas_event_data->TargetID; | ||
730 | channel = sas_event_data->Bus; | ||
731 | hd->resetPending = 0; | ||
732 | |||
733 | /* | ||
734 | * retry target reset | ||
735 | */ | ||
736 | if (!target_reset_list->target_reset_issued) { | ||
737 | if (mptsas_target_reset(ioc, channel, id)) { | ||
738 | target_reset_list->target_reset_issued = 1; | ||
739 | hd->resetPending = 1; | ||
740 | } | ||
741 | return; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * enable work queue to remove device from upper layers | ||
746 | */ | ||
747 | list_del(&target_reset_list->list); | ||
748 | |||
749 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | ||
750 | if (!ev) { | ||
751 | dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", | ||
752 | ioc->name,__FUNCTION__, __LINE__)); | ||
753 | return; | ||
754 | } | ||
755 | |||
756 | INIT_WORK(&ev->work, mptsas_hotplug_work); | ||
757 | ev->ioc = ioc; | ||
758 | ev->handle = le16_to_cpu(sas_event_data->DevHandle); | ||
759 | ev->parent_handle = | ||
760 | le16_to_cpu(sas_event_data->ParentDevHandle); | ||
761 | ev->channel = channel; | ||
762 | ev->id =id; | ||
763 | ev->phy_id = sas_event_data->PhyNum; | ||
764 | memcpy(&sas_address, &sas_event_data->SASAddress, | ||
765 | sizeof(__le64)); | ||
766 | ev->sas_address = le64_to_cpu(sas_address); | ||
767 | ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo); | ||
768 | ev->event_type = MPTSAS_DEL_DEVICE; | ||
769 | schedule_work(&ev->work); | ||
770 | kfree(target_reset_list); | ||
771 | |||
772 | /* | ||
773 | * issue target reset to next device in the queue | ||
774 | */ | ||
775 | |||
776 | head = &hd->target_reset_list; | ||
777 | if (list_empty(head)) | ||
778 | return; | ||
779 | |||
780 | target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, | ||
781 | list); | ||
782 | |||
783 | sas_event_data = &target_reset_list->sas_event_data; | ||
784 | id = sas_event_data->TargetID; | ||
785 | channel = sas_event_data->Bus; | ||
786 | |||
787 | if (mptsas_target_reset(ioc, channel, id)) { | ||
788 | target_reset_list->target_reset_issued = 1; | ||
789 | hd->resetPending = 1; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | /** | ||
794 | * mptsas_taskmgmt_complete | ||
795 | * | ||
796 | * @ioc | ||
797 | * @mf | ||
798 | * @mr | ||
799 | * | ||
800 | **/ | ||
801 | static int | ||
802 | mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | ||
803 | { | ||
804 | mptsas_dev_reset_complete(ioc); | ||
805 | return mptscsih_taskmgmt_complete(ioc, mf, mr); | ||
806 | } | ||
807 | |||
808 | /** | ||
809 | * mptscsih_ioc_reset | ||
810 | * | ||
811 | * @ioc | ||
812 | * @reset_phase | ||
813 | * | ||
814 | **/ | ||
815 | static int | ||
816 | mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | ||
817 | { | ||
818 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
819 | struct mptsas_target_reset_event *target_reset_list, *n; | ||
820 | int rc; | ||
821 | |||
822 | rc = mptscsih_ioc_reset(ioc, reset_phase); | ||
823 | |||
824 | if (ioc->bus_type != SAS) | ||
825 | goto out; | ||
826 | |||
827 | if (reset_phase != MPT_IOC_POST_RESET) | ||
828 | goto out; | ||
829 | |||
830 | if (!hd || !hd->ioc) | ||
831 | goto out; | ||
832 | |||
833 | if (list_empty(&hd->target_reset_list)) | ||
834 | goto out; | ||
835 | |||
836 | /* flush the target_reset_list */ | ||
837 | list_for_each_entry_safe(target_reset_list, n, | ||
838 | &hd->target_reset_list, list) { | ||
839 | list_del(&target_reset_list->list); | ||
840 | kfree(target_reset_list); | ||
841 | } | ||
842 | |||
843 | out: | ||
844 | return rc; | ||
845 | } | ||
846 | |||
580 | static int | 847 | static int |
581 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, | 848 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, |
582 | u32 form, u32 form_specific) | 849 | u32 form, u32 form_specific) |
@@ -661,8 +928,7 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
661 | struct Scsi_Host *host = dev_to_shost(&starget->dev); | 928 | struct Scsi_Host *host = dev_to_shost(&starget->dev); |
662 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 929 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
663 | VirtTarget *vtarget; | 930 | VirtTarget *vtarget; |
664 | u32 target_id; | 931 | u8 id, channel; |
665 | u32 channel; | ||
666 | struct sas_rphy *rphy; | 932 | struct sas_rphy *rphy; |
667 | struct mptsas_portinfo *p; | 933 | struct mptsas_portinfo *p; |
668 | int i; | 934 | int i; |
@@ -673,15 +939,19 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
673 | 939 | ||
674 | vtarget->starget = starget; | 940 | vtarget->starget = starget; |
675 | vtarget->ioc_id = hd->ioc->id; | 941 | vtarget->ioc_id = hd->ioc->id; |
676 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | 942 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; |
677 | 943 | id = starget->id; | |
678 | target_id = starget->id; | ||
679 | channel = 0; | 944 | channel = 0; |
680 | 945 | ||
681 | hd->Targets[target_id] = vtarget; | 946 | /* |
682 | 947 | * RAID volumes placed beyond the last expected port. | |
683 | if (starget->channel == MPTSAS_RAID_CHANNEL) | 948 | */ |
949 | if (starget->channel == MPTSAS_RAID_CHANNEL) { | ||
950 | for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) | ||
951 | if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) | ||
952 | channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; | ||
684 | goto out; | 953 | goto out; |
954 | } | ||
685 | 955 | ||
686 | rphy = dev_to_rphy(starget->dev.parent); | 956 | rphy = dev_to_rphy(starget->dev.parent); |
687 | mutex_lock(&hd->ioc->sas_topology_mutex); | 957 | mutex_lock(&hd->ioc->sas_topology_mutex); |
@@ -690,18 +960,19 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
690 | if (p->phy_info[i].attached.sas_address != | 960 | if (p->phy_info[i].attached.sas_address != |
691 | rphy->identify.sas_address) | 961 | rphy->identify.sas_address) |
692 | continue; | 962 | continue; |
693 | target_id = p->phy_info[i].attached.id; | 963 | id = p->phy_info[i].attached.id; |
694 | channel = p->phy_info[i].attached.channel; | 964 | channel = p->phy_info[i].attached.channel; |
695 | mptsas_set_starget(&p->phy_info[i], starget); | 965 | mptsas_set_starget(&p->phy_info[i], starget); |
696 | 966 | ||
697 | /* | 967 | /* |
698 | * Exposing hidden raid components | 968 | * Exposing hidden raid components |
699 | */ | 969 | */ |
700 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | 970 | if (mptscsih_is_phys_disk(hd->ioc, channel, id)) { |
701 | target_id = mptscsih_raid_id_to_num(hd, | 971 | id = mptscsih_raid_id_to_num(hd->ioc, |
702 | target_id); | 972 | channel, id); |
703 | vtarget->tflags |= | 973 | vtarget->tflags |= |
704 | MPT_TARGET_FLAGS_RAID_COMPONENT; | 974 | MPT_TARGET_FLAGS_RAID_COMPONENT; |
975 | p->phy_info[i].attached.phys_disk_num = id; | ||
705 | } | 976 | } |
706 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 977 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
707 | goto out; | 978 | goto out; |
@@ -713,8 +984,8 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
713 | return -ENXIO; | 984 | return -ENXIO; |
714 | 985 | ||
715 | out: | 986 | out: |
716 | vtarget->target_id = target_id; | 987 | vtarget->id = id; |
717 | vtarget->bus_id = channel; | 988 | vtarget->channel = channel; |
718 | starget->hostdata = vtarget; | 989 | starget->hostdata = vtarget; |
719 | return 0; | 990 | return 0; |
720 | } | 991 | } |
@@ -786,7 +1057,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
786 | * Exposing hidden raid components | 1057 | * Exposing hidden raid components |
787 | */ | 1058 | */ |
788 | if (mptscsih_is_phys_disk(hd->ioc, | 1059 | if (mptscsih_is_phys_disk(hd->ioc, |
789 | p->phy_info[i].attached.id)) | 1060 | p->phy_info[i].attached.channel, |
1061 | p->phy_info[i].attached.id)) | ||
790 | sdev->no_uld_attach = 1; | 1062 | sdev->no_uld_attach = 1; |
791 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 1063 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
792 | goto out; | 1064 | goto out; |
@@ -808,13 +1080,14 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
808 | { | 1080 | { |
809 | VirtDevice *vdev = SCpnt->device->hostdata; | 1081 | VirtDevice *vdev = SCpnt->device->hostdata; |
810 | 1082 | ||
811 | // scsi_print_command(SCpnt); | 1083 | if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) { |
812 | if (vdev->vtarget->deleted) { | ||
813 | SCpnt->result = DID_NO_CONNECT << 16; | 1084 | SCpnt->result = DID_NO_CONNECT << 16; |
814 | done(SCpnt); | 1085 | done(SCpnt); |
815 | return 0; | 1086 | return 0; |
816 | } | 1087 | } |
817 | 1088 | ||
1089 | // scsi_print_command(SCpnt); | ||
1090 | |||
818 | return mptscsih_qcmd(SCpnt,done); | 1091 | return mptscsih_qcmd(SCpnt,done); |
819 | } | 1092 | } |
820 | 1093 | ||
@@ -1114,9 +1387,6 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
1114 | goto out_free_consistent; | 1387 | goto out_free_consistent; |
1115 | } | 1388 | } |
1116 | 1389 | ||
1117 | if (port_info->num_phys) | ||
1118 | port_info->handle = | ||
1119 | le16_to_cpu(buffer->PhyData[0].ControllerDevHandle); | ||
1120 | for (i = 0; i < port_info->num_phys; i++) { | 1390 | for (i = 0; i < port_info->num_phys; i++) { |
1121 | mptsas_print_phy_data(&buffer->PhyData[i]); | 1391 | mptsas_print_phy_data(&buffer->PhyData[i]); |
1122 | port_info->phy_info[i].phy_id = i; | 1392 | port_info->phy_info[i].phy_id = i; |
@@ -1125,6 +1395,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
1125 | port_info->phy_info[i].negotiated_link_rate = | 1395 | port_info->phy_info[i].negotiated_link_rate = |
1126 | buffer->PhyData[i].NegotiatedLinkRate; | 1396 | buffer->PhyData[i].NegotiatedLinkRate; |
1127 | port_info->phy_info[i].portinfo = port_info; | 1397 | port_info->phy_info[i].portinfo = port_info; |
1398 | port_info->phy_info[i].handle = | ||
1399 | le16_to_cpu(buffer->PhyData[i].ControllerDevHandle); | ||
1128 | } | 1400 | } |
1129 | 1401 | ||
1130 | out_free_consistent: | 1402 | out_free_consistent: |
@@ -1261,6 +1533,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, | |||
1261 | device_info->phy_id = buffer->PhyNum; | 1533 | device_info->phy_id = buffer->PhyNum; |
1262 | device_info->port_id = buffer->PhysicalPort; | 1534 | device_info->port_id = buffer->PhysicalPort; |
1263 | device_info->id = buffer->TargetID; | 1535 | device_info->id = buffer->TargetID; |
1536 | device_info->phys_disk_num = ~0; | ||
1264 | device_info->channel = buffer->Bus; | 1537 | device_info->channel = buffer->Bus; |
1265 | memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); | 1538 | memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); |
1266 | device_info->sas_address = le64_to_cpu(sas_address); | 1539 | device_info->sas_address = le64_to_cpu(sas_address); |
@@ -1325,7 +1598,6 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
1325 | 1598 | ||
1326 | /* save config data */ | 1599 | /* save config data */ |
1327 | port_info->num_phys = buffer->NumPhys; | 1600 | port_info->num_phys = buffer->NumPhys; |
1328 | port_info->handle = le16_to_cpu(buffer->DevHandle); | ||
1329 | port_info->phy_info = kcalloc(port_info->num_phys, | 1601 | port_info->phy_info = kcalloc(port_info->num_phys, |
1330 | sizeof(*port_info->phy_info),GFP_KERNEL); | 1602 | sizeof(*port_info->phy_info),GFP_KERNEL); |
1331 | if (!port_info->phy_info) { | 1603 | if (!port_info->phy_info) { |
@@ -1333,8 +1605,11 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
1333 | goto out_free_consistent; | 1605 | goto out_free_consistent; |
1334 | } | 1606 | } |
1335 | 1607 | ||
1336 | for (i = 0; i < port_info->num_phys; i++) | 1608 | for (i = 0; i < port_info->num_phys; i++) { |
1337 | port_info->phy_info[i].portinfo = port_info; | 1609 | port_info->phy_info[i].portinfo = port_info; |
1610 | port_info->phy_info[i].handle = | ||
1611 | le16_to_cpu(buffer->DevHandle); | ||
1612 | } | ||
1338 | 1613 | ||
1339 | out_free_consistent: | 1614 | out_free_consistent: |
1340 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | 1615 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, |
@@ -1702,7 +1977,6 @@ static int | |||
1702 | mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | 1977 | mptsas_probe_hba_phys(MPT_ADAPTER *ioc) |
1703 | { | 1978 | { |
1704 | struct mptsas_portinfo *port_info, *hba; | 1979 | struct mptsas_portinfo *port_info, *hba; |
1705 | u32 handle = 0xFFFF; | ||
1706 | int error = -ENOMEM, i; | 1980 | int error = -ENOMEM, i; |
1707 | 1981 | ||
1708 | hba = kzalloc(sizeof(*port_info), GFP_KERNEL); | 1982 | hba = kzalloc(sizeof(*port_info), GFP_KERNEL); |
@@ -1714,34 +1988,36 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1714 | goto out_free_port_info; | 1988 | goto out_free_port_info; |
1715 | 1989 | ||
1716 | mutex_lock(&ioc->sas_topology_mutex); | 1990 | mutex_lock(&ioc->sas_topology_mutex); |
1717 | ioc->handle = hba->handle; | 1991 | ioc->handle = hba->phy_info[0].handle; |
1718 | port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); | 1992 | port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); |
1719 | if (!port_info) { | 1993 | if (!port_info) { |
1720 | port_info = hba; | 1994 | port_info = hba; |
1721 | list_add_tail(&port_info->list, &ioc->sas_topology); | 1995 | list_add_tail(&port_info->list, &ioc->sas_topology); |
1722 | } else { | 1996 | } else { |
1723 | port_info->handle = hba->handle; | 1997 | for (i = 0; i < hba->num_phys; i++) { |
1724 | for (i = 0; i < hba->num_phys; i++) | ||
1725 | port_info->phy_info[i].negotiated_link_rate = | 1998 | port_info->phy_info[i].negotiated_link_rate = |
1726 | hba->phy_info[i].negotiated_link_rate; | 1999 | hba->phy_info[i].negotiated_link_rate; |
2000 | port_info->phy_info[i].handle = | ||
2001 | hba->phy_info[i].handle; | ||
2002 | port_info->phy_info[i].port_id = | ||
2003 | hba->phy_info[i].port_id; | ||
2004 | } | ||
1727 | kfree(hba->phy_info); | 2005 | kfree(hba->phy_info); |
1728 | kfree(hba); | 2006 | kfree(hba); |
1729 | hba = NULL; | 2007 | hba = NULL; |
1730 | } | 2008 | } |
1731 | mutex_unlock(&ioc->sas_topology_mutex); | 2009 | mutex_unlock(&ioc->sas_topology_mutex); |
1732 | |||
1733 | for (i = 0; i < port_info->num_phys; i++) { | 2010 | for (i = 0; i < port_info->num_phys; i++) { |
1734 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], | 2011 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], |
1735 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << | 2012 | (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << |
1736 | MPI_SAS_PHY_PGAD_FORM_SHIFT), i); | 2013 | MPI_SAS_PHY_PGAD_FORM_SHIFT), i); |
1737 | 2014 | ||
1738 | mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify, | 2015 | mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify, |
1739 | (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE << | 2016 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << |
1740 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle); | 2017 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), |
2018 | port_info->phy_info[i].handle); | ||
1741 | port_info->phy_info[i].identify.phy_id = | 2019 | port_info->phy_info[i].identify.phy_id = |
1742 | port_info->phy_info[i].phy_id; | 2020 | port_info->phy_info[i].phy_id = i; |
1743 | handle = port_info->phy_info[i].identify.handle; | ||
1744 | |||
1745 | if (port_info->phy_info[i].attached.handle) | 2021 | if (port_info->phy_info[i].attached.handle) |
1746 | mptsas_sas_device_pg0(ioc, | 2022 | mptsas_sas_device_pg0(ioc, |
1747 | &port_info->phy_info[i].attached, | 2023 | &port_info->phy_info[i].attached, |
@@ -1777,12 +2053,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1777 | goto out; | 2053 | goto out; |
1778 | 2054 | ||
1779 | error = mptsas_sas_expander_pg0(ioc, ex, | 2055 | error = mptsas_sas_expander_pg0(ioc, ex, |
1780 | (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << | 2056 | (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << |
1781 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); | 2057 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); |
1782 | if (error) | 2058 | if (error) |
1783 | goto out_free_port_info; | 2059 | goto out_free_port_info; |
1784 | 2060 | ||
1785 | *handle = ex->handle; | 2061 | *handle = ex->phy_info[0].handle; |
1786 | 2062 | ||
1787 | mutex_lock(&ioc->sas_topology_mutex); | 2063 | mutex_lock(&ioc->sas_topology_mutex); |
1788 | port_info = mptsas_find_portinfo_by_handle(ioc, *handle); | 2064 | port_info = mptsas_find_portinfo_by_handle(ioc, *handle); |
@@ -1790,7 +2066,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1790 | port_info = ex; | 2066 | port_info = ex; |
1791 | list_add_tail(&port_info->list, &ioc->sas_topology); | 2067 | list_add_tail(&port_info->list, &ioc->sas_topology); |
1792 | } else { | 2068 | } else { |
1793 | port_info->handle = ex->handle; | 2069 | for (i = 0; i < ex->num_phys; i++) { |
2070 | port_info->phy_info[i].handle = | ||
2071 | ex->phy_info[i].handle; | ||
2072 | port_info->phy_info[i].port_id = | ||
2073 | ex->phy_info[i].port_id; | ||
2074 | } | ||
1794 | kfree(ex->phy_info); | 2075 | kfree(ex->phy_info); |
1795 | kfree(ex); | 2076 | kfree(ex); |
1796 | ex = NULL; | 2077 | ex = NULL; |
@@ -1868,8 +2149,6 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1868 | struct mptsas_portinfo buffer; | 2149 | struct mptsas_portinfo buffer; |
1869 | struct mptsas_portinfo *port_info, *n, *parent; | 2150 | struct mptsas_portinfo *port_info, *n, *parent; |
1870 | struct mptsas_phyinfo *phy_info; | 2151 | struct mptsas_phyinfo *phy_info; |
1871 | struct scsi_target * starget; | ||
1872 | VirtTarget * vtarget; | ||
1873 | struct sas_port * port; | 2152 | struct sas_port * port; |
1874 | int i; | 2153 | int i; |
1875 | u64 expander_sas_address; | 2154 | u64 expander_sas_address; |
@@ -1884,26 +2163,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1884 | 2163 | ||
1885 | if (mptsas_sas_expander_pg0(ioc, &buffer, | 2164 | if (mptsas_sas_expander_pg0(ioc, &buffer, |
1886 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE << | 2165 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE << |
1887 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { | 2166 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), |
1888 | 2167 | port_info->phy_info[0].handle)) { | |
1889 | /* | ||
1890 | * Issue target reset to all child end devices | ||
1891 | * then mark them deleted to prevent further | ||
1892 | * IO going to them. | ||
1893 | */ | ||
1894 | phy_info = port_info->phy_info; | ||
1895 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | ||
1896 | starget = mptsas_get_starget(phy_info); | ||
1897 | if (!starget) | ||
1898 | continue; | ||
1899 | vtarget = starget->hostdata; | ||
1900 | if(vtarget->deleted) | ||
1901 | continue; | ||
1902 | vtarget->deleted = 1; | ||
1903 | mptsas_target_reset(ioc, vtarget); | ||
1904 | sas_port_delete(mptsas_get_port(phy_info)); | ||
1905 | mptsas_port_delete(phy_info->port_details); | ||
1906 | } | ||
1907 | 2168 | ||
1908 | /* | 2169 | /* |
1909 | * Obtain the port_info instance to the parent port | 2170 | * Obtain the port_info instance to the parent port |
@@ -1972,11 +2233,13 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
1972 | /* | 2233 | /* |
1973 | Reporting RAID volumes. | 2234 | Reporting RAID volumes. |
1974 | */ | 2235 | */ |
2236 | if (!ioc->ir_firmware) | ||
2237 | goto out; | ||
1975 | if (!ioc->raid_data.pIocPg2) | 2238 | if (!ioc->raid_data.pIocPg2) |
1976 | goto out; | 2239 | goto out; |
1977 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) | 2240 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) |
1978 | goto out; | 2241 | goto out; |
1979 | for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | 2242 | for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { |
1980 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, | 2243 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, |
1981 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); | 2244 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); |
1982 | } | 2245 | } |
@@ -2030,12 +2293,37 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) | |||
2030 | mutex_lock(&ioc->sas_topology_mutex); | 2293 | mutex_lock(&ioc->sas_topology_mutex); |
2031 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2294 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
2032 | for (i = 0; i < port_info->num_phys; i++) { | 2295 | for (i = 0; i < port_info->num_phys; i++) { |
2296 | if (!mptsas_is_end_device( | ||
2297 | &port_info->phy_info[i].attached)) | ||
2298 | continue; | ||
2033 | if (port_info->phy_info[i].attached.sas_address | 2299 | if (port_info->phy_info[i].attached.sas_address |
2034 | != sas_address) | 2300 | != sas_address) |
2035 | continue; | 2301 | continue; |
2302 | phy_info = &port_info->phy_info[i]; | ||
2303 | break; | ||
2304 | } | ||
2305 | } | ||
2306 | mutex_unlock(&ioc->sas_topology_mutex); | ||
2307 | return phy_info; | ||
2308 | } | ||
2309 | |||
2310 | static struct mptsas_phyinfo * | ||
2311 | mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
2312 | { | ||
2313 | struct mptsas_portinfo *port_info; | ||
2314 | struct mptsas_phyinfo *phy_info = NULL; | ||
2315 | int i; | ||
2316 | |||
2317 | mutex_lock(&ioc->sas_topology_mutex); | ||
2318 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | ||
2319 | for (i = 0; i < port_info->num_phys; i++) { | ||
2036 | if (!mptsas_is_end_device( | 2320 | if (!mptsas_is_end_device( |
2037 | &port_info->phy_info[i].attached)) | 2321 | &port_info->phy_info[i].attached)) |
2038 | continue; | 2322 | continue; |
2323 | if (port_info->phy_info[i].attached.id != id) | ||
2324 | continue; | ||
2325 | if (port_info->phy_info[i].attached.channel != channel) | ||
2326 | continue; | ||
2039 | phy_info = &port_info->phy_info[i]; | 2327 | phy_info = &port_info->phy_info[i]; |
2040 | break; | 2328 | break; |
2041 | } | 2329 | } |
@@ -2045,7 +2333,7 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) | |||
2045 | } | 2333 | } |
2046 | 2334 | ||
2047 | static struct mptsas_phyinfo * | 2335 | static struct mptsas_phyinfo * |
2048 | mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | 2336 | mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2049 | { | 2337 | { |
2050 | struct mptsas_portinfo *port_info; | 2338 | struct mptsas_portinfo *port_info; |
2051 | struct mptsas_phyinfo *phy_info = NULL; | 2339 | struct mptsas_phyinfo *phy_info = NULL; |
@@ -2054,11 +2342,15 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
2054 | mutex_lock(&ioc->sas_topology_mutex); | 2342 | mutex_lock(&ioc->sas_topology_mutex); |
2055 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2343 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
2056 | for (i = 0; i < port_info->num_phys; i++) { | 2344 | for (i = 0; i < port_info->num_phys; i++) { |
2057 | if (port_info->phy_info[i].attached.id != id) | ||
2058 | continue; | ||
2059 | if (!mptsas_is_end_device( | 2345 | if (!mptsas_is_end_device( |
2060 | &port_info->phy_info[i].attached)) | 2346 | &port_info->phy_info[i].attached)) |
2061 | continue; | 2347 | continue; |
2348 | if (port_info->phy_info[i].attached.phys_disk_num == ~0) | ||
2349 | continue; | ||
2350 | if (port_info->phy_info[i].attached.phys_disk_num != id) | ||
2351 | continue; | ||
2352 | if (port_info->phy_info[i].attached.channel != channel) | ||
2353 | continue; | ||
2062 | phy_info = &port_info->phy_info[i]; | 2354 | phy_info = &port_info->phy_info[i]; |
2063 | break; | 2355 | break; |
2064 | } | 2356 | } |
@@ -2094,6 +2386,76 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) | |||
2094 | mptsas_reprobe_lun); | 2386 | mptsas_reprobe_lun); |
2095 | } | 2387 | } |
2096 | 2388 | ||
2389 | static void | ||
2390 | mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
2391 | { | ||
2392 | CONFIGPARMS cfg; | ||
2393 | ConfigPageHeader_t hdr; | ||
2394 | dma_addr_t dma_handle; | ||
2395 | pRaidVolumePage0_t buffer = NULL; | ||
2396 | RaidPhysDiskPage0_t phys_disk; | ||
2397 | int i; | ||
2398 | struct mptsas_hotplug_event *ev; | ||
2399 | |||
2400 | memset(&cfg, 0 , sizeof(CONFIGPARMS)); | ||
2401 | memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); | ||
2402 | hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; | ||
2403 | cfg.pageAddr = (channel << 8) + id; | ||
2404 | cfg.cfghdr.hdr = &hdr; | ||
2405 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
2406 | |||
2407 | if (mpt_config(ioc, &cfg) != 0) | ||
2408 | goto out; | ||
2409 | |||
2410 | if (!hdr.PageLength) | ||
2411 | goto out; | ||
2412 | |||
2413 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, | ||
2414 | &dma_handle); | ||
2415 | |||
2416 | if (!buffer) | ||
2417 | goto out; | ||
2418 | |||
2419 | cfg.physAddr = dma_handle; | ||
2420 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
2421 | |||
2422 | if (mpt_config(ioc, &cfg) != 0) | ||
2423 | goto out; | ||
2424 | |||
2425 | if (!(buffer->VolumeStatus.Flags & | ||
2426 | MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE)) | ||
2427 | goto out; | ||
2428 | |||
2429 | if (!buffer->NumPhysDisks) | ||
2430 | goto out; | ||
2431 | |||
2432 | for (i = 0; i < buffer->NumPhysDisks; i++) { | ||
2433 | |||
2434 | if (mpt_raid_phys_disk_pg0(ioc, | ||
2435 | buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) | ||
2436 | continue; | ||
2437 | |||
2438 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | ||
2439 | if (!ev) { | ||
2440 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | ||
2441 | goto out; | ||
2442 | } | ||
2443 | |||
2444 | INIT_WORK(&ev->work, mptsas_hotplug_work); | ||
2445 | ev->ioc = ioc; | ||
2446 | ev->id = phys_disk.PhysDiskID; | ||
2447 | ev->channel = phys_disk.PhysDiskBus; | ||
2448 | ev->phys_disk_num_valid = 1; | ||
2449 | ev->phys_disk_num = phys_disk.PhysDiskNum; | ||
2450 | ev->event_type = MPTSAS_ADD_DEVICE; | ||
2451 | schedule_work(&ev->work); | ||
2452 | } | ||
2453 | |||
2454 | out: | ||
2455 | if (buffer) | ||
2456 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, | ||
2457 | dma_handle); | ||
2458 | } | ||
2097 | /* | 2459 | /* |
2098 | * Work queue thread to handle SAS hotplug events | 2460 | * Work queue thread to handle SAS hotplug events |
2099 | */ | 2461 | */ |
@@ -2102,6 +2464,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2102 | { | 2464 | { |
2103 | struct mptsas_hotplug_event *ev = | 2465 | struct mptsas_hotplug_event *ev = |
2104 | container_of(work, struct mptsas_hotplug_event, work); | 2466 | container_of(work, struct mptsas_hotplug_event, work); |
2467 | |||
2105 | MPT_ADAPTER *ioc = ev->ioc; | 2468 | MPT_ADAPTER *ioc = ev->ioc; |
2106 | struct mptsas_phyinfo *phy_info; | 2469 | struct mptsas_phyinfo *phy_info; |
2107 | struct sas_rphy *rphy; | 2470 | struct sas_rphy *rphy; |
@@ -2114,17 +2477,43 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2114 | VirtTarget *vtarget; | 2477 | VirtTarget *vtarget; |
2115 | VirtDevice *vdevice; | 2478 | VirtDevice *vdevice; |
2116 | 2479 | ||
2117 | |||
2118 | mutex_lock(&ioc->sas_discovery_mutex); | 2480 | mutex_lock(&ioc->sas_discovery_mutex); |
2119 | switch (ev->event_type) { | 2481 | switch (ev->event_type) { |
2120 | case MPTSAS_DEL_DEVICE: | 2482 | case MPTSAS_DEL_DEVICE: |
2121 | 2483 | ||
2122 | phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); | 2484 | phy_info = NULL; |
2485 | if (ev->phys_disk_num_valid) { | ||
2486 | if (ev->hidden_raid_component){ | ||
2487 | if (mptsas_sas_device_pg0(ioc, &sas_device, | ||
2488 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << | ||
2489 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | ||
2490 | (ev->channel << 8) + ev->id)) { | ||
2491 | dfailprintk((MYIOC_s_ERR_FMT | ||
2492 | "%s: exit at line=%d\n", ioc->name, | ||
2493 | __FUNCTION__, __LINE__)); | ||
2494 | break; | ||
2495 | } | ||
2496 | phy_info = mptsas_find_phyinfo_by_sas_address( | ||
2497 | ioc, sas_device.sas_address); | ||
2498 | }else | ||
2499 | phy_info = mptsas_find_phyinfo_by_phys_disk_num( | ||
2500 | ioc, ev->channel, ev->phys_disk_num); | ||
2501 | } | ||
2502 | |||
2503 | if (!phy_info) | ||
2504 | phy_info = mptsas_find_phyinfo_by_target(ioc, | ||
2505 | ev->channel, ev->id); | ||
2123 | 2506 | ||
2124 | /* | 2507 | /* |
2125 | * Sanity checks, for non-existing phys and remote rphys. | 2508 | * Sanity checks, for non-existing phys and remote rphys. |
2126 | */ | 2509 | */ |
2127 | if (!phy_info || !phy_info->port_details) { | 2510 | if (!phy_info){ |
2511 | dfailprintk((MYIOC_s_ERR_FMT | ||
2512 | "%s: exit at line=%d\n", ioc->name, | ||
2513 | __FUNCTION__, __LINE__)); | ||
2514 | break; | ||
2515 | } | ||
2516 | if (!phy_info->port_details) { | ||
2128 | dfailprintk((MYIOC_s_ERR_FMT | 2517 | dfailprintk((MYIOC_s_ERR_FMT |
2129 | "%s: exit at line=%d\n", ioc->name, | 2518 | "%s: exit at line=%d\n", ioc->name, |
2130 | __FUNCTION__, __LINE__)); | 2519 | __FUNCTION__, __LINE__)); |
@@ -2137,6 +2526,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2137 | __FUNCTION__, __LINE__)); | 2526 | __FUNCTION__, __LINE__)); |
2138 | break; | 2527 | break; |
2139 | } | 2528 | } |
2529 | |||
2140 | port = mptsas_get_port(phy_info); | 2530 | port = mptsas_get_port(phy_info); |
2141 | if (!port) { | 2531 | if (!port) { |
2142 | dfailprintk((MYIOC_s_ERR_FMT | 2532 | dfailprintk((MYIOC_s_ERR_FMT |
@@ -2159,28 +2549,35 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2159 | /* | 2549 | /* |
2160 | * Handling RAID components | 2550 | * Handling RAID components |
2161 | */ | 2551 | */ |
2162 | if (ev->phys_disk_num_valid) { | 2552 | if (ev->phys_disk_num_valid && |
2163 | vtarget->target_id = ev->phys_disk_num; | 2553 | ev->hidden_raid_component) { |
2164 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | 2554 | printk(MYIOC_s_INFO_FMT |
2555 | "RAID Hidding: channel=%d, id=%d, " | ||
2556 | "physdsk %d \n", ioc->name, ev->channel, | ||
2557 | ev->id, ev->phys_disk_num); | ||
2558 | vtarget->id = ev->phys_disk_num; | ||
2559 | vtarget->tflags |= | ||
2560 | MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
2165 | mptsas_reprobe_target(starget, 1); | 2561 | mptsas_reprobe_target(starget, 1); |
2166 | break; | 2562 | phy_info->attached.phys_disk_num = |
2563 | ev->phys_disk_num; | ||
2564 | break; | ||
2167 | } | 2565 | } |
2168 | |||
2169 | vtarget->deleted = 1; | ||
2170 | mptsas_target_reset(ioc, vtarget); | ||
2171 | } | 2566 | } |
2172 | 2567 | ||
2173 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | 2568 | if (phy_info->attached.device_info & |
2569 | MPI_SAS_DEVICE_INFO_SSP_TARGET) | ||
2174 | ds = "ssp"; | 2570 | ds = "ssp"; |
2175 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | 2571 | if (phy_info->attached.device_info & |
2572 | MPI_SAS_DEVICE_INFO_STP_TARGET) | ||
2176 | ds = "stp"; | 2573 | ds = "stp"; |
2177 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) | 2574 | if (phy_info->attached.device_info & |
2575 | MPI_SAS_DEVICE_INFO_SATA_DEVICE) | ||
2178 | ds = "sata"; | 2576 | ds = "sata"; |
2179 | 2577 | ||
2180 | printk(MYIOC_s_INFO_FMT | 2578 | printk(MYIOC_s_INFO_FMT |
2181 | "removing %s device, channel %d, id %d, phy %d\n", | 2579 | "removing %s device, channel %d, id %d, phy %d\n", |
2182 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); | 2580 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); |
2183 | |||
2184 | #ifdef MPT_DEBUG_SAS_WIDE | 2581 | #ifdef MPT_DEBUG_SAS_WIDE |
2185 | dev_printk(KERN_DEBUG, &port->dev, | 2582 | dev_printk(KERN_DEBUG, &port->dev, |
2186 | "delete port (%d)\n", port->port_identifier); | 2583 | "delete port (%d)\n", port->port_identifier); |
@@ -2198,14 +2595,14 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2198 | */ | 2595 | */ |
2199 | if (mptsas_sas_device_pg0(ioc, &sas_device, | 2596 | if (mptsas_sas_device_pg0(ioc, &sas_device, |
2200 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << | 2597 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << |
2201 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { | 2598 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), |
2599 | (ev->channel << 8) + ev->id)) { | ||
2202 | dfailprintk((MYIOC_s_ERR_FMT | 2600 | dfailprintk((MYIOC_s_ERR_FMT |
2203 | "%s: exit at line=%d\n", ioc->name, | 2601 | "%s: exit at line=%d\n", ioc->name, |
2204 | __FUNCTION__, __LINE__)); | 2602 | __FUNCTION__, __LINE__)); |
2205 | break; | 2603 | break; |
2206 | } | 2604 | } |
2207 | 2605 | ||
2208 | ssleep(2); | ||
2209 | __mptsas_discovery_work(ioc); | 2606 | __mptsas_discovery_work(ioc); |
2210 | 2607 | ||
2211 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, | 2608 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
@@ -2219,7 +2616,8 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2219 | } | 2616 | } |
2220 | 2617 | ||
2221 | starget = mptsas_get_starget(phy_info); | 2618 | starget = mptsas_get_starget(phy_info); |
2222 | if (starget) { | 2619 | if (starget && (!ev->hidden_raid_component)){ |
2620 | |||
2223 | vtarget = starget->hostdata; | 2621 | vtarget = starget->hostdata; |
2224 | 2622 | ||
2225 | if (!vtarget) { | 2623 | if (!vtarget) { |
@@ -2232,9 +2630,15 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2232 | * Handling RAID components | 2630 | * Handling RAID components |
2233 | */ | 2631 | */ |
2234 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2632 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2235 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; | 2633 | printk(MYIOC_s_INFO_FMT |
2236 | vtarget->target_id = ev->id; | 2634 | "RAID Exposing: channel=%d, id=%d, " |
2635 | "physdsk %d \n", ioc->name, ev->channel, | ||
2636 | ev->id, ev->phys_disk_num); | ||
2637 | vtarget->tflags &= | ||
2638 | ~MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
2639 | vtarget->id = ev->id; | ||
2237 | mptsas_reprobe_target(starget, 0); | 2640 | mptsas_reprobe_target(starget, 0); |
2641 | phy_info->attached.phys_disk_num = ~0; | ||
2238 | } | 2642 | } |
2239 | break; | 2643 | break; |
2240 | } | 2644 | } |
@@ -2243,8 +2647,10 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2243 | dfailprintk((MYIOC_s_ERR_FMT | 2647 | dfailprintk((MYIOC_s_ERR_FMT |
2244 | "%s: exit at line=%d\n", ioc->name, | 2648 | "%s: exit at line=%d\n", ioc->name, |
2245 | __FUNCTION__, __LINE__)); | 2649 | __FUNCTION__, __LINE__)); |
2650 | if (ev->channel) printk("%d\n", __LINE__); | ||
2246 | break; | 2651 | break; |
2247 | } | 2652 | } |
2653 | |||
2248 | port = mptsas_get_port(phy_info); | 2654 | port = mptsas_get_port(phy_info); |
2249 | if (!port) { | 2655 | if (!port) { |
2250 | dfailprintk((MYIOC_s_ERR_FMT | 2656 | dfailprintk((MYIOC_s_ERR_FMT |
@@ -2252,15 +2658,17 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2252 | __FUNCTION__, __LINE__)); | 2658 | __FUNCTION__, __LINE__)); |
2253 | break; | 2659 | break; |
2254 | } | 2660 | } |
2255 | |||
2256 | memcpy(&phy_info->attached, &sas_device, | 2661 | memcpy(&phy_info->attached, &sas_device, |
2257 | sizeof(struct mptsas_devinfo)); | 2662 | sizeof(struct mptsas_devinfo)); |
2258 | 2663 | ||
2259 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | 2664 | if (phy_info->attached.device_info & |
2665 | MPI_SAS_DEVICE_INFO_SSP_TARGET) | ||
2260 | ds = "ssp"; | 2666 | ds = "ssp"; |
2261 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | 2667 | if (phy_info->attached.device_info & |
2668 | MPI_SAS_DEVICE_INFO_STP_TARGET) | ||
2262 | ds = "stp"; | 2669 | ds = "stp"; |
2263 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) | 2670 | if (phy_info->attached.device_info & |
2671 | MPI_SAS_DEVICE_INFO_SATA_DEVICE) | ||
2264 | ds = "sata"; | 2672 | ds = "sata"; |
2265 | 2673 | ||
2266 | printk(MYIOC_s_INFO_FMT | 2674 | printk(MYIOC_s_INFO_FMT |
@@ -2301,19 +2709,21 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2301 | break; | 2709 | break; |
2302 | case MPTSAS_DEL_RAID: | 2710 | case MPTSAS_DEL_RAID: |
2303 | sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, | 2711 | sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, |
2304 | ev->id, 0); | 2712 | ev->id, 0); |
2305 | if (!sdev) | 2713 | if (!sdev) |
2306 | break; | 2714 | break; |
2307 | printk(MYIOC_s_INFO_FMT | 2715 | printk(MYIOC_s_INFO_FMT |
2308 | "removing raid volume, channel %d, id %d\n", | 2716 | "removing raid volume, channel %d, id %d\n", |
2309 | ioc->name, MPTSAS_RAID_CHANNEL, ev->id); | 2717 | ioc->name, MPTSAS_RAID_CHANNEL, ev->id); |
2310 | vdevice = sdev->hostdata; | 2718 | vdevice = sdev->hostdata; |
2311 | vdevice->vtarget->deleted = 1; | ||
2312 | mptsas_target_reset(ioc, vdevice->vtarget); | ||
2313 | scsi_remove_device(sdev); | 2719 | scsi_remove_device(sdev); |
2314 | scsi_device_put(sdev); | 2720 | scsi_device_put(sdev); |
2315 | mpt_findImVolumes(ioc); | 2721 | mpt_findImVolumes(ioc); |
2316 | break; | 2722 | break; |
2723 | case MPTSAS_ADD_INACTIVE_VOLUME: | ||
2724 | mptsas_adding_inactive_raid_components(ioc, | ||
2725 | ev->channel, ev->id); | ||
2726 | break; | ||
2317 | case MPTSAS_IGNORE_EVENT: | 2727 | case MPTSAS_IGNORE_EVENT: |
2318 | default: | 2728 | default: |
2319 | break; | 2729 | break; |
@@ -2321,7 +2731,6 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2321 | 2731 | ||
2322 | mutex_unlock(&ioc->sas_discovery_mutex); | 2732 | mutex_unlock(&ioc->sas_discovery_mutex); |
2323 | kfree(ev); | 2733 | kfree(ev); |
2324 | |||
2325 | } | 2734 | } |
2326 | 2735 | ||
2327 | static void | 2736 | static void |
@@ -2339,8 +2748,12 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, | |||
2339 | return; | 2748 | return; |
2340 | 2749 | ||
2341 | switch (sas_event_data->ReasonCode) { | 2750 | switch (sas_event_data->ReasonCode) { |
2342 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: | ||
2343 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: | 2751 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: |
2752 | |||
2753 | mptsas_target_reset_queue(ioc, sas_event_data); | ||
2754 | break; | ||
2755 | |||
2756 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: | ||
2344 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | 2757 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
2345 | if (!ev) { | 2758 | if (!ev) { |
2346 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | 2759 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); |
@@ -2375,15 +2788,20 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, | |||
2375 | mptsas_persist_clear_table); | 2788 | mptsas_persist_clear_table); |
2376 | schedule_work(&ioc->sas_persist_task); | 2789 | schedule_work(&ioc->sas_persist_task); |
2377 | break; | 2790 | break; |
2791 | /* | ||
2792 | * TODO, handle other events | ||
2793 | */ | ||
2378 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: | 2794 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: |
2379 | /* TODO */ | 2795 | case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: |
2380 | case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: | 2796 | case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: |
2381 | /* TODO */ | 2797 | case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: |
2798 | case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: | ||
2799 | case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: | ||
2800 | case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: | ||
2382 | default: | 2801 | default: |
2383 | break; | 2802 | break; |
2384 | } | 2803 | } |
2385 | } | 2804 | } |
2386 | |||
2387 | static void | 2805 | static void |
2388 | mptsas_send_raid_event(MPT_ADAPTER *ioc, | 2806 | mptsas_send_raid_event(MPT_ADAPTER *ioc, |
2389 | EVENT_DATA_RAID *raid_event_data) | 2807 | EVENT_DATA_RAID *raid_event_data) |
@@ -2404,31 +2822,36 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc, | |||
2404 | INIT_WORK(&ev->work, mptsas_hotplug_work); | 2822 | INIT_WORK(&ev->work, mptsas_hotplug_work); |
2405 | ev->ioc = ioc; | 2823 | ev->ioc = ioc; |
2406 | ev->id = raid_event_data->VolumeID; | 2824 | ev->id = raid_event_data->VolumeID; |
2825 | ev->channel = raid_event_data->VolumeBus; | ||
2407 | ev->event_type = MPTSAS_IGNORE_EVENT; | 2826 | ev->event_type = MPTSAS_IGNORE_EVENT; |
2408 | 2827 | ||
2409 | switch (raid_event_data->ReasonCode) { | 2828 | switch (raid_event_data->ReasonCode) { |
2410 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: | 2829 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: |
2830 | ev->phys_disk_num_valid = 1; | ||
2831 | ev->phys_disk_num = raid_event_data->PhysDiskNum; | ||
2411 | ev->event_type = MPTSAS_ADD_DEVICE; | 2832 | ev->event_type = MPTSAS_ADD_DEVICE; |
2412 | break; | 2833 | break; |
2413 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: | 2834 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: |
2414 | ioc->raid_data.isRaid = 1; | ||
2415 | ev->phys_disk_num_valid = 1; | 2835 | ev->phys_disk_num_valid = 1; |
2416 | ev->phys_disk_num = raid_event_data->PhysDiskNum; | 2836 | ev->phys_disk_num = raid_event_data->PhysDiskNum; |
2837 | ev->hidden_raid_component = 1; | ||
2417 | ev->event_type = MPTSAS_DEL_DEVICE; | 2838 | ev->event_type = MPTSAS_DEL_DEVICE; |
2418 | break; | 2839 | break; |
2419 | case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: | 2840 | case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: |
2420 | switch (state) { | 2841 | switch (state) { |
2421 | case MPI_PD_STATE_ONLINE: | 2842 | case MPI_PD_STATE_ONLINE: |
2422 | ioc->raid_data.isRaid = 1; | 2843 | case MPI_PD_STATE_NOT_COMPATIBLE: |
2423 | ev->phys_disk_num_valid = 1; | 2844 | ev->phys_disk_num_valid = 1; |
2424 | ev->phys_disk_num = raid_event_data->PhysDiskNum; | 2845 | ev->phys_disk_num = raid_event_data->PhysDiskNum; |
2846 | ev->hidden_raid_component = 1; | ||
2425 | ev->event_type = MPTSAS_ADD_DEVICE; | 2847 | ev->event_type = MPTSAS_ADD_DEVICE; |
2426 | break; | 2848 | break; |
2427 | case MPI_PD_STATE_MISSING: | 2849 | case MPI_PD_STATE_MISSING: |
2428 | case MPI_PD_STATE_NOT_COMPATIBLE: | ||
2429 | case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: | 2850 | case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: |
2430 | case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: | 2851 | case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: |
2431 | case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: | 2852 | case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: |
2853 | ev->phys_disk_num_valid = 1; | ||
2854 | ev->phys_disk_num = raid_event_data->PhysDiskNum; | ||
2432 | ev->event_type = MPTSAS_DEL_DEVICE; | 2855 | ev->event_type = MPTSAS_DEL_DEVICE; |
2433 | break; | 2856 | break; |
2434 | default: | 2857 | default: |
@@ -2485,6 +2908,35 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc, | |||
2485 | schedule_work(&ev->work); | 2908 | schedule_work(&ev->work); |
2486 | }; | 2909 | }; |
2487 | 2910 | ||
2911 | /* | ||
2912 | * mptsas_send_ir2_event - handle exposing hidden disk when | ||
2913 | * an inactive raid volume is added | ||
2914 | * | ||
2915 | * @ioc: Pointer to MPT_ADAPTER structure | ||
2916 | * @ir2_data | ||
2917 | * | ||
2918 | */ | ||
2919 | static void | ||
2920 | mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data) | ||
2921 | { | ||
2922 | struct mptsas_hotplug_event *ev; | ||
2923 | |||
2924 | if (ir2_data->ReasonCode != | ||
2925 | MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED) | ||
2926 | return; | ||
2927 | |||
2928 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | ||
2929 | if (!ev) | ||
2930 | return; | ||
2931 | |||
2932 | INIT_WORK(&ev->work, mptsas_hotplug_work); | ||
2933 | ev->ioc = ioc; | ||
2934 | ev->id = ir2_data->TargetID; | ||
2935 | ev->channel = ir2_data->Bus; | ||
2936 | ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME; | ||
2937 | |||
2938 | schedule_work(&ev->work); | ||
2939 | }; | ||
2488 | 2940 | ||
2489 | static int | 2941 | static int |
2490 | mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | 2942 | mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) |
@@ -2524,6 +2976,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
2524 | mptsas_send_discovery_event(ioc, | 2976 | mptsas_send_discovery_event(ioc, |
2525 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); | 2977 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); |
2526 | break; | 2978 | break; |
2979 | case MPI_EVENT_IR2: | ||
2980 | mptsas_send_ir2_event(ioc, | ||
2981 | (PTR_MPI_EVENT_DATA_IR2)reply->Data); | ||
2982 | break; | ||
2527 | default: | 2983 | default: |
2528 | rc = mptscsih_event_process(ioc, reply); | 2984 | rc = mptscsih_event_process(ioc, reply); |
2529 | break; | 2985 | break; |
@@ -2611,12 +3067,11 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2611 | /* set 16 byte cdb's */ | 3067 | /* set 16 byte cdb's */ |
2612 | sh->max_cmd_len = 16; | 3068 | sh->max_cmd_len = 16; |
2613 | 3069 | ||
2614 | sh->max_id = ioc->pfacts->MaxDevices + 1; | 3070 | sh->max_id = ioc->pfacts[0].PortSCSIID; |
3071 | sh->max_lun = max_lun; | ||
2615 | 3072 | ||
2616 | sh->transportt = mptsas_transport_template; | 3073 | sh->transportt = mptsas_transport_template; |
2617 | 3074 | ||
2618 | sh->max_lun = MPT_LAST_LUN + 1; | ||
2619 | sh->max_channel = 0; | ||
2620 | sh->this_id = ioc->pfacts[0].PortSCSIID; | 3075 | sh->this_id = ioc->pfacts[0].PortSCSIID; |
2621 | 3076 | ||
2622 | /* Required entry. | 3077 | /* Required entry. |
@@ -2659,8 +3114,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2659 | sh->sg_tablesize = numSGE; | 3114 | sh->sg_tablesize = numSGE; |
2660 | } | 3115 | } |
2661 | 3116 | ||
2662 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
2663 | |||
2664 | hd = (MPT_SCSI_HOST *) sh->hostdata; | 3117 | hd = (MPT_SCSI_HOST *) sh->hostdata; |
2665 | hd->ioc = ioc; | 3118 | hd->ioc = ioc; |
2666 | 3119 | ||
@@ -2676,19 +3129,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2676 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 3129 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
2677 | ioc->name, hd->ScsiLookup)); | 3130 | ioc->name, hd->ScsiLookup)); |
2678 | 3131 | ||
2679 | /* Allocate memory for the device structures. | ||
2680 | * A non-Null pointer at an offset | ||
2681 | * indicates a device exists. | ||
2682 | * max_id = 1 + maximum id (hosts.h) | ||
2683 | */ | ||
2684 | hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); | ||
2685 | if (!hd->Targets) { | ||
2686 | error = -ENOMEM; | ||
2687 | goto out_mptsas_probe; | ||
2688 | } | ||
2689 | |||
2690 | dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets)); | ||
2691 | |||
2692 | /* Clear the TM flags | 3132 | /* Clear the TM flags |
2693 | */ | 3133 | */ |
2694 | hd->tmPending = 0; | 3134 | hd->tmPending = 0; |
@@ -2713,15 +3153,17 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2713 | 3153 | ||
2714 | ioc->sas_data.ptClear = mpt_pt_clear; | 3154 | ioc->sas_data.ptClear = mpt_pt_clear; |
2715 | 3155 | ||
3156 | init_waitqueue_head(&hd->scandv_waitq); | ||
3157 | hd->scandv_wait_done = 0; | ||
3158 | hd->last_queue_full = 0; | ||
3159 | INIT_LIST_HEAD(&hd->target_reset_list); | ||
3160 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
3161 | |||
2716 | if (ioc->sas_data.ptClear==1) { | 3162 | if (ioc->sas_data.ptClear==1) { |
2717 | mptbase_sas_persist_operation( | 3163 | mptbase_sas_persist_operation( |
2718 | ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); | 3164 | ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); |
2719 | } | 3165 | } |
2720 | 3166 | ||
2721 | init_waitqueue_head(&hd->scandv_waitq); | ||
2722 | hd->scandv_wait_done = 0; | ||
2723 | hd->last_queue_full = 0; | ||
2724 | |||
2725 | error = scsi_add_host(sh, &ioc->pcidev->dev); | 3167 | error = scsi_add_host(sh, &ioc->pcidev->dev); |
2726 | if (error) { | 3168 | if (error) { |
2727 | dprintk((KERN_ERR MYNAM | 3169 | dprintk((KERN_ERR MYNAM |
@@ -2745,7 +3187,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2745 | struct mptsas_portinfo *p, *n; | 3187 | struct mptsas_portinfo *p, *n; |
2746 | int i; | 3188 | int i; |
2747 | 3189 | ||
2748 | ioc->sas_discovery_ignore_events=1; | 3190 | ioc->sas_discovery_ignore_events = 1; |
2749 | sas_remove_host(ioc->sh); | 3191 | sas_remove_host(ioc->sh); |
2750 | 3192 | ||
2751 | mutex_lock(&ioc->sas_topology_mutex); | 3193 | mutex_lock(&ioc->sas_topology_mutex); |
@@ -2800,7 +3242,7 @@ mptsas_init(void) | |||
2800 | return -ENODEV; | 3242 | return -ENODEV; |
2801 | 3243 | ||
2802 | mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER); | 3244 | mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER); |
2803 | mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER); | 3245 | mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER); |
2804 | mptsasInternalCtx = | 3246 | mptsasInternalCtx = |
2805 | mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); | 3247 | mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); |
2806 | mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); | 3248 | mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); |
@@ -2810,7 +3252,7 @@ mptsas_init(void) | |||
2810 | ": Registered for IOC event notifications\n")); | 3252 | ": Registered for IOC event notifications\n")); |
2811 | } | 3253 | } |
2812 | 3254 | ||
2813 | if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) { | 3255 | if (mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset) == 0) { |
2814 | dprintk((KERN_INFO MYNAM | 3256 | dprintk((KERN_INFO MYNAM |
2815 | ": Registered for IOC reset notifications\n")); | 3257 | ": Registered for IOC reset notifications\n")); |
2816 | } | 3258 | } |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index f0cca3ea93b2..c417ae0b5fe6 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
5 | * | 5 | * |
6 | * Copyright (c) 1999-2007 LSI Logic Corporation | 6 | * Copyright (c) 1999-2007 LSI Logic Corporation |
7 | * (mailto:mpt_linux_developer@lsil.com) | 7 | * (mailto:mpt_linux_developer@lsi.com) |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -79,43 +79,6 @@ MODULE_LICENSE("GPL"); | |||
79 | MODULE_VERSION(my_VERSION); | 79 | MODULE_VERSION(my_VERSION); |
80 | 80 | ||
81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
82 | |||
83 | typedef struct _BIG_SENSE_BUF { | ||
84 | u8 data[MPT_SENSE_BUFFER_ALLOC]; | ||
85 | } BIG_SENSE_BUF; | ||
86 | |||
87 | #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ | ||
88 | #define MPT_SCANDV_DID_RESET (0x00000001) | ||
89 | #define MPT_SCANDV_SENSE (0x00000002) | ||
90 | #define MPT_SCANDV_SOME_ERROR (0x00000004) | ||
91 | #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) | ||
92 | #define MPT_SCANDV_ISSUE_SENSE (0x00000010) | ||
93 | #define MPT_SCANDV_FALLBACK (0x00000020) | ||
94 | |||
95 | #define MPT_SCANDV_MAX_RETRIES (10) | ||
96 | |||
97 | #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ | ||
98 | #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ | ||
99 | #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ | ||
100 | #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ | ||
101 | #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ | ||
102 | #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ | ||
103 | #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ | ||
104 | |||
105 | typedef struct _internal_cmd { | ||
106 | char *data; /* data pointer */ | ||
107 | dma_addr_t data_dma; /* data dma address */ | ||
108 | int size; /* transfer size */ | ||
109 | u8 cmd; /* SCSI Op Code */ | ||
110 | u8 bus; /* bus number */ | ||
111 | u8 id; /* SCSI ID (virtual) */ | ||
112 | u8 lun; | ||
113 | u8 flags; /* Bit Field - See above */ | ||
114 | u8 physDiskNum; /* Phys disk number, -1 else */ | ||
115 | u8 rsvd2; | ||
116 | u8 rsvd; | ||
117 | } INTERNAL_CMD; | ||
118 | |||
119 | /* | 82 | /* |
120 | * Other private/forward protos... | 83 | * Other private/forward protos... |
121 | */ | 84 | */ |
@@ -131,14 +94,11 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); | |||
131 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); | 94 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); |
132 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); | 95 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); |
133 | 96 | ||
134 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 97 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
135 | 98 | ||
136 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 99 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
137 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 100 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
138 | 101 | ||
139 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
140 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
141 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | ||
142 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 102 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
143 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 103 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
144 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); | 104 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
@@ -517,16 +477,100 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, | |||
517 | 477 | ||
518 | SEPMsg = (SEPRequest_t *)mf; | 478 | SEPMsg = (SEPRequest_t *)mf; |
519 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | 479 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; |
520 | SEPMsg->Bus = vtarget->bus_id; | 480 | SEPMsg->Bus = vtarget->channel; |
521 | SEPMsg->TargetID = vtarget->target_id; | 481 | SEPMsg->TargetID = vtarget->id; |
522 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; | 482 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; |
523 | SEPMsg->SlotStatus = SlotStatus; | 483 | SEPMsg->SlotStatus = SlotStatus; |
524 | devtverboseprintk((MYIOC_s_WARN_FMT | 484 | devtverboseprintk((MYIOC_s_WARN_FMT |
525 | "Sending SEP cmd=%x id=%d bus=%d\n", | 485 | "Sending SEP cmd=%x channel=%d id=%d\n", |
526 | ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); | 486 | ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID)); |
527 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | 487 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); |
528 | } | 488 | } |
529 | 489 | ||
490 | #ifdef MPT_DEBUG_REPLY | ||
491 | /** | ||
492 | * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO | ||
493 | * @ioc: Pointer to MPT_ADAPTER structure | ||
494 | * @ioc_status: U32 IOCStatus word from IOC | ||
495 | * @scsi_status: U8 sam status from target | ||
496 | * @scsi_state: U8 scsi state | ||
497 | * @sc: original scsi cmnd pointer | ||
498 | * @mf: Pointer to MPT request frame | ||
499 | * | ||
500 | * Refer to lsi/mpi.h. | ||
501 | **/ | ||
502 | static void | ||
503 | mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status, | ||
504 | u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc) | ||
505 | { | ||
506 | char extend_desc[EVENT_DESCR_STR_SZ]; | ||
507 | char *desc = NULL; | ||
508 | |||
509 | switch (ioc_status) { | ||
510 | |||
511 | case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ | ||
512 | desc = "SCSI Invalid Bus"; | ||
513 | break; | ||
514 | |||
515 | case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ | ||
516 | desc = "SCSI Invalid TargetID"; | ||
517 | break; | ||
518 | |||
519 | case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ | ||
520 | /* | ||
521 | * Inquiry is issued for device scanning | ||
522 | */ | ||
523 | if (sc->cmnd[0] != 0x12) | ||
524 | desc = "SCSI Device Not There"; | ||
525 | break; | ||
526 | |||
527 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | ||
528 | desc = "SCSI Data Overrun"; | ||
529 | break; | ||
530 | |||
531 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ | ||
532 | desc = "SCSI I/O Data Error"; | ||
533 | break; | ||
534 | |||
535 | case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ | ||
536 | desc = "SCSI Protocol Error"; | ||
537 | break; | ||
538 | |||
539 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | ||
540 | desc = "SCSI Task Terminated"; | ||
541 | break; | ||
542 | |||
543 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | ||
544 | desc = "SCSI Residual Mismatch"; | ||
545 | break; | ||
546 | |||
547 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ | ||
548 | desc = "SCSI Task Management Failed"; | ||
549 | break; | ||
550 | |||
551 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | ||
552 | desc = "SCSI IOC Terminated"; | ||
553 | break; | ||
554 | |||
555 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ | ||
556 | desc = "SCSI Ext Terminated"; | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (!desc) | ||
561 | return; | ||
562 | |||
563 | snprintf(extend_desc, EVENT_DESCR_STR_SZ, | ||
564 | "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh", | ||
565 | sc->device->host->host_no, | ||
566 | sc->device->channel, sc->device->id, sc->device->lun, | ||
567 | sc->cmnd[0], scsi_status, scsi_state); | ||
568 | |||
569 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n", | ||
570 | ioc->name, ioc_status, desc, extend_desc); | ||
571 | } | ||
572 | #endif | ||
573 | |||
530 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 574 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
531 | /* | 575 | /* |
532 | * mptscsih_io_done - Main SCSI IO callback routine registered to | 576 | * mptscsih_io_done - Main SCSI IO callback routine registered to |
@@ -613,12 +657,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
613 | u32 xfer_cnt; | 657 | u32 xfer_cnt; |
614 | u16 status; | 658 | u16 status; |
615 | u8 scsi_state, scsi_status; | 659 | u8 scsi_state, scsi_status; |
660 | u32 log_info; | ||
616 | 661 | ||
617 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 662 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; |
618 | scsi_state = pScsiReply->SCSIState; | 663 | scsi_state = pScsiReply->SCSIState; |
619 | scsi_status = pScsiReply->SCSIStatus; | 664 | scsi_status = pScsiReply->SCSIStatus; |
620 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); | 665 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); |
621 | sc->resid = sc->request_bufflen - xfer_cnt; | 666 | sc->resid = sc->request_bufflen - xfer_cnt; |
667 | log_info = le32_to_cpu(pScsiReply->IOCLogInfo); | ||
622 | 668 | ||
623 | /* | 669 | /* |
624 | * if we get a data underrun indication, yet no data was | 670 | * if we get a data underrun indication, yet no data was |
@@ -633,13 +679,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
633 | status = MPI_IOCSTATUS_SUCCESS; | 679 | status = MPI_IOCSTATUS_SUCCESS; |
634 | } | 680 | } |
635 | 681 | ||
636 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" | ||
637 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" | ||
638 | "resid=%d bufflen=%d xfer_cnt=%d\n", | ||
639 | ioc->id, sc->device->id, sc->device->lun, | ||
640 | status, scsi_state, scsi_status, sc->resid, | ||
641 | sc->request_bufflen, xfer_cnt)); | ||
642 | |||
643 | if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) | 682 | if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) |
644 | mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); | 683 | mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); |
645 | 684 | ||
@@ -648,9 +687,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
648 | */ | 687 | */ |
649 | if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && | 688 | if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && |
650 | pScsiReply->ResponseInfo) { | 689 | pScsiReply->ResponseInfo) { |
651 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " | 690 | printk(KERN_NOTICE "[%d:%d:%d:%d] " |
652 | "FCP_ResponseInfo=%08xh\n", | 691 | "FCP_ResponseInfo=%08xh\n", |
653 | ioc->id, sc->device->id, sc->device->lun, | 692 | sc->device->host->host_no, sc->device->channel, |
693 | sc->device->id, sc->device->lun, | ||
654 | le32_to_cpu(pScsiReply->ResponseInfo)); | 694 | le32_to_cpu(pScsiReply->ResponseInfo)); |
655 | } | 695 | } |
656 | 696 | ||
@@ -695,9 +735,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
695 | if ( ioc->bus_type == SAS ) { | 735 | if ( ioc->bus_type == SAS ) { |
696 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); | 736 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); |
697 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { | 737 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { |
698 | u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); | 738 | if ((log_info & SAS_LOGINFO_MASK) |
699 | log_info &=SAS_LOGINFO_MASK; | 739 | == SAS_LOGINFO_NEXUS_LOSS) { |
700 | if (log_info == SAS_LOGINFO_NEXUS_LOSS) { | ||
701 | sc->result = (DID_BUS_BUSY << 16); | 740 | sc->result = (DID_BUS_BUSY << 16); |
702 | break; | 741 | break; |
703 | } | 742 | } |
@@ -735,7 +774,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
735 | else /* Sufficient data transfer occurred */ | 774 | else /* Sufficient data transfer occurred */ |
736 | sc->result = (DID_OK << 16) | scsi_status; | 775 | sc->result = (DID_OK << 16) | scsi_status; |
737 | dreplyprintk((KERN_NOTICE | 776 | dreplyprintk((KERN_NOTICE |
738 | "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); | 777 | "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n", |
778 | sc->result, sc->device->channel, sc->device->id)); | ||
739 | break; | 779 | break; |
740 | 780 | ||
741 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ | 781 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ |
@@ -848,7 +888,28 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
848 | 888 | ||
849 | } /* switch(status) */ | 889 | } /* switch(status) */ |
850 | 890 | ||
851 | dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result)); | 891 | #ifdef MPT_DEBUG_REPLY |
892 | if (sc->result) { | ||
893 | |||
894 | mptscsih_iocstatus_info_scsiio(ioc, status, | ||
895 | scsi_status, scsi_state, sc); | ||
896 | |||
897 | dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x " | ||
898 | "result=0x%08x\n\tiocstatus=0x%04X " | ||
899 | "scsi_state=0x%02X scsi_status=0x%02X " | ||
900 | "loginfo=0x%08X\n", __FUNCTION__, | ||
901 | sc->device->host->host_no, sc->device->channel, sc->device->id, | ||
902 | sc->device->lun, sc->cmnd[0], sc->result, status, | ||
903 | scsi_state, scsi_status, log_info)); | ||
904 | |||
905 | dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d " | ||
906 | "bufflen=%d xfer_cnt=%d\n", __FUNCTION__, | ||
907 | sc->device->host->host_no, sc->device->channel, sc->device->id, | ||
908 | sc->device->lun, sc->resid, sc->request_bufflen, | ||
909 | xfer_cnt)); | ||
910 | } | ||
911 | #endif | ||
912 | |||
852 | } /* end of address reply case */ | 913 | } /* end of address reply case */ |
853 | 914 | ||
854 | /* Unmap the DMA buffers, if any. */ | 915 | /* Unmap the DMA buffers, if any. */ |
@@ -955,9 +1016,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
955 | int ii; | 1016 | int ii; |
956 | int max = hd->ioc->req_depth; | 1017 | int max = hd->ioc->req_depth; |
957 | struct scsi_cmnd *sc; | 1018 | struct scsi_cmnd *sc; |
1019 | struct scsi_lun lun; | ||
958 | 1020 | ||
959 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", | 1021 | dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n", |
960 | vdevice->vtarget->target_id, vdevice->lun, max)); | 1022 | vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); |
961 | 1023 | ||
962 | for (ii=0; ii < max; ii++) { | 1024 | for (ii=0; ii < max; ii++) { |
963 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 1025 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
@@ -965,10 +1027,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
965 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); | 1027 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); |
966 | if (mf == NULL) | 1028 | if (mf == NULL) |
967 | continue; | 1029 | continue; |
968 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 1030 | int_to_scsilun(vdevice->lun, &lun); |
969 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 1031 | if ((mf->Bus != vdevice->vtarget->channel) || |
970 | if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) | 1032 | (mf->TargetID != vdevice->vtarget->id) || |
1033 | memcmp(lun.scsi_lun, mf->LUN, 8)) | ||
971 | continue; | 1034 | continue; |
1035 | dsprintk(( "search_running: found (sc=%p, mf = %p) " | ||
1036 | "channel %d id %d, lun %d \n", hd->ScsiLookup[ii], | ||
1037 | mf, mf->Bus, mf->TargetID, vdevice->lun)); | ||
972 | 1038 | ||
973 | /* Cleanup | 1039 | /* Cleanup |
974 | */ | 1040 | */ |
@@ -1065,12 +1131,6 @@ mptscsih_remove(struct pci_dev *pdev) | |||
1065 | hd->ScsiLookup = NULL; | 1131 | hd->ScsiLookup = NULL; |
1066 | } | 1132 | } |
1067 | 1133 | ||
1068 | /* | ||
1069 | * Free pointer array. | ||
1070 | */ | ||
1071 | kfree(hd->Targets); | ||
1072 | hd->Targets = NULL; | ||
1073 | |||
1074 | dprintk((MYIOC_s_INFO_FMT | 1134 | dprintk((MYIOC_s_INFO_FMT |
1075 | "Free'd ScsiLookup (%d) memory\n", | 1135 | "Free'd ScsiLookup (%d) memory\n", |
1076 | hd->ioc->name, sz1)); | 1136 | hd->ioc->name, sz1)); |
@@ -1317,14 +1377,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1317 | return SCSI_MLQUEUE_HOST_BUSY; | 1377 | return SCSI_MLQUEUE_HOST_BUSY; |
1318 | } | 1378 | } |
1319 | 1379 | ||
1320 | if ((hd->ioc->bus_type == SPI) && | ||
1321 | vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT && | ||
1322 | mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) { | ||
1323 | SCpnt->result = DID_NO_CONNECT << 16; | ||
1324 | done(SCpnt); | ||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | /* | 1380 | /* |
1329 | * Put together a MPT SCSI request... | 1381 | * Put together a MPT SCSI request... |
1330 | */ | 1382 | */ |
@@ -1368,8 +1420,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1368 | 1420 | ||
1369 | /* Use the above information to set up the message frame | 1421 | /* Use the above information to set up the message frame |
1370 | */ | 1422 | */ |
1371 | pScsiReq->TargetID = (u8) vdev->vtarget->target_id; | 1423 | pScsiReq->TargetID = (u8) vdev->vtarget->id; |
1372 | pScsiReq->Bus = vdev->vtarget->bus_id; | 1424 | pScsiReq->Bus = vdev->vtarget->channel; |
1373 | pScsiReq->ChainOffset = 0; | 1425 | pScsiReq->ChainOffset = 0; |
1374 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) | 1426 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) |
1375 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 1427 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
@@ -1379,14 +1431,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1379 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; | 1431 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; |
1380 | pScsiReq->Reserved = 0; | 1432 | pScsiReq->Reserved = 0; |
1381 | pScsiReq->MsgFlags = mpt_msg_flags(); | 1433 | pScsiReq->MsgFlags = mpt_msg_flags(); |
1382 | pScsiReq->LUN[0] = 0; | 1434 | int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN); |
1383 | pScsiReq->LUN[1] = lun; | ||
1384 | pScsiReq->LUN[2] = 0; | ||
1385 | pScsiReq->LUN[3] = 0; | ||
1386 | pScsiReq->LUN[4] = 0; | ||
1387 | pScsiReq->LUN[5] = 0; | ||
1388 | pScsiReq->LUN[6] = 0; | ||
1389 | pScsiReq->LUN[7] = 0; | ||
1390 | pScsiReq->Control = cpu_to_le32(scsictl); | 1435 | pScsiReq->Control = cpu_to_le32(scsictl); |
1391 | 1436 | ||
1392 | /* | 1437 | /* |
@@ -1491,14 +1536,14 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1491 | */ | 1536 | */ |
1492 | 1537 | ||
1493 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1538 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1494 | /* | 1539 | /** |
1495 | * mptscsih_TMHandler - Generic handler for SCSI Task Management. | 1540 | * mptscsih_TMHandler - Generic handler for SCSI Task Management. |
1496 | * Fall through to mpt_HardResetHandler if: not operational, too many | 1541 | * Fall through to mpt_HardResetHandler if: not operational, too many |
1497 | * failed TM requests or handshake failure. | 1542 | * failed TM requests or handshake failure. |
1498 | * | 1543 | * |
1499 | * @ioc: Pointer to MPT_ADAPTER structure | 1544 | * @ioc: Pointer to MPT_ADAPTER structure |
1500 | * @type: Task Management type | 1545 | * @type: Task Management type |
1501 | * @target: Logical Target ID for reset (if appropriate) | 1546 | * @id: Logical Target ID for reset (if appropriate) |
1502 | * @lun: Logical Unit for reset (if appropriate) | 1547 | * @lun: Logical Unit for reset (if appropriate) |
1503 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1548 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1504 | * | 1549 | * |
@@ -1507,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1507 | * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC | 1552 | * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC |
1508 | * will be active. | 1553 | * will be active. |
1509 | * | 1554 | * |
1510 | * Returns 0 for SUCCESS or -1 if FAILED. | 1555 | * Returns 0 for SUCCESS, or FAILED. |
1511 | */ | 1556 | **/ |
1512 | int | 1557 | int |
1513 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1558 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1514 | { | 1559 | { |
1515 | MPT_ADAPTER *ioc; | 1560 | MPT_ADAPTER *ioc; |
1516 | int rc = -1; | 1561 | int rc = -1; |
1517 | int doTask = 1; | ||
1518 | u32 ioc_raw_state; | 1562 | u32 ioc_raw_state; |
1519 | unsigned long flags; | 1563 | unsigned long flags; |
1520 | 1564 | ||
1521 | /* If FW is being reloaded currently, return success to | ||
1522 | * the calling function. | ||
1523 | */ | ||
1524 | if (hd == NULL) | ||
1525 | return 0; | ||
1526 | |||
1527 | ioc = hd->ioc; | 1565 | ioc = hd->ioc; |
1528 | if (ioc == NULL) { | ||
1529 | printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); | ||
1530 | return FAILED; | ||
1531 | } | ||
1532 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); | 1566 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); |
1533 | 1567 | ||
1534 | // SJR - CHECKME - Can we avoid this here? | 1568 | // SJR - CHECKME - Can we avoid this here? |
@@ -1541,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1541 | spin_unlock_irqrestore(&ioc->diagLock, flags); | 1575 | spin_unlock_irqrestore(&ioc->diagLock, flags); |
1542 | 1576 | ||
1543 | /* Wait a fixed amount of time for the TM pending flag to be cleared. | 1577 | /* Wait a fixed amount of time for the TM pending flag to be cleared. |
1544 | * If we time out and not bus reset, then we return a FAILED status to the caller. | 1578 | * If we time out and not bus reset, then we return a FAILED status |
1545 | * The call to mptscsih_tm_pending_wait() will set the pending flag if we are | 1579 | * to the caller. |
1580 | * The call to mptscsih_tm_pending_wait() will set the pending flag | ||
1581 | * if we are | ||
1546 | * successful. Otherwise, reload the FW. | 1582 | * successful. Otherwise, reload the FW. |
1547 | */ | 1583 | */ |
1548 | if (mptscsih_tm_pending_wait(hd) == FAILED) { | 1584 | if (mptscsih_tm_pending_wait(hd) == FAILED) { |
@@ -1552,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1552 | hd->ioc->name, hd->tmPending)); | 1588 | hd->ioc->name, hd->tmPending)); |
1553 | return FAILED; | 1589 | return FAILED; |
1554 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { | 1590 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { |
1555 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " | 1591 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target " |
1556 | "Timed out waiting for last TM (%d) to complete! \n", | 1592 | "reset: Timed out waiting for last TM (%d) " |
1557 | hd->ioc->name, hd->tmPending)); | 1593 | "to complete! \n", hd->ioc->name, |
1594 | hd->tmPending)); | ||
1558 | return FAILED; | 1595 | return FAILED; |
1559 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { | 1596 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { |
1560 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " | 1597 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " |
1561 | "Timed out waiting for last TM (%d) to complete! \n", | 1598 | "Timed out waiting for last TM (%d) to complete! \n", |
1562 | hd->ioc->name, hd->tmPending)); | 1599 | hd->ioc->name, hd->tmPending)); |
1563 | if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) | 1600 | return FAILED; |
1564 | return FAILED; | ||
1565 | |||
1566 | doTask = 0; | ||
1567 | } | 1601 | } |
1568 | } else { | 1602 | } else { |
1569 | spin_lock_irqsave(&hd->ioc->FreeQlock, flags); | 1603 | spin_lock_irqsave(&hd->ioc->FreeQlock, flags); |
@@ -1571,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1571 | spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); | 1605 | spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); |
1572 | } | 1606 | } |
1573 | 1607 | ||
1574 | /* Is operational? | ||
1575 | */ | ||
1576 | ioc_raw_state = mpt_GetIocState(hd->ioc, 0); | 1608 | ioc_raw_state = mpt_GetIocState(hd->ioc, 0); |
1577 | 1609 | ||
1578 | #ifdef MPT_DEBUG_RESET | ||
1579 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { | 1610 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { |
1580 | printk(MYIOC_s_WARN_FMT | 1611 | printk(MYIOC_s_WARN_FMT |
1581 | "TM Handler: IOC Not operational(0x%x)!\n", | 1612 | "TM Handler for type=%x: IOC Not operational (0x%x)!\n", |
1582 | hd->ioc->name, ioc_raw_state); | 1613 | ioc->name, type, ioc_raw_state); |
1583 | } | 1614 | printk(KERN_WARNING " Issuing HardReset!!\n"); |
1584 | #endif | 1615 | if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) |
1585 | 1616 | printk((KERN_WARNING "TMHandler: HardReset " | |
1586 | if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) | 1617 | "FAILED!!\n")); |
1587 | && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { | 1618 | return FAILED; |
1588 | |||
1589 | /* Isse the Task Mgmt request. | ||
1590 | */ | ||
1591 | if (hd->hard_resets < -1) | ||
1592 | hd->hard_resets++; | ||
1593 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout); | ||
1594 | if (rc) { | ||
1595 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); | ||
1596 | } else { | ||
1597 | dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); | ||
1598 | } | ||
1599 | } | 1619 | } |
1600 | 1620 | ||
1601 | /* Only fall through to the HRH if this is a bus reset | 1621 | if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { |
1602 | */ | 1622 | printk(MYIOC_s_WARN_FMT |
1603 | if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || | 1623 | "TM Handler for type=%x: ioc_state: " |
1604 | ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { | 1624 | "DOORBELL_ACTIVE (0x%x)!\n", |
1605 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", | 1625 | ioc->name, type, ioc_raw_state); |
1606 | hd->ioc->name)); | 1626 | return FAILED; |
1607 | rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); | ||
1608 | } | 1627 | } |
1609 | 1628 | ||
1610 | /* | 1629 | /* Isse the Task Mgmt request. |
1611 | * Check IOCStatus from TM reply message | ||
1612 | */ | 1630 | */ |
1613 | if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) | 1631 | if (hd->hard_resets < -1) |
1614 | rc = FAILED; | 1632 | hd->hard_resets++; |
1633 | |||
1634 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, | ||
1635 | ctx2abort, timeout); | ||
1636 | if (rc) | ||
1637 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", | ||
1638 | hd->ioc->name); | ||
1639 | else | ||
1640 | dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", | ||
1641 | hd->ioc->name)); | ||
1615 | 1642 | ||
1616 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); | 1643 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); |
1617 | 1644 | ||
@@ -1620,11 +1647,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1620 | 1647 | ||
1621 | 1648 | ||
1622 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1649 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1623 | /* | 1650 | /** |
1624 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. | 1651 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. |
1625 | * @hd: Pointer to MPT_SCSI_HOST structure | 1652 | * @hd: Pointer to MPT_SCSI_HOST structure |
1626 | * @type: Task Management type | 1653 | * @type: Task Management type |
1627 | * @target: Logical Target ID for reset (if appropriate) | 1654 | * @id: Logical Target ID for reset (if appropriate) |
1628 | * @lun: Logical Unit for reset (if appropriate) | 1655 | * @lun: Logical Unit for reset (if appropriate) |
1629 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1656 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1630 | * | 1657 | * |
@@ -1633,11 +1660,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1633 | * | 1660 | * |
1634 | * Not all fields are meaningfull for all task types. | 1661 | * Not all fields are meaningfull for all task types. |
1635 | * | 1662 | * |
1636 | * Returns 0 for SUCCESS, -999 for "no msg frames", | 1663 | * Returns 0 for SUCCESS, or FAILED. |
1637 | * else other non-zero value returned. | 1664 | * |
1638 | */ | 1665 | **/ |
1639 | static int | 1666 | static int |
1640 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1667 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1641 | { | 1668 | { |
1642 | MPT_FRAME_HDR *mf; | 1669 | MPT_FRAME_HDR *mf; |
1643 | SCSITaskMgmt_t *pScsiTm; | 1670 | SCSITaskMgmt_t *pScsiTm; |
@@ -1657,7 +1684,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1657 | /* Format the Request | 1684 | /* Format the Request |
1658 | */ | 1685 | */ |
1659 | pScsiTm = (SCSITaskMgmt_t *) mf; | 1686 | pScsiTm = (SCSITaskMgmt_t *) mf; |
1660 | pScsiTm->TargetID = target; | 1687 | pScsiTm->TargetID = id; |
1661 | pScsiTm->Bus = channel; | 1688 | pScsiTm->Bus = channel; |
1662 | pScsiTm->ChainOffset = 0; | 1689 | pScsiTm->ChainOffset = 0; |
1663 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 1690 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
@@ -1668,42 +1695,59 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1668 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) | 1695 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) |
1669 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; | 1696 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; |
1670 | 1697 | ||
1671 | for (ii= 0; ii < 8; ii++) { | 1698 | int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN); |
1672 | pScsiTm->LUN[ii] = 0; | ||
1673 | } | ||
1674 | pScsiTm->LUN[1] = lun; | ||
1675 | 1699 | ||
1676 | for (ii=0; ii < 7; ii++) | 1700 | for (ii=0; ii < 7; ii++) |
1677 | pScsiTm->Reserved2[ii] = 0; | 1701 | pScsiTm->Reserved2[ii] = 0; |
1678 | 1702 | ||
1679 | pScsiTm->TaskMsgContext = ctx2abort; | 1703 | pScsiTm->TaskMsgContext = ctx2abort; |
1680 | 1704 | ||
1681 | dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", | 1705 | dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " |
1682 | hd->ioc->name, ctx2abort, type)); | 1706 | "type=%d\n", hd->ioc->name, ctx2abort, type)); |
1683 | 1707 | ||
1684 | DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); | 1708 | DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); |
1685 | 1709 | ||
1686 | if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, | 1710 | if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, |
1687 | sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, | 1711 | sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { |
1688 | CAN_SLEEP)) != 0) { | 1712 | dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!" |
1689 | dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" | 1713 | " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd, |
1690 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, | 1714 | hd->ioc, mf, retval)); |
1691 | hd->ioc, mf)); | 1715 | goto fail_out; |
1692 | mpt_free_msg_frame(hd->ioc, mf); | ||
1693 | return retval; | ||
1694 | } | 1716 | } |
1695 | 1717 | ||
1696 | if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { | 1718 | if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { |
1697 | dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" | 1719 | dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!" |
1698 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, | 1720 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, |
1699 | hd->ioc, mf)); | 1721 | hd->ioc, mf)); |
1700 | mpt_free_msg_frame(hd->ioc, mf); | ||
1701 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", | 1722 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", |
1702 | hd->ioc->name)); | 1723 | hd->ioc->name)); |
1703 | retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); | 1724 | retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); |
1725 | dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n", | ||
1726 | hd->ioc->name, retval)); | ||
1727 | goto fail_out; | ||
1704 | } | 1728 | } |
1705 | 1729 | ||
1730 | /* | ||
1731 | * Handle success case, see if theres a non-zero ioc_status. | ||
1732 | */ | ||
1733 | if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS || | ||
1734 | hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED || | ||
1735 | hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED) | ||
1736 | retval = 0; | ||
1737 | else | ||
1738 | retval = FAILED; | ||
1739 | |||
1706 | return retval; | 1740 | return retval; |
1741 | |||
1742 | fail_out: | ||
1743 | |||
1744 | /* | ||
1745 | * Free task managment mf, and corresponding tm flags | ||
1746 | */ | ||
1747 | mpt_free_msg_frame(hd->ioc, mf); | ||
1748 | hd->tmPending = 0; | ||
1749 | hd->tmState = TM_STATE_NONE; | ||
1750 | return FAILED; | ||
1707 | } | 1751 | } |
1708 | 1752 | ||
1709 | static int | 1753 | static int |
@@ -1728,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) | |||
1728 | * (linux scsi_host_template.eh_abort_handler routine) | 1772 | * (linux scsi_host_template.eh_abort_handler routine) |
1729 | * | 1773 | * |
1730 | * Returns SUCCESS or FAILED. | 1774 | * Returns SUCCESS or FAILED. |
1731 | */ | 1775 | **/ |
1732 | int | 1776 | int |
1733 | mptscsih_abort(struct scsi_cmnd * SCpnt) | 1777 | mptscsih_abort(struct scsi_cmnd * SCpnt) |
1734 | { | 1778 | { |
@@ -1764,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1764 | return SUCCESS; | 1808 | return SUCCESS; |
1765 | } | 1809 | } |
1766 | 1810 | ||
1767 | if (hd->resetPending) { | 1811 | if (hd->resetPending) |
1768 | return FAILED; | 1812 | return FAILED; |
1769 | } | ||
1770 | 1813 | ||
1771 | if (hd->timeouts < -1) | 1814 | if (hd->timeouts < -1) |
1772 | hd->timeouts++; | 1815 | hd->timeouts++; |
@@ -1789,13 +1832,12 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1789 | 1832 | ||
1790 | vdev = SCpnt->device->hostdata; | 1833 | vdev = SCpnt->device->hostdata; |
1791 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1834 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
1792 | vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, | 1835 | vdev->vtarget->channel, vdev->vtarget->id, vdev->lun, |
1793 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); | 1836 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); |
1794 | 1837 | ||
1795 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && | 1838 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && |
1796 | SCpnt->serial_number == sn) { | 1839 | SCpnt->serial_number == sn) |
1797 | retval = FAILED; | 1840 | retval = FAILED; |
1798 | } | ||
1799 | 1841 | ||
1800 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1842 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
1801 | hd->ioc->name, | 1843 | hd->ioc->name, |
@@ -1803,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1803 | 1845 | ||
1804 | if (retval == 0) | 1846 | if (retval == 0) |
1805 | return SUCCESS; | 1847 | return SUCCESS; |
1806 | 1848 | else | |
1807 | if(retval != FAILED ) { | 1849 | return FAILED; |
1808 | hd->tmPending = 0; | ||
1809 | hd->tmState = TM_STATE_NONE; | ||
1810 | } | ||
1811 | return FAILED; | ||
1812 | } | 1850 | } |
1813 | 1851 | ||
1814 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1852 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -1819,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1819 | * (linux scsi_host_template.eh_dev_reset_handler routine) | 1857 | * (linux scsi_host_template.eh_dev_reset_handler routine) |
1820 | * | 1858 | * |
1821 | * Returns SUCCESS or FAILED. | 1859 | * Returns SUCCESS or FAILED. |
1822 | */ | 1860 | **/ |
1823 | int | 1861 | int |
1824 | mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | 1862 | mptscsih_dev_reset(struct scsi_cmnd * SCpnt) |
1825 | { | 1863 | { |
@@ -1845,7 +1883,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1845 | 1883 | ||
1846 | vdev = SCpnt->device->hostdata; | 1884 | vdev = SCpnt->device->hostdata; |
1847 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1885 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
1848 | vdev->vtarget->bus_id, vdev->vtarget->target_id, | 1886 | vdev->vtarget->channel, vdev->vtarget->id, |
1849 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1887 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1850 | 1888 | ||
1851 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1889 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
@@ -1854,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1854 | 1892 | ||
1855 | if (retval == 0) | 1893 | if (retval == 0) |
1856 | return SUCCESS; | 1894 | return SUCCESS; |
1857 | 1895 | else | |
1858 | if(retval != FAILED ) { | 1896 | return FAILED; |
1859 | hd->tmPending = 0; | ||
1860 | hd->tmState = TM_STATE_NONE; | ||
1861 | } | ||
1862 | return FAILED; | ||
1863 | } | 1897 | } |
1864 | 1898 | ||
1899 | |||
1865 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1900 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1866 | /** | 1901 | /** |
1867 | * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant | 1902 | * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant |
@@ -1870,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1870 | * (linux scsi_host_template.eh_bus_reset_handler routine) | 1905 | * (linux scsi_host_template.eh_bus_reset_handler routine) |
1871 | * | 1906 | * |
1872 | * Returns SUCCESS or FAILED. | 1907 | * Returns SUCCESS or FAILED. |
1873 | */ | 1908 | **/ |
1874 | int | 1909 | int |
1875 | mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | 1910 | mptscsih_bus_reset(struct scsi_cmnd * SCpnt) |
1876 | { | 1911 | { |
@@ -1896,7 +1931,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1896 | 1931 | ||
1897 | vdev = SCpnt->device->hostdata; | 1932 | vdev = SCpnt->device->hostdata; |
1898 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1933 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
1899 | vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1934 | vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1900 | 1935 | ||
1901 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1936 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
1902 | hd->ioc->name, | 1937 | hd->ioc->name, |
@@ -1904,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1904 | 1939 | ||
1905 | if (retval == 0) | 1940 | if (retval == 0) |
1906 | return SUCCESS; | 1941 | return SUCCESS; |
1907 | 1942 | else | |
1908 | if(retval != FAILED ) { | 1943 | return FAILED; |
1909 | hd->tmPending = 0; | ||
1910 | hd->tmState = TM_STATE_NONE; | ||
1911 | } | ||
1912 | return FAILED; | ||
1913 | } | 1944 | } |
1914 | 1945 | ||
1915 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1946 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -1992,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) | |||
1992 | /** | 2023 | /** |
1993 | * mptscsih_tm_wait_for_completion - wait for completion of TM task | 2024 | * mptscsih_tm_wait_for_completion - wait for completion of TM task |
1994 | * @hd: Pointer to MPT host structure. | 2025 | * @hd: Pointer to MPT host structure. |
1995 | * @timeout: timeout in seconds | ||
1996 | * | 2026 | * |
1997 | * Returns {SUCCESS,FAILED}. | 2027 | * Returns {SUCCESS,FAILED}. |
1998 | */ | 2028 | */ |
@@ -2066,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code) | |||
2066 | * load/init time via the mpt_register() API call. | 2096 | * load/init time via the mpt_register() API call. |
2067 | * | 2097 | * |
2068 | * Returns 1 indicating alloc'd request frame ptr should be freed. | 2098 | * Returns 1 indicating alloc'd request frame ptr should be freed. |
2069 | */ | 2099 | **/ |
2070 | int | 2100 | int |
2071 | mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | 2101 | mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) |
2072 | { | 2102 | { |
@@ -2076,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m | |||
2076 | unsigned long flags; | 2106 | unsigned long flags; |
2077 | u16 iocstatus; | 2107 | u16 iocstatus; |
2078 | u8 tmType; | 2108 | u8 tmType; |
2109 | u32 termination_count; | ||
2079 | 2110 | ||
2080 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", | 2111 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", |
2081 | ioc->name, mf, mr)); | 2112 | ioc->name, mf, mr)); |
2082 | if (ioc->sh) { | 2113 | if (!ioc->sh) { |
2083 | /* Depending on the thread, a timer is activated for | 2114 | dtmprintk((MYIOC_s_WARN_FMT |
2084 | * the TM request. Delete this timer on completion of TM. | 2115 | "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name)); |
2085 | * Decrement count of outstanding TM requests. | ||
2086 | */ | ||
2087 | hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
2088 | } else { | ||
2089 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", | ||
2090 | ioc->name)); | ||
2091 | return 1; | 2116 | return 1; |
2092 | } | 2117 | } |
2093 | 2118 | ||
2094 | if (mr == NULL) { | 2119 | if (mr == NULL) { |
2095 | dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", | 2120 | dtmprintk((MYIOC_s_WARN_FMT |
2096 | ioc->name, mf)); | 2121 | "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf)); |
2097 | return 1; | 2122 | return 1; |
2098 | } else { | 2123 | } |
2099 | pScsiTmReply = (SCSITaskMgmtReply_t*)mr; | ||
2100 | pScsiTmReq = (SCSITaskMgmt_t*)mf; | ||
2101 | |||
2102 | /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ | ||
2103 | tmType = pScsiTmReq->TaskType; | ||
2104 | 2124 | ||
2105 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && | 2125 | hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; |
2106 | pScsiTmReply->ResponseCode) | 2126 | pScsiTmReply = (SCSITaskMgmtReply_t*)mr; |
2107 | mptscsih_taskmgmt_response_code(ioc, | 2127 | pScsiTmReq = (SCSITaskMgmt_t*)mf; |
2108 | pScsiTmReply->ResponseCode); | 2128 | tmType = pScsiTmReq->TaskType; |
2129 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; | ||
2130 | termination_count = le32_to_cpu(pScsiTmReply->TerminationCount); | ||
2131 | |||
2132 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && | ||
2133 | pScsiTmReply->ResponseCode) | ||
2134 | mptscsih_taskmgmt_response_code(ioc, | ||
2135 | pScsiTmReply->ResponseCode); | ||
2136 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | ||
2137 | |||
2138 | #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM) | ||
2139 | printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " | ||
2140 | "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " | ||
2141 | "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, | ||
2142 | pScsiTmReply->TargetID, pScsiTmReq->TaskType, | ||
2143 | le16_to_cpu(pScsiTmReply->IOCStatus), | ||
2144 | le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, | ||
2145 | le32_to_cpu(pScsiTmReply->TerminationCount)); | ||
2146 | #endif | ||
2147 | if (!iocstatus) { | ||
2148 | dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); | ||
2149 | hd->abortSCpnt = NULL; | ||
2150 | goto out; | ||
2151 | } | ||
2109 | 2152 | ||
2110 | dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", | 2153 | /* Error? (anything non-zero?) */ |
2111 | ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); | ||
2112 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | ||
2113 | 2154 | ||
2114 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 2155 | /* clear flags and continue. |
2115 | hd->tm_iocstatus = iocstatus; | 2156 | */ |
2116 | dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", | 2157 | switch (tmType) { |
2117 | ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); | ||
2118 | /* Error? (anything non-zero?) */ | ||
2119 | if (iocstatus) { | ||
2120 | 2158 | ||
2121 | /* clear flags and continue. | 2159 | case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK: |
2122 | */ | 2160 | if (termination_count == 1) |
2123 | if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) | 2161 | iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED; |
2124 | hd->abortSCpnt = NULL; | 2162 | hd->abortSCpnt = NULL; |
2163 | break; | ||
2125 | 2164 | ||
2126 | /* If an internal command is present | 2165 | case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS: |
2127 | * or the TM failed - reload the FW. | ||
2128 | * FC FW may respond FAILED to an ABORT | ||
2129 | */ | ||
2130 | if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { | ||
2131 | if ((hd->cmdPtr) || | ||
2132 | (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) { | ||
2133 | if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { | ||
2134 | printk((KERN_WARNING | ||
2135 | " Firmware Reload FAILED!!\n")); | ||
2136 | } | ||
2137 | } | ||
2138 | } | ||
2139 | } else { | ||
2140 | dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); | ||
2141 | 2166 | ||
2142 | hd->abortSCpnt = NULL; | 2167 | /* If an internal command is present |
2168 | * or the TM failed - reload the FW. | ||
2169 | * FC FW may respond FAILED to an ABORT | ||
2170 | */ | ||
2171 | if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED || | ||
2172 | hd->cmdPtr) | ||
2173 | if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) | ||
2174 | printk((KERN_WARNING " Firmware Reload FAILED!!\n")); | ||
2175 | break; | ||
2143 | 2176 | ||
2144 | } | 2177 | case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET: |
2178 | default: | ||
2179 | break; | ||
2145 | } | 2180 | } |
2146 | 2181 | ||
2182 | out: | ||
2147 | spin_lock_irqsave(&ioc->FreeQlock, flags); | 2183 | spin_lock_irqsave(&ioc->FreeQlock, flags); |
2148 | hd->tmPending = 0; | 2184 | hd->tmPending = 0; |
2149 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
2150 | hd->tmState = TM_STATE_NONE; | 2185 | hd->tmState = TM_STATE_NONE; |
2186 | hd->tm_iocstatus = iocstatus; | ||
2187 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
2151 | 2188 | ||
2152 | return 1; | 2189 | return 1; |
2153 | } | 2190 | } |
@@ -2191,7 +2228,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2191 | 2228 | ||
2192 | dprintk((KERN_NOTICE | 2229 | dprintk((KERN_NOTICE |
2193 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", | 2230 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", |
2194 | sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors)); | 2231 | sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors)); |
2195 | 2232 | ||
2196 | return 0; | 2233 | return 0; |
2197 | } | 2234 | } |
@@ -2200,115 +2237,78 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2200 | * | 2237 | * |
2201 | */ | 2238 | */ |
2202 | int | 2239 | int |
2203 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | 2240 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2204 | { | 2241 | { |
2242 | struct inactive_raid_component_info *component_info; | ||
2205 | int i; | 2243 | int i; |
2244 | int rc = 0; | ||
2206 | 2245 | ||
2207 | if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) | 2246 | if (!ioc->raid_data.pIocPg3) |
2208 | return 0; | 2247 | goto out; |
2209 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | 2248 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2210 | if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | 2249 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2211 | return 1; | 2250 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2212 | } | 2251 | rc = 1; |
2213 | return 0; | 2252 | goto out; |
2214 | } | 2253 | } |
2215 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2216 | |||
2217 | int | ||
2218 | mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid) | ||
2219 | { | ||
2220 | int i; | ||
2221 | |||
2222 | if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3) | ||
2223 | return -ENXIO; | ||
2224 | |||
2225 | for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | ||
2226 | if (physdiskid == | ||
2227 | hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | ||
2228 | return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; | ||
2229 | } | 2254 | } |
2230 | 2255 | ||
2231 | return -ENXIO; | 2256 | /* |
2232 | } | 2257 | * Check inactive list for matching phys disks |
2233 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | 2258 | */ |
2259 | if (list_empty(&ioc->raid_data.inactive_list)) | ||
2260 | goto out; | ||
2234 | 2261 | ||
2235 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2262 | down(&ioc->raid_data.inactive_list_mutex); |
2236 | /* | 2263 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, |
2237 | * OS entry point to allow host driver to alloc memory | 2264 | list) { |
2238 | * for each scsi target. Called once per device the bus scan. | 2265 | if ((component_info->d.PhysDiskID == id) && |
2239 | * Return non-zero if allocation fails. | 2266 | (component_info->d.PhysDiskBus == channel)) |
2240 | */ | 2267 | rc = 1; |
2241 | int | 2268 | } |
2242 | mptscsih_target_alloc(struct scsi_target *starget) | 2269 | up(&ioc->raid_data.inactive_list_mutex); |
2243 | { | ||
2244 | VirtTarget *vtarget; | ||
2245 | 2270 | ||
2246 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | 2271 | out: |
2247 | if (!vtarget) | 2272 | return rc; |
2248 | return -ENOMEM; | ||
2249 | starget->hostdata = vtarget; | ||
2250 | vtarget->starget = starget; | ||
2251 | return 0; | ||
2252 | } | 2273 | } |
2274 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2253 | 2275 | ||
2254 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2276 | u8 |
2255 | /* | 2277 | mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2256 | * OS entry point to allow host driver to alloc memory | ||
2257 | * for each scsi device. Called once per device the bus scan. | ||
2258 | * Return non-zero if allocation fails. | ||
2259 | */ | ||
2260 | int | ||
2261 | mptscsih_slave_alloc(struct scsi_device *sdev) | ||
2262 | { | 2278 | { |
2263 | struct Scsi_Host *host = sdev->host; | 2279 | struct inactive_raid_component_info *component_info; |
2264 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2280 | int i; |
2265 | VirtTarget *vtarget; | 2281 | int rc = -ENXIO; |
2266 | VirtDevice *vdev; | ||
2267 | struct scsi_target *starget; | ||
2268 | 2282 | ||
2269 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | 2283 | if (!ioc->raid_data.pIocPg3) |
2270 | if (!vdev) { | 2284 | goto out; |
2271 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 2285 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2272 | hd->ioc->name, sizeof(VirtDevice)); | 2286 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2273 | return -ENOMEM; | 2287 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2288 | rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; | ||
2289 | goto out; | ||
2290 | } | ||
2274 | } | 2291 | } |
2275 | 2292 | ||
2276 | vdev->lun = sdev->lun; | 2293 | /* |
2277 | sdev->hostdata = vdev; | 2294 | * Check inactive list for matching phys disks |
2278 | 2295 | */ | |
2279 | starget = scsi_target(sdev); | 2296 | if (list_empty(&ioc->raid_data.inactive_list)) |
2280 | vtarget = starget->hostdata; | 2297 | goto out; |
2281 | 2298 | ||
2282 | vdev->vtarget = vtarget; | 2299 | down(&ioc->raid_data.inactive_list_mutex); |
2283 | 2300 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, | |
2284 | if (vtarget->num_luns == 0) { | 2301 | list) { |
2285 | hd->Targets[sdev->id] = vtarget; | 2302 | if ((component_info->d.PhysDiskID == id) && |
2286 | vtarget->ioc_id = hd->ioc->id; | 2303 | (component_info->d.PhysDiskBus == channel)) |
2287 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | 2304 | rc = component_info->d.PhysDiskNum; |
2288 | vtarget->target_id = sdev->id; | ||
2289 | vtarget->bus_id = sdev->channel; | ||
2290 | if (hd->ioc->bus_type == SPI && sdev->channel == 0 && | ||
2291 | hd->ioc->raid_data.isRaid & (1 << sdev->id)) { | ||
2292 | vtarget->raidVolume = 1; | ||
2293 | ddvtprintk((KERN_INFO | ||
2294 | "RAID Volume @ id %d\n", sdev->id)); | ||
2295 | } | ||
2296 | } | 2305 | } |
2297 | vtarget->num_luns++; | 2306 | up(&ioc->raid_data.inactive_list_mutex); |
2298 | return 0; | ||
2299 | } | ||
2300 | 2307 | ||
2301 | /* | 2308 | out: |
2302 | * OS entry point to allow for host driver to free allocated memory | 2309 | return rc; |
2303 | * Called if no device present or device being unloaded | ||
2304 | */ | ||
2305 | void | ||
2306 | mptscsih_target_destroy(struct scsi_target *starget) | ||
2307 | { | ||
2308 | if (starget->hostdata) | ||
2309 | kfree(starget->hostdata); | ||
2310 | starget->hostdata = NULL; | ||
2311 | } | 2310 | } |
2311 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | ||
2312 | 2312 | ||
2313 | /* | 2313 | /* |
2314 | * OS entry point to allow for host driver to free allocated memory | 2314 | * OS entry point to allow for host driver to free allocated memory |
@@ -2328,11 +2328,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2328 | vdevice = sdev->hostdata; | 2328 | vdevice = sdev->hostdata; |
2329 | 2329 | ||
2330 | mptscsih_search_running_cmds(hd, vdevice); | 2330 | mptscsih_search_running_cmds(hd, vdevice); |
2331 | vtarget->luns[0] &= ~(1 << vdevice->lun); | ||
2332 | vtarget->num_luns--; | 2331 | vtarget->num_luns--; |
2333 | if (vtarget->num_luns == 0) { | ||
2334 | hd->Targets[sdev->id] = NULL; | ||
2335 | } | ||
2336 | mptscsih_synchronize_cache(hd, vdevice); | 2332 | mptscsih_synchronize_cache(hd, vdevice); |
2337 | kfree(vdevice); | 2333 | kfree(vdevice); |
2338 | sdev->hostdata = NULL; | 2334 | sdev->hostdata = NULL; |
@@ -2394,15 +2390,14 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2394 | VirtDevice *vdevice; | 2390 | VirtDevice *vdevice; |
2395 | struct scsi_target *starget; | 2391 | struct scsi_target *starget; |
2396 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; | 2392 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; |
2397 | int indexed_lun, lun_index; | ||
2398 | 2393 | ||
2399 | starget = scsi_target(sdev); | 2394 | starget = scsi_target(sdev); |
2400 | vtarget = starget->hostdata; | 2395 | vtarget = starget->hostdata; |
2401 | vdevice = sdev->hostdata; | 2396 | vdevice = sdev->hostdata; |
2402 | 2397 | ||
2403 | dsprintk((MYIOC_s_INFO_FMT | 2398 | dsprintk((MYIOC_s_INFO_FMT |
2404 | "device @ %p, id=%d, LUN=%d, channel=%d\n", | 2399 | "device @ %p, channel=%d, id=%d, lun=%d\n", |
2405 | hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); | 2400 | hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun)); |
2406 | if (hd->ioc->bus_type == SPI) | 2401 | if (hd->ioc->bus_type == SPI) |
2407 | dsprintk((MYIOC_s_INFO_FMT | 2402 | dsprintk((MYIOC_s_INFO_FMT |
2408 | "sdtr %d wdtr %d ppr %d inq length=%d\n", | 2403 | "sdtr %d wdtr %d ppr %d inq length=%d\n", |
@@ -2415,11 +2410,7 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2415 | goto slave_configure_exit; | 2410 | goto slave_configure_exit; |
2416 | } | 2411 | } |
2417 | 2412 | ||
2418 | vdevice->configured_lun=1; | 2413 | vdevice->configured_lun = 1; |
2419 | lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ | ||
2420 | indexed_lun = (vdevice->lun % 32); | ||
2421 | vtarget->luns[lun_index] |= (1 << indexed_lun); | ||
2422 | mptscsih_initTarget(hd, vtarget, sdev); | ||
2423 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2414 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); |
2424 | 2415 | ||
2425 | dsprintk((MYIOC_s_INFO_FMT | 2416 | dsprintk((MYIOC_s_INFO_FMT |
@@ -2683,285 +2674,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2683 | 2674 | ||
2684 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2675 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2685 | /* | 2676 | /* |
2686 | * mptscsih_initTarget - Target, LUN alloc/free functionality. | ||
2687 | * @hd: Pointer to MPT_SCSI_HOST structure | ||
2688 | * @vtarget: per target private data | ||
2689 | * @sdev: SCSI device | ||
2690 | * | ||
2691 | * NOTE: It's only SAFE to call this routine if data points to | ||
2692 | * sane & valid STANDARD INQUIRY data! | ||
2693 | * | ||
2694 | * Allocate and initialize memory for this target. | ||
2695 | * Save inquiry data. | ||
2696 | * | ||
2697 | */ | ||
2698 | static void | ||
2699 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | ||
2700 | struct scsi_device *sdev) | ||
2701 | { | ||
2702 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", | ||
2703 | hd->ioc->name, vtarget->bus_id, vtarget->target_id, | ||
2704 | sdev->lun, hd)); | ||
2705 | |||
2706 | /* Is LUN supported? If so, upper 2 bits will be 0 | ||
2707 | * in first byte of inquiry data. | ||
2708 | */ | ||
2709 | if (sdev->inq_periph_qual != 0) | ||
2710 | return; | ||
2711 | |||
2712 | if (vtarget == NULL) | ||
2713 | return; | ||
2714 | |||
2715 | vtarget->type = sdev->type; | ||
2716 | |||
2717 | if (hd->ioc->bus_type != SPI) | ||
2718 | return; | ||
2719 | |||
2720 | if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | ||
2721 | /* Treat all Processors as SAF-TE if | ||
2722 | * command line option is set */ | ||
2723 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2724 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | ||
2725 | }else if ((sdev->type == TYPE_PROCESSOR) && | ||
2726 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | ||
2727 | if (sdev->inquiry_len > 49 ) { | ||
2728 | if (sdev->inquiry[44] == 'S' && | ||
2729 | sdev->inquiry[45] == 'A' && | ||
2730 | sdev->inquiry[46] == 'F' && | ||
2731 | sdev->inquiry[47] == '-' && | ||
2732 | sdev->inquiry[48] == 'T' && | ||
2733 | sdev->inquiry[49] == 'E' ) { | ||
2734 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2735 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | ||
2736 | } | ||
2737 | } | ||
2738 | } | ||
2739 | mptscsih_setTargetNegoParms(hd, vtarget, sdev); | ||
2740 | } | ||
2741 | |||
2742 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2743 | /* | ||
2744 | * Update the target negotiation parameters based on the | ||
2745 | * the Inquiry data, adapter capabilities, and NVRAM settings. | ||
2746 | * | ||
2747 | */ | ||
2748 | static void | ||
2749 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | ||
2750 | struct scsi_device *sdev) | ||
2751 | { | ||
2752 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | ||
2753 | int id = (int) target->target_id; | ||
2754 | int nvram; | ||
2755 | u8 width = MPT_NARROW; | ||
2756 | u8 factor = MPT_ASYNC; | ||
2757 | u8 offset = 0; | ||
2758 | u8 nfactor; | ||
2759 | u8 noQas = 1; | ||
2760 | |||
2761 | target->negoFlags = pspi_data->noQas; | ||
2762 | |||
2763 | /* noQas == 0 => device supports QAS. */ | ||
2764 | |||
2765 | if (sdev->scsi_level < SCSI_2) { | ||
2766 | width = 0; | ||
2767 | factor = MPT_ULTRA2; | ||
2768 | offset = pspi_data->maxSyncOffset; | ||
2769 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2770 | } else { | ||
2771 | if (scsi_device_wide(sdev)) { | ||
2772 | width = 1; | ||
2773 | } | ||
2774 | |||
2775 | if (scsi_device_sync(sdev)) { | ||
2776 | factor = pspi_data->minSyncFactor; | ||
2777 | if (!scsi_device_dt(sdev)) | ||
2778 | factor = MPT_ULTRA2; | ||
2779 | else { | ||
2780 | if (!scsi_device_ius(sdev) && | ||
2781 | !scsi_device_qas(sdev)) | ||
2782 | factor = MPT_ULTRA160; | ||
2783 | else { | ||
2784 | factor = MPT_ULTRA320; | ||
2785 | if (scsi_device_qas(sdev)) { | ||
2786 | ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); | ||
2787 | noQas = 0; | ||
2788 | } | ||
2789 | if (sdev->type == TYPE_TAPE && | ||
2790 | scsi_device_ius(sdev)) | ||
2791 | target->negoFlags |= MPT_TAPE_NEGO_IDP; | ||
2792 | } | ||
2793 | } | ||
2794 | offset = pspi_data->maxSyncOffset; | ||
2795 | |||
2796 | /* If RAID, never disable QAS | ||
2797 | * else if non RAID, do not disable | ||
2798 | * QAS if bit 1 is set | ||
2799 | * bit 1 QAS support, non-raid only | ||
2800 | * bit 0 IU support | ||
2801 | */ | ||
2802 | if (target->raidVolume == 1) { | ||
2803 | noQas = 0; | ||
2804 | } | ||
2805 | } else { | ||
2806 | factor = MPT_ASYNC; | ||
2807 | offset = 0; | ||
2808 | } | ||
2809 | } | ||
2810 | |||
2811 | if (!sdev->tagged_supported) { | ||
2812 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2813 | } | ||
2814 | |||
2815 | /* Update tflags based on NVRAM settings. (SCSI only) | ||
2816 | */ | ||
2817 | if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
2818 | nvram = pspi_data->nvram[id]; | ||
2819 | nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; | ||
2820 | |||
2821 | if (width) | ||
2822 | width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; | ||
2823 | |||
2824 | if (offset > 0) { | ||
2825 | /* Ensure factor is set to the | ||
2826 | * maximum of: adapter, nvram, inquiry | ||
2827 | */ | ||
2828 | if (nfactor) { | ||
2829 | if (nfactor < pspi_data->minSyncFactor ) | ||
2830 | nfactor = pspi_data->minSyncFactor; | ||
2831 | |||
2832 | factor = max(factor, nfactor); | ||
2833 | if (factor == MPT_ASYNC) | ||
2834 | offset = 0; | ||
2835 | } else { | ||
2836 | offset = 0; | ||
2837 | factor = MPT_ASYNC; | ||
2838 | } | ||
2839 | } else { | ||
2840 | factor = MPT_ASYNC; | ||
2841 | } | ||
2842 | } | ||
2843 | |||
2844 | /* Make sure data is consistent | ||
2845 | */ | ||
2846 | if ((!width) && (factor < MPT_ULTRA2)) { | ||
2847 | factor = MPT_ULTRA2; | ||
2848 | } | ||
2849 | |||
2850 | /* Save the data to the target structure. | ||
2851 | */ | ||
2852 | target->minSyncFactor = factor; | ||
2853 | target->maxOffset = offset; | ||
2854 | target->maxWidth = width; | ||
2855 | |||
2856 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | ||
2857 | |||
2858 | /* Disable unused features. | ||
2859 | */ | ||
2860 | if (!width) | ||
2861 | target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; | ||
2862 | |||
2863 | if (!offset) | ||
2864 | target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; | ||
2865 | |||
2866 | if ( factor > MPT_ULTRA320 ) | ||
2867 | noQas = 0; | ||
2868 | |||
2869 | if (noQas && (pspi_data->noQas == 0)) { | ||
2870 | pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; | ||
2871 | target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | ||
2872 | |||
2873 | /* Disable QAS in a mixed configuration case | ||
2874 | */ | ||
2875 | |||
2876 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | ||
2877 | } | ||
2878 | } | ||
2879 | |||
2880 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2881 | |||
2882 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2883 | /* | ||
2884 | * SCSI Config Page functionality ... | ||
2885 | */ | ||
2886 | |||
2887 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2888 | /* mptscsih_writeIOCPage4 - write IOC Page 4 | ||
2889 | * @hd: Pointer to a SCSI Host Structure | ||
2890 | * @target_id: write IOC Page4 for this ID & Bus | ||
2891 | * | ||
2892 | * Return: -EAGAIN if unable to obtain a Message Frame | ||
2893 | * or 0 if success. | ||
2894 | * | ||
2895 | * Remark: We do not wait for a return, write pages sequentially. | ||
2896 | */ | ||
2897 | static int | ||
2898 | mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) | ||
2899 | { | ||
2900 | MPT_ADAPTER *ioc = hd->ioc; | ||
2901 | Config_t *pReq; | ||
2902 | IOCPage4_t *IOCPage4Ptr; | ||
2903 | MPT_FRAME_HDR *mf; | ||
2904 | dma_addr_t dataDma; | ||
2905 | u16 req_idx; | ||
2906 | u32 frameOffset; | ||
2907 | u32 flagsLength; | ||
2908 | int ii; | ||
2909 | |||
2910 | /* Get a MF for this command. | ||
2911 | */ | ||
2912 | if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { | ||
2913 | dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", | ||
2914 | ioc->name)); | ||
2915 | return -EAGAIN; | ||
2916 | } | ||
2917 | |||
2918 | /* Set the request and the data pointers. | ||
2919 | * Place data at end of MF. | ||
2920 | */ | ||
2921 | pReq = (Config_t *)mf; | ||
2922 | |||
2923 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
2924 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
2925 | |||
2926 | /* Complete the request frame (same for all requests). | ||
2927 | */ | ||
2928 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
2929 | pReq->Reserved = 0; | ||
2930 | pReq->ChainOffset = 0; | ||
2931 | pReq->Function = MPI_FUNCTION_CONFIG; | ||
2932 | pReq->ExtPageLength = 0; | ||
2933 | pReq->ExtPageType = 0; | ||
2934 | pReq->MsgFlags = 0; | ||
2935 | for (ii=0; ii < 8; ii++) { | ||
2936 | pReq->Reserved2[ii] = 0; | ||
2937 | } | ||
2938 | |||
2939 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | ||
2940 | dataDma = ioc->spi_data.IocPg4_dma; | ||
2941 | ii = IOCPage4Ptr->ActiveSEP++; | ||
2942 | IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; | ||
2943 | IOCPage4Ptr->SEP[ii].SEPBus = bus; | ||
2944 | pReq->Header = IOCPage4Ptr->Header; | ||
2945 | pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); | ||
2946 | |||
2947 | /* Add a SGE to the config request. | ||
2948 | */ | ||
2949 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | | ||
2950 | (IOCPage4Ptr->Header.PageLength + ii) * 4; | ||
2951 | |||
2952 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | ||
2953 | |||
2954 | dinitprintk((MYIOC_s_INFO_FMT | ||
2955 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", | ||
2956 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus)); | ||
2957 | |||
2958 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
2959 | |||
2960 | return 0; | ||
2961 | } | ||
2962 | |||
2963 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2964 | /* | ||
2965 | * Bus Scan and Domain Validation functionality ... | 2677 | * Bus Scan and Domain Validation functionality ... |
2966 | */ | 2678 | */ |
2967 | 2679 | ||
@@ -3343,7 +3055,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3343 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 3055 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
3344 | } else { | 3056 | } else { |
3345 | pScsiReq->TargetID = io->id; | 3057 | pScsiReq->TargetID = io->id; |
3346 | pScsiReq->Bus = io->bus; | 3058 | pScsiReq->Bus = io->channel; |
3347 | pScsiReq->ChainOffset = 0; | 3059 | pScsiReq->ChainOffset = 0; |
3348 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; | 3060 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; |
3349 | } | 3061 | } |
@@ -3356,9 +3068,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3356 | pScsiReq->MsgFlags = mpt_msg_flags(); | 3068 | pScsiReq->MsgFlags = mpt_msg_flags(); |
3357 | /* MsgContext set in mpt_get_msg_fram call */ | 3069 | /* MsgContext set in mpt_get_msg_fram call */ |
3358 | 3070 | ||
3359 | for (ii=0; ii < 8; ii++) | 3071 | int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN); |
3360 | pScsiReq->LUN[ii] = 0; | ||
3361 | pScsiReq->LUN[1] = io->lun; | ||
3362 | 3072 | ||
3363 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) | 3073 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) |
3364 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); | 3074 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); |
@@ -3379,7 +3089,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3379 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); | 3089 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); |
3380 | 3090 | ||
3381 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", | 3091 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", |
3382 | hd->ioc->name, cmd, io->bus, io->id, io->lun)); | 3092 | hd->ioc->name, cmd, io->channel, io->id, io->lun)); |
3383 | 3093 | ||
3384 | if (dir == MPI_SCSIIO_CONTROL_READ) { | 3094 | if (dir == MPI_SCSIIO_CONTROL_READ) { |
3385 | mpt_add_sge((char *) &pScsiReq->SGL, | 3095 | mpt_add_sge((char *) &pScsiReq->SGL, |
@@ -3462,9 +3172,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
3462 | iocmd.data_dma = -1; | 3172 | iocmd.data_dma = -1; |
3463 | iocmd.size = 0; | 3173 | iocmd.size = 0; |
3464 | iocmd.rsvd = iocmd.rsvd2 = 0; | 3174 | iocmd.rsvd = iocmd.rsvd2 = 0; |
3465 | iocmd.bus = vdevice->vtarget->bus_id; | 3175 | iocmd.channel = vdevice->vtarget->channel; |
3466 | iocmd.id = vdevice->vtarget->target_id; | 3176 | iocmd.id = vdevice->vtarget->id; |
3467 | iocmd.lun = (u8)vdevice->lun; | 3177 | iocmd.lun = vdevice->lun; |
3468 | 3178 | ||
3469 | if ((vdevice->vtarget->type == TYPE_DISK) && | 3179 | if ((vdevice->vtarget->type == TYPE_DISK) && |
3470 | (vdevice->configured_lun)) | 3180 | (vdevice->configured_lun)) |
@@ -3480,9 +3190,6 @@ EXPORT_SYMBOL(mptscsih_resume); | |||
3480 | EXPORT_SYMBOL(mptscsih_proc_info); | 3190 | EXPORT_SYMBOL(mptscsih_proc_info); |
3481 | EXPORT_SYMBOL(mptscsih_info); | 3191 | EXPORT_SYMBOL(mptscsih_info); |
3482 | EXPORT_SYMBOL(mptscsih_qcmd); | 3192 | EXPORT_SYMBOL(mptscsih_qcmd); |
3483 | EXPORT_SYMBOL(mptscsih_target_alloc); | ||
3484 | EXPORT_SYMBOL(mptscsih_slave_alloc); | ||
3485 | EXPORT_SYMBOL(mptscsih_target_destroy); | ||
3486 | EXPORT_SYMBOL(mptscsih_slave_destroy); | 3193 | EXPORT_SYMBOL(mptscsih_slave_destroy); |
3487 | EXPORT_SYMBOL(mptscsih_slave_configure); | 3194 | EXPORT_SYMBOL(mptscsih_slave_configure); |
3488 | EXPORT_SYMBOL(mptscsih_abort); | 3195 | EXPORT_SYMBOL(mptscsih_abort); |
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 187c8af0890b..843c01a6aa0e 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 6 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
7 | * | 7 | * |
8 | * Copyright (c) 1999-2007 LSI Logic Corporation | 8 | * Copyright (c) 1999-2007 LSI Logic Corporation |
9 | * (mailto:mpt_linux_developer@lsil.com) | 9 | * (mailto:mpt_linux_developer@lsi.com) |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 12 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -53,6 +53,24 @@ | |||
53 | * SCSI Public stuff... | 53 | * SCSI Public stuff... |
54 | */ | 54 | */ |
55 | 55 | ||
56 | #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ | ||
57 | #define MPT_SCANDV_DID_RESET (0x00000001) | ||
58 | #define MPT_SCANDV_SENSE (0x00000002) | ||
59 | #define MPT_SCANDV_SOME_ERROR (0x00000004) | ||
60 | #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) | ||
61 | #define MPT_SCANDV_ISSUE_SENSE (0x00000010) | ||
62 | #define MPT_SCANDV_FALLBACK (0x00000020) | ||
63 | |||
64 | #define MPT_SCANDV_MAX_RETRIES (10) | ||
65 | |||
66 | #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ | ||
67 | #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ | ||
68 | #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ | ||
69 | #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ | ||
70 | #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ | ||
71 | #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ | ||
72 | #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ | ||
73 | |||
56 | #define MPT_SCSI_CMD_PER_DEV_HIGH 64 | 74 | #define MPT_SCSI_CMD_PER_DEV_HIGH 64 |
57 | #define MPT_SCSI_CMD_PER_DEV_LOW 32 | 75 | #define MPT_SCSI_CMD_PER_DEV_LOW 32 |
58 | 76 | ||
@@ -69,9 +87,22 @@ | |||
69 | #define MPTSCSIH_SAF_TE 0 | 87 | #define MPTSCSIH_SAF_TE 0 |
70 | #define MPTSCSIH_PT_CLEAR 0 | 88 | #define MPTSCSIH_PT_CLEAR 0 |
71 | 89 | ||
72 | |||
73 | #endif | 90 | #endif |
74 | 91 | ||
92 | typedef struct _internal_cmd { | ||
93 | char *data; /* data pointer */ | ||
94 | dma_addr_t data_dma; /* data dma address */ | ||
95 | int size; /* transfer size */ | ||
96 | u8 cmd; /* SCSI Op Code */ | ||
97 | u8 channel; /* bus number */ | ||
98 | u8 id; /* SCSI ID (virtual) */ | ||
99 | int lun; | ||
100 | u8 flags; /* Bit Field - See above */ | ||
101 | u8 physDiskNum; /* Phys disk number, -1 else */ | ||
102 | u8 rsvd2; | ||
103 | u8 rsvd; | ||
104 | } INTERNAL_CMD; | ||
105 | |||
75 | extern void mptscsih_remove(struct pci_dev *); | 106 | extern void mptscsih_remove(struct pci_dev *); |
76 | extern void mptscsih_shutdown(struct pci_dev *); | 107 | extern void mptscsih_shutdown(struct pci_dev *); |
77 | #ifdef CONFIG_PM | 108 | #ifdef CONFIG_PM |
@@ -81,9 +112,6 @@ extern int mptscsih_resume(struct pci_dev *pdev); | |||
81 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); | 112 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); |
82 | extern const char * mptscsih_info(struct Scsi_Host *SChost); | 113 | extern const char * mptscsih_info(struct Scsi_Host *SChost); |
83 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); | 114 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); |
84 | extern int mptscsih_target_alloc(struct scsi_target *starget); | ||
85 | extern int mptscsih_slave_alloc(struct scsi_device *device); | ||
86 | extern void mptscsih_target_destroy(struct scsi_target *starget); | ||
87 | extern void mptscsih_slave_destroy(struct scsi_device *device); | 115 | extern void mptscsih_slave_destroy(struct scsi_device *device); |
88 | extern int mptscsih_slave_configure(struct scsi_device *device); | 116 | extern int mptscsih_slave_configure(struct scsi_device *device); |
89 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); | 117 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); |
@@ -98,6 +126,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE | |||
98 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 126 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
99 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); | 127 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); |
100 | extern void mptscsih_timer_expired(unsigned long data); | 128 | extern void mptscsih_timer_expired(unsigned long data); |
101 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 129 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
102 | extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid); | 130 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); |
103 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | 131 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 203c661d2c79..c31a9e3c8a26 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
5 | * | 5 | * |
6 | * Copyright (c) 1999-2007 LSI Logic Corporation | 6 | * Copyright (c) 1999-2007 LSI Logic Corporation |
7 | * (mailto:mpt_linux_developer@lsil.com) | 7 | * (mailto:mpt_linux_developer@lsi.com) |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -65,6 +65,7 @@ | |||
65 | #include <scsi/scsi_tcq.h> | 65 | #include <scsi/scsi_tcq.h> |
66 | #include <scsi/scsi_transport.h> | 66 | #include <scsi/scsi_transport.h> |
67 | #include <scsi/scsi_transport_spi.h> | 67 | #include <scsi/scsi_transport_spi.h> |
68 | #include <scsi/scsi_dbg.h> | ||
68 | 69 | ||
69 | #include "mptbase.h" | 70 | #include "mptbase.h" |
70 | #include "mptscsih.h" | 71 | #include "mptscsih.h" |
@@ -95,25 +96,339 @@ static int mptspiDoneCtx = -1; | |||
95 | static int mptspiTaskCtx = -1; | 96 | static int mptspiTaskCtx = -1; |
96 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ | 97 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ |
97 | 98 | ||
99 | /** | ||
100 | * mptspi_setTargetNegoParms - Update the target negotiation | ||
101 | * parameters based on the the Inquiry data, adapter capabilities, | ||
102 | * and NVRAM settings | ||
103 | * | ||
104 | * @hd: Pointer to a SCSI Host Structure | ||
105 | * @vtarget: per target private data | ||
106 | * @sdev: SCSI device | ||
107 | * | ||
108 | **/ | ||
109 | static void | ||
110 | mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | ||
111 | struct scsi_device *sdev) | ||
112 | { | ||
113 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | ||
114 | int id = (int) target->id; | ||
115 | int nvram; | ||
116 | u8 width = MPT_NARROW; | ||
117 | u8 factor = MPT_ASYNC; | ||
118 | u8 offset = 0; | ||
119 | u8 nfactor; | ||
120 | u8 noQas = 1; | ||
121 | |||
122 | target->negoFlags = pspi_data->noQas; | ||
123 | |||
124 | if (sdev->scsi_level < SCSI_2) { | ||
125 | width = 0; | ||
126 | factor = MPT_ULTRA2; | ||
127 | offset = pspi_data->maxSyncOffset; | ||
128 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
129 | } else { | ||
130 | if (scsi_device_wide(sdev)) | ||
131 | width = 1; | ||
132 | |||
133 | if (scsi_device_sync(sdev)) { | ||
134 | factor = pspi_data->minSyncFactor; | ||
135 | if (!scsi_device_dt(sdev)) | ||
136 | factor = MPT_ULTRA2; | ||
137 | else { | ||
138 | if (!scsi_device_ius(sdev) && | ||
139 | !scsi_device_qas(sdev)) | ||
140 | factor = MPT_ULTRA160; | ||
141 | else { | ||
142 | factor = MPT_ULTRA320; | ||
143 | if (scsi_device_qas(sdev)) { | ||
144 | ddvprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); | ||
145 | noQas = 0; | ||
146 | } | ||
147 | if (sdev->type == TYPE_TAPE && | ||
148 | scsi_device_ius(sdev)) | ||
149 | target->negoFlags |= MPT_TAPE_NEGO_IDP; | ||
150 | } | ||
151 | } | ||
152 | offset = pspi_data->maxSyncOffset; | ||
153 | |||
154 | /* If RAID, never disable QAS | ||
155 | * else if non RAID, do not disable | ||
156 | * QAS if bit 1 is set | ||
157 | * bit 1 QAS support, non-raid only | ||
158 | * bit 0 IU support | ||
159 | */ | ||
160 | if (target->raidVolume == 1) | ||
161 | noQas = 0; | ||
162 | } else { | ||
163 | factor = MPT_ASYNC; | ||
164 | offset = 0; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | if (!sdev->tagged_supported) | ||
169 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
170 | |||
171 | /* Update tflags based on NVRAM settings. (SCSI only) | ||
172 | */ | ||
173 | if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
174 | nvram = pspi_data->nvram[id]; | ||
175 | nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; | ||
176 | |||
177 | if (width) | ||
178 | width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; | ||
179 | |||
180 | if (offset > 0) { | ||
181 | /* Ensure factor is set to the | ||
182 | * maximum of: adapter, nvram, inquiry | ||
183 | */ | ||
184 | if (nfactor) { | ||
185 | if (nfactor < pspi_data->minSyncFactor ) | ||
186 | nfactor = pspi_data->minSyncFactor; | ||
187 | |||
188 | factor = max(factor, nfactor); | ||
189 | if (factor == MPT_ASYNC) | ||
190 | offset = 0; | ||
191 | } else { | ||
192 | offset = 0; | ||
193 | factor = MPT_ASYNC; | ||
194 | } | ||
195 | } else { | ||
196 | factor = MPT_ASYNC; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | /* Make sure data is consistent | ||
201 | */ | ||
202 | if ((!width) && (factor < MPT_ULTRA2)) | ||
203 | factor = MPT_ULTRA2; | ||
204 | |||
205 | /* Save the data to the target structure. | ||
206 | */ | ||
207 | target->minSyncFactor = factor; | ||
208 | target->maxOffset = offset; | ||
209 | target->maxWidth = width; | ||
210 | |||
211 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | ||
212 | |||
213 | /* Disable unused features. | ||
214 | */ | ||
215 | if (!width) | ||
216 | target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; | ||
217 | |||
218 | if (!offset) | ||
219 | target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; | ||
220 | |||
221 | if ( factor > MPT_ULTRA320 ) | ||
222 | noQas = 0; | ||
223 | |||
224 | if (noQas && (pspi_data->noQas == 0)) { | ||
225 | pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; | ||
226 | target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | ||
227 | |||
228 | /* Disable QAS in a mixed configuration case | ||
229 | */ | ||
230 | |||
231 | ddvprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * mptspi_writeIOCPage4 - write IOC Page 4 | ||
237 | * @hd: Pointer to a SCSI Host Structure | ||
238 | * @channel: | ||
239 | * @id: write IOC Page4 for this ID & Bus | ||
240 | * | ||
241 | * Return: -EAGAIN if unable to obtain a Message Frame | ||
242 | * or 0 if success. | ||
243 | * | ||
244 | * Remark: We do not wait for a return, write pages sequentially. | ||
245 | **/ | ||
246 | static int | ||
247 | mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id) | ||
248 | { | ||
249 | MPT_ADAPTER *ioc = hd->ioc; | ||
250 | Config_t *pReq; | ||
251 | IOCPage4_t *IOCPage4Ptr; | ||
252 | MPT_FRAME_HDR *mf; | ||
253 | dma_addr_t dataDma; | ||
254 | u16 req_idx; | ||
255 | u32 frameOffset; | ||
256 | u32 flagsLength; | ||
257 | int ii; | ||
258 | |||
259 | /* Get a MF for this command. | ||
260 | */ | ||
261 | if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { | ||
262 | dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", | ||
263 | ioc->name)); | ||
264 | return -EAGAIN; | ||
265 | } | ||
266 | |||
267 | /* Set the request and the data pointers. | ||
268 | * Place data at end of MF. | ||
269 | */ | ||
270 | pReq = (Config_t *)mf; | ||
271 | |||
272 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
273 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
274 | |||
275 | /* Complete the request frame (same for all requests). | ||
276 | */ | ||
277 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
278 | pReq->Reserved = 0; | ||
279 | pReq->ChainOffset = 0; | ||
280 | pReq->Function = MPI_FUNCTION_CONFIG; | ||
281 | pReq->ExtPageLength = 0; | ||
282 | pReq->ExtPageType = 0; | ||
283 | pReq->MsgFlags = 0; | ||
284 | for (ii=0; ii < 8; ii++) { | ||
285 | pReq->Reserved2[ii] = 0; | ||
286 | } | ||
287 | |||
288 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | ||
289 | dataDma = ioc->spi_data.IocPg4_dma; | ||
290 | ii = IOCPage4Ptr->ActiveSEP++; | ||
291 | IOCPage4Ptr->SEP[ii].SEPTargetID = id; | ||
292 | IOCPage4Ptr->SEP[ii].SEPBus = channel; | ||
293 | pReq->Header = IOCPage4Ptr->Header; | ||
294 | pReq->PageAddress = cpu_to_le32(id | (channel << 8 )); | ||
295 | |||
296 | /* Add a SGE to the config request. | ||
297 | */ | ||
298 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | | ||
299 | (IOCPage4Ptr->Header.PageLength + ii) * 4; | ||
300 | |||
301 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | ||
302 | |||
303 | ddvprintk((MYIOC_s_INFO_FMT | ||
304 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", | ||
305 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel)); | ||
306 | |||
307 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | /** | ||
313 | * mptspi_initTarget - Target, LUN alloc/free functionality. | ||
314 | * @hd: Pointer to MPT_SCSI_HOST structure | ||
315 | * @vtarget: per target private data | ||
316 | * @sdev: SCSI device | ||
317 | * | ||
318 | * NOTE: It's only SAFE to call this routine if data points to | ||
319 | * sane & valid STANDARD INQUIRY data! | ||
320 | * | ||
321 | * Allocate and initialize memory for this target. | ||
322 | * Save inquiry data. | ||
323 | * | ||
324 | **/ | ||
325 | static void | ||
326 | mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | ||
327 | struct scsi_device *sdev) | ||
328 | { | ||
329 | |||
330 | /* Is LUN supported? If so, upper 2 bits will be 0 | ||
331 | * in first byte of inquiry data. | ||
332 | */ | ||
333 | if (sdev->inq_periph_qual != 0) | ||
334 | return; | ||
335 | |||
336 | if (vtarget == NULL) | ||
337 | return; | ||
338 | |||
339 | vtarget->type = sdev->type; | ||
340 | |||
341 | if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | ||
342 | /* Treat all Processors as SAF-TE if | ||
343 | * command line option is set */ | ||
344 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
345 | mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
346 | }else if ((sdev->type == TYPE_PROCESSOR) && | ||
347 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | ||
348 | if (sdev->inquiry_len > 49 ) { | ||
349 | if (sdev->inquiry[44] == 'S' && | ||
350 | sdev->inquiry[45] == 'A' && | ||
351 | sdev->inquiry[46] == 'F' && | ||
352 | sdev->inquiry[47] == '-' && | ||
353 | sdev->inquiry[48] == 'T' && | ||
354 | sdev->inquiry[49] == 'E' ) { | ||
355 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
356 | mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | mptspi_setTargetNegoParms(hd, vtarget, sdev); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * mptspi_is_raid - Determines whether target is belonging to volume | ||
365 | * @hd: Pointer to a SCSI HOST structure | ||
366 | * @id: target device id | ||
367 | * | ||
368 | * Return: | ||
369 | * non-zero = true | ||
370 | * zero = false | ||
371 | * | ||
372 | */ | ||
373 | static int | ||
374 | mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id) | ||
375 | { | ||
376 | int i, rc = 0; | ||
377 | |||
378 | if (!hd->ioc->raid_data.pIocPg2) | ||
379 | goto out; | ||
380 | |||
381 | if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes) | ||
382 | goto out; | ||
383 | for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | ||
384 | if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) { | ||
385 | rc = 1; | ||
386 | goto out; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | out: | ||
391 | return rc; | ||
392 | } | ||
393 | |||
98 | static int mptspi_target_alloc(struct scsi_target *starget) | 394 | static int mptspi_target_alloc(struct scsi_target *starget) |
99 | { | 395 | { |
100 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | 396 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); |
101 | struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; | 397 | struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; |
102 | int ret; | 398 | VirtTarget *vtarget; |
103 | 399 | ||
104 | if (hd == NULL) | 400 | if (hd == NULL) |
105 | return -ENODEV; | 401 | return -ENODEV; |
106 | 402 | ||
107 | ret = mptscsih_target_alloc(starget); | 403 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); |
108 | if (ret) | 404 | if (!vtarget) |
109 | return ret; | 405 | return -ENOMEM; |
406 | |||
407 | vtarget->ioc_id = hd->ioc->id; | ||
408 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
409 | vtarget->id = (u8)starget->id; | ||
410 | vtarget->channel = (u8)starget->channel; | ||
411 | vtarget->starget = starget; | ||
412 | starget->hostdata = vtarget; | ||
413 | |||
414 | if (starget->channel == 1) { | ||
415 | if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0) | ||
416 | return 0; | ||
417 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
418 | /* The real channel for this device is zero */ | ||
419 | vtarget->channel = 0; | ||
420 | /* The actual physdisknum (for RAID passthrough) */ | ||
421 | vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0, | ||
422 | starget->id); | ||
423 | } | ||
110 | 424 | ||
111 | /* if we're a device on virtual channel 1 and we're not part | 425 | if (starget->channel == 0 && |
112 | * of an array, just return here (otherwise the setup below | 426 | mptspi_is_raid(hd, starget->id)) { |
113 | * may actually affect a real physical device on channel 0 */ | 427 | vtarget->raidVolume = 1; |
114 | if (starget->channel == 1 && | 428 | ddvprintk((KERN_INFO |
115 | mptscsih_raid_id_to_num(hd, starget->id) < 0) | 429 | "RAID Volume @ channel=%d id=%d\n", starget->channel, |
116 | return 0; | 430 | starget->id)); |
431 | } | ||
117 | 432 | ||
118 | if (hd->ioc->spi_data.nvram && | 433 | if (hd->ioc->spi_data.nvram && |
119 | hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { | 434 | hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { |
@@ -132,6 +447,64 @@ static int mptspi_target_alloc(struct scsi_target *starget) | |||
132 | return 0; | 447 | return 0; |
133 | } | 448 | } |
134 | 449 | ||
450 | void | ||
451 | mptspi_target_destroy(struct scsi_target *starget) | ||
452 | { | ||
453 | if (starget->hostdata) | ||
454 | kfree(starget->hostdata); | ||
455 | starget->hostdata = NULL; | ||
456 | } | ||
457 | |||
458 | /** | ||
459 | * mptspi_print_write_nego - negotiation parameters debug info that is being sent | ||
460 | * @hd: Pointer to a SCSI HOST structure | ||
461 | * @starget: SCSI target | ||
462 | * @ii: negotiation parameters | ||
463 | * | ||
464 | */ | ||
465 | static void | ||
466 | mptspi_print_write_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii) | ||
467 | { | ||
468 | ddvprintk((MYIOC_s_INFO_FMT "id=%d Requested = 0x%08x" | ||
469 | " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n", | ||
470 | hd->ioc->name, starget->id, ii, | ||
471 | ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "", | ||
472 | ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF), | ||
473 | ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "", | ||
474 | ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "", | ||
475 | ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "", | ||
476 | ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "", | ||
477 | ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "", | ||
478 | ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "", | ||
479 | ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "", | ||
480 | ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": "")); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * mptspi_print_read_nego - negotiation parameters debug info that is being read | ||
485 | * @hd: Pointer to a SCSI HOST structure | ||
486 | * @starget: SCSI target | ||
487 | * @ii: negotiation parameters | ||
488 | * | ||
489 | */ | ||
490 | static void | ||
491 | mptspi_print_read_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii) | ||
492 | { | ||
493 | ddvprintk((MYIOC_s_INFO_FMT "id=%d Read = 0x%08x" | ||
494 | " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n", | ||
495 | hd->ioc->name, starget->id, ii, | ||
496 | ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "", | ||
497 | ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF), | ||
498 | ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "", | ||
499 | ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "", | ||
500 | ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "", | ||
501 | ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "", | ||
502 | ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "", | ||
503 | ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "", | ||
504 | ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "", | ||
505 | ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": "")); | ||
506 | } | ||
507 | |||
135 | static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | 508 | static int mptspi_read_spi_device_pg0(struct scsi_target *starget, |
136 | struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) | 509 | struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) |
137 | { | 510 | { |
@@ -147,7 +520,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | |||
147 | 520 | ||
148 | /* No SPI parameters for RAID devices */ | 521 | /* No SPI parameters for RAID devices */ |
149 | if (starget->channel == 0 && | 522 | if (starget->channel == 0 && |
150 | (hd->ioc->raid_data.isRaid & (1 << starget->id))) | 523 | mptspi_is_raid(hd, starget->id)) |
151 | return -1; | 524 | return -1; |
152 | 525 | ||
153 | size = ioc->spi_data.sdp0length * 4; | 526 | size = ioc->spi_data.sdp0length * 4; |
@@ -185,6 +558,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | |||
185 | err = 0; | 558 | err = 0; |
186 | memcpy(pass_pg0, pg0, size); | 559 | memcpy(pass_pg0, pg0, size); |
187 | 560 | ||
561 | mptspi_print_read_nego(hd, starget, le32_to_cpu(pg0->NegotiatedParameters)); | ||
562 | |||
188 | out_free: | 563 | out_free: |
189 | dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); | 564 | dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); |
190 | return err; | 565 | return err; |
@@ -233,7 +608,7 @@ static void mptspi_read_parameters(struct scsi_target *starget) | |||
233 | } | 608 | } |
234 | 609 | ||
235 | static int | 610 | static int |
236 | mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | 611 | mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) |
237 | { | 612 | { |
238 | MpiRaidActionRequest_t *pReq; | 613 | MpiRaidActionRequest_t *pReq; |
239 | MPT_FRAME_HDR *mf; | 614 | MPT_FRAME_HDR *mf; |
@@ -253,8 +628,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | |||
253 | pReq->Reserved1 = 0; | 628 | pReq->Reserved1 = 0; |
254 | pReq->ChainOffset = 0; | 629 | pReq->ChainOffset = 0; |
255 | pReq->Function = MPI_FUNCTION_RAID_ACTION; | 630 | pReq->Function = MPI_FUNCTION_RAID_ACTION; |
256 | pReq->VolumeID = disk; | 631 | pReq->VolumeID = id; |
257 | pReq->VolumeBus = 0; | 632 | pReq->VolumeBus = channel; |
258 | pReq->PhysDiskNum = 0; | 633 | pReq->PhysDiskNum = 0; |
259 | pReq->MsgFlags = 0; | 634 | pReq->MsgFlags = 0; |
260 | pReq->Reserved2 = 0; | 635 | pReq->Reserved2 = 0; |
@@ -263,8 +638,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | |||
263 | mpt_add_sge((char *)&pReq->ActionDataSGE, | 638 | mpt_add_sge((char *)&pReq->ActionDataSGE, |
264 | MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); | 639 | MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); |
265 | 640 | ||
266 | ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", | 641 | ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action=%x channel=%d id=%d\n", |
267 | hd->ioc->name, action, io->id)); | 642 | hd->ioc->name, pReq->Action, channel, id)); |
268 | 643 | ||
269 | hd->pLocal = NULL; | 644 | hd->pLocal = NULL; |
270 | hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ | 645 | hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ |
@@ -292,12 +667,12 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
292 | 667 | ||
293 | /* no DV on RAID devices */ | 668 | /* no DV on RAID devices */ |
294 | if (sdev->channel == 0 && | 669 | if (sdev->channel == 0 && |
295 | (hd->ioc->raid_data.isRaid & (1 << sdev->id))) | 670 | mptspi_is_raid(hd, sdev->id)) |
296 | return; | 671 | return; |
297 | 672 | ||
298 | /* If this is a piece of a RAID, then quiesce first */ | 673 | /* If this is a piece of a RAID, then quiesce first */ |
299 | if (sdev->channel == 1 && | 674 | if (sdev->channel == 1 && |
300 | mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) { | 675 | mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { |
301 | starget_printk(KERN_ERR, scsi_target(sdev), | 676 | starget_printk(KERN_ERR, scsi_target(sdev), |
302 | "Integrated RAID quiesce failed\n"); | 677 | "Integrated RAID quiesce failed\n"); |
303 | return; | 678 | return; |
@@ -306,7 +681,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
306 | spi_dv_device(sdev); | 681 | spi_dv_device(sdev); |
307 | 682 | ||
308 | if (sdev->channel == 1 && | 683 | if (sdev->channel == 1 && |
309 | mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0) | 684 | mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) |
310 | starget_printk(KERN_ERR, scsi_target(sdev), | 685 | starget_printk(KERN_ERR, scsi_target(sdev), |
311 | "Integrated RAID resume failed\n"); | 686 | "Integrated RAID resume failed\n"); |
312 | 687 | ||
@@ -317,54 +692,89 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
317 | 692 | ||
318 | static int mptspi_slave_alloc(struct scsi_device *sdev) | 693 | static int mptspi_slave_alloc(struct scsi_device *sdev) |
319 | { | 694 | { |
320 | int ret; | ||
321 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; | 695 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; |
322 | /* gcc doesn't see that all uses of this variable occur within | 696 | VirtTarget *vtarget; |
323 | * the if() statements, so stop it from whining */ | 697 | VirtDevice *vdev; |
324 | int physdisknum = 0; | 698 | struct scsi_target *starget; |
325 | |||
326 | if (sdev->channel == 1) { | ||
327 | physdisknum = mptscsih_raid_id_to_num(hd, sdev->id); | ||
328 | 699 | ||
329 | if (physdisknum < 0) | 700 | if (sdev->channel == 1 && |
330 | return physdisknum; | 701 | mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0) |
702 | return -ENXIO; | ||
703 | |||
704 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | ||
705 | if (!vdev) { | ||
706 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | ||
707 | hd->ioc->name, sizeof(VirtDevice)); | ||
708 | return -ENOMEM; | ||
331 | } | 709 | } |
332 | 710 | ||
333 | ret = mptscsih_slave_alloc(sdev); | 711 | vdev->lun = sdev->lun; |
712 | sdev->hostdata = vdev; | ||
334 | 713 | ||
335 | if (ret) | 714 | starget = scsi_target(sdev); |
336 | return ret; | 715 | vtarget = starget->hostdata; |
716 | vdev->vtarget = vtarget; | ||
717 | vtarget->num_luns++; | ||
337 | 718 | ||
338 | if (sdev->channel == 1) { | 719 | if (sdev->channel == 1) |
339 | VirtDevice *vdev = sdev->hostdata; | ||
340 | sdev->no_uld_attach = 1; | 720 | sdev->no_uld_attach = 1; |
341 | vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
342 | /* The real channel for this device is zero */ | ||
343 | vdev->vtarget->bus_id = 0; | ||
344 | /* The actual physdisknum (for RAID passthrough) */ | ||
345 | vdev->vtarget->target_id = physdisknum; | ||
346 | } | ||
347 | 721 | ||
348 | return 0; | 722 | return 0; |
349 | } | 723 | } |
350 | 724 | ||
351 | static int mptspi_slave_configure(struct scsi_device *sdev) | 725 | static int mptspi_slave_configure(struct scsi_device *sdev) |
352 | { | 726 | { |
353 | int ret = mptscsih_slave_configure(sdev); | ||
354 | struct _MPT_SCSI_HOST *hd = | 727 | struct _MPT_SCSI_HOST *hd = |
355 | (struct _MPT_SCSI_HOST *)sdev->host->hostdata; | 728 | (struct _MPT_SCSI_HOST *)sdev->host->hostdata; |
729 | VirtTarget *vtarget = scsi_target(sdev)->hostdata; | ||
730 | int ret = mptscsih_slave_configure(sdev); | ||
356 | 731 | ||
357 | if (ret) | 732 | if (ret) |
358 | return ret; | 733 | return ret; |
359 | 734 | ||
735 | mptspi_initTarget(hd, vtarget, sdev); | ||
736 | |||
737 | ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x" | ||
738 | " max_offset=0x%02x max_width=%d\n", hd->ioc->name, | ||
739 | sdev->id, spi_min_period(scsi_target(sdev)), | ||
740 | spi_max_offset(scsi_target(sdev)), | ||
741 | spi_max_width(scsi_target(sdev)))); | ||
742 | |||
360 | if ((sdev->channel == 1 || | 743 | if ((sdev->channel == 1 || |
361 | !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) && | 744 | !(mptspi_is_raid(hd, sdev->id))) && |
362 | !spi_initial_dv(sdev->sdev_target)) | 745 | !spi_initial_dv(sdev->sdev_target)) |
363 | mptspi_dv_device(hd, sdev); | 746 | mptspi_dv_device(hd, sdev); |
364 | 747 | ||
365 | return 0; | 748 | return 0; |
366 | } | 749 | } |
367 | 750 | ||
751 | static int | ||
752 | mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | ||
753 | { | ||
754 | struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; | ||
755 | VirtDevice *vdev = SCpnt->device->hostdata; | ||
756 | |||
757 | if (!vdev || !vdev->vtarget) { | ||
758 | SCpnt->result = DID_NO_CONNECT << 16; | ||
759 | done(SCpnt); | ||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | if (SCpnt->device->channel == 1 && | ||
764 | mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) { | ||
765 | SCpnt->result = DID_NO_CONNECT << 16; | ||
766 | done(SCpnt); | ||
767 | return 0; | ||
768 | } | ||
769 | |||
770 | #ifdef MPT_DEBUG_DV | ||
771 | if (spi_dv_pending(scsi_target(SCpnt->device))) | ||
772 | scsi_print_command(SCpnt); | ||
773 | #endif | ||
774 | |||
775 | return mptscsih_qcmd(SCpnt,done); | ||
776 | } | ||
777 | |||
368 | static void mptspi_slave_destroy(struct scsi_device *sdev) | 778 | static void mptspi_slave_destroy(struct scsi_device *sdev) |
369 | { | 779 | { |
370 | struct scsi_target *starget = scsi_target(sdev); | 780 | struct scsi_target *starget = scsi_target(sdev); |
@@ -392,11 +802,11 @@ static struct scsi_host_template mptspi_driver_template = { | |||
392 | .proc_info = mptscsih_proc_info, | 802 | .proc_info = mptscsih_proc_info, |
393 | .name = "MPT SPI Host", | 803 | .name = "MPT SPI Host", |
394 | .info = mptscsih_info, | 804 | .info = mptscsih_info, |
395 | .queuecommand = mptscsih_qcmd, | 805 | .queuecommand = mptspi_qcmd, |
396 | .target_alloc = mptspi_target_alloc, | 806 | .target_alloc = mptspi_target_alloc, |
397 | .slave_alloc = mptspi_slave_alloc, | 807 | .slave_alloc = mptspi_slave_alloc, |
398 | .slave_configure = mptspi_slave_configure, | 808 | .slave_configure = mptspi_slave_configure, |
399 | .target_destroy = mptscsih_target_destroy, | 809 | .target_destroy = mptspi_target_destroy, |
400 | .slave_destroy = mptspi_slave_destroy, | 810 | .slave_destroy = mptspi_slave_destroy, |
401 | .change_queue_depth = mptscsih_change_queue_depth, | 811 | .change_queue_depth = mptscsih_change_queue_depth, |
402 | .eh_abort_handler = mptscsih_abort, | 812 | .eh_abort_handler = mptscsih_abort, |
@@ -427,7 +837,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, | |||
427 | 837 | ||
428 | /* don't allow updating nego parameters on RAID devices */ | 838 | /* don't allow updating nego parameters on RAID devices */ |
429 | if (starget->channel == 0 && | 839 | if (starget->channel == 0 && |
430 | (hd->ioc->raid_data.isRaid & (1 << starget->id))) | 840 | mptspi_is_raid(hd, starget->id)) |
431 | return -1; | 841 | return -1; |
432 | 842 | ||
433 | size = ioc->spi_data.sdp1length * 4; | 843 | size = ioc->spi_data.sdp1length * 4; |
@@ -460,6 +870,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, | |||
460 | pg1->Header.PageNumber = hdr.PageNumber; | 870 | pg1->Header.PageNumber = hdr.PageNumber; |
461 | pg1->Header.PageType = hdr.PageType; | 871 | pg1->Header.PageType = hdr.PageType; |
462 | 872 | ||
873 | mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters)); | ||
874 | |||
463 | if (mpt_config(ioc, &cfg)) { | 875 | if (mpt_config(ioc, &cfg)) { |
464 | starget_printk(KERN_ERR, starget, "mpt_config failed\n"); | 876 | starget_printk(KERN_ERR, starget, "mpt_config failed\n"); |
465 | goto out_free; | 877 | goto out_free; |
@@ -672,9 +1084,9 @@ static void mpt_work_wrapper(struct work_struct *work) | |||
672 | if (sdev->channel != 1) | 1084 | if (sdev->channel != 1) |
673 | continue; | 1085 | continue; |
674 | 1086 | ||
675 | /* The target_id is the raid PhysDiskNum, even if | 1087 | /* The id is the raid PhysDiskNum, even if |
676 | * starget->id is the actual target address */ | 1088 | * starget->id is the actual target address */ |
677 | if(vtarget->target_id != disk) | 1089 | if(vtarget->id != disk) |
678 | continue; | 1090 | continue; |
679 | 1091 | ||
680 | starget_printk(KERN_INFO, vtarget->starget, | 1092 | starget_printk(KERN_INFO, vtarget->starget, |
@@ -727,7 +1139,7 @@ mptspi_deny_binding(struct scsi_target *starget) | |||
727 | { | 1139 | { |
728 | struct _MPT_SCSI_HOST *hd = | 1140 | struct _MPT_SCSI_HOST *hd = |
729 | (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; | 1141 | (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; |
730 | return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) && | 1142 | return ((mptspi_is_raid(hd, starget->id)) && |
731 | starget->channel == 0) ? 1 : 0; | 1143 | starget->channel == 0) ? 1 : 0; |
732 | } | 1144 | } |
733 | 1145 | ||
@@ -945,14 +1357,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
945 | * max_lun = 1 + actual last lun, | 1357 | * max_lun = 1 + actual last lun, |
946 | * see hosts.h :o( | 1358 | * see hosts.h :o( |
947 | */ | 1359 | */ |
948 | sh->max_id = MPT_MAX_SCSI_DEVICES; | 1360 | sh->max_id = ioc->devices_per_bus; |
949 | 1361 | ||
950 | sh->max_lun = MPT_LAST_LUN + 1; | 1362 | sh->max_lun = MPT_LAST_LUN + 1; |
951 | /* | 1363 | /* |
952 | * If RAID Firmware Detected, setup virtual channel | 1364 | * If RAID Firmware Detected, setup virtual channel |
953 | */ | 1365 | */ |
954 | if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | 1366 | if (ioc->ir_firmware) |
955 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) | ||
956 | sh->max_channel = 1; | 1367 | sh->max_channel = 1; |
957 | else | 1368 | else |
958 | sh->max_channel = 0; | 1369 | sh->max_channel = 0; |
@@ -1009,20 +1420,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1009 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 1420 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
1010 | ioc->name, hd->ScsiLookup)); | 1421 | ioc->name, hd->ScsiLookup)); |
1011 | 1422 | ||
1012 | /* Allocate memory for the device structures. | ||
1013 | * A non-Null pointer at an offset | ||
1014 | * indicates a device exists. | ||
1015 | * max_id = 1 + maximum id (hosts.h) | ||
1016 | */ | ||
1017 | hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1), | ||
1018 | sizeof(void *), GFP_ATOMIC); | ||
1019 | if (!hd->Targets) { | ||
1020 | error = -ENOMEM; | ||
1021 | goto out_mptspi_probe; | ||
1022 | } | ||
1023 | |||
1024 | dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); | ||
1025 | |||
1026 | /* Clear the TM flags | 1423 | /* Clear the TM flags |
1027 | */ | 1424 | */ |
1028 | hd->tmPending = 0; | 1425 | hd->tmPending = 0; |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 88642dec080c..421da1e7c0ea 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -838,32 +838,28 @@ zfcp_erp_action_exists(struct zfcp_erp_action *erp_action) | |||
838 | * and does appropriate preparations (dismiss fsf request, ...) | 838 | * and does appropriate preparations (dismiss fsf request, ...) |
839 | * | 839 | * |
840 | * locks: called under erp_lock (disabled interrupts) | 840 | * locks: called under erp_lock (disabled interrupts) |
841 | * | ||
842 | * returns: 0 | ||
843 | */ | 841 | */ |
844 | static int | 842 | static void |
845 | zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | 843 | zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) |
846 | { | 844 | { |
847 | int retval = 0; | ||
848 | struct zfcp_fsf_req *fsf_req = NULL; | ||
849 | struct zfcp_adapter *adapter = erp_action->adapter; | 845 | struct zfcp_adapter *adapter = erp_action->adapter; |
850 | 846 | ||
851 | if (erp_action->fsf_req) { | 847 | if (erp_action->fsf_req) { |
852 | /* take lock to ensure that request is not deleted meanwhile */ | 848 | /* take lock to ensure that request is not deleted meanwhile */ |
853 | spin_lock(&adapter->req_list_lock); | 849 | spin_lock(&adapter->req_list_lock); |
854 | if ((!zfcp_reqlist_ismember(adapter, | 850 | if (zfcp_reqlist_ismember(adapter, |
855 | erp_action->fsf_req->req_id)) && | 851 | erp_action->fsf_req->req_id)) { |
856 | (fsf_req->erp_action == erp_action)) { | ||
857 | /* fsf_req still exists */ | 852 | /* fsf_req still exists */ |
858 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); | 853 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); |
859 | debug_event(adapter->erp_dbf, 3, &fsf_req, | 854 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, |
860 | sizeof (unsigned long)); | 855 | sizeof (unsigned long)); |
861 | /* dismiss fsf_req of timed out/dismissed erp_action */ | 856 | /* dismiss fsf_req of timed out/dismissed erp_action */ |
862 | if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | | 857 | if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | |
863 | ZFCP_STATUS_ERP_TIMEDOUT)) { | 858 | ZFCP_STATUS_ERP_TIMEDOUT)) { |
864 | debug_text_event(adapter->erp_dbf, 3, | 859 | debug_text_event(adapter->erp_dbf, 3, |
865 | "a_ca_disreq"); | 860 | "a_ca_disreq"); |
866 | fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; | 861 | erp_action->fsf_req->status |= |
862 | ZFCP_STATUS_FSFREQ_DISMISSED; | ||
867 | } | 863 | } |
868 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 864 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
869 | ZFCP_LOG_NORMAL("error: erp step timed out " | 865 | ZFCP_LOG_NORMAL("error: erp step timed out " |
@@ -876,11 +872,11 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
876 | * then keep it running asynchronously and don't mess | 872 | * then keep it running asynchronously and don't mess |
877 | * with the association of erp_action and fsf_req. | 873 | * with the association of erp_action and fsf_req. |
878 | */ | 874 | */ |
879 | if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED | | 875 | if (erp_action->fsf_req->status & |
876 | (ZFCP_STATUS_FSFREQ_COMPLETED | | ||
880 | ZFCP_STATUS_FSFREQ_DISMISSED)) { | 877 | ZFCP_STATUS_FSFREQ_DISMISSED)) { |
881 | /* forget about association between fsf_req | 878 | /* forget about association between fsf_req |
882 | and erp_action */ | 879 | and erp_action */ |
883 | fsf_req->erp_action = NULL; | ||
884 | erp_action->fsf_req = NULL; | 880 | erp_action->fsf_req = NULL; |
885 | } | 881 | } |
886 | } else { | 882 | } else { |
@@ -894,8 +890,6 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
894 | spin_unlock(&adapter->req_list_lock); | 890 | spin_unlock(&adapter->req_list_lock); |
895 | } else | 891 | } else |
896 | debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq"); | 892 | debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq"); |
897 | |||
898 | return retval; | ||
899 | } | 893 | } |
900 | 894 | ||
901 | /** | 895 | /** |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index cda0cc095ad1..01386ac688a2 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -89,7 +89,7 @@ extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, | |||
89 | u32, u32, struct zfcp_sg_list *); | 89 | u32, u32, struct zfcp_sg_list *); |
90 | extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); | 90 | extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); |
91 | extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); | 91 | extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); |
92 | extern int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); | 92 | extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); |
93 | extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); | 93 | extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); |
94 | extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, | 94 | extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, |
95 | unsigned long *, struct zfcp_fsf_req **); | 95 | unsigned long *, struct zfcp_fsf_req **); |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 4b3ae3f22e78..ef16f7ca4bb1 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -176,28 +176,25 @@ static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter, | |||
176 | /** | 176 | /** |
177 | * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests | 177 | * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests |
178 | */ | 178 | */ |
179 | int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) | 179 | void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) |
180 | { | 180 | { |
181 | struct zfcp_fsf_req *request, *tmp; | 181 | struct zfcp_fsf_req *request, *tmp; |
182 | unsigned long flags; | 182 | unsigned long flags; |
183 | LIST_HEAD(remove_queue); | ||
183 | unsigned int i, counter; | 184 | unsigned int i, counter; |
184 | 185 | ||
185 | spin_lock_irqsave(&adapter->req_list_lock, flags); | 186 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
186 | atomic_set(&adapter->reqs_active, 0); | 187 | atomic_set(&adapter->reqs_active, 0); |
187 | for (i=0; i<REQUEST_LIST_SIZE; i++) { | 188 | for (i=0; i<REQUEST_LIST_SIZE; i++) |
188 | if (list_empty(&adapter->req_list[i])) | 189 | list_splice_init(&adapter->req_list[i], &remove_queue); |
189 | continue; | 190 | |
190 | |||
191 | counter = 0; | ||
192 | list_for_each_entry_safe(request, tmp, | ||
193 | &adapter->req_list[i], list) { | ||
194 | zfcp_fsf_req_dismiss(adapter, request, counter); | ||
195 | counter++; | ||
196 | } | ||
197 | } | ||
198 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 191 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
199 | 192 | ||
200 | return 0; | 193 | counter = 0; |
194 | list_for_each_entry_safe(request, tmp, &remove_queue, list) { | ||
195 | zfcp_fsf_req_dismiss(adapter, request, counter); | ||
196 | counter++; | ||
197 | } | ||
201 | } | 198 | } |
202 | 199 | ||
203 | /* | 200 | /* |
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 68103e508db7..88e061d13d0b 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -667,12 +667,30 @@ NCR_700_chip_setup(struct Scsi_Host *host) | |||
667 | __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); | 667 | __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP); |
668 | 668 | ||
669 | if(hostdata->chip710) { | 669 | if(hostdata->chip710) { |
670 | __u8 burst_disable = hostdata->burst_disable | 670 | __u8 burst_disable = 0; |
671 | ? BURST_DISABLE : 0; | 671 | __u8 burst_length = 0; |
672 | |||
673 | switch (hostdata->burst_length) { | ||
674 | case 1: | ||
675 | burst_length = BURST_LENGTH_1; | ||
676 | break; | ||
677 | case 2: | ||
678 | burst_length = BURST_LENGTH_2; | ||
679 | break; | ||
680 | case 4: | ||
681 | burst_length = BURST_LENGTH_4; | ||
682 | break; | ||
683 | case 8: | ||
684 | burst_length = BURST_LENGTH_8; | ||
685 | break; | ||
686 | default: | ||
687 | burst_disable = BURST_DISABLE; | ||
688 | break; | ||
689 | } | ||
672 | dcntl_extra = COMPAT_700_MODE; | 690 | dcntl_extra = COMPAT_700_MODE; |
673 | 691 | ||
674 | NCR_700_writeb(dcntl_extra, host, DCNTL_REG); | 692 | NCR_700_writeb(dcntl_extra, host, DCNTL_REG); |
675 | NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra, | 693 | NCR_700_writeb(burst_length | hostdata->dmode_extra, |
676 | host, DMODE_710_REG); | 694 | host, DMODE_710_REG); |
677 | NCR_700_writeb(burst_disable | (hostdata->differential ? | 695 | NCR_700_writeb(burst_disable | (hostdata->differential ? |
678 | DIFF : 0), host, CTEST7_REG); | 696 | DIFF : 0), host, CTEST7_REG); |
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index f38822db4210..841e1bb27d57 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h | |||
@@ -203,7 +203,7 @@ struct NCR_700_Host_Parameters { | |||
203 | __u32 force_le_on_be:1; | 203 | __u32 force_le_on_be:1; |
204 | #endif | 204 | #endif |
205 | __u32 chip710:1; /* set if really a 710 not 700 */ | 205 | __u32 chip710:1; /* set if really a 710 not 700 */ |
206 | __u32 burst_disable:1; /* set to 1 to disable 710 bursting */ | 206 | __u32 burst_length:4; /* set to 0 to disable 710 bursting */ |
207 | 207 | ||
208 | /* NOTHING BELOW HERE NEEDS ALTERING */ | 208 | /* NOTHING BELOW HERE NEEDS ALTERING */ |
209 | __u32 fast:1; /* if we can alter the SCSI bus clock | 209 | __u32 fast:1; /* if we can alter the SCSI bus clock |
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index 9c3794310879..93b41f45638a 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c | |||
@@ -4399,7 +4399,7 @@ abort_connected (struct Scsi_Host *host) { | |||
4399 | * account the current synchronous offset) | 4399 | * account the current synchronous offset) |
4400 | */ | 4400 | */ |
4401 | 4401 | ||
4402 | sstat = (NCR53c8x0_read8 (SSTAT2_REG); | 4402 | sstat = NCR53c8x0_read8 (SSTAT2_REG); |
4403 | offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; | 4403 | offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; |
4404 | phase = sstat & SSTAT2_PHASE_MASK; | 4404 | phase = sstat & SSTAT2_PHASE_MASK; |
4405 | 4405 | ||
@@ -5422,7 +5422,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { | |||
5422 | --buffers, offset += segment->length, ++segment) | 5422 | --buffers, offset += segment->length, ++segment) |
5423 | #if 0 | 5423 | #if 0 |
5424 | printk("scsi%d: comparing 0x%p to 0x%p\n", | 5424 | printk("scsi%d: comparing 0x%p to 0x%p\n", |
5425 | cmd->device->host->host_no, saved, page_address(segment->page+segment->offset); | 5425 | cmd->device->host->host_no, saved, page_address(segment->page+segment->offset)); |
5426 | #else | 5426 | #else |
5427 | ; | 5427 | ; |
5428 | #endif | 5428 | #endif |
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 3075204915c8..e874b8944875 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -192,7 +192,7 @@ static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, vo | |||
192 | BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. | 192 | BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter. |
193 | */ | 193 | */ |
194 | 194 | ||
195 | static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter) | 195 | static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter) |
196 | { | 196 | { |
197 | int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); | 197 | int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); |
198 | void *BlockPointer; | 198 | void *BlockPointer; |
@@ -238,7 +238,7 @@ static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter) | |||
238 | multiple host adapters share the same IRQ Channel. | 238 | multiple host adapters share the same IRQ Channel. |
239 | */ | 239 | */ |
240 | 240 | ||
241 | static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, boolean SuccessMessageP) | 241 | static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP) |
242 | { | 242 | { |
243 | int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); | 243 | int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); |
244 | int PreviouslyAllocated = HostAdapter->AllocatedCCBs; | 244 | int PreviouslyAllocated = HostAdapter->AllocatedCCBs; |
@@ -362,10 +362,8 @@ static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLo | |||
362 | interrupt could occur if the IRQ Channel was previously enabled by another | 362 | interrupt could occur if the IRQ Channel was previously enabled by another |
363 | BusLogic Host Adapter or another driver sharing the same IRQ Channel. | 363 | BusLogic Host Adapter or another driver sharing the same IRQ Channel. |
364 | */ | 364 | */ |
365 | if (!HostAdapter->IRQ_ChannelAcquired) { | 365 | if (!HostAdapter->IRQ_ChannelAcquired) |
366 | local_irq_save(ProcessorFlags); | 366 | local_irq_save(ProcessorFlags); |
367 | local_irq_disable(); | ||
368 | } | ||
369 | /* | 367 | /* |
370 | Wait for the Host Adapter Ready bit to be set and the Command/Parameter | 368 | Wait for the Host Adapter Ready bit to be set and the Command/Parameter |
371 | Register Busy bit to be reset in the Status Register. | 369 | Register Busy bit to be reset in the Status Register. |
@@ -639,9 +637,9 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd | |||
639 | struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; | 637 | struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; |
640 | int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; | 638 | int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; |
641 | int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; | 639 | int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; |
642 | boolean ForceBusDeviceScanningOrder = false; | 640 | bool ForceBusDeviceScanningOrder = false; |
643 | boolean ForceBusDeviceScanningOrderChecked = false; | 641 | bool ForceBusDeviceScanningOrderChecked = false; |
644 | boolean StandardAddressSeen[6]; | 642 | bool StandardAddressSeen[6]; |
645 | struct pci_dev *PCI_Device = NULL; | 643 | struct pci_dev *PCI_Device = NULL; |
646 | int i; | 644 | int i; |
647 | if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) | 645 | if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) |
@@ -1011,7 +1009,7 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter | |||
1011 | BusLogic_Failure prints a standardized error message, and then returns false. | 1009 | BusLogic_Failure prints a standardized error message, and then returns false. |
1012 | */ | 1010 | */ |
1013 | 1011 | ||
1014 | static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage) | 1012 | static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage) |
1015 | { | 1013 | { |
1016 | BusLogic_AnnounceDriver(HostAdapter); | 1014 | BusLogic_AnnounceDriver(HostAdapter); |
1017 | if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) { | 1015 | if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) { |
@@ -1030,7 +1028,7 @@ static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char * | |||
1030 | BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter. | 1028 | BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter. |
1031 | */ | 1029 | */ |
1032 | 1030 | ||
1033 | static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter) | 1031 | static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter) |
1034 | { | 1032 | { |
1035 | union BusLogic_StatusRegister StatusRegister; | 1033 | union BusLogic_StatusRegister StatusRegister; |
1036 | union BusLogic_InterruptRegister InterruptRegister; | 1034 | union BusLogic_InterruptRegister InterruptRegister; |
@@ -1101,8 +1099,8 @@ static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *Hos | |||
1101 | SCSI Bus Reset. | 1099 | SCSI Bus Reset. |
1102 | */ | 1100 | */ |
1103 | 1101 | ||
1104 | static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter | 1102 | static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter |
1105 | *HostAdapter, boolean HardReset) | 1103 | *HostAdapter, bool HardReset) |
1106 | { | 1104 | { |
1107 | union BusLogic_StatusRegister StatusRegister; | 1105 | union BusLogic_StatusRegister StatusRegister; |
1108 | int TimeoutCounter; | 1106 | int TimeoutCounter; |
@@ -1205,11 +1203,11 @@ static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter | |||
1205 | Host Adapter. | 1203 | Host Adapter. |
1206 | */ | 1204 | */ |
1207 | 1205 | ||
1208 | static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter) | 1206 | static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter) |
1209 | { | 1207 | { |
1210 | struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; | 1208 | struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; |
1211 | unsigned char RequestedReplyLength; | 1209 | unsigned char RequestedReplyLength; |
1212 | boolean Result = true; | 1210 | bool Result = true; |
1213 | /* | 1211 | /* |
1214 | FlashPoint Host Adapters do not require this protection. | 1212 | FlashPoint Host Adapters do not require this protection. |
1215 | */ | 1213 | */ |
@@ -1239,7 +1237,7 @@ static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *Hos | |||
1239 | from Host Adapter and initializes the Host Adapter structure. | 1237 | from Host Adapter and initializes the Host Adapter structure. |
1240 | */ | 1238 | */ |
1241 | 1239 | ||
1242 | static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter | 1240 | static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter |
1243 | *HostAdapter) | 1241 | *HostAdapter) |
1244 | { | 1242 | { |
1245 | struct BusLogic_BoardID BoardID; | 1243 | struct BusLogic_BoardID BoardID; |
@@ -1686,14 +1684,14 @@ static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_Host | |||
1686 | Host Adapter. | 1684 | Host Adapter. |
1687 | */ | 1685 | */ |
1688 | 1686 | ||
1689 | static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter | 1687 | static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter |
1690 | *HostAdapter) | 1688 | *HostAdapter) |
1691 | { | 1689 | { |
1692 | unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; | 1690 | unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; |
1693 | unsigned short SynchronousPermitted, FastPermitted; | 1691 | unsigned short SynchronousPermitted, FastPermitted; |
1694 | unsigned short UltraPermitted, WidePermitted; | 1692 | unsigned short UltraPermitted, WidePermitted; |
1695 | unsigned short DisconnectPermitted, TaggedQueuingPermitted; | 1693 | unsigned short DisconnectPermitted, TaggedQueuingPermitted; |
1696 | boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth; | 1694 | bool CommonSynchronousNegotiation, CommonTaggedQueueDepth; |
1697 | char SynchronousString[BusLogic_MaxTargetDevices + 1]; | 1695 | char SynchronousString[BusLogic_MaxTargetDevices + 1]; |
1698 | char WideString[BusLogic_MaxTargetDevices + 1]; | 1696 | char WideString[BusLogic_MaxTargetDevices + 1]; |
1699 | char DisconnectString[BusLogic_MaxTargetDevices + 1]; | 1697 | char DisconnectString[BusLogic_MaxTargetDevices + 1]; |
@@ -1835,7 +1833,7 @@ static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_Ho | |||
1835 | Host Adapter. | 1833 | Host Adapter. |
1836 | */ | 1834 | */ |
1837 | 1835 | ||
1838 | static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter) | 1836 | static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter) |
1839 | { | 1837 | { |
1840 | if (HostAdapter->IRQ_Channel == 0) { | 1838 | if (HostAdapter->IRQ_Channel == 0) { |
1841 | BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter); | 1839 | BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter); |
@@ -1903,7 +1901,7 @@ static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter) | |||
1903 | of the Host Adapter from its initial power on or hard reset state. | 1901 | of the Host Adapter from its initial power on or hard reset state. |
1904 | */ | 1902 | */ |
1905 | 1903 | ||
1906 | static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter | 1904 | static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter |
1907 | *HostAdapter) | 1905 | *HostAdapter) |
1908 | { | 1906 | { |
1909 | struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest; | 1907 | struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest; |
@@ -2002,7 +2000,7 @@ static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter | |||
2002 | through Host Adapter. | 2000 | through Host Adapter. |
2003 | */ | 2001 | */ |
2004 | 2002 | ||
2005 | static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter | 2003 | static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter |
2006 | *HostAdapter) | 2004 | *HostAdapter) |
2007 | { | 2005 | { |
2008 | u16 InstalledDevices; | 2006 | u16 InstalledDevices; |
@@ -2739,7 +2737,7 @@ static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdenti | |||
2739 | already have been acquired by the caller. | 2737 | already have been acquired by the caller. |
2740 | */ | 2738 | */ |
2741 | 2739 | ||
2742 | static boolean BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter | 2740 | static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter |
2743 | *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB) | 2741 | *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB) |
2744 | { | 2742 | { |
2745 | struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; | 2743 | struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; |
@@ -3058,7 +3056,7 @@ static int BusLogic_AbortCommand(struct scsi_cmnd *Command) | |||
3058 | currently executing SCSI Commands as having been Reset. | 3056 | currently executing SCSI Commands as having been Reset. |
3059 | */ | 3057 | */ |
3060 | 3058 | ||
3061 | static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, boolean HardReset) | 3059 | static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset) |
3062 | { | 3060 | { |
3063 | struct BusLogic_CCB *CCB; | 3061 | struct BusLogic_CCB *CCB; |
3064 | int TargetID; | 3062 | int TargetID; |
@@ -3309,7 +3307,7 @@ Target Requested Completed Requested Completed Requested Completed\n\ | |||
3309 | static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...) | 3307 | static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...) |
3310 | { | 3308 | { |
3311 | static char Buffer[BusLogic_LineBufferSize]; | 3309 | static char Buffer[BusLogic_LineBufferSize]; |
3312 | static boolean BeginningOfLine = true; | 3310 | static bool BeginningOfLine = true; |
3313 | va_list Arguments; | 3311 | va_list Arguments; |
3314 | int Length = 0; | 3312 | int Length = 0; |
3315 | va_start(Arguments, HostAdapter); | 3313 | va_start(Arguments, HostAdapter); |
@@ -3347,7 +3345,7 @@ static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Form | |||
3347 | and updates the pointer if the keyword is recognized and false otherwise. | 3345 | and updates the pointer if the keyword is recognized and false otherwise. |
3348 | */ | 3346 | */ |
3349 | 3347 | ||
3350 | static boolean __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword) | 3348 | static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword) |
3351 | { | 3349 | { |
3352 | char *Pointer = *StringPointer; | 3350 | char *Pointer = *StringPointer; |
3353 | while (*Keyword != '\0') { | 3351 | while (*Keyword != '\0') { |
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index cca6d45eee4d..bfbfb5c3a8f6 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h | |||
@@ -234,12 +234,6 @@ enum BusLogic_BIOS_DiskGeometryTranslation { | |||
234 | 234 | ||
235 | 235 | ||
236 | /* | 236 | /* |
237 | Define a Boolean data type. | ||
238 | */ | ||
239 | |||
240 | typedef bool boolean; | ||
241 | |||
242 | /* | ||
243 | Define a 10^18 Statistics Byte Counter data type. | 237 | Define a 10^18 Statistics Byte Counter data type. |
244 | */ | 238 | */ |
245 | 239 | ||
@@ -269,19 +263,19 @@ struct BusLogic_ProbeInfo { | |||
269 | */ | 263 | */ |
270 | 264 | ||
271 | struct BusLogic_ProbeOptions { | 265 | struct BusLogic_ProbeOptions { |
272 | boolean NoProbe:1; /* Bit 0 */ | 266 | bool NoProbe:1; /* Bit 0 */ |
273 | boolean NoProbeISA:1; /* Bit 1 */ | 267 | bool NoProbeISA:1; /* Bit 1 */ |
274 | boolean NoProbePCI:1; /* Bit 2 */ | 268 | bool NoProbePCI:1; /* Bit 2 */ |
275 | boolean NoSortPCI:1; /* Bit 3 */ | 269 | bool NoSortPCI:1; /* Bit 3 */ |
276 | boolean MultiMasterFirst:1; /* Bit 4 */ | 270 | bool MultiMasterFirst:1;/* Bit 4 */ |
277 | boolean FlashPointFirst:1; /* Bit 5 */ | 271 | bool FlashPointFirst:1; /* Bit 5 */ |
278 | boolean LimitedProbeISA:1; /* Bit 6 */ | 272 | bool LimitedProbeISA:1; /* Bit 6 */ |
279 | boolean Probe330:1; /* Bit 7 */ | 273 | bool Probe330:1; /* Bit 7 */ |
280 | boolean Probe334:1; /* Bit 8 */ | 274 | bool Probe334:1; /* Bit 8 */ |
281 | boolean Probe230:1; /* Bit 9 */ | 275 | bool Probe230:1; /* Bit 9 */ |
282 | boolean Probe234:1; /* Bit 10 */ | 276 | bool Probe234:1; /* Bit 10 */ |
283 | boolean Probe130:1; /* Bit 11 */ | 277 | bool Probe130:1; /* Bit 11 */ |
284 | boolean Probe134:1; /* Bit 12 */ | 278 | bool Probe134:1; /* Bit 12 */ |
285 | }; | 279 | }; |
286 | 280 | ||
287 | /* | 281 | /* |
@@ -289,10 +283,10 @@ struct BusLogic_ProbeOptions { | |||
289 | */ | 283 | */ |
290 | 284 | ||
291 | struct BusLogic_GlobalOptions { | 285 | struct BusLogic_GlobalOptions { |
292 | boolean TraceProbe:1; /* Bit 0 */ | 286 | bool TraceProbe:1; /* Bit 0 */ |
293 | boolean TraceHardwareReset:1; /* Bit 1 */ | 287 | bool TraceHardwareReset:1; /* Bit 1 */ |
294 | boolean TraceConfiguration:1; /* Bit 2 */ | 288 | bool TraceConfiguration:1; /* Bit 2 */ |
295 | boolean TraceErrors:1; /* Bit 3 */ | 289 | bool TraceErrors:1; /* Bit 3 */ |
296 | }; | 290 | }; |
297 | 291 | ||
298 | /* | 292 | /* |
@@ -300,7 +294,7 @@ struct BusLogic_GlobalOptions { | |||
300 | */ | 294 | */ |
301 | 295 | ||
302 | struct BusLogic_LocalOptions { | 296 | struct BusLogic_LocalOptions { |
303 | boolean InhibitTargetInquiry:1; /* Bit 0 */ | 297 | bool InhibitTargetInquiry:1; /* Bit 0 */ |
304 | }; | 298 | }; |
305 | 299 | ||
306 | /* | 300 | /* |
@@ -322,10 +316,10 @@ union BusLogic_ControlRegister { | |||
322 | unsigned char All; | 316 | unsigned char All; |
323 | struct { | 317 | struct { |
324 | unsigned char:4; /* Bits 0-3 */ | 318 | unsigned char:4; /* Bits 0-3 */ |
325 | boolean SCSIBusReset:1; /* Bit 4 */ | 319 | bool SCSIBusReset:1; /* Bit 4 */ |
326 | boolean InterruptReset:1; /* Bit 5 */ | 320 | bool InterruptReset:1; /* Bit 5 */ |
327 | boolean SoftReset:1; /* Bit 6 */ | 321 | bool SoftReset:1; /* Bit 6 */ |
328 | boolean HardReset:1; /* Bit 7 */ | 322 | bool HardReset:1; /* Bit 7 */ |
329 | } cr; | 323 | } cr; |
330 | }; | 324 | }; |
331 | 325 | ||
@@ -336,14 +330,14 @@ union BusLogic_ControlRegister { | |||
336 | union BusLogic_StatusRegister { | 330 | union BusLogic_StatusRegister { |
337 | unsigned char All; | 331 | unsigned char All; |
338 | struct { | 332 | struct { |
339 | boolean CommandInvalid:1; /* Bit 0 */ | 333 | bool CommandInvalid:1; /* Bit 0 */ |
340 | boolean Reserved:1; /* Bit 1 */ | 334 | bool Reserved:1; /* Bit 1 */ |
341 | boolean DataInRegisterReady:1; /* Bit 2 */ | 335 | bool DataInRegisterReady:1; /* Bit 2 */ |
342 | boolean CommandParameterRegisterBusy:1; /* Bit 3 */ | 336 | bool CommandParameterRegisterBusy:1; /* Bit 3 */ |
343 | boolean HostAdapterReady:1; /* Bit 4 */ | 337 | bool HostAdapterReady:1; /* Bit 4 */ |
344 | boolean InitializationRequired:1; /* Bit 5 */ | 338 | bool InitializationRequired:1; /* Bit 5 */ |
345 | boolean DiagnosticFailure:1; /* Bit 6 */ | 339 | bool DiagnosticFailure:1; /* Bit 6 */ |
346 | boolean DiagnosticActive:1; /* Bit 7 */ | 340 | bool DiagnosticActive:1; /* Bit 7 */ |
347 | } sr; | 341 | } sr; |
348 | }; | 342 | }; |
349 | 343 | ||
@@ -354,12 +348,12 @@ union BusLogic_StatusRegister { | |||
354 | union BusLogic_InterruptRegister { | 348 | union BusLogic_InterruptRegister { |
355 | unsigned char All; | 349 | unsigned char All; |
356 | struct { | 350 | struct { |
357 | boolean IncomingMailboxLoaded:1; /* Bit 0 */ | 351 | bool IncomingMailboxLoaded:1; /* Bit 0 */ |
358 | boolean OutgoingMailboxAvailable:1; /* Bit 1 */ | 352 | bool OutgoingMailboxAvailable:1;/* Bit 1 */ |
359 | boolean CommandComplete:1; /* Bit 2 */ | 353 | bool CommandComplete:1; /* Bit 2 */ |
360 | boolean ExternalBusReset:1; /* Bit 3 */ | 354 | bool ExternalBusReset:1; /* Bit 3 */ |
361 | unsigned char Reserved:3; /* Bits 4-6 */ | 355 | unsigned char Reserved:3; /* Bits 4-6 */ |
362 | boolean InterruptValid:1; /* Bit 7 */ | 356 | bool InterruptValid:1; /* Bit 7 */ |
363 | } ir; | 357 | } ir; |
364 | }; | 358 | }; |
365 | 359 | ||
@@ -373,7 +367,7 @@ union BusLogic_GeometryRegister { | |||
373 | enum BusLogic_BIOS_DiskGeometryTranslation Drive0Geometry:2; /* Bits 0-1 */ | 367 | enum BusLogic_BIOS_DiskGeometryTranslation Drive0Geometry:2; /* Bits 0-1 */ |
374 | enum BusLogic_BIOS_DiskGeometryTranslation Drive1Geometry:2; /* Bits 2-3 */ | 368 | enum BusLogic_BIOS_DiskGeometryTranslation Drive1Geometry:2; /* Bits 2-3 */ |
375 | unsigned char:3; /* Bits 4-6 */ | 369 | unsigned char:3; /* Bits 4-6 */ |
376 | boolean ExtendedTranslationEnabled:1; /* Bit 7 */ | 370 | bool ExtendedTranslationEnabled:1; /* Bit 7 */ |
377 | } gr; | 371 | } gr; |
378 | }; | 372 | }; |
379 | 373 | ||
@@ -445,16 +439,16 @@ struct BusLogic_BoardID { | |||
445 | 439 | ||
446 | struct BusLogic_Configuration { | 440 | struct BusLogic_Configuration { |
447 | unsigned char:5; /* Byte 0 Bits 0-4 */ | 441 | unsigned char:5; /* Byte 0 Bits 0-4 */ |
448 | boolean DMA_Channel5:1; /* Byte 0 Bit 5 */ | 442 | bool DMA_Channel5:1; /* Byte 0 Bit 5 */ |
449 | boolean DMA_Channel6:1; /* Byte 0 Bit 6 */ | 443 | bool DMA_Channel6:1; /* Byte 0 Bit 6 */ |
450 | boolean DMA_Channel7:1; /* Byte 0 Bit 7 */ | 444 | bool DMA_Channel7:1; /* Byte 0 Bit 7 */ |
451 | boolean IRQ_Channel9:1; /* Byte 1 Bit 0 */ | 445 | bool IRQ_Channel9:1; /* Byte 1 Bit 0 */ |
452 | boolean IRQ_Channel10:1; /* Byte 1 Bit 1 */ | 446 | bool IRQ_Channel10:1; /* Byte 1 Bit 1 */ |
453 | boolean IRQ_Channel11:1; /* Byte 1 Bit 2 */ | 447 | bool IRQ_Channel11:1; /* Byte 1 Bit 2 */ |
454 | boolean IRQ_Channel12:1; /* Byte 1 Bit 3 */ | 448 | bool IRQ_Channel12:1; /* Byte 1 Bit 3 */ |
455 | unsigned char:1; /* Byte 1 Bit 4 */ | 449 | unsigned char:1; /* Byte 1 Bit 4 */ |
456 | boolean IRQ_Channel14:1; /* Byte 1 Bit 5 */ | 450 | bool IRQ_Channel14:1; /* Byte 1 Bit 5 */ |
457 | boolean IRQ_Channel15:1; /* Byte 1 Bit 6 */ | 451 | bool IRQ_Channel15:1; /* Byte 1 Bit 6 */ |
458 | unsigned char:1; /* Byte 1 Bit 7 */ | 452 | unsigned char:1; /* Byte 1 Bit 7 */ |
459 | unsigned char HostAdapterID:4; /* Byte 2 Bits 0-3 */ | 453 | unsigned char HostAdapterID:4; /* Byte 2 Bits 0-3 */ |
460 | unsigned char:4; /* Byte 2 Bits 4-7 */ | 454 | unsigned char:4; /* Byte 2 Bits 4-7 */ |
@@ -467,12 +461,12 @@ struct BusLogic_Configuration { | |||
467 | struct BusLogic_SynchronousValue { | 461 | struct BusLogic_SynchronousValue { |
468 | unsigned char Offset:4; /* Bits 0-3 */ | 462 | unsigned char Offset:4; /* Bits 0-3 */ |
469 | unsigned char TransferPeriod:3; /* Bits 4-6 */ | 463 | unsigned char TransferPeriod:3; /* Bits 4-6 */ |
470 | boolean Synchronous:1; /* Bit 7 */ | 464 | bool Synchronous:1; /* Bit 7 */ |
471 | }; | 465 | }; |
472 | 466 | ||
473 | struct BusLogic_SetupInformation { | 467 | struct BusLogic_SetupInformation { |
474 | boolean SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */ | 468 | bool SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */ |
475 | boolean ParityCheckingEnabled:1; /* Byte 0 Bit 1 */ | 469 | bool ParityCheckingEnabled:1; /* Byte 0 Bit 1 */ |
476 | unsigned char:6; /* Byte 0 Bits 2-7 */ | 470 | unsigned char:6; /* Byte 0 Bits 2-7 */ |
477 | unsigned char BusTransferRate; /* Byte 1 */ | 471 | unsigned char BusTransferRate; /* Byte 1 */ |
478 | unsigned char PreemptTimeOnBus; /* Byte 2 */ | 472 | unsigned char PreemptTimeOnBus; /* Byte 2 */ |
@@ -523,13 +517,13 @@ enum BusLogic_ISACompatibleIOPort { | |||
523 | struct BusLogic_PCIHostAdapterInformation { | 517 | struct BusLogic_PCIHostAdapterInformation { |
524 | enum BusLogic_ISACompatibleIOPort ISACompatibleIOPort; /* Byte 0 */ | 518 | enum BusLogic_ISACompatibleIOPort ISACompatibleIOPort; /* Byte 0 */ |
525 | unsigned char PCIAssignedIRQChannel; /* Byte 1 */ | 519 | unsigned char PCIAssignedIRQChannel; /* Byte 1 */ |
526 | boolean LowByteTerminated:1; /* Byte 2 Bit 0 */ | 520 | bool LowByteTerminated:1; /* Byte 2 Bit 0 */ |
527 | boolean HighByteTerminated:1; /* Byte 2 Bit 1 */ | 521 | bool HighByteTerminated:1; /* Byte 2 Bit 1 */ |
528 | unsigned char:2; /* Byte 2 Bits 2-3 */ | 522 | unsigned char:2; /* Byte 2 Bits 2-3 */ |
529 | boolean JP1:1; /* Byte 2 Bit 4 */ | 523 | bool JP1:1; /* Byte 2 Bit 4 */ |
530 | boolean JP2:1; /* Byte 2 Bit 5 */ | 524 | bool JP2:1; /* Byte 2 Bit 5 */ |
531 | boolean JP3:1; /* Byte 2 Bit 6 */ | 525 | bool JP3:1; /* Byte 2 Bit 6 */ |
532 | boolean GenericInfoValid:1; /* Byte 2 Bit 7 */ | 526 | bool GenericInfoValid:1;/* Byte 2 Bit 7 */ |
533 | unsigned char:8; /* Byte 3 */ | 527 | unsigned char:8; /* Byte 3 */ |
534 | }; | 528 | }; |
535 | 529 | ||
@@ -545,17 +539,17 @@ struct BusLogic_ExtendedSetupInformation { | |||
545 | u32 BaseMailboxAddress; /* Bytes 5-8 */ | 539 | u32 BaseMailboxAddress; /* Bytes 5-8 */ |
546 | struct { | 540 | struct { |
547 | unsigned char:2; /* Byte 9 Bits 0-1 */ | 541 | unsigned char:2; /* Byte 9 Bits 0-1 */ |
548 | boolean FastOnEISA:1; /* Byte 9 Bit 2 */ | 542 | bool FastOnEISA:1; /* Byte 9 Bit 2 */ |
549 | unsigned char:3; /* Byte 9 Bits 3-5 */ | 543 | unsigned char:3; /* Byte 9 Bits 3-5 */ |
550 | boolean LevelSensitiveInterrupt:1; /* Byte 9 Bit 6 */ | 544 | bool LevelSensitiveInterrupt:1; /* Byte 9 Bit 6 */ |
551 | unsigned char:1; /* Byte 9 Bit 7 */ | 545 | unsigned char:1; /* Byte 9 Bit 7 */ |
552 | } Misc; | 546 | } Misc; |
553 | unsigned char FirmwareRevision[3]; /* Bytes 10-12 */ | 547 | unsigned char FirmwareRevision[3]; /* Bytes 10-12 */ |
554 | boolean HostWideSCSI:1; /* Byte 13 Bit 0 */ | 548 | bool HostWideSCSI:1; /* Byte 13 Bit 0 */ |
555 | boolean HostDifferentialSCSI:1; /* Byte 13 Bit 1 */ | 549 | bool HostDifferentialSCSI:1; /* Byte 13 Bit 1 */ |
556 | boolean HostSupportsSCAM:1; /* Byte 13 Bit 2 */ | 550 | bool HostSupportsSCAM:1; /* Byte 13 Bit 2 */ |
557 | boolean HostUltraSCSI:1; /* Byte 13 Bit 3 */ | 551 | bool HostUltraSCSI:1; /* Byte 13 Bit 3 */ |
558 | boolean HostSmartTermination:1; /* Byte 13 Bit 4 */ | 552 | bool HostSmartTermination:1; /* Byte 13 Bit 4 */ |
559 | unsigned char:3; /* Byte 13 Bits 5-7 */ | 553 | unsigned char:3; /* Byte 13 Bits 5-7 */ |
560 | } PACKED; | 554 | } PACKED; |
561 | 555 | ||
@@ -590,35 +584,35 @@ struct BusLogic_AutoSCSIData { | |||
590 | unsigned char InformationByteCount; /* Byte 2 */ | 584 | unsigned char InformationByteCount; /* Byte 2 */ |
591 | unsigned char HostAdapterType[6]; /* Bytes 3-8 */ | 585 | unsigned char HostAdapterType[6]; /* Bytes 3-8 */ |
592 | unsigned char:8; /* Byte 9 */ | 586 | unsigned char:8; /* Byte 9 */ |
593 | boolean FloppyEnabled:1; /* Byte 10 Bit 0 */ | 587 | bool FloppyEnabled:1; /* Byte 10 Bit 0 */ |
594 | boolean FloppySecondary:1; /* Byte 10 Bit 1 */ | 588 | bool FloppySecondary:1; /* Byte 10 Bit 1 */ |
595 | boolean LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */ | 589 | bool LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */ |
596 | unsigned char:2; /* Byte 10 Bits 3-4 */ | 590 | unsigned char:2; /* Byte 10 Bits 3-4 */ |
597 | unsigned char SystemRAMAreaForBIOS:3; /* Byte 10 Bits 5-7 */ | 591 | unsigned char SystemRAMAreaForBIOS:3; /* Byte 10 Bits 5-7 */ |
598 | unsigned char DMA_Channel:7; /* Byte 11 Bits 0-6 */ | 592 | unsigned char DMA_Channel:7; /* Byte 11 Bits 0-6 */ |
599 | boolean DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */ | 593 | bool DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */ |
600 | unsigned char IRQ_Channel:7; /* Byte 12 Bits 0-6 */ | 594 | unsigned char IRQ_Channel:7; /* Byte 12 Bits 0-6 */ |
601 | boolean IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */ | 595 | bool IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */ |
602 | unsigned char DMA_TransferRate; /* Byte 13 */ | 596 | unsigned char DMA_TransferRate; /* Byte 13 */ |
603 | unsigned char SCSI_ID; /* Byte 14 */ | 597 | unsigned char SCSI_ID; /* Byte 14 */ |
604 | boolean LowByteTerminated:1; /* Byte 15 Bit 0 */ | 598 | bool LowByteTerminated:1; /* Byte 15 Bit 0 */ |
605 | boolean ParityCheckingEnabled:1; /* Byte 15 Bit 1 */ | 599 | bool ParityCheckingEnabled:1; /* Byte 15 Bit 1 */ |
606 | boolean HighByteTerminated:1; /* Byte 15 Bit 2 */ | 600 | bool HighByteTerminated:1; /* Byte 15 Bit 2 */ |
607 | boolean NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */ | 601 | bool NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */ |
608 | boolean FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */ | 602 | bool FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */ |
609 | boolean BusResetEnabled:1; /* Byte 15 Bit 5 */ | 603 | bool BusResetEnabled:1; /* Byte 15 Bit 5 */ |
610 | boolean:1; /* Byte 15 Bit 6 */ | 604 | bool:1; /* Byte 15 Bit 6 */ |
611 | boolean ActiveNegationEnabled:1; /* Byte 15 Bit 7 */ | 605 | bool ActiveNegationEnabled:1; /* Byte 15 Bit 7 */ |
612 | unsigned char BusOnDelay; /* Byte 16 */ | 606 | unsigned char BusOnDelay; /* Byte 16 */ |
613 | unsigned char BusOffDelay; /* Byte 17 */ | 607 | unsigned char BusOffDelay; /* Byte 17 */ |
614 | boolean HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */ | 608 | bool HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */ |
615 | boolean BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */ | 609 | bool BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */ |
616 | boolean ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */ | 610 | bool ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */ |
617 | boolean MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */ | 611 | bool MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */ |
618 | boolean:1; /* Byte 18 Bit 4 */ | 612 | bool:1; /* Byte 18 Bit 4 */ |
619 | boolean BIOSSupportsMoreThan2DrivesEnabled:1; /* Byte 18 Bit 5 */ | 613 | bool BIOSSupportsMoreThan2DrivesEnabled:1; /* Byte 18 Bit 5 */ |
620 | boolean BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */ | 614 | bool BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */ |
621 | boolean FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */ | 615 | bool FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */ |
622 | unsigned short DeviceEnabled; /* Bytes 19-20 */ | 616 | unsigned short DeviceEnabled; /* Bytes 19-20 */ |
623 | unsigned short WidePermitted; /* Bytes 21-22 */ | 617 | unsigned short WidePermitted; /* Bytes 21-22 */ |
624 | unsigned short FastPermitted; /* Bytes 23-24 */ | 618 | unsigned short FastPermitted; /* Bytes 23-24 */ |
@@ -628,22 +622,22 @@ struct BusLogic_AutoSCSIData { | |||
628 | unsigned short IgnoreInBIOSScan; /* Bytes 31-32 */ | 622 | unsigned short IgnoreInBIOSScan; /* Bytes 31-32 */ |
629 | unsigned char PCIInterruptPin:2; /* Byte 33 Bits 0-1 */ | 623 | unsigned char PCIInterruptPin:2; /* Byte 33 Bits 0-1 */ |
630 | unsigned char HostAdapterIOPortAddress:2; /* Byte 33 Bits 2-3 */ | 624 | unsigned char HostAdapterIOPortAddress:2; /* Byte 33 Bits 2-3 */ |
631 | boolean StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */ | 625 | bool StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */ |
632 | boolean VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */ | 626 | bool VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */ |
633 | boolean VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */ | 627 | bool VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */ |
634 | boolean VESABurstReadEnabled:1; /* Byte 33 Bit 7 */ | 628 | bool VESABurstReadEnabled:1; /* Byte 33 Bit 7 */ |
635 | unsigned short UltraPermitted; /* Bytes 34-35 */ | 629 | unsigned short UltraPermitted; /* Bytes 34-35 */ |
636 | unsigned int:32; /* Bytes 36-39 */ | 630 | unsigned int:32; /* Bytes 36-39 */ |
637 | unsigned char:8; /* Byte 40 */ | 631 | unsigned char:8; /* Byte 40 */ |
638 | unsigned char AutoSCSIMaximumLUN; /* Byte 41 */ | 632 | unsigned char AutoSCSIMaximumLUN; /* Byte 41 */ |
639 | boolean:1; /* Byte 42 Bit 0 */ | 633 | bool:1; /* Byte 42 Bit 0 */ |
640 | boolean SCAM_Dominant:1; /* Byte 42 Bit 1 */ | 634 | bool SCAM_Dominant:1; /* Byte 42 Bit 1 */ |
641 | boolean SCAM_Enabled:1; /* Byte 42 Bit 2 */ | 635 | bool SCAM_Enabled:1; /* Byte 42 Bit 2 */ |
642 | boolean SCAM_Level2:1; /* Byte 42 Bit 3 */ | 636 | bool SCAM_Level2:1; /* Byte 42 Bit 3 */ |
643 | unsigned char:4; /* Byte 42 Bits 4-7 */ | 637 | unsigned char:4; /* Byte 42 Bits 4-7 */ |
644 | boolean INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */ | 638 | bool INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */ |
645 | boolean:1; /* Byte 43 Bit 1 */ | 639 | bool:1; /* Byte 43 Bit 1 */ |
646 | boolean CDROMBootEnabled:1; /* Byte 43 Bit 2 */ | 640 | bool CDROMBootEnabled:1; /* Byte 43 Bit 2 */ |
647 | unsigned char:5; /* Byte 43 Bits 3-7 */ | 641 | unsigned char:5; /* Byte 43 Bits 3-7 */ |
648 | unsigned char BootTargetID:4; /* Byte 44 Bits 0-3 */ | 642 | unsigned char BootTargetID:4; /* Byte 44 Bits 0-3 */ |
649 | unsigned char BootChannel:4; /* Byte 44 Bits 4-7 */ | 643 | unsigned char BootChannel:4; /* Byte 44 Bits 4-7 */ |
@@ -852,7 +846,7 @@ struct BusLogic_CCB { | |||
852 | enum BusLogic_CCB_Opcode Opcode; /* Byte 0 */ | 846 | enum BusLogic_CCB_Opcode Opcode; /* Byte 0 */ |
853 | unsigned char:3; /* Byte 1 Bits 0-2 */ | 847 | unsigned char:3; /* Byte 1 Bits 0-2 */ |
854 | enum BusLogic_DataDirection DataDirection:2; /* Byte 1 Bits 3-4 */ | 848 | enum BusLogic_DataDirection DataDirection:2; /* Byte 1 Bits 3-4 */ |
855 | boolean TagEnable:1; /* Byte 1 Bit 5 */ | 849 | bool TagEnable:1; /* Byte 1 Bit 5 */ |
856 | enum BusLogic_QueueTag QueueTag:2; /* Byte 1 Bits 6-7 */ | 850 | enum BusLogic_QueueTag QueueTag:2; /* Byte 1 Bits 6-7 */ |
857 | unsigned char CDB_Length; /* Byte 2 */ | 851 | unsigned char CDB_Length; /* Byte 2 */ |
858 | unsigned char SenseDataLength; /* Byte 3 */ | 852 | unsigned char SenseDataLength; /* Byte 3 */ |
@@ -864,7 +858,7 @@ struct BusLogic_CCB { | |||
864 | enum BusLogic_TargetDeviceStatus TargetDeviceStatus; /* Byte 15 */ | 858 | enum BusLogic_TargetDeviceStatus TargetDeviceStatus; /* Byte 15 */ |
865 | unsigned char TargetID; /* Byte 16 */ | 859 | unsigned char TargetID; /* Byte 16 */ |
866 | unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */ | 860 | unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */ |
867 | boolean LegacyTagEnable:1; /* Byte 17 Bit 5 */ | 861 | bool LegacyTagEnable:1; /* Byte 17 Bit 5 */ |
868 | enum BusLogic_QueueTag LegacyQueueTag:2; /* Byte 17 Bits 6-7 */ | 862 | enum BusLogic_QueueTag LegacyQueueTag:2; /* Byte 17 Bits 6-7 */ |
869 | SCSI_CDB_T CDB; /* Bytes 18-29 */ | 863 | SCSI_CDB_T CDB; /* Bytes 18-29 */ |
870 | unsigned char:8; /* Byte 30 */ | 864 | unsigned char:8; /* Byte 30 */ |
@@ -939,13 +933,13 @@ struct BusLogic_DriverOptions { | |||
939 | */ | 933 | */ |
940 | 934 | ||
941 | struct BusLogic_TargetFlags { | 935 | struct BusLogic_TargetFlags { |
942 | boolean TargetExists:1; | 936 | bool TargetExists:1; |
943 | boolean TaggedQueuingSupported:1; | 937 | bool TaggedQueuingSupported:1; |
944 | boolean WideTransfersSupported:1; | 938 | bool WideTransfersSupported:1; |
945 | boolean TaggedQueuingActive:1; | 939 | bool TaggedQueuingActive:1; |
946 | boolean WideTransfersActive:1; | 940 | bool WideTransfersActive:1; |
947 | boolean CommandSuccessfulFlag:1; | 941 | bool CommandSuccessfulFlag:1; |
948 | boolean TargetInfoReported:1; | 942 | bool TargetInfoReported:1; |
949 | }; | 943 | }; |
950 | 944 | ||
951 | /* | 945 | /* |
@@ -992,7 +986,7 @@ typedef unsigned int FlashPoint_CardHandle_T; | |||
992 | 986 | ||
993 | struct FlashPoint_Info { | 987 | struct FlashPoint_Info { |
994 | u32 BaseAddress; /* Bytes 0-3 */ | 988 | u32 BaseAddress; /* Bytes 0-3 */ |
995 | boolean Present; /* Byte 4 */ | 989 | bool Present; /* Byte 4 */ |
996 | unsigned char IRQ_Channel; /* Byte 5 */ | 990 | unsigned char IRQ_Channel; /* Byte 5 */ |
997 | unsigned char SCSI_ID; /* Byte 6 */ | 991 | unsigned char SCSI_ID; /* Byte 6 */ |
998 | unsigned char SCSI_LUN; /* Byte 7 */ | 992 | unsigned char SCSI_LUN; /* Byte 7 */ |
@@ -1002,15 +996,15 @@ struct FlashPoint_Info { | |||
1002 | unsigned short UltraPermitted; /* Bytes 14-15 */ | 996 | unsigned short UltraPermitted; /* Bytes 14-15 */ |
1003 | unsigned short DisconnectPermitted; /* Bytes 16-17 */ | 997 | unsigned short DisconnectPermitted; /* Bytes 16-17 */ |
1004 | unsigned short WidePermitted; /* Bytes 18-19 */ | 998 | unsigned short WidePermitted; /* Bytes 18-19 */ |
1005 | boolean ParityCheckingEnabled:1; /* Byte 20 Bit 0 */ | 999 | bool ParityCheckingEnabled:1; /* Byte 20 Bit 0 */ |
1006 | boolean HostWideSCSI:1; /* Byte 20 Bit 1 */ | 1000 | bool HostWideSCSI:1; /* Byte 20 Bit 1 */ |
1007 | boolean HostSoftReset:1; /* Byte 20 Bit 2 */ | 1001 | bool HostSoftReset:1; /* Byte 20 Bit 2 */ |
1008 | boolean ExtendedTranslationEnabled:1; /* Byte 20 Bit 3 */ | 1002 | bool ExtendedTranslationEnabled:1; /* Byte 20 Bit 3 */ |
1009 | boolean LowByteTerminated:1; /* Byte 20 Bit 4 */ | 1003 | bool LowByteTerminated:1; /* Byte 20 Bit 4 */ |
1010 | boolean HighByteTerminated:1; /* Byte 20 Bit 5 */ | 1004 | bool HighByteTerminated:1; /* Byte 20 Bit 5 */ |
1011 | boolean ReportDataUnderrun:1; /* Byte 20 Bit 6 */ | 1005 | bool ReportDataUnderrun:1; /* Byte 20 Bit 6 */ |
1012 | boolean SCAM_Enabled:1; /* Byte 20 Bit 7 */ | 1006 | bool SCAM_Enabled:1; /* Byte 20 Bit 7 */ |
1013 | boolean SCAM_Level2:1; /* Byte 21 Bit 0 */ | 1007 | bool SCAM_Level2:1; /* Byte 21 Bit 0 */ |
1014 | unsigned char:7; /* Byte 21 Bits 1-7 */ | 1008 | unsigned char:7; /* Byte 21 Bits 1-7 */ |
1015 | unsigned char Family; /* Byte 22 */ | 1009 | unsigned char Family; /* Byte 22 */ |
1016 | unsigned char BusType; /* Byte 23 */ | 1010 | unsigned char BusType; /* Byte 23 */ |
@@ -1044,29 +1038,29 @@ struct BusLogic_HostAdapter { | |||
1044 | unsigned char IRQ_Channel; | 1038 | unsigned char IRQ_Channel; |
1045 | unsigned char DMA_Channel; | 1039 | unsigned char DMA_Channel; |
1046 | unsigned char SCSI_ID; | 1040 | unsigned char SCSI_ID; |
1047 | boolean IRQ_ChannelAcquired:1; | 1041 | bool IRQ_ChannelAcquired:1; |
1048 | boolean DMA_ChannelAcquired:1; | 1042 | bool DMA_ChannelAcquired:1; |
1049 | boolean ExtendedTranslationEnabled:1; | 1043 | bool ExtendedTranslationEnabled:1; |
1050 | boolean ParityCheckingEnabled:1; | 1044 | bool ParityCheckingEnabled:1; |
1051 | boolean BusResetEnabled:1; | 1045 | bool BusResetEnabled:1; |
1052 | boolean LevelSensitiveInterrupt:1; | 1046 | bool LevelSensitiveInterrupt:1; |
1053 | boolean HostWideSCSI:1; | 1047 | bool HostWideSCSI:1; |
1054 | boolean HostDifferentialSCSI:1; | 1048 | bool HostDifferentialSCSI:1; |
1055 | boolean HostSupportsSCAM:1; | 1049 | bool HostSupportsSCAM:1; |
1056 | boolean HostUltraSCSI:1; | 1050 | bool HostUltraSCSI:1; |
1057 | boolean ExtendedLUNSupport:1; | 1051 | bool ExtendedLUNSupport:1; |
1058 | boolean TerminationInfoValid:1; | 1052 | bool TerminationInfoValid:1; |
1059 | boolean LowByteTerminated:1; | 1053 | bool LowByteTerminated:1; |
1060 | boolean HighByteTerminated:1; | 1054 | bool HighByteTerminated:1; |
1061 | boolean BounceBuffersRequired:1; | 1055 | bool BounceBuffersRequired:1; |
1062 | boolean StrictRoundRobinModeSupport:1; | 1056 | bool StrictRoundRobinModeSupport:1; |
1063 | boolean SCAM_Enabled:1; | 1057 | bool SCAM_Enabled:1; |
1064 | boolean SCAM_Level2:1; | 1058 | bool SCAM_Level2:1; |
1065 | boolean HostAdapterInitialized:1; | 1059 | bool HostAdapterInitialized:1; |
1066 | boolean HostAdapterExternalReset:1; | 1060 | bool HostAdapterExternalReset:1; |
1067 | boolean HostAdapterInternalError:1; | 1061 | bool HostAdapterInternalError:1; |
1068 | boolean ProcessCompletedCCBsActive; | 1062 | bool ProcessCompletedCCBsActive; |
1069 | volatile boolean HostAdapterCommandCompleted; | 1063 | volatile bool HostAdapterCommandCompleted; |
1070 | unsigned short HostAdapterScatterGatherLimit; | 1064 | unsigned short HostAdapterScatterGatherLimit; |
1071 | unsigned short DriverScatterGatherLimit; | 1065 | unsigned short DriverScatterGatherLimit; |
1072 | unsigned short MaxTargetDevices; | 1066 | unsigned short MaxTargetDevices; |
@@ -1141,25 +1135,25 @@ struct SCSI_Inquiry { | |||
1141 | unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ | 1135 | unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ |
1142 | unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ | 1136 | unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ |
1143 | unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ | 1137 | unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ |
1144 | boolean RMB:1; /* Byte 1 Bit 7 */ | 1138 | bool RMB:1; /* Byte 1 Bit 7 */ |
1145 | unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ | 1139 | unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ |
1146 | unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ | 1140 | unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ |
1147 | unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ | 1141 | unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ |
1148 | unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ | 1142 | unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ |
1149 | unsigned char:2; /* Byte 3 Bits 4-5 */ | 1143 | unsigned char:2; /* Byte 3 Bits 4-5 */ |
1150 | boolean TrmIOP:1; /* Byte 3 Bit 6 */ | 1144 | bool TrmIOP:1; /* Byte 3 Bit 6 */ |
1151 | boolean AENC:1; /* Byte 3 Bit 7 */ | 1145 | bool AENC:1; /* Byte 3 Bit 7 */ |
1152 | unsigned char AdditionalLength; /* Byte 4 */ | 1146 | unsigned char AdditionalLength; /* Byte 4 */ |
1153 | unsigned char:8; /* Byte 5 */ | 1147 | unsigned char:8; /* Byte 5 */ |
1154 | unsigned char:8; /* Byte 6 */ | 1148 | unsigned char:8; /* Byte 6 */ |
1155 | boolean SftRe:1; /* Byte 7 Bit 0 */ | 1149 | bool SftRe:1; /* Byte 7 Bit 0 */ |
1156 | boolean CmdQue:1; /* Byte 7 Bit 1 */ | 1150 | bool CmdQue:1; /* Byte 7 Bit 1 */ |
1157 | boolean:1; /* Byte 7 Bit 2 */ | 1151 | bool:1; /* Byte 7 Bit 2 */ |
1158 | boolean Linked:1; /* Byte 7 Bit 3 */ | 1152 | bool Linked:1; /* Byte 7 Bit 3 */ |
1159 | boolean Sync:1; /* Byte 7 Bit 4 */ | 1153 | bool Sync:1; /* Byte 7 Bit 4 */ |
1160 | boolean WBus16:1; /* Byte 7 Bit 5 */ | 1154 | bool WBus16:1; /* Byte 7 Bit 5 */ |
1161 | boolean WBus32:1; /* Byte 7 Bit 6 */ | 1155 | bool WBus32:1; /* Byte 7 Bit 6 */ |
1162 | boolean RelAdr:1; /* Byte 7 Bit 7 */ | 1156 | bool RelAdr:1; /* Byte 7 Bit 7 */ |
1163 | unsigned char VendorIdentification[8]; /* Bytes 8-15 */ | 1157 | unsigned char VendorIdentification[8]; /* Bytes 8-15 */ |
1164 | unsigned char ProductIdentification[16]; /* Bytes 16-31 */ | 1158 | unsigned char ProductIdentification[16]; /* Bytes 16-31 */ |
1165 | unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ | 1159 | unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ |
@@ -1348,7 +1342,7 @@ static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t | |||
1348 | static int BusLogic_SlaveConfigure(struct scsi_device *); | 1342 | static int BusLogic_SlaveConfigure(struct scsi_device *); |
1349 | static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *); | 1343 | static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *); |
1350 | static irqreturn_t BusLogic_InterruptHandler(int, void *); | 1344 | static irqreturn_t BusLogic_InterruptHandler(int, void *); |
1351 | static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, boolean HardReset); | 1345 | static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, bool HardReset); |
1352 | static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...); | 1346 | static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...); |
1353 | static int __init BusLogic_Setup(char *); | 1347 | static int __init BusLogic_Setup(char *); |
1354 | 1348 | ||
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 7c0068049586..a7f916c0c9cd 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c | |||
@@ -7609,7 +7609,7 @@ FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, | |||
7609 | FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); | 7609 | FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); |
7610 | } | 7610 | } |
7611 | 7611 | ||
7612 | static inline boolean | 7612 | static inline bool |
7613 | FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle) | 7613 | FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle) |
7614 | { | 7614 | { |
7615 | return FlashPoint_InterruptPending(CardHandle); | 7615 | return FlashPoint_InterruptPending(CardHandle); |
@@ -7640,7 +7640,7 @@ extern FlashPoint_CardHandle_T | |||
7640 | FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *); | 7640 | FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *); |
7641 | extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); | 7641 | extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); |
7642 | extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); | 7642 | extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *); |
7643 | extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T); | 7643 | extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T); |
7644 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); | 7644 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); |
7645 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); | 7645 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); |
7646 | 7646 | ||
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 7869c34a4a3e..5bf3f07870ba 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -973,6 +973,15 @@ config SCSI_LASI700 | |||
973 | many PA-RISC workstations & servers. If you do not know whether you | 973 | many PA-RISC workstations & servers. If you do not know whether you |
974 | have a Lasi chip, it is safe to say "Y" here. | 974 | have a Lasi chip, it is safe to say "Y" here. |
975 | 975 | ||
976 | config SCSI_SNI_53C710 | ||
977 | tristate "SNI RM SCSI support for 53c710" | ||
978 | depends on SNI_RM && SCSI | ||
979 | select SCSI_SPI_ATTRS | ||
980 | select 53C700_LE_ON_BE | ||
981 | help | ||
982 | This is a driver for the onboard SCSI controller found in older | ||
983 | SNI RM workstations & servers. | ||
984 | |||
976 | config 53C700_LE_ON_BE | 985 | config 53C700_LE_ON_BE |
977 | bool | 986 | bool |
978 | depends on SCSI_LASI700 | 987 | depends on SCSI_LASI700 |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index bd7c9888f7f4..79ecf4ebe6eb 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -124,6 +124,7 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o | |||
124 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o | 124 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o |
125 | obj-$(CONFIG_SCSI_FCAL) += fcal.o | 125 | obj-$(CONFIG_SCSI_FCAL) += fcal.o |
126 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o | 126 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o |
127 | obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o | ||
127 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o | 128 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o |
128 | obj-$(CONFIG_SCSI_IPR) += ipr.o | 129 | obj-$(CONFIG_SCSI_IPR) += ipr.o |
129 | obj-$(CONFIG_SCSI_SRP) += libsrp.o | 130 | obj-$(CONFIG_SCSI_SRP) += libsrp.o |
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 9859cd17fc57..f12864abed2f 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c | |||
@@ -200,6 +200,7 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, | |||
200 | hostdata->base = ioport_map(region, 64); | 200 | hostdata->base = ioport_map(region, 64); |
201 | hostdata->differential = (((1<<siop) & differential) != 0); | 201 | hostdata->differential = (((1<<siop) & differential) != 0); |
202 | hostdata->clock = NCR_D700_CLOCK_MHZ; | 202 | hostdata->clock = NCR_D700_CLOCK_MHZ; |
203 | hostdata->burst_length = 8; | ||
203 | 204 | ||
204 | /* and register the siop */ | 205 | /* and register the siop */ |
205 | host = NCR_700_detect(&NCR_D700_driver_template, hostdata, p->dev); | 206 | host = NCR_700_detect(&NCR_D700_driver_template, hostdata, p->dev); |
diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile index 28d133a3094f..f1cca4ee5410 100644 --- a/drivers/scsi/aacraid/Makefile +++ b/drivers/scsi/aacraid/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | obj-$(CONFIG_SCSI_AACRAID) := aacraid.o | 3 | obj-$(CONFIG_SCSI_AACRAID) := aacraid.o |
4 | 4 | ||
5 | aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \ | 5 | aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \ |
6 | dpcsup.o rx.o sa.o rkt.o | 6 | dpcsup.o rx.o sa.o rkt.o nark.o |
7 | 7 | ||
8 | EXTRA_CFLAGS := -Idrivers/scsi | 8 | EXTRA_CFLAGS := -Idrivers/scsi |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 426cd6f49f5d..ddb33b06e0ef 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -170,9 +170,9 @@ int acbsize = -1; | |||
170 | module_param(acbsize, int, S_IRUGO|S_IWUSR); | 170 | module_param(acbsize, int, S_IRUGO|S_IWUSR); |
171 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); | 171 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); |
172 | 172 | ||
173 | int expose_physicals = 0; | 173 | int expose_physicals = -1; |
174 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); | 174 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); |
175 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. 0=off, 1=on"); | 175 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); |
176 | /** | 176 | /** |
177 | * aac_get_config_status - check the adapter configuration | 177 | * aac_get_config_status - check the adapter configuration |
178 | * @common: adapter to query | 178 | * @common: adapter to query |
@@ -706,6 +706,309 @@ static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, | |||
706 | } | 706 | } |
707 | } | 707 | } |
708 | 708 | ||
709 | static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba) | ||
710 | { | ||
711 | if (lba & 0xffffffff00000000LL) { | ||
712 | int cid = scmd_id(cmd); | ||
713 | dprintk((KERN_DEBUG "aacraid: Illegal lba\n")); | ||
714 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | | ||
715 | SAM_STAT_CHECK_CONDITION; | ||
716 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
717 | HARDWARE_ERROR, | ||
718 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
719 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
720 | 0, 0); | ||
721 | memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
722 | (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(cmd->sense_buffer)) | ||
723 | ? sizeof(cmd->sense_buffer) | ||
724 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
725 | cmd->scsi_done(cmd); | ||
726 | return 1; | ||
727 | } | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static int aac_bounds_64(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba) | ||
732 | { | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static void io_callback(void *context, struct fib * fibptr); | ||
737 | |||
738 | static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
739 | { | ||
740 | u16 fibsize; | ||
741 | struct aac_raw_io *readcmd; | ||
742 | aac_fib_init(fib); | ||
743 | readcmd = (struct aac_raw_io *) fib_data(fib); | ||
744 | readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
745 | readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
746 | readcmd->count = cpu_to_le32(count<<9); | ||
747 | readcmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
748 | readcmd->flags = cpu_to_le16(1); | ||
749 | readcmd->bpTotal = 0; | ||
750 | readcmd->bpComplete = 0; | ||
751 | |||
752 | aac_build_sgraw(cmd, &readcmd->sg); | ||
753 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
754 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); | ||
755 | /* | ||
756 | * Now send the Fib to the adapter | ||
757 | */ | ||
758 | return aac_fib_send(ContainerRawIo, | ||
759 | fib, | ||
760 | fibsize, | ||
761 | FsaNormal, | ||
762 | 0, 1, | ||
763 | (fib_callback) io_callback, | ||
764 | (void *) cmd); | ||
765 | } | ||
766 | |||
767 | static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
768 | { | ||
769 | u16 fibsize; | ||
770 | struct aac_read64 *readcmd; | ||
771 | aac_fib_init(fib); | ||
772 | readcmd = (struct aac_read64 *) fib_data(fib); | ||
773 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | ||
774 | readcmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
775 | readcmd->sector_count = cpu_to_le16(count); | ||
776 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
777 | readcmd->pad = 0; | ||
778 | readcmd->flags = 0; | ||
779 | |||
780 | aac_build_sg64(cmd, &readcmd->sg); | ||
781 | fibsize = sizeof(struct aac_read64) + | ||
782 | ((le32_to_cpu(readcmd->sg.count) - 1) * | ||
783 | sizeof (struct sgentry64)); | ||
784 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
785 | sizeof(struct aac_fibhdr))); | ||
786 | /* | ||
787 | * Now send the Fib to the adapter | ||
788 | */ | ||
789 | return aac_fib_send(ContainerCommand64, | ||
790 | fib, | ||
791 | fibsize, | ||
792 | FsaNormal, | ||
793 | 0, 1, | ||
794 | (fib_callback) io_callback, | ||
795 | (void *) cmd); | ||
796 | } | ||
797 | |||
798 | static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
799 | { | ||
800 | u16 fibsize; | ||
801 | struct aac_read *readcmd; | ||
802 | aac_fib_init(fib); | ||
803 | readcmd = (struct aac_read *) fib_data(fib); | ||
804 | readcmd->command = cpu_to_le32(VM_CtBlockRead); | ||
805 | readcmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
806 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
807 | readcmd->count = cpu_to_le32(count * 512); | ||
808 | |||
809 | aac_build_sg(cmd, &readcmd->sg); | ||
810 | fibsize = sizeof(struct aac_read) + | ||
811 | ((le32_to_cpu(readcmd->sg.count) - 1) * | ||
812 | sizeof (struct sgentry)); | ||
813 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
814 | sizeof(struct aac_fibhdr))); | ||
815 | /* | ||
816 | * Now send the Fib to the adapter | ||
817 | */ | ||
818 | return aac_fib_send(ContainerCommand, | ||
819 | fib, | ||
820 | fibsize, | ||
821 | FsaNormal, | ||
822 | 0, 1, | ||
823 | (fib_callback) io_callback, | ||
824 | (void *) cmd); | ||
825 | } | ||
826 | |||
827 | static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
828 | { | ||
829 | u16 fibsize; | ||
830 | struct aac_raw_io *writecmd; | ||
831 | aac_fib_init(fib); | ||
832 | writecmd = (struct aac_raw_io *) fib_data(fib); | ||
833 | writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
834 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
835 | writecmd->count = cpu_to_le32(count<<9); | ||
836 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
837 | writecmd->flags = 0; | ||
838 | writecmd->bpTotal = 0; | ||
839 | writecmd->bpComplete = 0; | ||
840 | |||
841 | aac_build_sgraw(cmd, &writecmd->sg); | ||
842 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
843 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); | ||
844 | /* | ||
845 | * Now send the Fib to the adapter | ||
846 | */ | ||
847 | return aac_fib_send(ContainerRawIo, | ||
848 | fib, | ||
849 | fibsize, | ||
850 | FsaNormal, | ||
851 | 0, 1, | ||
852 | (fib_callback) io_callback, | ||
853 | (void *) cmd); | ||
854 | } | ||
855 | |||
856 | static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
857 | { | ||
858 | u16 fibsize; | ||
859 | struct aac_write64 *writecmd; | ||
860 | aac_fib_init(fib); | ||
861 | writecmd = (struct aac_write64 *) fib_data(fib); | ||
862 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); | ||
863 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
864 | writecmd->sector_count = cpu_to_le16(count); | ||
865 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
866 | writecmd->pad = 0; | ||
867 | writecmd->flags = 0; | ||
868 | |||
869 | aac_build_sg64(cmd, &writecmd->sg); | ||
870 | fibsize = sizeof(struct aac_write64) + | ||
871 | ((le32_to_cpu(writecmd->sg.count) - 1) * | ||
872 | sizeof (struct sgentry64)); | ||
873 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
874 | sizeof(struct aac_fibhdr))); | ||
875 | /* | ||
876 | * Now send the Fib to the adapter | ||
877 | */ | ||
878 | return aac_fib_send(ContainerCommand64, | ||
879 | fib, | ||
880 | fibsize, | ||
881 | FsaNormal, | ||
882 | 0, 1, | ||
883 | (fib_callback) io_callback, | ||
884 | (void *) cmd); | ||
885 | } | ||
886 | |||
887 | static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | ||
888 | { | ||
889 | u16 fibsize; | ||
890 | struct aac_write *writecmd; | ||
891 | aac_fib_init(fib); | ||
892 | writecmd = (struct aac_write *) fib_data(fib); | ||
893 | writecmd->command = cpu_to_le32(VM_CtBlockWrite); | ||
894 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
895 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
896 | writecmd->count = cpu_to_le32(count * 512); | ||
897 | writecmd->sg.count = cpu_to_le32(1); | ||
898 | /* ->stable is not used - it did mean which type of write */ | ||
899 | |||
900 | aac_build_sg(cmd, &writecmd->sg); | ||
901 | fibsize = sizeof(struct aac_write) + | ||
902 | ((le32_to_cpu(writecmd->sg.count) - 1) * | ||
903 | sizeof (struct sgentry)); | ||
904 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
905 | sizeof(struct aac_fibhdr))); | ||
906 | /* | ||
907 | * Now send the Fib to the adapter | ||
908 | */ | ||
909 | return aac_fib_send(ContainerCommand, | ||
910 | fib, | ||
911 | fibsize, | ||
912 | FsaNormal, | ||
913 | 0, 1, | ||
914 | (fib_callback) io_callback, | ||
915 | (void *) cmd); | ||
916 | } | ||
917 | |||
918 | static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd) | ||
919 | { | ||
920 | struct aac_srb * srbcmd; | ||
921 | u32 flag; | ||
922 | u32 timeout; | ||
923 | |||
924 | aac_fib_init(fib); | ||
925 | switch(cmd->sc_data_direction){ | ||
926 | case DMA_TO_DEVICE: | ||
927 | flag = SRB_DataOut; | ||
928 | break; | ||
929 | case DMA_BIDIRECTIONAL: | ||
930 | flag = SRB_DataIn | SRB_DataOut; | ||
931 | break; | ||
932 | case DMA_FROM_DEVICE: | ||
933 | flag = SRB_DataIn; | ||
934 | break; | ||
935 | case DMA_NONE: | ||
936 | default: /* shuts up some versions of gcc */ | ||
937 | flag = SRB_NoDataXfer; | ||
938 | break; | ||
939 | } | ||
940 | |||
941 | srbcmd = (struct aac_srb*) fib_data(fib); | ||
942 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); | ||
943 | srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(cmd))); | ||
944 | srbcmd->id = cpu_to_le32(scmd_id(cmd)); | ||
945 | srbcmd->lun = cpu_to_le32(cmd->device->lun); | ||
946 | srbcmd->flags = cpu_to_le32(flag); | ||
947 | timeout = cmd->timeout_per_command/HZ; | ||
948 | if (timeout == 0) | ||
949 | timeout = 1; | ||
950 | srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds | ||
951 | srbcmd->retry_limit = 0; /* Obsolete parameter */ | ||
952 | srbcmd->cdb_size = cpu_to_le32(cmd->cmd_len); | ||
953 | return srbcmd; | ||
954 | } | ||
955 | |||
956 | static void aac_srb_callback(void *context, struct fib * fibptr); | ||
957 | |||
958 | static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd) | ||
959 | { | ||
960 | u16 fibsize; | ||
961 | struct aac_srb * srbcmd = aac_scsi_common(fib, cmd); | ||
962 | |||
963 | aac_build_sg64(cmd, (struct sgmap64*) &srbcmd->sg); | ||
964 | srbcmd->count = cpu_to_le32(cmd->request_bufflen); | ||
965 | |||
966 | memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); | ||
967 | memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len); | ||
968 | /* | ||
969 | * Build Scatter/Gather list | ||
970 | */ | ||
971 | fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) + | ||
972 | ((le32_to_cpu(srbcmd->sg.count) & 0xff) * | ||
973 | sizeof (struct sgentry64)); | ||
974 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
975 | sizeof(struct aac_fibhdr))); | ||
976 | |||
977 | /* | ||
978 | * Now send the Fib to the adapter | ||
979 | */ | ||
980 | return aac_fib_send(ScsiPortCommand64, fib, | ||
981 | fibsize, FsaNormal, 0, 1, | ||
982 | (fib_callback) aac_srb_callback, | ||
983 | (void *) cmd); | ||
984 | } | ||
985 | |||
986 | static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd) | ||
987 | { | ||
988 | u16 fibsize; | ||
989 | struct aac_srb * srbcmd = aac_scsi_common(fib, cmd); | ||
990 | |||
991 | aac_build_sg(cmd, (struct sgmap*)&srbcmd->sg); | ||
992 | srbcmd->count = cpu_to_le32(cmd->request_bufflen); | ||
993 | |||
994 | memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); | ||
995 | memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len); | ||
996 | /* | ||
997 | * Build Scatter/Gather list | ||
998 | */ | ||
999 | fibsize = sizeof (struct aac_srb) + | ||
1000 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | ||
1001 | sizeof (struct sgentry)); | ||
1002 | BUG_ON (fibsize > (fib->dev->max_fib_size - | ||
1003 | sizeof(struct aac_fibhdr))); | ||
1004 | |||
1005 | /* | ||
1006 | * Now send the Fib to the adapter | ||
1007 | */ | ||
1008 | return aac_fib_send(ScsiPortCommand, fib, fibsize, FsaNormal, 0, 1, | ||
1009 | (fib_callback) aac_srb_callback, (void *) cmd); | ||
1010 | } | ||
1011 | |||
709 | int aac_get_adapter_info(struct aac_dev* dev) | 1012 | int aac_get_adapter_info(struct aac_dev* dev) |
710 | { | 1013 | { |
711 | struct fib* fibptr; | 1014 | struct fib* fibptr; |
@@ -874,14 +1177,27 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
874 | } | 1177 | } |
875 | } | 1178 | } |
876 | /* | 1179 | /* |
877 | * 57 scatter gather elements | 1180 | * Deal with configuring for the individualized limits of each packet |
1181 | * interface. | ||
878 | */ | 1182 | */ |
879 | if (!(dev->raw_io_interface)) { | 1183 | dev->a_ops.adapter_scsi = (dev->dac_support) |
1184 | ? aac_scsi_64 | ||
1185 | : aac_scsi_32; | ||
1186 | if (dev->raw_io_interface) { | ||
1187 | dev->a_ops.adapter_bounds = (dev->raw_io_64) | ||
1188 | ? aac_bounds_64 | ||
1189 | : aac_bounds_32; | ||
1190 | dev->a_ops.adapter_read = aac_read_raw_io; | ||
1191 | dev->a_ops.adapter_write = aac_write_raw_io; | ||
1192 | } else { | ||
1193 | dev->a_ops.adapter_bounds = aac_bounds_32; | ||
880 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - | 1194 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - |
881 | sizeof(struct aac_fibhdr) - | 1195 | sizeof(struct aac_fibhdr) - |
882 | sizeof(struct aac_write) + sizeof(struct sgentry)) / | 1196 | sizeof(struct aac_write) + sizeof(struct sgentry)) / |
883 | sizeof(struct sgentry); | 1197 | sizeof(struct sgentry); |
884 | if (dev->dac_support) { | 1198 | if (dev->dac_support) { |
1199 | dev->a_ops.adapter_read = aac_read_block64; | ||
1200 | dev->a_ops.adapter_write = aac_write_block64; | ||
885 | /* | 1201 | /* |
886 | * 38 scatter gather elements | 1202 | * 38 scatter gather elements |
887 | */ | 1203 | */ |
@@ -891,6 +1207,9 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
891 | sizeof(struct aac_write64) + | 1207 | sizeof(struct aac_write64) + |
892 | sizeof(struct sgentry64)) / | 1208 | sizeof(struct sgentry64)) / |
893 | sizeof(struct sgentry64); | 1209 | sizeof(struct sgentry64); |
1210 | } else { | ||
1211 | dev->a_ops.adapter_read = aac_read_block; | ||
1212 | dev->a_ops.adapter_write = aac_write_block; | ||
894 | } | 1213 | } |
895 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | 1214 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; |
896 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | 1215 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { |
@@ -1004,8 +1323,6 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1004 | u64 lba; | 1323 | u64 lba; |
1005 | u32 count; | 1324 | u32 count; |
1006 | int status; | 1325 | int status; |
1007 | |||
1008 | u16 fibsize; | ||
1009 | struct aac_dev *dev; | 1326 | struct aac_dev *dev; |
1010 | struct fib * cmd_fibcontext; | 1327 | struct fib * cmd_fibcontext; |
1011 | 1328 | ||
@@ -1059,23 +1376,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1059 | } | 1376 | } |
1060 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", | 1377 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", |
1061 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1378 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1062 | if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) && | 1379 | if (aac_adapter_bounds(dev,scsicmd,lba)) |
1063 | (lba & 0xffffffff00000000LL)) { | ||
1064 | dprintk((KERN_DEBUG "aac_read: Illegal lba\n")); | ||
1065 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | | ||
1066 | SAM_STAT_CHECK_CONDITION; | ||
1067 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
1068 | HARDWARE_ERROR, | ||
1069 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
1070 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
1071 | 0, 0); | ||
1072 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1073 | (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) | ||
1074 | ? sizeof(scsicmd->sense_buffer) | ||
1075 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
1076 | scsicmd->scsi_done(scsicmd); | ||
1077 | return 0; | 1380 | return 0; |
1078 | } | ||
1079 | /* | 1381 | /* |
1080 | * Alocate and initialize a Fib | 1382 | * Alocate and initialize a Fib |
1081 | */ | 1383 | */ |
@@ -1083,85 +1385,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1083 | return -1; | 1385 | return -1; |
1084 | } | 1386 | } |
1085 | 1387 | ||
1086 | aac_fib_init(cmd_fibcontext); | 1388 | status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count); |
1087 | |||
1088 | if (dev->raw_io_interface) { | ||
1089 | struct aac_raw_io *readcmd; | ||
1090 | readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
1091 | readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1092 | readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
1093 | readcmd->count = cpu_to_le32(count<<9); | ||
1094 | readcmd->cid = cpu_to_le16(cid); | ||
1095 | readcmd->flags = cpu_to_le16(1); | ||
1096 | readcmd->bpTotal = 0; | ||
1097 | readcmd->bpComplete = 0; | ||
1098 | |||
1099 | aac_build_sgraw(scsicmd, &readcmd->sg); | ||
1100 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
1101 | BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); | ||
1102 | /* | ||
1103 | * Now send the Fib to the adapter | ||
1104 | */ | ||
1105 | status = aac_fib_send(ContainerRawIo, | ||
1106 | cmd_fibcontext, | ||
1107 | fibsize, | ||
1108 | FsaNormal, | ||
1109 | 0, 1, | ||
1110 | (fib_callback) io_callback, | ||
1111 | (void *) scsicmd); | ||
1112 | } else if (dev->dac_support == 1) { | ||
1113 | struct aac_read64 *readcmd; | ||
1114 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); | ||
1115 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | ||
1116 | readcmd->cid = cpu_to_le16(cid); | ||
1117 | readcmd->sector_count = cpu_to_le16(count); | ||
1118 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1119 | readcmd->pad = 0; | ||
1120 | readcmd->flags = 0; | ||
1121 | |||
1122 | aac_build_sg64(scsicmd, &readcmd->sg); | ||
1123 | fibsize = sizeof(struct aac_read64) + | ||
1124 | ((le32_to_cpu(readcmd->sg.count) - 1) * | ||
1125 | sizeof (struct sgentry64)); | ||
1126 | BUG_ON (fibsize > (dev->max_fib_size - | ||
1127 | sizeof(struct aac_fibhdr))); | ||
1128 | /* | ||
1129 | * Now send the Fib to the adapter | ||
1130 | */ | ||
1131 | status = aac_fib_send(ContainerCommand64, | ||
1132 | cmd_fibcontext, | ||
1133 | fibsize, | ||
1134 | FsaNormal, | ||
1135 | 0, 1, | ||
1136 | (fib_callback) io_callback, | ||
1137 | (void *) scsicmd); | ||
1138 | } else { | ||
1139 | struct aac_read *readcmd; | ||
1140 | readcmd = (struct aac_read *) fib_data(cmd_fibcontext); | ||
1141 | readcmd->command = cpu_to_le32(VM_CtBlockRead); | ||
1142 | readcmd->cid = cpu_to_le32(cid); | ||
1143 | readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1144 | readcmd->count = cpu_to_le32(count * 512); | ||
1145 | |||
1146 | aac_build_sg(scsicmd, &readcmd->sg); | ||
1147 | fibsize = sizeof(struct aac_read) + | ||
1148 | ((le32_to_cpu(readcmd->sg.count) - 1) * | ||
1149 | sizeof (struct sgentry)); | ||
1150 | BUG_ON (fibsize > (dev->max_fib_size - | ||
1151 | sizeof(struct aac_fibhdr))); | ||
1152 | /* | ||
1153 | * Now send the Fib to the adapter | ||
1154 | */ | ||
1155 | status = aac_fib_send(ContainerCommand, | ||
1156 | cmd_fibcontext, | ||
1157 | fibsize, | ||
1158 | FsaNormal, | ||
1159 | 0, 1, | ||
1160 | (fib_callback) io_callback, | ||
1161 | (void *) scsicmd); | ||
1162 | } | ||
1163 | |||
1164 | |||
1165 | 1389 | ||
1166 | /* | 1390 | /* |
1167 | * Check that the command queued to the controller | 1391 | * Check that the command queued to the controller |
@@ -1187,7 +1411,6 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1187 | u64 lba; | 1411 | u64 lba; |
1188 | u32 count; | 1412 | u32 count; |
1189 | int status; | 1413 | int status; |
1190 | u16 fibsize; | ||
1191 | struct aac_dev *dev; | 1414 | struct aac_dev *dev; |
1192 | struct fib * cmd_fibcontext; | 1415 | struct fib * cmd_fibcontext; |
1193 | 1416 | ||
@@ -1227,22 +1450,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1227 | } | 1450 | } |
1228 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", | 1451 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", |
1229 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1452 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1230 | if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) | 1453 | if (aac_adapter_bounds(dev,scsicmd,lba)) |
1231 | && (lba & 0xffffffff00000000LL)) { | ||
1232 | dprintk((KERN_DEBUG "aac_write: Illegal lba\n")); | ||
1233 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | ||
1234 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
1235 | HARDWARE_ERROR, | ||
1236 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
1237 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
1238 | 0, 0); | ||
1239 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1240 | (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) | ||
1241 | ? sizeof(scsicmd->sense_buffer) | ||
1242 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
1243 | scsicmd->scsi_done(scsicmd); | ||
1244 | return 0; | 1454 | return 0; |
1245 | } | ||
1246 | /* | 1455 | /* |
1247 | * Allocate and initialize a Fib then setup a BlockWrite command | 1456 | * Allocate and initialize a Fib then setup a BlockWrite command |
1248 | */ | 1457 | */ |
@@ -1251,85 +1460,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1251 | scsicmd->scsi_done(scsicmd); | 1460 | scsicmd->scsi_done(scsicmd); |
1252 | return 0; | 1461 | return 0; |
1253 | } | 1462 | } |
1254 | aac_fib_init(cmd_fibcontext); | ||
1255 | 1463 | ||
1256 | if (dev->raw_io_interface) { | 1464 | status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count); |
1257 | struct aac_raw_io *writecmd; | ||
1258 | writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
1259 | writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1260 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
1261 | writecmd->count = cpu_to_le32(count<<9); | ||
1262 | writecmd->cid = cpu_to_le16(cid); | ||
1263 | writecmd->flags = 0; | ||
1264 | writecmd->bpTotal = 0; | ||
1265 | writecmd->bpComplete = 0; | ||
1266 | |||
1267 | aac_build_sgraw(scsicmd, &writecmd->sg); | ||
1268 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
1269 | BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); | ||
1270 | /* | ||
1271 | * Now send the Fib to the adapter | ||
1272 | */ | ||
1273 | status = aac_fib_send(ContainerRawIo, | ||
1274 | cmd_fibcontext, | ||
1275 | fibsize, | ||
1276 | FsaNormal, | ||
1277 | 0, 1, | ||
1278 | (fib_callback) io_callback, | ||
1279 | (void *) scsicmd); | ||
1280 | } else if (dev->dac_support == 1) { | ||
1281 | struct aac_write64 *writecmd; | ||
1282 | writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); | ||
1283 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); | ||
1284 | writecmd->cid = cpu_to_le16(cid); | ||
1285 | writecmd->sector_count = cpu_to_le16(count); | ||
1286 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1287 | writecmd->pad = 0; | ||
1288 | writecmd->flags = 0; | ||
1289 | |||
1290 | aac_build_sg64(scsicmd, &writecmd->sg); | ||
1291 | fibsize = sizeof(struct aac_write64) + | ||
1292 | ((le32_to_cpu(writecmd->sg.count) - 1) * | ||
1293 | sizeof (struct sgentry64)); | ||
1294 | BUG_ON (fibsize > (dev->max_fib_size - | ||
1295 | sizeof(struct aac_fibhdr))); | ||
1296 | /* | ||
1297 | * Now send the Fib to the adapter | ||
1298 | */ | ||
1299 | status = aac_fib_send(ContainerCommand64, | ||
1300 | cmd_fibcontext, | ||
1301 | fibsize, | ||
1302 | FsaNormal, | ||
1303 | 0, 1, | ||
1304 | (fib_callback) io_callback, | ||
1305 | (void *) scsicmd); | ||
1306 | } else { | ||
1307 | struct aac_write *writecmd; | ||
1308 | writecmd = (struct aac_write *) fib_data(cmd_fibcontext); | ||
1309 | writecmd->command = cpu_to_le32(VM_CtBlockWrite); | ||
1310 | writecmd->cid = cpu_to_le32(cid); | ||
1311 | writecmd->block = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1312 | writecmd->count = cpu_to_le32(count * 512); | ||
1313 | writecmd->sg.count = cpu_to_le32(1); | ||
1314 | /* ->stable is not used - it did mean which type of write */ | ||
1315 | |||
1316 | aac_build_sg(scsicmd, &writecmd->sg); | ||
1317 | fibsize = sizeof(struct aac_write) + | ||
1318 | ((le32_to_cpu(writecmd->sg.count) - 1) * | ||
1319 | sizeof (struct sgentry)); | ||
1320 | BUG_ON (fibsize > (dev->max_fib_size - | ||
1321 | sizeof(struct aac_fibhdr))); | ||
1322 | /* | ||
1323 | * Now send the Fib to the adapter | ||
1324 | */ | ||
1325 | status = aac_fib_send(ContainerCommand, | ||
1326 | cmd_fibcontext, | ||
1327 | fibsize, | ||
1328 | FsaNormal, | ||
1329 | 0, 1, | ||
1330 | (fib_callback) io_callback, | ||
1331 | (void *) scsicmd); | ||
1332 | } | ||
1333 | 1465 | ||
1334 | /* | 1466 | /* |
1335 | * Check that the command queued to the controller | 1467 | * Check that the command queued to the controller |
@@ -2099,10 +2231,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2099 | struct fib* cmd_fibcontext; | 2231 | struct fib* cmd_fibcontext; |
2100 | struct aac_dev* dev; | 2232 | struct aac_dev* dev; |
2101 | int status; | 2233 | int status; |
2102 | struct aac_srb *srbcmd; | ||
2103 | u16 fibsize; | ||
2104 | u32 flag; | ||
2105 | u32 timeout; | ||
2106 | 2234 | ||
2107 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 2235 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
2108 | if (scmd_id(scsicmd) >= dev->maximum_num_physicals || | 2236 | if (scmd_id(scsicmd) >= dev->maximum_num_physicals || |
@@ -2112,88 +2240,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2112 | return 0; | 2240 | return 0; |
2113 | } | 2241 | } |
2114 | 2242 | ||
2115 | switch(scsicmd->sc_data_direction){ | ||
2116 | case DMA_TO_DEVICE: | ||
2117 | flag = SRB_DataOut; | ||
2118 | break; | ||
2119 | case DMA_BIDIRECTIONAL: | ||
2120 | flag = SRB_DataIn | SRB_DataOut; | ||
2121 | break; | ||
2122 | case DMA_FROM_DEVICE: | ||
2123 | flag = SRB_DataIn; | ||
2124 | break; | ||
2125 | case DMA_NONE: | ||
2126 | default: /* shuts up some versions of gcc */ | ||
2127 | flag = SRB_NoDataXfer; | ||
2128 | break; | ||
2129 | } | ||
2130 | |||
2131 | |||
2132 | /* | 2243 | /* |
2133 | * Allocate and initialize a Fib then setup a BlockWrite command | 2244 | * Allocate and initialize a Fib then setup a BlockWrite command |
2134 | */ | 2245 | */ |
2135 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { | 2246 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
2136 | return -1; | 2247 | return -1; |
2137 | } | 2248 | } |
2138 | aac_fib_init(cmd_fibcontext); | 2249 | status = aac_adapter_scsi(cmd_fibcontext, scsicmd); |
2139 | |||
2140 | srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); | ||
2141 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); | ||
2142 | srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd))); | ||
2143 | srbcmd->id = cpu_to_le32(scmd_id(scsicmd)); | ||
2144 | srbcmd->lun = cpu_to_le32(scsicmd->device->lun); | ||
2145 | srbcmd->flags = cpu_to_le32(flag); | ||
2146 | timeout = scsicmd->timeout_per_command/HZ; | ||
2147 | if(timeout == 0){ | ||
2148 | timeout = 1; | ||
2149 | } | ||
2150 | srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds | ||
2151 | srbcmd->retry_limit = 0; /* Obsolete parameter */ | ||
2152 | srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len); | ||
2153 | |||
2154 | if( dev->dac_support == 1 ) { | ||
2155 | aac_build_sg64(scsicmd, (struct sgmap64*) &srbcmd->sg); | ||
2156 | srbcmd->count = cpu_to_le32(scsicmd->request_bufflen); | ||
2157 | |||
2158 | memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); | ||
2159 | memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len); | ||
2160 | /* | ||
2161 | * Build Scatter/Gather list | ||
2162 | */ | ||
2163 | fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) + | ||
2164 | ((le32_to_cpu(srbcmd->sg.count) & 0xff) * | ||
2165 | sizeof (struct sgentry64)); | ||
2166 | BUG_ON (fibsize > (dev->max_fib_size - | ||
2167 | sizeof(struct aac_fibhdr))); | ||
2168 | 2250 | ||
2169 | /* | ||
2170 | * Now send the Fib to the adapter | ||
2171 | */ | ||
2172 | status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext, | ||
2173 | fibsize, FsaNormal, 0, 1, | ||
2174 | (fib_callback) aac_srb_callback, | ||
2175 | (void *) scsicmd); | ||
2176 | } else { | ||
2177 | aac_build_sg(scsicmd, (struct sgmap*)&srbcmd->sg); | ||
2178 | srbcmd->count = cpu_to_le32(scsicmd->request_bufflen); | ||
2179 | |||
2180 | memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); | ||
2181 | memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len); | ||
2182 | /* | ||
2183 | * Build Scatter/Gather list | ||
2184 | */ | ||
2185 | fibsize = sizeof (struct aac_srb) + | ||
2186 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | ||
2187 | sizeof (struct sgentry)); | ||
2188 | BUG_ON (fibsize > (dev->max_fib_size - | ||
2189 | sizeof(struct aac_fibhdr))); | ||
2190 | |||
2191 | /* | ||
2192 | * Now send the Fib to the adapter | ||
2193 | */ | ||
2194 | status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, | ||
2195 | (fib_callback) aac_srb_callback, (void *) scsicmd); | ||
2196 | } | ||
2197 | /* | 2251 | /* |
2198 | * Check that the command queued to the controller | 2252 | * Check that the command queued to the controller |
2199 | */ | 2253 | */ |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 4f8b4c53d435..39ecd0d22eb0 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #define _nblank(x) #x | 5 | #define _nblank(x) #x |
6 | #define nblank(x) _nblank(x)[0] | 6 | #define nblank(x) _nblank(x)[0] |
7 | 7 | ||
8 | #include <linux/interrupt.h> | ||
8 | 9 | ||
9 | /*------------------------------------------------------------------------------ | 10 | /*------------------------------------------------------------------------------ |
10 | * D E F I N E S | 11 | * D E F I N E S |
@@ -485,16 +486,28 @@ enum aac_log_level { | |||
485 | 486 | ||
486 | struct aac_dev; | 487 | struct aac_dev; |
487 | struct fib; | 488 | struct fib; |
489 | struct scsi_cmnd; | ||
488 | 490 | ||
489 | struct adapter_ops | 491 | struct adapter_ops |
490 | { | 492 | { |
493 | /* Low level operations */ | ||
491 | void (*adapter_interrupt)(struct aac_dev *dev); | 494 | void (*adapter_interrupt)(struct aac_dev *dev); |
492 | void (*adapter_notify)(struct aac_dev *dev, u32 event); | 495 | void (*adapter_notify)(struct aac_dev *dev, u32 event); |
493 | void (*adapter_disable_int)(struct aac_dev *dev); | 496 | void (*adapter_disable_int)(struct aac_dev *dev); |
497 | void (*adapter_enable_int)(struct aac_dev *dev); | ||
494 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); | 498 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); |
495 | int (*adapter_check_health)(struct aac_dev *dev); | 499 | int (*adapter_check_health)(struct aac_dev *dev); |
496 | int (*adapter_send)(struct fib * fib); | 500 | /* Transport operations */ |
497 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); | 501 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); |
502 | irqreturn_t (*adapter_intr)(int irq, void *dev_id); | ||
503 | /* Packet operations */ | ||
504 | int (*adapter_deliver)(struct fib * fib); | ||
505 | int (*adapter_bounds)(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba); | ||
506 | int (*adapter_read)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count); | ||
507 | int (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count); | ||
508 | int (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd); | ||
509 | /* Administrative operations */ | ||
510 | int (*adapter_comm)(struct aac_dev * dev, int comm); | ||
498 | }; | 511 | }; |
499 | 512 | ||
500 | /* | 513 | /* |
@@ -1018,7 +1031,9 @@ struct aac_dev | |||
1018 | u8 nondasd_support; | 1031 | u8 nondasd_support; |
1019 | u8 dac_support; | 1032 | u8 dac_support; |
1020 | u8 raid_scsi_mode; | 1033 | u8 raid_scsi_mode; |
1021 | u8 new_comm_interface; | 1034 | u8 comm_interface; |
1035 | # define AAC_COMM_PRODUCER 0 | ||
1036 | # define AAC_COMM_MESSAGE 1 | ||
1022 | /* macro side-effects BEWARE */ | 1037 | /* macro side-effects BEWARE */ |
1023 | # define raw_io_interface \ | 1038 | # define raw_io_interface \ |
1024 | init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) | 1039 | init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) |
@@ -1036,18 +1051,36 @@ struct aac_dev | |||
1036 | #define aac_adapter_disable_int(dev) \ | 1051 | #define aac_adapter_disable_int(dev) \ |
1037 | (dev)->a_ops.adapter_disable_int(dev) | 1052 | (dev)->a_ops.adapter_disable_int(dev) |
1038 | 1053 | ||
1054 | #define aac_adapter_enable_int(dev) \ | ||
1055 | (dev)->a_ops.adapter_enable_int(dev) | ||
1056 | |||
1039 | #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \ | 1057 | #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \ |
1040 | (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) | 1058 | (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) |
1041 | 1059 | ||
1042 | #define aac_adapter_check_health(dev) \ | 1060 | #define aac_adapter_check_health(dev) \ |
1043 | (dev)->a_ops.adapter_check_health(dev) | 1061 | (dev)->a_ops.adapter_check_health(dev) |
1044 | 1062 | ||
1045 | #define aac_adapter_send(fib) \ | ||
1046 | ((fib)->dev)->a_ops.adapter_send(fib) | ||
1047 | |||
1048 | #define aac_adapter_ioremap(dev, size) \ | 1063 | #define aac_adapter_ioremap(dev, size) \ |
1049 | (dev)->a_ops.adapter_ioremap(dev, size) | 1064 | (dev)->a_ops.adapter_ioremap(dev, size) |
1050 | 1065 | ||
1066 | #define aac_adapter_deliver(fib) \ | ||
1067 | ((fib)->dev)->a_ops.adapter_deliver(fib) | ||
1068 | |||
1069 | #define aac_adapter_bounds(dev,cmd,lba) \ | ||
1070 | dev->a_ops.adapter_bounds(dev,cmd,lba) | ||
1071 | |||
1072 | #define aac_adapter_read(fib,cmd,lba,count) \ | ||
1073 | ((fib)->dev)->a_ops.adapter_read(fib,cmd,lba,count) | ||
1074 | |||
1075 | #define aac_adapter_write(fib,cmd,lba,count) \ | ||
1076 | ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count) | ||
1077 | |||
1078 | #define aac_adapter_scsi(fib,cmd) \ | ||
1079 | ((fib)->dev)->a_ops.adapter_scsi(fib,cmd) | ||
1080 | |||
1081 | #define aac_adapter_comm(dev,comm) \ | ||
1082 | (dev)->a_ops.adapter_comm(dev, comm) | ||
1083 | |||
1051 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) | 1084 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) |
1052 | 1085 | ||
1053 | /* | 1086 | /* |
@@ -1767,7 +1800,6 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor) | |||
1767 | return (u32)capacity; | 1800 | return (u32)capacity; |
1768 | } | 1801 | } |
1769 | 1802 | ||
1770 | struct scsi_cmnd; | ||
1771 | /* SCp.phase values */ | 1803 | /* SCp.phase values */ |
1772 | #define AAC_OWNER_MIDLEVEL 0x101 | 1804 | #define AAC_OWNER_MIDLEVEL 0x101 |
1773 | #define AAC_OWNER_LOWLEVEL 0x102 | 1805 | #define AAC_OWNER_LOWLEVEL 0x102 |
@@ -1794,7 +1826,9 @@ int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); | |||
1794 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg); | 1826 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg); |
1795 | int aac_rx_init(struct aac_dev *dev); | 1827 | int aac_rx_init(struct aac_dev *dev); |
1796 | int aac_rkt_init(struct aac_dev *dev); | 1828 | int aac_rkt_init(struct aac_dev *dev); |
1829 | int aac_nark_init(struct aac_dev *dev); | ||
1797 | int aac_sa_init(struct aac_dev *dev); | 1830 | int aac_sa_init(struct aac_dev *dev); |
1831 | int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify); | ||
1798 | unsigned int aac_response_normal(struct aac_queue * q); | 1832 | unsigned int aac_response_normal(struct aac_queue * q); |
1799 | unsigned int aac_command_normal(struct aac_queue * q); | 1833 | unsigned int aac_command_normal(struct aac_queue * q); |
1800 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); | 1834 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 6d305b2f854e..df67ba686023 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -95,7 +95,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
95 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | 95 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
96 | 96 | ||
97 | init->InitFlags = 0; | 97 | init->InitFlags = 0; |
98 | if (dev->new_comm_interface) { | 98 | if (dev->comm_interface == AAC_COMM_MESSAGE) { |
99 | init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); | 99 | init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); |
100 | dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); | 100 | dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); |
101 | } | 101 | } |
@@ -297,21 +297,23 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
297 | - sizeof(struct aac_fibhdr) | 297 | - sizeof(struct aac_fibhdr) |
298 | - sizeof(struct aac_write) + sizeof(struct sgentry)) | 298 | - sizeof(struct aac_write) + sizeof(struct sgentry)) |
299 | / sizeof(struct sgentry); | 299 | / sizeof(struct sgentry); |
300 | dev->new_comm_interface = 0; | 300 | dev->comm_interface = AAC_COMM_PRODUCER; |
301 | dev->raw_io_64 = 0; | 301 | dev->raw_io_64 = 0; |
302 | if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, | 302 | if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, |
303 | 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && | 303 | 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && |
304 | (status[0] == 0x00000001)) { | 304 | (status[0] == 0x00000001)) { |
305 | if (status[1] & AAC_OPT_NEW_COMM_64) | 305 | if (status[1] & AAC_OPT_NEW_COMM_64) |
306 | dev->raw_io_64 = 1; | 306 | dev->raw_io_64 = 1; |
307 | if (status[1] & AAC_OPT_NEW_COMM) | 307 | if (dev->a_ops.adapter_comm && |
308 | dev->new_comm_interface = dev->a_ops.adapter_send != 0; | 308 | (status[1] & AAC_OPT_NEW_COMM)) |
309 | if (dev->new_comm_interface && (status[2] > dev->base_size)) { | 309 | dev->comm_interface = AAC_COMM_MESSAGE; |
310 | if ((dev->comm_interface == AAC_COMM_MESSAGE) && | ||
311 | (status[2] > dev->base_size)) { | ||
310 | aac_adapter_ioremap(dev, 0); | 312 | aac_adapter_ioremap(dev, 0); |
311 | dev->base_size = status[2]; | 313 | dev->base_size = status[2]; |
312 | if (aac_adapter_ioremap(dev, status[2])) { | 314 | if (aac_adapter_ioremap(dev, status[2])) { |
313 | /* remap failed, go back ... */ | 315 | /* remap failed, go back ... */ |
314 | dev->new_comm_interface = 0; | 316 | dev->comm_interface = AAC_COMM_PRODUCER; |
315 | if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) { | 317 | if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) { |
316 | printk(KERN_WARNING | 318 | printk(KERN_WARNING |
317 | "aacraid: unable to map adapter.\n"); | 319 | "aacraid: unable to map adapter.\n"); |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 4893a6d06a33..1b97f60652ba 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -317,7 +317,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr | |||
317 | * success. | 317 | * success. |
318 | */ | 318 | */ |
319 | 319 | ||
320 | static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify) | 320 | int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify) |
321 | { | 321 | { |
322 | struct aac_entry * entry = NULL; | 322 | struct aac_entry * entry = NULL; |
323 | int map = 0; | 323 | int map = 0; |
@@ -387,7 +387,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
387 | { | 387 | { |
388 | struct aac_dev * dev = fibptr->dev; | 388 | struct aac_dev * dev = fibptr->dev; |
389 | struct hw_fib * hw_fib = fibptr->hw_fib; | 389 | struct hw_fib * hw_fib = fibptr->hw_fib; |
390 | struct aac_queue * q; | ||
391 | unsigned long flags = 0; | 390 | unsigned long flags = 0; |
392 | unsigned long qflags; | 391 | unsigned long qflags; |
393 | 392 | ||
@@ -469,38 +468,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
469 | 468 | ||
470 | if (!dev->queues) | 469 | if (!dev->queues) |
471 | return -EBUSY; | 470 | return -EBUSY; |
472 | q = &dev->queues->queue[AdapNormCmdQueue]; | ||
473 | 471 | ||
474 | if(wait) | 472 | if(wait) |
475 | spin_lock_irqsave(&fibptr->event_lock, flags); | 473 | spin_lock_irqsave(&fibptr->event_lock, flags); |
476 | spin_lock_irqsave(q->lock, qflags); | 474 | aac_adapter_deliver(fibptr); |
477 | if (dev->new_comm_interface) { | ||
478 | unsigned long count = 10000000L; /* 50 seconds */ | ||
479 | q->numpending++; | ||
480 | spin_unlock_irqrestore(q->lock, qflags); | ||
481 | while (aac_adapter_send(fibptr) != 0) { | ||
482 | if (--count == 0) { | ||
483 | if (wait) | ||
484 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
485 | spin_lock_irqsave(q->lock, qflags); | ||
486 | q->numpending--; | ||
487 | spin_unlock_irqrestore(q->lock, qflags); | ||
488 | return -ETIMEDOUT; | ||
489 | } | ||
490 | udelay(5); | ||
491 | } | ||
492 | } else { | ||
493 | u32 index; | ||
494 | unsigned long nointr = 0; | ||
495 | aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); | ||
496 | |||
497 | q->numpending++; | ||
498 | *(q->headers.producer) = cpu_to_le32(index + 1); | ||
499 | spin_unlock_irqrestore(q->lock, qflags); | ||
500 | dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index)); | ||
501 | if (!(nointr & aac_config.irq_mod)) | ||
502 | aac_adapter_notify(dev, AdapNormCmdQueue); | ||
503 | } | ||
504 | 475 | ||
505 | /* | 476 | /* |
506 | * If the caller wanted us to wait for response wait now. | 477 | * If the caller wanted us to wait for response wait now. |
@@ -520,6 +491,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
520 | while (down_trylock(&fibptr->event_wait)) { | 491 | while (down_trylock(&fibptr->event_wait)) { |
521 | int blink; | 492 | int blink; |
522 | if (--count == 0) { | 493 | if (--count == 0) { |
494 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; | ||
523 | spin_lock_irqsave(q->lock, qflags); | 495 | spin_lock_irqsave(q->lock, qflags); |
524 | q->numpending--; | 496 | q->numpending--; |
525 | spin_unlock_irqrestore(q->lock, qflags); | 497 | spin_unlock_irqrestore(q->lock, qflags); |
@@ -659,7 +631,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
659 | unsigned long qflags; | 631 | unsigned long qflags; |
660 | 632 | ||
661 | if (hw_fib->header.XferState == 0) { | 633 | if (hw_fib->header.XferState == 0) { |
662 | if (dev->new_comm_interface) | 634 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
663 | kfree (hw_fib); | 635 | kfree (hw_fib); |
664 | return 0; | 636 | return 0; |
665 | } | 637 | } |
@@ -667,7 +639,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
667 | * If we plan to do anything check the structure type first. | 639 | * If we plan to do anything check the structure type first. |
668 | */ | 640 | */ |
669 | if ( hw_fib->header.StructType != FIB_MAGIC ) { | 641 | if ( hw_fib->header.StructType != FIB_MAGIC ) { |
670 | if (dev->new_comm_interface) | 642 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
671 | kfree (hw_fib); | 643 | kfree (hw_fib); |
672 | return -EINVAL; | 644 | return -EINVAL; |
673 | } | 645 | } |
@@ -679,7 +651,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
679 | * send the completed cdb to the adapter. | 651 | * send the completed cdb to the adapter. |
680 | */ | 652 | */ |
681 | if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { | 653 | if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { |
682 | if (dev->new_comm_interface) { | 654 | if (dev->comm_interface == AAC_COMM_MESSAGE) { |
683 | kfree (hw_fib); | 655 | kfree (hw_fib); |
684 | } else { | 656 | } else { |
685 | u32 index; | 657 | u32 index; |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index d2cf875af59b..a9734e08fe28 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -157,6 +157,7 @@ static struct pci_device_id aac_pci_tbl[] = { | |||
157 | { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */ | 157 | { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */ |
158 | { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */ | 158 | { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */ |
159 | { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */ | 159 | { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */ |
160 | { 0x9005, 0x0288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 61 }, /* Adaptec NEMER/ARK Catch All */ | ||
160 | { 0,} | 161 | { 0,} |
161 | }; | 162 | }; |
162 | MODULE_DEVICE_TABLE(pci, aac_pci_tbl); | 163 | MODULE_DEVICE_TABLE(pci, aac_pci_tbl); |
@@ -230,7 +231,8 @@ static struct aac_driver_ident aac_drivers[] = { | |||
230 | { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */ | 231 | { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */ |
231 | { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */ | 232 | { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */ |
232 | { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */ | 233 | { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */ |
233 | { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec Rocket Catch All */ | 234 | { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */ |
235 | { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */ | ||
234 | }; | 236 | }; |
235 | 237 | ||
236 | /** | 238 | /** |
@@ -396,11 +398,15 @@ static int aac_slave_configure(struct scsi_device *sdev) | |||
396 | sdev->skip_ms_page_3f = 1; | 398 | sdev->skip_ms_page_3f = 1; |
397 | } | 399 | } |
398 | if ((sdev->type == TYPE_DISK) && | 400 | if ((sdev->type == TYPE_DISK) && |
399 | !expose_physicals && | ||
400 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { | 401 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { |
401 | struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; | 402 | if (expose_physicals == 0) |
402 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) | 403 | return -ENXIO; |
403 | sdev->no_uld_attach = 1; | 404 | if (expose_physicals < 0) { |
405 | struct aac_dev *aac = | ||
406 | (struct aac_dev *)sdev->host->hostdata; | ||
407 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) | ||
408 | sdev->no_uld_attach = 1; | ||
409 | } | ||
404 | } | 410 | } |
405 | if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && | 411 | if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && |
406 | (sdev_channel(sdev) == CONTAINER_CHANNEL)) { | 412 | (sdev_channel(sdev) == CONTAINER_CHANNEL)) { |
@@ -804,7 +810,6 @@ static struct scsi_host_template aac_driver_template = { | |||
804 | .emulated = 1, | 810 | .emulated = 1, |
805 | }; | 811 | }; |
806 | 812 | ||
807 | |||
808 | static int __devinit aac_probe_one(struct pci_dev *pdev, | 813 | static int __devinit aac_probe_one(struct pci_dev *pdev, |
809 | const struct pci_device_id *id) | 814 | const struct pci_device_id *id) |
810 | { | 815 | { |
diff --git a/drivers/scsi/aacraid/nark.c b/drivers/scsi/aacraid/nark.c new file mode 100644 index 000000000000..c76b611b6afb --- /dev/null +++ b/drivers/scsi/aacraid/nark.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Adaptec AAC series RAID controller driver | ||
3 | * (c) Copyright 2001 Red Hat Inc. <alan@redhat.com> | ||
4 | * | ||
5 | * based on the old aacraid driver that is.. | ||
6 | * Adaptec aacraid device driver for Linux. | ||
7 | * | ||
8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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 as published by | ||
12 | * the Free Software Foundation; either version 2, or (at your option) | ||
13 | * any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; see the file COPYING. If not, write to | ||
22 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * Module Name: | ||
25 | * nark.c | ||
26 | * | ||
27 | * Abstract: Hardware Device Interface for NEMER/ARK | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #include <linux/pci.h> | ||
32 | #include <linux/blkdev.h> | ||
33 | |||
34 | #include <scsi/scsi_host.h> | ||
35 | |||
36 | #include "aacraid.h" | ||
37 | |||
38 | /** | ||
39 | * aac_nark_ioremap | ||
40 | * @size: mapping resize request | ||
41 | * | ||
42 | */ | ||
43 | static int aac_nark_ioremap(struct aac_dev * dev, u32 size) | ||
44 | { | ||
45 | if (!size) { | ||
46 | iounmap(dev->regs.rx); | ||
47 | dev->regs.rx = NULL; | ||
48 | iounmap(dev->base); | ||
49 | dev->base = NULL; | ||
50 | return 0; | ||
51 | } | ||
52 | dev->scsi_host_ptr->base = pci_resource_start(dev->pdev, 2); | ||
53 | dev->regs.rx = ioremap((u64)pci_resource_start(dev->pdev, 0) | | ||
54 | ((u64)pci_resource_start(dev->pdev, 1) << 32), | ||
55 | sizeof(struct rx_registers) - sizeof(struct rx_inbound)); | ||
56 | dev->base = NULL; | ||
57 | if (dev->regs.rx == NULL) | ||
58 | return -1; | ||
59 | dev->base = ioremap(dev->scsi_host_ptr->base, size); | ||
60 | if (dev->base == NULL) { | ||
61 | iounmap(dev->regs.rx); | ||
62 | dev->regs.rx = NULL; | ||
63 | return -1; | ||
64 | } | ||
65 | dev->IndexRegs = &((struct rx_registers __iomem *)dev->base)->IndexRegs; | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * aac_nark_init - initialize an NEMER/ARK Split Bar card | ||
71 | * @dev: device to configure | ||
72 | * | ||
73 | */ | ||
74 | |||
75 | int aac_nark_init(struct aac_dev * dev) | ||
76 | { | ||
77 | extern int _aac_rx_init(struct aac_dev *dev); | ||
78 | extern int aac_rx_select_comm(struct aac_dev *dev, int comm); | ||
79 | |||
80 | /* | ||
81 | * Fill in the function dispatch table. | ||
82 | */ | ||
83 | dev->a_ops.adapter_ioremap = aac_nark_ioremap; | ||
84 | dev->a_ops.adapter_comm = aac_rx_select_comm; | ||
85 | |||
86 | return _aac_rx_init(dev); | ||
87 | } | ||
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index 643f23b5ded8..d953c3fe998a 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c | |||
@@ -34,6 +34,40 @@ | |||
34 | 34 | ||
35 | #include "aacraid.h" | 35 | #include "aacraid.h" |
36 | 36 | ||
37 | #define AAC_NUM_IO_FIB_RKT (246 - AAC_NUM_MGT_FIB) | ||
38 | |||
39 | /** | ||
40 | * aac_rkt_select_comm - Select communications method | ||
41 | * @dev: Adapter | ||
42 | * @comm: communications method | ||
43 | */ | ||
44 | |||
45 | static int aac_rkt_select_comm(struct aac_dev *dev, int comm) | ||
46 | { | ||
47 | int retval; | ||
48 | extern int aac_rx_select_comm(struct aac_dev *dev, int comm); | ||
49 | retval = aac_rx_select_comm(dev, comm); | ||
50 | if (comm == AAC_COMM_MESSAGE) { | ||
51 | /* | ||
52 | * FIB Setup has already been done, but we can minimize the | ||
53 | * damage by at least ensuring the OS never issues more | ||
54 | * commands than we can handle. The Rocket adapters currently | ||
55 | * can only handle 246 commands and 8 AIFs at the same time, | ||
56 | * and in fact do notify us accordingly if we negotiate the | ||
57 | * FIB size. The problem that causes us to add this check is | ||
58 | * to ensure that we do not overdo it with the adapter when a | ||
59 | * hard coded FIB override is being utilized. This special | ||
60 | * case warrants this half baked, but convenient, check here. | ||
61 | */ | ||
62 | if (dev->scsi_host_ptr->can_queue > AAC_NUM_IO_FIB_RKT) { | ||
63 | dev->init->MaxIoCommands = | ||
64 | cpu_to_le32(AAC_NUM_IO_FIB_RKT + AAC_NUM_MGT_FIB); | ||
65 | dev->scsi_host_ptr->can_queue = AAC_NUM_IO_FIB_RKT; | ||
66 | } | ||
67 | } | ||
68 | return retval; | ||
69 | } | ||
70 | |||
37 | /** | 71 | /** |
38 | * aac_rkt_ioremap | 72 | * aac_rkt_ioremap |
39 | * @size: mapping resize request | 73 | * @size: mapping resize request |
@@ -63,39 +97,13 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size) | |||
63 | 97 | ||
64 | int aac_rkt_init(struct aac_dev *dev) | 98 | int aac_rkt_init(struct aac_dev *dev) |
65 | { | 99 | { |
66 | int retval; | ||
67 | extern int _aac_rx_init(struct aac_dev *dev); | 100 | extern int _aac_rx_init(struct aac_dev *dev); |
68 | extern void aac_rx_start_adapter(struct aac_dev *dev); | ||
69 | 101 | ||
70 | /* | 102 | /* |
71 | * Fill in the function dispatch table. | 103 | * Fill in the function dispatch table. |
72 | */ | 104 | */ |
73 | dev->a_ops.adapter_ioremap = aac_rkt_ioremap; | 105 | dev->a_ops.adapter_ioremap = aac_rkt_ioremap; |
106 | dev->a_ops.adapter_comm = aac_rkt_select_comm; | ||
74 | 107 | ||
75 | retval = _aac_rx_init(dev); | 108 | return _aac_rx_init(dev); |
76 | if (retval) | ||
77 | return retval; | ||
78 | if (dev->new_comm_interface) { | ||
79 | /* | ||
80 | * FIB Setup has already been done, but we can minimize the | ||
81 | * damage by at least ensuring the OS never issues more | ||
82 | * commands than we can handle. The Rocket adapters currently | ||
83 | * can only handle 246 commands and 8 AIFs at the same time, | ||
84 | * and in fact do notify us accordingly if we negotiate the | ||
85 | * FIB size. The problem that causes us to add this check is | ||
86 | * to ensure that we do not overdo it with the adapter when a | ||
87 | * hard coded FIB override is being utilized. This special | ||
88 | * case warrants this half baked, but convenient, check here. | ||
89 | */ | ||
90 | if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) { | ||
91 | dev->init->MaxIoCommands = cpu_to_le32(246); | ||
92 | dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB; | ||
93 | } | ||
94 | } | ||
95 | /* | ||
96 | * Tell the adapter that all is configured, and it can start | ||
97 | * accepting requests | ||
98 | */ | ||
99 | aac_rx_start_adapter(dev); | ||
100 | return 0; | ||
101 | } | 109 | } |
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index dcc8b0ea7a9d..c632d9354a26 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
@@ -46,60 +46,60 @@ | |||
46 | 46 | ||
47 | #include "aacraid.h" | 47 | #include "aacraid.h" |
48 | 48 | ||
49 | static irqreturn_t aac_rx_intr(int irq, void *dev_id) | 49 | static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id) |
50 | { | 50 | { |
51 | struct aac_dev *dev = dev_id; | 51 | struct aac_dev *dev = dev_id; |
52 | unsigned long bellbits; | ||
53 | u8 intstat = rx_readb(dev, MUnit.OISR); | ||
52 | 54 | ||
53 | dprintk((KERN_DEBUG "aac_rx_intr(%d,%p)\n", irq, dev_id)); | 55 | /* |
54 | if (dev->new_comm_interface) { | 56 | * Read mask and invert because drawbridge is reversed. |
55 | u32 Index = rx_readl(dev, MUnit.OutboundQueue); | 57 | * This allows us to only service interrupts that have |
56 | if (Index == 0xFFFFFFFFL) | 58 | * been enabled. |
57 | Index = rx_readl(dev, MUnit.OutboundQueue); | 59 | * Check to see if this is our interrupt. If it isn't just return |
58 | if (Index != 0xFFFFFFFFL) { | 60 | */ |
59 | do { | 61 | if (intstat & ~(dev->OIMR)) { |
60 | if (aac_intr_normal(dev, Index)) { | 62 | bellbits = rx_readl(dev, OutboundDoorbellReg); |
61 | rx_writel(dev, MUnit.OutboundQueue, Index); | 63 | if (bellbits & DoorBellPrintfReady) { |
62 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); | 64 | aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); |
63 | } | 65 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); |
64 | Index = rx_readl(dev, MUnit.OutboundQueue); | 66 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); |
65 | } while (Index != 0xFFFFFFFFL); | ||
66 | return IRQ_HANDLED; | ||
67 | } | 67 | } |
68 | } else { | 68 | else if (bellbits & DoorBellAdapterNormCmdReady) { |
69 | unsigned long bellbits; | 69 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); |
70 | u8 intstat; | 70 | aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); |
71 | intstat = rx_readb(dev, MUnit.OISR); | 71 | } |
72 | /* | 72 | else if (bellbits & DoorBellAdapterNormRespReady) { |
73 | * Read mask and invert because drawbridge is reversed. | 73 | rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); |
74 | * This allows us to only service interrupts that have | 74 | aac_response_normal(&dev->queues->queue[HostNormRespQueue]); |
75 | * been enabled. | 75 | } |
76 | * Check to see if this is our interrupt. If it isn't just return | 76 | else if (bellbits & DoorBellAdapterNormCmdNotFull) { |
77 | */ | 77 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); |
78 | if (intstat & ~(dev->OIMR)) | ||
79 | { | ||
80 | bellbits = rx_readl(dev, OutboundDoorbellReg); | ||
81 | if (bellbits & DoorBellPrintfReady) { | ||
82 | aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); | ||
83 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); | ||
84 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); | ||
85 | } | ||
86 | else if (bellbits & DoorBellAdapterNormCmdReady) { | ||
87 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); | ||
88 | aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); | ||
89 | } | ||
90 | else if (bellbits & DoorBellAdapterNormRespReady) { | ||
91 | rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); | ||
92 | aac_response_normal(&dev->queues->queue[HostNormRespQueue]); | ||
93 | } | ||
94 | else if (bellbits & DoorBellAdapterNormCmdNotFull) { | ||
95 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | ||
96 | } | ||
97 | else if (bellbits & DoorBellAdapterNormRespNotFull) { | ||
98 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | ||
99 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); | ||
100 | } | ||
101 | return IRQ_HANDLED; | ||
102 | } | 78 | } |
79 | else if (bellbits & DoorBellAdapterNormRespNotFull) { | ||
80 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | ||
81 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); | ||
82 | } | ||
83 | return IRQ_HANDLED; | ||
84 | } | ||
85 | return IRQ_NONE; | ||
86 | } | ||
87 | |||
88 | static irqreturn_t aac_rx_intr_message(int irq, void *dev_id) | ||
89 | { | ||
90 | struct aac_dev *dev = dev_id; | ||
91 | u32 Index = rx_readl(dev, MUnit.OutboundQueue); | ||
92 | if (Index == 0xFFFFFFFFL) | ||
93 | Index = rx_readl(dev, MUnit.OutboundQueue); | ||
94 | if (Index != 0xFFFFFFFFL) { | ||
95 | do { | ||
96 | if (aac_intr_normal(dev, Index)) { | ||
97 | rx_writel(dev, MUnit.OutboundQueue, Index); | ||
98 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); | ||
99 | } | ||
100 | Index = rx_readl(dev, MUnit.OutboundQueue); | ||
101 | } while (Index != 0xFFFFFFFFL); | ||
102 | return IRQ_HANDLED; | ||
103 | } | 103 | } |
104 | return IRQ_NONE; | 104 | return IRQ_NONE; |
105 | } | 105 | } |
@@ -115,6 +115,26 @@ static void aac_rx_disable_interrupt(struct aac_dev *dev) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * aac_rx_enable_interrupt_producer - Enable interrupts | ||
119 | * @dev: Adapter | ||
120 | */ | ||
121 | |||
122 | static void aac_rx_enable_interrupt_producer(struct aac_dev *dev) | ||
123 | { | ||
124 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * aac_rx_enable_interrupt_message - Enable interrupts | ||
129 | * @dev: Adapter | ||
130 | */ | ||
131 | |||
132 | static void aac_rx_enable_interrupt_message(struct aac_dev *dev) | ||
133 | { | ||
134 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
135 | } | ||
136 | |||
137 | /** | ||
118 | * rx_sync_cmd - send a command and wait | 138 | * rx_sync_cmd - send a command and wait |
119 | * @dev: Adapter | 139 | * @dev: Adapter |
120 | * @command: Command to execute | 140 | * @command: Command to execute |
@@ -189,10 +209,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, | |||
189 | /* | 209 | /* |
190 | * Restore interrupt mask even though we timed out | 210 | * Restore interrupt mask even though we timed out |
191 | */ | 211 | */ |
192 | if (dev->new_comm_interface) | 212 | aac_adapter_enable_int(dev); |
193 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
194 | else | ||
195 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
196 | return -ETIMEDOUT; | 213 | return -ETIMEDOUT; |
197 | } | 214 | } |
198 | /* | 215 | /* |
@@ -215,10 +232,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, | |||
215 | /* | 232 | /* |
216 | * Restore interrupt mask | 233 | * Restore interrupt mask |
217 | */ | 234 | */ |
218 | if (dev->new_comm_interface) | 235 | aac_adapter_enable_int(dev); |
219 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | ||
220 | else | ||
221 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | ||
222 | return 0; | 236 | return 0; |
223 | 237 | ||
224 | } | 238 | } |
@@ -360,35 +374,72 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
360 | } | 374 | } |
361 | 375 | ||
362 | /** | 376 | /** |
363 | * aac_rx_send | 377 | * aac_rx_deliver_producer |
364 | * @fib: fib to issue | 378 | * @fib: fib to issue |
365 | * | 379 | * |
366 | * Will send a fib, returning 0 if successful. | 380 | * Will send a fib, returning 0 if successful. |
367 | */ | 381 | */ |
368 | static int aac_rx_send(struct fib * fib) | 382 | static int aac_rx_deliver_producer(struct fib * fib) |
369 | { | 383 | { |
370 | u64 addr = fib->hw_fib_pa; | ||
371 | struct aac_dev *dev = fib->dev; | 384 | struct aac_dev *dev = fib->dev; |
372 | volatile void __iomem *device = dev->regs.rx; | 385 | struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; |
386 | unsigned long qflags; | ||
373 | u32 Index; | 387 | u32 Index; |
388 | unsigned long nointr = 0; | ||
374 | 389 | ||
375 | dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr)); | 390 | spin_lock_irqsave(q->lock, qflags); |
376 | Index = rx_readl(dev, MUnit.InboundQueue); | 391 | aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib, 1, fib, &nointr); |
377 | if (Index == 0xFFFFFFFFL) | 392 | |
393 | q->numpending++; | ||
394 | *(q->headers.producer) = cpu_to_le32(Index + 1); | ||
395 | spin_unlock_irqrestore(q->lock, qflags); | ||
396 | if (!(nointr & aac_config.irq_mod)) | ||
397 | aac_adapter_notify(dev, AdapNormCmdQueue); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * aac_rx_deliver_message | ||
404 | * @fib: fib to issue | ||
405 | * | ||
406 | * Will send a fib, returning 0 if successful. | ||
407 | */ | ||
408 | static int aac_rx_deliver_message(struct fib * fib) | ||
409 | { | ||
410 | struct aac_dev *dev = fib->dev; | ||
411 | struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; | ||
412 | unsigned long qflags; | ||
413 | u32 Index; | ||
414 | u64 addr; | ||
415 | volatile void __iomem *device; | ||
416 | |||
417 | unsigned long count = 10000000L; /* 50 seconds */ | ||
418 | spin_lock_irqsave(q->lock, qflags); | ||
419 | q->numpending++; | ||
420 | spin_unlock_irqrestore(q->lock, qflags); | ||
421 | for(;;) { | ||
378 | Index = rx_readl(dev, MUnit.InboundQueue); | 422 | Index = rx_readl(dev, MUnit.InboundQueue); |
379 | dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); | 423 | if (Index == 0xFFFFFFFFL) |
380 | if (Index == 0xFFFFFFFFL) | 424 | Index = rx_readl(dev, MUnit.InboundQueue); |
381 | return Index; | 425 | if (Index != 0xFFFFFFFFL) |
426 | break; | ||
427 | if (--count == 0) { | ||
428 | spin_lock_irqsave(q->lock, qflags); | ||
429 | q->numpending--; | ||
430 | spin_unlock_irqrestore(q->lock, qflags); | ||
431 | return -ETIMEDOUT; | ||
432 | } | ||
433 | udelay(5); | ||
434 | } | ||
382 | device = dev->base + Index; | 435 | device = dev->base + Index; |
383 | dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), | 436 | addr = fib->hw_fib_pa; |
384 | (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); | ||
385 | writel((u32)(addr & 0xffffffff), device); | 437 | writel((u32)(addr & 0xffffffff), device); |
386 | device += sizeof(u32); | 438 | device += sizeof(u32); |
387 | writel((u32)(addr >> 32), device); | 439 | writel((u32)(addr >> 32), device); |
388 | device += sizeof(u32); | 440 | device += sizeof(u32); |
389 | writel(le16_to_cpu(fib->hw_fib->header.Size), device); | 441 | writel(le16_to_cpu(fib->hw_fib->header.Size), device); |
390 | rx_writel(dev, MUnit.InboundQueue, Index); | 442 | rx_writel(dev, MUnit.InboundQueue, Index); |
391 | dprintk((KERN_DEBUG "aac_rx_send - return 0\n")); | ||
392 | return 0; | 443 | return 0; |
393 | } | 444 | } |
394 | 445 | ||
@@ -430,6 +481,31 @@ static int aac_rx_restart_adapter(struct aac_dev *dev) | |||
430 | } | 481 | } |
431 | 482 | ||
432 | /** | 483 | /** |
484 | * aac_rx_select_comm - Select communications method | ||
485 | * @dev: Adapter | ||
486 | * @comm: communications method | ||
487 | */ | ||
488 | |||
489 | int aac_rx_select_comm(struct aac_dev *dev, int comm) | ||
490 | { | ||
491 | switch (comm) { | ||
492 | case AAC_COMM_PRODUCER: | ||
493 | dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_producer; | ||
494 | dev->a_ops.adapter_intr = aac_rx_intr_producer; | ||
495 | dev->a_ops.adapter_deliver = aac_rx_deliver_producer; | ||
496 | break; | ||
497 | case AAC_COMM_MESSAGE: | ||
498 | dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_message; | ||
499 | dev->a_ops.adapter_intr = aac_rx_intr_message; | ||
500 | dev->a_ops.adapter_deliver = aac_rx_deliver_message; | ||
501 | break; | ||
502 | default: | ||
503 | return 1; | ||
504 | } | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | /** | ||
433 | * aac_rx_init - initialize an i960 based AAC card | 509 | * aac_rx_init - initialize an i960 based AAC card |
434 | * @dev: device to configure | 510 | * @dev: device to configure |
435 | * | 511 | * |
@@ -489,40 +565,42 @@ int _aac_rx_init(struct aac_dev *dev) | |||
489 | } | 565 | } |
490 | msleep(1); | 566 | msleep(1); |
491 | } | 567 | } |
492 | if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev)<0) | ||
493 | { | ||
494 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); | ||
495 | goto error_iounmap; | ||
496 | } | ||
497 | /* | 568 | /* |
498 | * Fill in the function dispatch table. | 569 | * Fill in the common function dispatch table. |
499 | */ | 570 | */ |
500 | dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; | 571 | dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; |
501 | dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; | 572 | dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; |
502 | dev->a_ops.adapter_notify = aac_rx_notify_adapter; | 573 | dev->a_ops.adapter_notify = aac_rx_notify_adapter; |
503 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; | 574 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; |
504 | dev->a_ops.adapter_check_health = aac_rx_check_health; | 575 | dev->a_ops.adapter_check_health = aac_rx_check_health; |
505 | dev->a_ops.adapter_send = aac_rx_send; | ||
506 | 576 | ||
507 | /* | 577 | /* |
508 | * First clear out all interrupts. Then enable the one's that we | 578 | * First clear out all interrupts. Then enable the one's that we |
509 | * can handle. | 579 | * can handle. |
510 | */ | 580 | */ |
511 | rx_writeb(dev, MUnit.OIMR, 0xff); | 581 | aac_adapter_comm(dev, AAC_COMM_PRODUCER); |
582 | aac_adapter_disable_int(dev); | ||
512 | rx_writel(dev, MUnit.ODR, 0xffffffff); | 583 | rx_writel(dev, MUnit.ODR, 0xffffffff); |
513 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); | 584 | aac_adapter_enable_int(dev); |
514 | 585 | ||
515 | if (aac_init_adapter(dev) == NULL) | 586 | if (aac_init_adapter(dev) == NULL) |
516 | goto error_irq; | 587 | goto error_iounmap; |
517 | if (dev->new_comm_interface) | 588 | aac_adapter_comm(dev, dev->comm_interface); |
518 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); | 589 | if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr, |
590 | IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) { | ||
591 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", | ||
592 | name, instance); | ||
593 | goto error_iounmap; | ||
594 | } | ||
595 | aac_adapter_enable_int(dev); | ||
596 | /* | ||
597 | * Tell the adapter that all is configured, and it can | ||
598 | * start accepting requests | ||
599 | */ | ||
600 | aac_rx_start_adapter(dev); | ||
519 | 601 | ||
520 | return 0; | 602 | return 0; |
521 | 603 | ||
522 | error_irq: | ||
523 | rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); | ||
524 | free_irq(dev->scsi_host_ptr->irq, (void *)dev); | ||
525 | |||
526 | error_iounmap: | 604 | error_iounmap: |
527 | 605 | ||
528 | return -1; | 606 | return -1; |
@@ -530,20 +608,11 @@ error_iounmap: | |||
530 | 608 | ||
531 | int aac_rx_init(struct aac_dev *dev) | 609 | int aac_rx_init(struct aac_dev *dev) |
532 | { | 610 | { |
533 | int retval; | ||
534 | |||
535 | /* | 611 | /* |
536 | * Fill in the function dispatch table. | 612 | * Fill in the function dispatch table. |
537 | */ | 613 | */ |
538 | dev->a_ops.adapter_ioremap = aac_rx_ioremap; | 614 | dev->a_ops.adapter_ioremap = aac_rx_ioremap; |
615 | dev->a_ops.adapter_comm = aac_rx_select_comm; | ||
539 | 616 | ||
540 | retval = _aac_rx_init(dev); | 617 | return _aac_rx_init(dev); |
541 | if (!retval) { | ||
542 | /* | ||
543 | * Tell the adapter that all is configured, and it can | ||
544 | * start accepting requests | ||
545 | */ | ||
546 | aac_rx_start_adapter(dev); | ||
547 | } | ||
548 | return retval; | ||
549 | } | 618 | } |
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 511b0a938fb1..8535db068c2f 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
@@ -92,6 +92,17 @@ static void aac_sa_disable_interrupt (struct aac_dev *dev) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * aac_sa_enable_interrupt - enable interrupt | ||
96 | * @dev: Which adapter to enable. | ||
97 | */ | ||
98 | |||
99 | static void aac_sa_enable_interrupt (struct aac_dev *dev) | ||
100 | { | ||
101 | sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | | ||
102 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); | ||
103 | } | ||
104 | |||
105 | /** | ||
95 | * aac_sa_notify_adapter - handle adapter notification | 106 | * aac_sa_notify_adapter - handle adapter notification |
96 | * @dev: Adapter that notification is for | 107 | * @dev: Adapter that notification is for |
97 | * @event: Event to notidy | 108 | * @event: Event to notidy |
@@ -347,32 +358,36 @@ int aac_sa_init(struct aac_dev *dev) | |||
347 | msleep(1); | 358 | msleep(1); |
348 | } | 359 | } |
349 | 360 | ||
350 | if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev ) < 0) { | ||
351 | printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", name, instance); | ||
352 | goto error_iounmap; | ||
353 | } | ||
354 | |||
355 | /* | 361 | /* |
356 | * Fill in the function dispatch table. | 362 | * Fill in the function dispatch table. |
357 | */ | 363 | */ |
358 | 364 | ||
359 | dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter; | 365 | dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter; |
360 | dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt; | 366 | dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt; |
367 | dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt; | ||
361 | dev->a_ops.adapter_notify = aac_sa_notify_adapter; | 368 | dev->a_ops.adapter_notify = aac_sa_notify_adapter; |
362 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; | 369 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; |
363 | dev->a_ops.adapter_check_health = aac_sa_check_health; | 370 | dev->a_ops.adapter_check_health = aac_sa_check_health; |
371 | dev->a_ops.adapter_intr = aac_sa_intr; | ||
364 | dev->a_ops.adapter_ioremap = aac_sa_ioremap; | 372 | dev->a_ops.adapter_ioremap = aac_sa_ioremap; |
365 | 373 | ||
366 | /* | 374 | /* |
367 | * First clear out all interrupts. Then enable the one's that | 375 | * First clear out all interrupts. Then enable the one's that |
368 | * we can handle. | 376 | * we can handle. |
369 | */ | 377 | */ |
370 | sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); | 378 | aac_adapter_disable_int(dev); |
371 | sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | | 379 | aac_adapter_enable_int(dev); |
372 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); | ||
373 | 380 | ||
374 | if(aac_init_adapter(dev) == NULL) | 381 | if(aac_init_adapter(dev) == NULL) |
375 | goto error_irq; | 382 | goto error_irq; |
383 | if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr, | ||
384 | IRQF_SHARED|IRQF_DISABLED, | ||
385 | "aacraid", (void *)dev ) < 0) { | ||
386 | printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", | ||
387 | name, instance); | ||
388 | goto error_iounmap; | ||
389 | } | ||
390 | aac_adapter_enable_int(dev); | ||
376 | 391 | ||
377 | /* | 392 | /* |
378 | * Tell the adapter that all is configure, and it can start | 393 | * Tell the adapter that all is configure, and it can start |
@@ -382,7 +397,7 @@ int aac_sa_init(struct aac_dev *dev) | |||
382 | return 0; | 397 | return 0; |
383 | 398 | ||
384 | error_irq: | 399 | error_irq: |
385 | sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); | 400 | aac_sa_disable_interrupt(dev); |
386 | free_irq(dev->scsi_host_ptr->irq, (void *)dev); | 401 | free_irq(dev->scsi_host_ptr->irq, (void *)dev); |
387 | 402 | ||
388 | error_iounmap: | 403 | error_iounmap: |
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 306bec355e45..9b3303b64113 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -4403,7 +4403,7 @@ advansys_detect(struct scsi_host_template *tpnt) | |||
4403 | ASC_DBG1(1, | 4403 | ASC_DBG1(1, |
4404 | "advansys_detect: probing I/O port 0x%x...\n", | 4404 | "advansys_detect: probing I/O port 0x%x...\n", |
4405 | iop); | 4405 | iop); |
4406 | if (check_region(iop, ASC_IOADR_GAP) != 0) { | 4406 | if (!request_region(iop, ASC_IOADR_GAP, "advansys")){ |
4407 | printk( | 4407 | printk( |
4408 | "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop); | 4408 | "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop); |
4409 | /* Don't try this I/O port twice. */ | 4409 | /* Don't try this I/O port twice. */ |
@@ -4413,6 +4413,7 @@ advansys_detect(struct scsi_host_template *tpnt) | |||
4413 | printk( | 4413 | printk( |
4414 | "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop); | 4414 | "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop); |
4415 | /* Don't try this I/O port twice. */ | 4415 | /* Don't try this I/O port twice. */ |
4416 | release_region(iop, ASC_IOADR_GAP); | ||
4416 | asc_ioport[ioport] = 0; | 4417 | asc_ioport[ioport] = 0; |
4417 | goto ioport_try_again; | 4418 | goto ioport_try_again; |
4418 | } else { | 4419 | } else { |
@@ -4431,6 +4432,7 @@ advansys_detect(struct scsi_host_template *tpnt) | |||
4431 | * 'ioport' past this board. | 4432 | * 'ioport' past this board. |
4432 | */ | 4433 | */ |
4433 | ioport++; | 4434 | ioport++; |
4435 | release_region(iop, ASC_IOADR_GAP); | ||
4434 | goto ioport_try_again; | 4436 | goto ioport_try_again; |
4435 | } | 4437 | } |
4436 | } | 4438 | } |
@@ -9740,13 +9742,14 @@ AscSearchIOPortAddr11( | |||
9740 | } | 9742 | } |
9741 | for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { | 9743 | for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { |
9742 | iop_base = _asc_def_iop_base[i]; | 9744 | iop_base = _asc_def_iop_base[i]; |
9743 | if (check_region(iop_base, ASC_IOADR_GAP) != 0) { | 9745 | if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")){ |
9744 | ASC_DBG1(1, | 9746 | ASC_DBG1(1, |
9745 | "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n", | 9747 | "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n", |
9746 | iop_base); | 9748 | iop_base); |
9747 | continue; | 9749 | continue; |
9748 | } | 9750 | } |
9749 | ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base); | 9751 | ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base); |
9752 | release_region(iop_base, ASC_IOADR_GAP); | ||
9750 | if (AscFindSignature(iop_base)) { | 9753 | if (AscFindSignature(iop_base)) { |
9751 | return (iop_base); | 9754 | return (iop_base); |
9752 | } | 9755 | } |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 170a4344cbb2..27adbb294ac1 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1337,9 +1337,6 @@ int ahd_pci_test_register_access(struct ahd_softc *); | |||
1337 | /************************** SCB and SCB queue management **********************/ | 1337 | /************************** SCB and SCB queue management **********************/ |
1338 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, | 1338 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, |
1339 | struct scb *scb); | 1339 | struct scb *scb); |
1340 | int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, | ||
1341 | int target, char channel, int lun, | ||
1342 | u_int tag, role_t role); | ||
1343 | 1340 | ||
1344 | /****************************** Initialization ********************************/ | 1341 | /****************************** Initialization ********************************/ |
1345 | struct ahd_softc *ahd_alloc(void *platform_arg, char *name); | 1342 | struct ahd_softc *ahd_alloc(void *platform_arg, char *name); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 07a86a30f676..9ddc6e4a74b0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -262,6 +262,9 @@ static void ahd_update_coalescing_values(struct ahd_softc *ahd, | |||
262 | u_int mincmds); | 262 | u_int mincmds); |
263 | static int ahd_verify_vpd_cksum(struct vpd_config *vpd); | 263 | static int ahd_verify_vpd_cksum(struct vpd_config *vpd); |
264 | static int ahd_wait_seeprom(struct ahd_softc *ahd); | 264 | static int ahd_wait_seeprom(struct ahd_softc *ahd); |
265 | static int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, | ||
266 | int target, char channel, int lun, | ||
267 | u_int tag, role_t role); | ||
265 | 268 | ||
266 | /******************************** Private Inlines *****************************/ | 269 | /******************************** Private Inlines *****************************/ |
267 | 270 | ||
@@ -7256,7 +7259,7 @@ ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) | |||
7256 | } | 7259 | } |
7257 | 7260 | ||
7258 | /************************** SCB and SCB queue management **********************/ | 7261 | /************************** SCB and SCB queue management **********************/ |
7259 | int | 7262 | static int |
7260 | ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, | 7263 | ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, |
7261 | char channel, int lun, u_int tag, role_t role) | 7264 | char channel, int lun, u_int tag, role_t role) |
7262 | { | 7265 | { |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 9bfcca5ede08..c7fe478f4813 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -1126,15 +1126,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa | |||
1126 | return 0; | 1126 | return 0; |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | uint64_t | ||
1130 | ahd_linux_get_memsize(void) | ||
1131 | { | ||
1132 | struct sysinfo si; | ||
1133 | |||
1134 | si_meminfo(&si); | ||
1135 | return ((uint64_t)si.totalram << PAGE_SHIFT); | ||
1136 | } | ||
1137 | |||
1138 | /* | 1129 | /* |
1139 | * Place the SCSI bus into a known state by either resetting it, | 1130 | * Place the SCSI bus into a known state by either resetting it, |
1140 | * or forcing transfer negotiations on the next command to any | 1131 | * or forcing transfer negotiations on the next command to any |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 3a67fc578d78..147c83c456a5 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -496,8 +496,6 @@ ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count) | |||
496 | int ahd_linux_register_host(struct ahd_softc *, | 496 | int ahd_linux_register_host(struct ahd_softc *, |
497 | struct scsi_host_template *); | 497 | struct scsi_host_template *); |
498 | 498 | ||
499 | uint64_t ahd_linux_get_memsize(void); | ||
500 | |||
501 | /*************************** Pretty Printing **********************************/ | 499 | /*************************** Pretty Printing **********************************/ |
502 | struct info_str { | 500 | struct info_str { |
503 | char *buffer; | 501 | char *buffer; |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 1a3ab6aa856b..c62ce41f2793 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -132,6 +132,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
132 | struct ahd_pci_identity *entry; | 132 | struct ahd_pci_identity *entry; |
133 | char *name; | 133 | char *name; |
134 | int error; | 134 | int error; |
135 | struct device *dev = &pdev->dev; | ||
135 | 136 | ||
136 | pci = pdev; | 137 | pci = pdev; |
137 | entry = ahd_find_pci_device(pci); | 138 | entry = ahd_find_pci_device(pci); |
@@ -161,20 +162,18 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
161 | pci_set_master(pdev); | 162 | pci_set_master(pdev); |
162 | 163 | ||
163 | if (sizeof(dma_addr_t) > 4) { | 164 | if (sizeof(dma_addr_t) > 4) { |
164 | uint64_t memsize; | 165 | const u64 required_mask = dma_get_required_mask(dev); |
165 | const uint64_t mask_39bit = 0x7FFFFFFFFFULL; | ||
166 | 166 | ||
167 | memsize = ahd_linux_get_memsize(); | 167 | if (required_mask > DMA_39BIT_MASK && |
168 | 168 | dma_set_mask(dev, DMA_64BIT_MASK) == 0) | |
169 | if (memsize >= 0x8000000000ULL | ||
170 | && pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { | ||
171 | ahd->flags |= AHD_64BIT_ADDRESSING; | 169 | ahd->flags |= AHD_64BIT_ADDRESSING; |
172 | } else if (memsize > 0x80000000 | 170 | else if (required_mask > DMA_32BIT_MASK && |
173 | && pci_set_dma_mask(pdev, mask_39bit) == 0) { | 171 | dma_set_mask(dev, DMA_39BIT_MASK) == 0) |
174 | ahd->flags |= AHD_39BIT_ADDRESSING; | 172 | ahd->flags |= AHD_39BIT_ADDRESSING; |
175 | } | 173 | else |
174 | dma_set_mask(dev, DMA_32BIT_MASK); | ||
176 | } else { | 175 | } else { |
177 | pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 176 | dma_set_mask(dev, DMA_32BIT_MASK); |
178 | } | 177 | } |
179 | ahd->dev_softc = pci; | 178 | ahd->dev_softc = pci; |
180 | error = ahd_pci_config(ahd, entry); | 179 | error = ahd_pci_config(ahd, entry); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 2cf7bb3123f0..8d72bbae96ad 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c | |||
@@ -88,7 +88,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) | |||
88 | 88 | ||
89 | #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) | 89 | #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20) |
90 | 90 | ||
91 | #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6) | 91 | #define SUBID_9005_SEEPTYPE(id) (((id) & 0x0C0) >> 6) |
92 | #define SUBID_9005_SEEPTYPE_NONE 0x0 | 92 | #define SUBID_9005_SEEPTYPE_NONE 0x0 |
93 | #define SUBID_9005_SEEPTYPE_4K 0x1 | 93 | #define SUBID_9005_SEEPTYPE_4K 0x1 |
94 | 94 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index 6f8901b748f7..c520e5b41fb5 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c | |||
@@ -37,18 +37,14 @@ | |||
37 | 37 | ||
38 | static inline int asd_get_ddb(struct asd_ha_struct *asd_ha) | 38 | static inline int asd_get_ddb(struct asd_ha_struct *asd_ha) |
39 | { | 39 | { |
40 | unsigned long flags; | ||
41 | int ddb, i; | 40 | int ddb, i; |
42 | 41 | ||
43 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
44 | ddb = FIND_FREE_DDB(asd_ha); | 42 | ddb = FIND_FREE_DDB(asd_ha); |
45 | if (ddb >= asd_ha->hw_prof.max_ddbs) { | 43 | if (ddb >= asd_ha->hw_prof.max_ddbs) { |
46 | ddb = -ENOMEM; | 44 | ddb = -ENOMEM; |
47 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
48 | goto out; | 45 | goto out; |
49 | } | 46 | } |
50 | SET_DDB(ddb, asd_ha); | 47 | SET_DDB(ddb, asd_ha); |
51 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
52 | 48 | ||
53 | for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4) | 49 | for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4) |
54 | asd_ddbsite_write_dword(asd_ha, ddb, i, 0); | 50 | asd_ddbsite_write_dword(asd_ha, ddb, i, 0); |
@@ -77,14 +73,10 @@ out: | |||
77 | 73 | ||
78 | static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) | 74 | static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) |
79 | { | 75 | { |
80 | unsigned long flags; | ||
81 | |||
82 | if (!ddb || ddb >= 0xFFFF) | 76 | if (!ddb || ddb >= 0xFFFF) |
83 | return; | 77 | return; |
84 | asd_ddbsite_write_byte(asd_ha, ddb, DDB_TYPE, DDB_TYPE_UNUSED); | 78 | asd_ddbsite_write_byte(asd_ha, ddb, DDB_TYPE, DDB_TYPE_UNUSED); |
85 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
86 | CLEAR_DDB(ddb, asd_ha); | 79 | CLEAR_DDB(ddb, asd_ha); |
87 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
88 | } | 80 | } |
89 | 81 | ||
90 | static inline void asd_set_ddb_type(struct domain_device *dev) | 82 | static inline void asd_set_ddb_type(struct domain_device *dev) |
@@ -320,8 +312,11 @@ out: | |||
320 | 312 | ||
321 | int asd_dev_found(struct domain_device *dev) | 313 | int asd_dev_found(struct domain_device *dev) |
322 | { | 314 | { |
315 | unsigned long flags; | ||
323 | int res = 0; | 316 | int res = 0; |
317 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | ||
324 | 318 | ||
319 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
325 | switch (dev->dev_type) { | 320 | switch (dev->dev_type) { |
326 | case SATA_PM: | 321 | case SATA_PM: |
327 | res = asd_init_sata_pm_ddb(dev); | 322 | res = asd_init_sata_pm_ddb(dev); |
@@ -335,14 +330,18 @@ int asd_dev_found(struct domain_device *dev) | |||
335 | else | 330 | else |
336 | res = asd_init_initiator_ddb(dev); | 331 | res = asd_init_initiator_ddb(dev); |
337 | } | 332 | } |
333 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
334 | |||
338 | return res; | 335 | return res; |
339 | } | 336 | } |
340 | 337 | ||
341 | void asd_dev_gone(struct domain_device *dev) | 338 | void asd_dev_gone(struct domain_device *dev) |
342 | { | 339 | { |
343 | int ddb, sister_ddb; | 340 | int ddb, sister_ddb; |
341 | unsigned long flags; | ||
344 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | 342 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; |
345 | 343 | ||
344 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
346 | ddb = (int) (unsigned long) dev->lldd_dev; | 345 | ddb = (int) (unsigned long) dev->lldd_dev; |
347 | sister_ddb = asd_ddbsite_read_word(asd_ha, ddb, SISTER_DDB); | 346 | sister_ddb = asd_ddbsite_read_word(asd_ha, ddb, SISTER_DDB); |
348 | 347 | ||
@@ -350,4 +349,5 @@ void asd_dev_gone(struct domain_device *dev) | |||
350 | asd_free_ddb(asd_ha, sister_ddb); | 349 | asd_free_ddb(asd_ha, sister_ddb); |
351 | asd_free_ddb(asd_ha, ddb); | 350 | asd_free_ddb(asd_ha, ddb); |
352 | dev->lldd_dev = NULL; | 351 | dev->lldd_dev = NULL; |
352 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
353 | } | 353 | } |
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c index e6ade5996d95..6bd8e3059d27 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.c +++ b/drivers/scsi/aic94xx/aic94xx_dump.c | |||
@@ -556,7 +556,7 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq) | |||
556 | PRINT_LMIP_word(asd_ha, lseq, Q_TGTXFR_TAIL); | 556 | PRINT_LMIP_word(asd_ha, lseq, Q_TGTXFR_TAIL); |
557 | PRINT_LMIP_byte(asd_ha, lseq, LINK_NUMBER); | 557 | PRINT_LMIP_byte(asd_ha, lseq, LINK_NUMBER); |
558 | PRINT_LMIP_byte(asd_ha, lseq, SCRATCH_FLAGS); | 558 | PRINT_LMIP_byte(asd_ha, lseq, SCRATCH_FLAGS); |
559 | PRINT_LMIP_qword(asd_ha, lseq, CONNECTION_STATE); | 559 | PRINT_LMIP_dword(asd_ha, lseq, CONNECTION_STATE); |
560 | PRINT_LMIP_word(asd_ha, lseq, CONCTL); | 560 | PRINT_LMIP_word(asd_ha, lseq, CONCTL); |
561 | PRINT_LMIP_byte(asd_ha, lseq, CONSTAT); | 561 | PRINT_LMIP_byte(asd_ha, lseq, CONSTAT); |
562 | PRINT_LMIP_byte(asd_ha, lseq, CONNECTION_MODES); | 562 | PRINT_LMIP_byte(asd_ha, lseq, CONNECTION_MODES); |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index fbc82b00a418..bc7744e35ad0 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "aic94xx_seq.h" | 38 | #include "aic94xx_seq.h" |
39 | 39 | ||
40 | /* The format is "version.release.patchlevel" */ | 40 | /* The format is "version.release.patchlevel" */ |
41 | #define ASD_DRIVER_VERSION "1.0.2" | 41 | #define ASD_DRIVER_VERSION "1.0.3" |
42 | 42 | ||
43 | static int use_msi = 0; | 43 | static int use_msi = 0; |
44 | module_param_named(use_msi, use_msi, int, S_IRUGO); | 44 | module_param_named(use_msi, use_msi, int, S_IRUGO); |
@@ -57,6 +57,8 @@ MODULE_PARM_DESC(collector, "\n" | |||
57 | char sas_addr_str[2*SAS_ADDR_SIZE + 1] = ""; | 57 | char sas_addr_str[2*SAS_ADDR_SIZE + 1] = ""; |
58 | 58 | ||
59 | static struct scsi_transport_template *aic94xx_transport_template; | 59 | static struct scsi_transport_template *aic94xx_transport_template; |
60 | static int asd_scan_finished(struct Scsi_Host *, unsigned long); | ||
61 | static void asd_scan_start(struct Scsi_Host *); | ||
60 | 62 | ||
61 | static struct scsi_host_template aic94xx_sht = { | 63 | static struct scsi_host_template aic94xx_sht = { |
62 | .module = THIS_MODULE, | 64 | .module = THIS_MODULE, |
@@ -66,6 +68,8 @@ static struct scsi_host_template aic94xx_sht = { | |||
66 | .target_alloc = sas_target_alloc, | 68 | .target_alloc = sas_target_alloc, |
67 | .slave_configure = sas_slave_configure, | 69 | .slave_configure = sas_slave_configure, |
68 | .slave_destroy = sas_slave_destroy, | 70 | .slave_destroy = sas_slave_destroy, |
71 | .scan_finished = asd_scan_finished, | ||
72 | .scan_start = asd_scan_start, | ||
69 | .change_queue_depth = sas_change_queue_depth, | 73 | .change_queue_depth = sas_change_queue_depth, |
70 | .change_queue_type = sas_change_queue_type, | 74 | .change_queue_type = sas_change_queue_type, |
71 | .bios_param = sas_bios_param, | 75 | .bios_param = sas_bios_param, |
@@ -75,6 +79,8 @@ static struct scsi_host_template aic94xx_sht = { | |||
75 | .sg_tablesize = SG_ALL, | 79 | .sg_tablesize = SG_ALL, |
76 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, | 80 | .max_sectors = SCSI_DEFAULT_MAX_SECTORS, |
77 | .use_clustering = ENABLE_CLUSTERING, | 81 | .use_clustering = ENABLE_CLUSTERING, |
82 | .eh_device_reset_handler = sas_eh_device_reset_handler, | ||
83 | .eh_bus_reset_handler = sas_eh_bus_reset_handler, | ||
78 | }; | 84 | }; |
79 | 85 | ||
80 | static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha) | 86 | static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha) |
@@ -234,7 +240,7 @@ static int __devinit asd_common_setup(struct asd_ha_struct *asd_ha) | |||
234 | } | 240 | } |
235 | /* Provide some sane default values. */ | 241 | /* Provide some sane default values. */ |
236 | asd_ha->hw_prof.max_scbs = 512; | 242 | asd_ha->hw_prof.max_scbs = 512; |
237 | asd_ha->hw_prof.max_ddbs = 128; | 243 | asd_ha->hw_prof.max_ddbs = ASD_MAX_DDBS; |
238 | asd_ha->hw_prof.num_phys = ASD_MAX_PHYS; | 244 | asd_ha->hw_prof.num_phys = ASD_MAX_PHYS; |
239 | /* All phys are enabled, by default. */ | 245 | /* All phys are enabled, by default. */ |
240 | asd_ha->hw_prof.enabled_phys = 0xFF; | 246 | asd_ha->hw_prof.enabled_phys = 0xFF; |
@@ -526,6 +532,7 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha) | |||
526 | asd_ha->sas_ha.num_phys= ASD_MAX_PHYS; | 532 | asd_ha->sas_ha.num_phys= ASD_MAX_PHYS; |
527 | 533 | ||
528 | asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue; | 534 | asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue; |
535 | asd_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num; | ||
529 | 536 | ||
530 | return sas_register_ha(&asd_ha->sas_ha); | 537 | return sas_register_ha(&asd_ha->sas_ha); |
531 | } | 538 | } |
@@ -671,21 +678,10 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
671 | if (err) | 678 | if (err) |
672 | goto Err_reg_sas; | 679 | goto Err_reg_sas; |
673 | 680 | ||
674 | err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys); | 681 | scsi_scan_host(shost); |
675 | if (err) { | ||
676 | asd_printk("coudln't enable phys, err:%d\n", err); | ||
677 | goto Err_en_phys; | ||
678 | } | ||
679 | ASD_DPRINTK("enabled phys\n"); | ||
680 | /* give the phy enabling interrupt event time to come in (1s | ||
681 | * is empirically about all it takes) */ | ||
682 | ssleep(1); | ||
683 | /* Wait for discovery to finish */ | ||
684 | scsi_flush_work(asd_ha->sas_ha.core.shost); | ||
685 | 682 | ||
686 | return 0; | 683 | return 0; |
687 | Err_en_phys: | 684 | |
688 | asd_unregister_sas_ha(asd_ha); | ||
689 | Err_reg_sas: | 685 | Err_reg_sas: |
690 | asd_remove_dev_attrs(asd_ha); | 686 | asd_remove_dev_attrs(asd_ha); |
691 | Err_dev_attrs: | 687 | Err_dev_attrs: |
@@ -778,6 +774,28 @@ static void __devexit asd_pci_remove(struct pci_dev *dev) | |||
778 | return; | 774 | return; |
779 | } | 775 | } |
780 | 776 | ||
777 | static void asd_scan_start(struct Scsi_Host *shost) | ||
778 | { | ||
779 | struct asd_ha_struct *asd_ha; | ||
780 | int err; | ||
781 | |||
782 | asd_ha = SHOST_TO_SAS_HA(shost)->lldd_ha; | ||
783 | err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys); | ||
784 | if (err) | ||
785 | asd_printk("Couldn't enable phys, err:%d\n", err); | ||
786 | } | ||
787 | |||
788 | static int asd_scan_finished(struct Scsi_Host *shost, unsigned long time) | ||
789 | { | ||
790 | /* give the phy enabling interrupt event time to come in (1s | ||
791 | * is empirically about all it takes) */ | ||
792 | if (time < HZ) | ||
793 | return 0; | ||
794 | /* Wait for discovery to finish */ | ||
795 | scsi_flush_work(shost); | ||
796 | return 1; | ||
797 | } | ||
798 | |||
781 | static ssize_t asd_version_show(struct device_driver *driver, char *buf) | 799 | static ssize_t asd_version_show(struct device_driver *driver, char *buf) |
782 | { | 800 | { |
783 | return snprintf(buf, PAGE_SIZE, "%s\n", ASD_DRIVER_VERSION); | 801 | return snprintf(buf, PAGE_SIZE, "%s\n", ASD_DRIVER_VERSION); |
@@ -885,6 +903,7 @@ static void __exit aic94xx_exit(void) | |||
885 | asd_remove_driver_attrs(&aic94xx_pci_driver.driver); | 903 | asd_remove_driver_attrs(&aic94xx_pci_driver.driver); |
886 | pci_unregister_driver(&aic94xx_pci_driver); | 904 | pci_unregister_driver(&aic94xx_pci_driver); |
887 | sas_release_transport(aic94xx_transport_template); | 905 | sas_release_transport(aic94xx_transport_template); |
906 | asd_release_firmware(); | ||
888 | asd_destroy_global_caches(); | 907 | asd_destroy_global_caches(); |
889 | asd_printk("%s version %s unloaded\n", ASD_DRIVER_DESCRIPTION, | 908 | asd_printk("%s version %s unloaded\n", ASD_DRIVER_DESCRIPTION, |
890 | ASD_DRIVER_VERSION); | 909 | ASD_DRIVER_VERSION); |
diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index a11f4e6d8bd9..a43e8cdf4ee4 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h | |||
@@ -2226,9 +2226,10 @@ | |||
2226 | #define LmSEQ_SAS_RESET_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x0074) | 2226 | #define LmSEQ_SAS_RESET_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x0074) |
2227 | #define LmSEQ_LINK_RESET_RETRY_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0075) | 2227 | #define LmSEQ_LINK_RESET_RETRY_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0075) |
2228 | #define LmSEQ_NUM_LINK_RESET_RETRIES(LinkNum) (LmSCRATCH(LinkNum) + 0x0076) | 2228 | #define LmSEQ_NUM_LINK_RESET_RETRIES(LinkNum) (LmSCRATCH(LinkNum) + 0x0076) |
2229 | #define LmSEQ_OOB_INT_ENABLES(LinkNum) (LmSCRATCH(LinkNum) + 0x007A) | 2229 | #define LmSEQ_OOB_INT_ENABLES(LinkNum) (LmSCRATCH(LinkNum) + 0x0078) |
2230 | #define LmSEQ_NOTIFY_TIMER_DOWN_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007A) | ||
2230 | #define LmSEQ_NOTIFY_TIMER_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x007C) | 2231 | #define LmSEQ_NOTIFY_TIMER_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x007C) |
2231 | #define LmSEQ_NOTIFY_TIMER_DOWN_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007E) | 2232 | #define LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007E) |
2232 | 2233 | ||
2233 | /* Mode dependent scratch page 1, mode 0 and mode 1 */ | 2234 | /* Mode dependent scratch page 1, mode 0 and mode 1 */ |
2234 | #define LmSEQ_SG_LIST_PTR_ADDR0(LinkNum) (LmSCRATCH(LinkNum) + 0x0020) | 2235 | #define LmSEQ_SG_LIST_PTR_ADDR0(LinkNum) (LmSCRATCH(LinkNum) + 0x0020) |
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index 9050e93bfd5e..fa7c5290257d 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h | |||
@@ -34,6 +34,7 @@ | |||
34 | * domain that this sequencer can maintain low-level connections for | 34 | * domain that this sequencer can maintain low-level connections for |
35 | * us. They are be 64 bytes. | 35 | * us. They are be 64 bytes. |
36 | */ | 36 | */ |
37 | #define ASD_MAX_DDBS 128 | ||
37 | 38 | ||
38 | struct asd_ddb_ssp_smp_target_port { | 39 | struct asd_ddb_ssp_smp_target_port { |
39 | u8 conn_type; /* byte 0 */ | 40 | u8 conn_type; /* byte 0 */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 75ed6b0569d1..8f43ff772f23 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -413,40 +413,6 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id) | |||
413 | } | 413 | } |
414 | } | 414 | } |
415 | 415 | ||
416 | /* hard reset a phy later */ | ||
417 | static void do_phy_reset_later(struct work_struct *work) | ||
418 | { | ||
419 | struct sas_phy *sas_phy = | ||
420 | container_of(work, struct sas_phy, reset_work); | ||
421 | int error; | ||
422 | |||
423 | ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__, | ||
424 | sas_phy->identify.phy_identifier); | ||
425 | /* Reset device port */ | ||
426 | error = sas_phy_reset(sas_phy, 1); | ||
427 | if (error) | ||
428 | ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n", | ||
429 | __FUNCTION__, sas_phy->identify.phy_identifier, error); | ||
430 | } | ||
431 | |||
432 | static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost) | ||
433 | { | ||
434 | INIT_WORK(&sas_phy->reset_work, do_phy_reset_later); | ||
435 | queue_work(shost->work_q, &sas_phy->reset_work); | ||
436 | } | ||
437 | |||
438 | /* start up the ABORT TASK tmf... */ | ||
439 | static void task_kill_later(struct asd_ascb *ascb) | ||
440 | { | ||
441 | struct asd_ha_struct *asd_ha = ascb->ha; | ||
442 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | ||
443 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
444 | struct sas_task *task = ascb->uldd_task; | ||
445 | |||
446 | INIT_WORK(&task->abort_work, sas_task_abort); | ||
447 | queue_work(shost->work_q, &task->abort_work); | ||
448 | } | ||
449 | |||
450 | static void escb_tasklet_complete(struct asd_ascb *ascb, | 416 | static void escb_tasklet_complete(struct asd_ascb *ascb, |
451 | struct done_list_struct *dl) | 417 | struct done_list_struct *dl) |
452 | { | 418 | { |
@@ -479,26 +445,55 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
479 | case REQ_TASK_ABORT: { | 445 | case REQ_TASK_ABORT: { |
480 | struct asd_ascb *a, *b; | 446 | struct asd_ascb *a, *b; |
481 | u16 tc_abort; | 447 | u16 tc_abort; |
448 | struct domain_device *failed_dev = NULL; | ||
449 | |||
450 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", | ||
451 | __FUNCTION__, dl->status_block[3]); | ||
482 | 452 | ||
453 | /* | ||
454 | * Find the task that caused the abort and abort it first. | ||
455 | * The sequencer won't put anything on the done list until | ||
456 | * that happens. | ||
457 | */ | ||
483 | tc_abort = *((u16*)(&dl->status_block[1])); | 458 | tc_abort = *((u16*)(&dl->status_block[1])); |
484 | tc_abort = le16_to_cpu(tc_abort); | 459 | tc_abort = le16_to_cpu(tc_abort); |
485 | 460 | ||
486 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", | 461 | list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { |
487 | __FUNCTION__, dl->status_block[3]); | 462 | struct sas_task *task = ascb->uldd_task; |
488 | 463 | ||
489 | /* Find the pending task and abort it. */ | 464 | if (task && a->tc_index == tc_abort) { |
490 | list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) | 465 | failed_dev = task->dev; |
491 | if (a->tc_index == tc_abort) { | 466 | sas_task_abort(task); |
492 | task_kill_later(a); | ||
493 | break; | 467 | break; |
494 | } | 468 | } |
469 | } | ||
470 | |||
471 | if (!failed_dev) { | ||
472 | ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n", | ||
473 | __FUNCTION__, tc_abort); | ||
474 | goto out; | ||
475 | } | ||
476 | |||
477 | /* | ||
478 | * Now abort everything else for that device (hba?) so | ||
479 | * that the EH will wake up and do something. | ||
480 | */ | ||
481 | list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { | ||
482 | struct sas_task *task = ascb->uldd_task; | ||
483 | |||
484 | if (task && | ||
485 | task->dev == failed_dev && | ||
486 | a->tc_index != tc_abort) | ||
487 | sas_task_abort(task); | ||
488 | } | ||
489 | |||
495 | goto out; | 490 | goto out; |
496 | } | 491 | } |
497 | case REQ_DEVICE_RESET: { | 492 | case REQ_DEVICE_RESET: { |
498 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
499 | struct sas_phy *dev_phy; | ||
500 | struct asd_ascb *a; | 493 | struct asd_ascb *a; |
501 | u16 conn_handle; | 494 | u16 conn_handle; |
495 | unsigned long flags; | ||
496 | struct sas_task *last_dev_task = NULL; | ||
502 | 497 | ||
503 | conn_handle = *((u16*)(&dl->status_block[1])); | 498 | conn_handle = *((u16*)(&dl->status_block[1])); |
504 | conn_handle = le16_to_cpu(conn_handle); | 499 | conn_handle = le16_to_cpu(conn_handle); |
@@ -506,32 +501,47 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
506 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, | 501 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, |
507 | dl->status_block[3]); | 502 | dl->status_block[3]); |
508 | 503 | ||
509 | /* Kill all pending tasks and reset the device */ | 504 | /* Find the last pending task for the device... */ |
510 | dev_phy = NULL; | ||
511 | list_for_each_entry(a, &asd_ha->seq.pend_q, list) { | 505 | list_for_each_entry(a, &asd_ha->seq.pend_q, list) { |
512 | struct sas_task *task; | ||
513 | struct domain_device *dev; | ||
514 | u16 x; | 506 | u16 x; |
507 | struct domain_device *dev; | ||
508 | struct sas_task *task = a->uldd_task; | ||
515 | 509 | ||
516 | task = a->uldd_task; | ||
517 | if (!task) | 510 | if (!task) |
518 | continue; | 511 | continue; |
519 | dev = task->dev; | 512 | dev = task->dev; |
520 | 513 | ||
521 | x = (unsigned long)dev->lldd_dev; | 514 | x = (unsigned long)dev->lldd_dev; |
522 | if (x == conn_handle) { | 515 | if (x == conn_handle) |
523 | dev_phy = dev->port->phy; | 516 | last_dev_task = task; |
524 | task_kill_later(a); | ||
525 | } | ||
526 | } | 517 | } |
527 | 518 | ||
528 | /* Reset device port */ | 519 | if (!last_dev_task) { |
529 | if (!dev_phy) { | 520 | ASD_DPRINTK("%s: Device reset for idle device %d?\n", |
530 | ASD_DPRINTK("%s: No pending commands; can't reset.\n", | 521 | __FUNCTION__, conn_handle); |
531 | __FUNCTION__); | ||
532 | goto out; | 522 | goto out; |
533 | } | 523 | } |
534 | phy_reset_later(dev_phy, shost); | 524 | |
525 | /* ...and set the reset flag */ | ||
526 | spin_lock_irqsave(&last_dev_task->task_state_lock, flags); | ||
527 | last_dev_task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; | ||
528 | spin_unlock_irqrestore(&last_dev_task->task_state_lock, flags); | ||
529 | |||
530 | /* Kill all pending tasks for the device */ | ||
531 | list_for_each_entry(a, &asd_ha->seq.pend_q, list) { | ||
532 | u16 x; | ||
533 | struct domain_device *dev; | ||
534 | struct sas_task *task = a->uldd_task; | ||
535 | |||
536 | if (!task) | ||
537 | continue; | ||
538 | dev = task->dev; | ||
539 | |||
540 | x = (unsigned long)dev->lldd_dev; | ||
541 | if (x == conn_handle) | ||
542 | sas_task_abort(task); | ||
543 | } | ||
544 | |||
535 | goto out; | 545 | goto out; |
536 | } | 546 | } |
537 | case SIGNAL_NCQ_ERROR: | 547 | case SIGNAL_NCQ_ERROR: |
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index e5a0ec37e954..5b0932f61473 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c | |||
@@ -427,7 +427,7 @@ struct asd_manuf_sec { | |||
427 | 427 | ||
428 | struct asd_manuf_phy_desc { | 428 | struct asd_manuf_phy_desc { |
429 | u8 state; /* low 4 bits */ | 429 | u8 state; /* low 4 bits */ |
430 | #define MS_PHY_STATE_ENABLEABLE 0 | 430 | #define MS_PHY_STATE_ENABLED 0 |
431 | #define MS_PHY_STATE_REPORTED 1 | 431 | #define MS_PHY_STATE_REPORTED 1 |
432 | #define MS_PHY_STATE_HIDDEN 2 | 432 | #define MS_PHY_STATE_HIDDEN 2 |
433 | u8 phy_id; | 433 | u8 phy_id; |
@@ -756,11 +756,11 @@ static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1) | |||
756 | * | 756 | * |
757 | * HIDDEN phys do not count in the total count. REPORTED phys cannot | 757 | * HIDDEN phys do not count in the total count. REPORTED phys cannot |
758 | * be enabled but are reported and counted towards the total. | 758 | * be enabled but are reported and counted towards the total. |
759 | * ENEBLEABLE phys are enabled by default and count towards the total. | 759 | * ENABLED phys are enabled by default and count towards the total. |
760 | * The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys | 760 | * The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys |
761 | * merely specifies the number of phys the host adapter decided to | 761 | * merely specifies the number of phys the host adapter decided to |
762 | * report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN, | 762 | * report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN, |
763 | * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENEBLEABLE. | 763 | * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENABLED. |
764 | * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2 | 764 | * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2 |
765 | * are actually enabled (enabled by default, max number of phys | 765 | * are actually enabled (enabled by default, max number of phys |
766 | * enableable in this case). | 766 | * enableable in this case). |
@@ -816,8 +816,8 @@ static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha, | |||
816 | asd_ha->hw_prof.enabled_phys &= ~(1 << i); | 816 | asd_ha->hw_prof.enabled_phys &= ~(1 << i); |
817 | rep_phys++; | 817 | rep_phys++; |
818 | continue; | 818 | continue; |
819 | case MS_PHY_STATE_ENABLEABLE: | 819 | case MS_PHY_STATE_ENABLED: |
820 | ASD_DPRINTK("ms: phy%d: ENEBLEABLE\n", i); | 820 | ASD_DPRINTK("ms: phy%d: ENABLED\n", i); |
821 | asd_ha->hw_prof.enabled_phys |= (1 << i); | 821 | asd_ha->hw_prof.enabled_phys |= (1 << i); |
822 | en_phys++; | 822 | en_phys++; |
823 | break; | 823 | break; |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 845112539d05..eae7a247bece 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -810,6 +810,8 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq) | |||
810 | /* No delay for the first NOTIFY to be sent to the attached target. */ | 810 | /* No delay for the first NOTIFY to be sent to the attached target. */ |
811 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq), | 811 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq), |
812 | ASD_NOTIFY_DOWN_COUNT); | 812 | ASD_NOTIFY_DOWN_COUNT); |
813 | asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(lseq), | ||
814 | ASD_NOTIFY_DOWN_COUNT); | ||
813 | 815 | ||
814 | /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */ | 816 | /* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */ |
815 | for (i = 0; i < 2; i++) { | 817 | for (i = 0; i < 2; i++) { |
@@ -907,6 +909,16 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha) | |||
907 | for (i = 0; i < ASD_SCB_SIZE; i += 4) | 909 | for (i = 0; i < ASD_SCB_SIZE; i += 4) |
908 | asd_scbsite_write_dword(asd_ha, site_no, i, 0); | 910 | asd_scbsite_write_dword(asd_ha, site_no, i, 0); |
909 | 911 | ||
912 | /* Initialize SCB Site Opcode field to invalid. */ | ||
913 | asd_scbsite_write_byte(asd_ha, site_no, | ||
914 | offsetof(struct scb_header, opcode), | ||
915 | 0xFF); | ||
916 | |||
917 | /* Initialize SCB Site Flags field to mean a response | ||
918 | * frame has been received. This means inadvertent | ||
919 | * frames received to be dropped. */ | ||
920 | asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01); | ||
921 | |||
910 | /* Workaround needed by SEQ to fix a SATA issue is to exclude | 922 | /* Workaround needed by SEQ to fix a SATA issue is to exclude |
911 | * certain SCB sites from the free list. */ | 923 | * certain SCB sites from the free list. */ |
912 | if (!SCB_SITE_VALID(site_no)) | 924 | if (!SCB_SITE_VALID(site_no)) |
@@ -922,16 +934,6 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha) | |||
922 | /* Q_NEXT field of the last SCB is invalidated. */ | 934 | /* Q_NEXT field of the last SCB is invalidated. */ |
923 | asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no); | 935 | asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no); |
924 | 936 | ||
925 | /* Initialize SCB Site Opcode field to invalid. */ | ||
926 | asd_scbsite_write_byte(asd_ha, site_no, | ||
927 | offsetof(struct scb_header, opcode), | ||
928 | 0xFF); | ||
929 | |||
930 | /* Initialize SCB Site Flags field to mean a response | ||
931 | * frame has been received. This means inadvertent | ||
932 | * frames received to be dropped. */ | ||
933 | asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01); | ||
934 | |||
935 | first_scb_site_no = site_no; | 937 | first_scb_site_no = site_no; |
936 | max_scbs++; | 938 | max_scbs++; |
937 | } | 939 | } |
@@ -1173,6 +1175,16 @@ static void asd_init_ddb_0(struct asd_ha_struct *asd_ha) | |||
1173 | set_bit(0, asd_ha->hw_prof.ddb_bitmap); | 1175 | set_bit(0, asd_ha->hw_prof.ddb_bitmap); |
1174 | } | 1176 | } |
1175 | 1177 | ||
1178 | static void asd_seq_init_ddb_sites(struct asd_ha_struct *asd_ha) | ||
1179 | { | ||
1180 | unsigned int i; | ||
1181 | unsigned int ddb_site; | ||
1182 | |||
1183 | for (ddb_site = 0 ; ddb_site < ASD_MAX_DDBS; ddb_site++) | ||
1184 | for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4) | ||
1185 | asd_ddbsite_write_dword(asd_ha, ddb_site, i, 0); | ||
1186 | } | ||
1187 | |||
1176 | /** | 1188 | /** |
1177 | * asd_seq_setup_seqs -- setup and initialize central and link sequencers | 1189 | * asd_seq_setup_seqs -- setup and initialize central and link sequencers |
1178 | * @asd_ha: pointer to host adapter structure | 1190 | * @asd_ha: pointer to host adapter structure |
@@ -1182,6 +1194,9 @@ static void asd_seq_setup_seqs(struct asd_ha_struct *asd_ha) | |||
1182 | int lseq; | 1194 | int lseq; |
1183 | u8 lseq_mask; | 1195 | u8 lseq_mask; |
1184 | 1196 | ||
1197 | /* Initialize DDB sites */ | ||
1198 | asd_seq_init_ddb_sites(asd_ha); | ||
1199 | |||
1185 | /* Initialize SCB sites. Done first to compute some values which | 1200 | /* Initialize SCB sites. Done first to compute some values which |
1186 | * the rest of the init code depends on. */ | 1201 | * the rest of the init code depends on. */ |
1187 | asd_init_scb_sites(asd_ha); | 1202 | asd_init_scb_sites(asd_ha); |
@@ -1232,6 +1247,13 @@ static int asd_seq_start_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
1232 | return asd_seq_unpause_lseq(asd_ha, lseq); | 1247 | return asd_seq_unpause_lseq(asd_ha, lseq); |
1233 | } | 1248 | } |
1234 | 1249 | ||
1250 | int asd_release_firmware(void) | ||
1251 | { | ||
1252 | if (sequencer_fw) | ||
1253 | release_firmware(sequencer_fw); | ||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1235 | static int asd_request_firmware(struct asd_ha_struct *asd_ha) | 1257 | static int asd_request_firmware(struct asd_ha_struct *asd_ha) |
1236 | { | 1258 | { |
1237 | int err, i; | 1259 | int err, i; |
@@ -1375,7 +1397,9 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
1375 | u8 phy_is_up; | 1397 | u8 phy_is_up; |
1376 | u8 mask; | 1398 | u8 mask; |
1377 | int i, err; | 1399 | int i, err; |
1400 | unsigned long flags; | ||
1378 | 1401 | ||
1402 | spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); | ||
1379 | for_each_phy(phy_mask, mask, i) | 1403 | for_each_phy(phy_mask, mask, i) |
1380 | asd_ddbsite_write_byte(asd_ha, 0, | 1404 | asd_ddbsite_write_byte(asd_ha, 0, |
1381 | offsetof(struct asd_ddb_seq_shared, | 1405 | offsetof(struct asd_ddb_seq_shared, |
@@ -1395,6 +1419,7 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
1395 | break; | 1419 | break; |
1396 | } | 1420 | } |
1397 | } | 1421 | } |
1422 | spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags); | ||
1398 | 1423 | ||
1399 | if (err) | 1424 | if (err) |
1400 | asd_printk("couldn't update DDB 0:error:%d\n", err); | 1425 | asd_printk("couldn't update DDB 0:error:%d\n", err); |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h index 9e715e5496af..9437ff0ae3a4 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/drivers/scsi/aic94xx/aic94xx_seq.h | |||
@@ -63,6 +63,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | |||
63 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | 63 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); |
64 | int asd_init_seqs(struct asd_ha_struct *asd_ha); | 64 | int asd_init_seqs(struct asd_ha_struct *asd_ha); |
65 | int asd_start_seqs(struct asd_ha_struct *asd_ha); | 65 | int asd_start_seqs(struct asd_ha_struct *asd_ha); |
66 | int asd_release_firmware(void); | ||
66 | 67 | ||
67 | void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy); | 68 | void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy); |
68 | #endif | 69 | #endif |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index d202ed5a6709..e2ad5bed9403 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -349,6 +349,7 @@ Again: | |||
349 | 349 | ||
350 | spin_lock_irqsave(&task->task_state_lock, flags); | 350 | spin_lock_irqsave(&task->task_state_lock, flags); |
351 | task->task_state_flags &= ~SAS_TASK_STATE_PENDING; | 351 | task->task_state_flags &= ~SAS_TASK_STATE_PENDING; |
352 | task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | ||
352 | task->task_state_flags |= SAS_TASK_STATE_DONE; | 353 | task->task_state_flags |= SAS_TASK_STATE_DONE; |
353 | if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) { | 354 | if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) { |
354 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 355 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
@@ -557,6 +558,7 @@ int asd_execute_task(struct sas_task *task, const int num, | |||
557 | struct sas_task *t = task; | 558 | struct sas_task *t = task; |
558 | struct asd_ascb *ascb = NULL, *a; | 559 | struct asd_ascb *ascb = NULL, *a; |
559 | struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; | 560 | struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; |
561 | unsigned long flags; | ||
560 | 562 | ||
561 | res = asd_can_queue(asd_ha, num); | 563 | res = asd_can_queue(asd_ha, num); |
562 | if (res) | 564 | if (res) |
@@ -599,6 +601,10 @@ int asd_execute_task(struct sas_task *task, const int num, | |||
599 | } | 601 | } |
600 | if (res) | 602 | if (res) |
601 | goto out_err_unmap; | 603 | goto out_err_unmap; |
604 | |||
605 | spin_lock_irqsave(&t->task_state_lock, flags); | ||
606 | t->task_state_flags |= SAS_TASK_AT_INITIATOR; | ||
607 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
602 | } | 608 | } |
603 | list_del_init(&alist); | 609 | list_del_init(&alist); |
604 | 610 | ||
@@ -617,6 +623,9 @@ out_err_unmap: | |||
617 | if (a == b) | 623 | if (a == b) |
618 | break; | 624 | break; |
619 | t = a->uldd_task; | 625 | t = a->uldd_task; |
626 | spin_lock_irqsave(&t->task_state_lock, flags); | ||
627 | t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; | ||
628 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
620 | switch (t->task_proto) { | 629 | switch (t->task_proto) { |
621 | case SATA_PROTO: | 630 | case SATA_PROTO: |
622 | case SAS_PROTO_STP: | 631 | case SAS_PROTO_STP: |
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 61234384503b..9a14a6d97275 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c | |||
@@ -566,9 +566,7 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun, | |||
566 | res = TMF_RESP_FUNC_ESUPP; | 566 | res = TMF_RESP_FUNC_ESUPP; |
567 | break; | 567 | break; |
568 | default: | 568 | default: |
569 | ASD_DPRINTK("%s: converting result 0x%x to TMF_RESP_FUNC_FAILED\n", | 569 | /* Allow TMF response codes to propagate upwards */ |
570 | __FUNCTION__, res); | ||
571 | res = TMF_RESP_FUNC_FAILED; | ||
572 | break; | 570 | break; |
573 | } | 571 | } |
574 | out_err: | 572 | out_err: |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 821386c7b576..95045e33710d 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -595,10 +595,8 @@ static int ipr_save_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg) | |||
595 | { | 595 | { |
596 | int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX); | 596 | int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX); |
597 | 597 | ||
598 | if (pcix_cmd_reg == 0) { | 598 | if (pcix_cmd_reg == 0) |
599 | dev_err(&ioa_cfg->pdev->dev, "Failed to save PCI-X command register\n"); | 599 | return 0; |
600 | return -EIO; | ||
601 | } | ||
602 | 600 | ||
603 | if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD, | 601 | if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD, |
604 | &ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) { | 602 | &ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) { |
@@ -627,10 +625,6 @@ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg) | |||
627 | dev_err(&ioa_cfg->pdev->dev, "Failed to setup PCI-X command register\n"); | 625 | dev_err(&ioa_cfg->pdev->dev, "Failed to setup PCI-X command register\n"); |
628 | return -EIO; | 626 | return -EIO; |
629 | } | 627 | } |
630 | } else { | ||
631 | dev_err(&ioa_cfg->pdev->dev, | ||
632 | "Failed to setup PCI-X command register\n"); | ||
633 | return -EIO; | ||
634 | } | 628 | } |
635 | 629 | ||
636 | return 0; | 630 | return 0; |
@@ -6314,7 +6308,6 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) | |||
6314 | int rc; | 6308 | int rc; |
6315 | 6309 | ||
6316 | ENTER; | 6310 | ENTER; |
6317 | pci_unblock_user_cfg_access(ioa_cfg->pdev); | ||
6318 | rc = pci_restore_state(ioa_cfg->pdev); | 6311 | rc = pci_restore_state(ioa_cfg->pdev); |
6319 | 6312 | ||
6320 | if (rc != PCIBIOS_SUCCESSFUL) { | 6313 | if (rc != PCIBIOS_SUCCESSFUL) { |
@@ -6355,6 +6348,24 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) | |||
6355 | } | 6348 | } |
6356 | 6349 | ||
6357 | /** | 6350 | /** |
6351 | * ipr_reset_bist_done - BIST has completed on the adapter. | ||
6352 | * @ipr_cmd: ipr command struct | ||
6353 | * | ||
6354 | * Description: Unblock config space and resume the reset process. | ||
6355 | * | ||
6356 | * Return value: | ||
6357 | * IPR_RC_JOB_CONTINUE | ||
6358 | **/ | ||
6359 | static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd) | ||
6360 | { | ||
6361 | ENTER; | ||
6362 | pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); | ||
6363 | ipr_cmd->job_step = ipr_reset_restore_cfg_space; | ||
6364 | LEAVE; | ||
6365 | return IPR_RC_JOB_CONTINUE; | ||
6366 | } | ||
6367 | |||
6368 | /** | ||
6358 | * ipr_reset_start_bist - Run BIST on the adapter. | 6369 | * ipr_reset_start_bist - Run BIST on the adapter. |
6359 | * @ipr_cmd: ipr command struct | 6370 | * @ipr_cmd: ipr command struct |
6360 | * | 6371 | * |
@@ -6376,7 +6387,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) | |||
6376 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | 6387 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); |
6377 | rc = IPR_RC_JOB_CONTINUE; | 6388 | rc = IPR_RC_JOB_CONTINUE; |
6378 | } else { | 6389 | } else { |
6379 | ipr_cmd->job_step = ipr_reset_restore_cfg_space; | 6390 | ipr_cmd->job_step = ipr_reset_bist_done; |
6380 | ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); | 6391 | ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); |
6381 | rc = IPR_RC_JOB_RETURN; | 6392 | rc = IPR_RC_JOB_RETURN; |
6382 | } | 6393 | } |
@@ -7166,9 +7177,6 @@ ipr_get_chip_cfg(const struct pci_device_id *dev_id) | |||
7166 | { | 7177 | { |
7167 | int i; | 7178 | int i; |
7168 | 7179 | ||
7169 | if (dev_id->driver_data) | ||
7170 | return (const struct ipr_chip_cfg_t *)dev_id->driver_data; | ||
7171 | |||
7172 | for (i = 0; i < ARRAY_SIZE(ipr_chip); i++) | 7180 | for (i = 0; i < ARRAY_SIZE(ipr_chip); i++) |
7173 | if (ipr_chip[i].vendor == dev_id->vendor && | 7181 | if (ipr_chip[i].vendor == dev_id->vendor && |
7174 | ipr_chip[i].device == dev_id->device) | 7182 | ipr_chip[i].device == dev_id->device) |
@@ -7517,62 +7525,43 @@ static void ipr_shutdown(struct pci_dev *pdev) | |||
7517 | 7525 | ||
7518 | static struct pci_device_id ipr_pci_table[] __devinitdata = { | 7526 | static struct pci_device_id ipr_pci_table[] __devinitdata = { |
7519 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, | 7527 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, |
7520 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5702, | 7528 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5702, 0, 0, 0 }, |
7521 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7522 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, | 7529 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, |
7523 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5703, | 7530 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5703, 0, 0, 0 }, |
7524 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7525 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, | 7531 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, |
7526 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573D, | 7532 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573D, 0, 0, 0 }, |
7527 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7528 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, | 7533 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, |
7529 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573E, | 7534 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573E, 0, 0, 0 }, |
7530 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7531 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, | 7535 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, |
7532 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571B, | 7536 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571B, 0, 0, 0 }, |
7533 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7534 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, | 7537 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, |
7535 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572E, | 7538 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572E, 0, 0, 0 }, |
7536 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7537 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, | 7539 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, |
7538 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, | 7540 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, 0, 0, 0 }, |
7539 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7540 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, | 7541 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, |
7541 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, | 7542 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, 0 }, |
7542 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7543 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, | 7543 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, |
7544 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, | 7544 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, |
7545 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7546 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, | 7545 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, |
7547 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, | 7546 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, |
7548 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7549 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, | 7547 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, |
7550 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, | 7548 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, |
7551 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7552 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | 7549 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, |
7553 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, | 7550 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, |
7554 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7555 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | 7551 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, |
7556 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, | 7552 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, |
7557 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7558 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | 7553 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, |
7559 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, | 7554 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, |
7560 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7561 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | 7555 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, |
7562 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, | 7556 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, 0 }, |
7563 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7564 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, | 7557 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, |
7565 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, | 7558 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, 0 }, |
7566 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | ||
7567 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 7559 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7568 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, | 7560 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, 0, 0, 0 }, |
7569 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | ||
7570 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 7561 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7571 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, | 7562 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, 0 }, |
7572 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | ||
7573 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 7563 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7574 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, | 7564 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, 0 }, |
7575 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | ||
7576 | { } | 7565 | { } |
7577 | }; | 7566 | }; |
7578 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); | 7567 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 9f62a1d4d511..88f285de97bb 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.3.0" | 40 | #define IPR_DRIVER_VERSION "2.3.1" |
41 | #define IPR_DRIVER_DATE "(November 8, 2006)" | 41 | #define IPR_DRIVER_DATE "(January 23, 2007)" |
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/lasi700.c b/drivers/scsi/lasi700.c index f0871c3ac3d9..2aae1b081fcf 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c | |||
@@ -123,6 +123,7 @@ lasi700_probe(struct parisc_device *dev) | |||
123 | hostdata->force_le_on_be = 0; | 123 | hostdata->force_le_on_be = 0; |
124 | hostdata->chip710 = 1; | 124 | hostdata->chip710 = 1; |
125 | hostdata->dmode_extra = DMODE_FC2; | 125 | hostdata->dmode_extra = DMODE_FC2; |
126 | hostdata->burst_length = 8; | ||
126 | } | 127 | } |
127 | 128 | ||
128 | host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev); | 129 | host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev); |
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index fb7df7b75811..a65598b1e536 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
@@ -548,7 +548,7 @@ int sas_discover_sata(struct domain_device *dev) | |||
548 | 548 | ||
549 | res = sas_notify_lldd_dev_found(dev); | 549 | res = sas_notify_lldd_dev_found(dev); |
550 | if (res) | 550 | if (res) |
551 | return res; | 551 | goto out_err2; |
552 | 552 | ||
553 | switch (dev->dev_type) { | 553 | switch (dev->dev_type) { |
554 | case SATA_DEV: | 554 | case SATA_DEV: |
@@ -560,11 +560,23 @@ int sas_discover_sata(struct domain_device *dev) | |||
560 | default: | 560 | default: |
561 | break; | 561 | break; |
562 | } | 562 | } |
563 | if (res) | ||
564 | goto out_err; | ||
563 | 565 | ||
564 | sas_notify_lldd_dev_gone(dev); | 566 | sas_notify_lldd_dev_gone(dev); |
565 | if (!res) { | 567 | res = sas_notify_lldd_dev_found(dev); |
566 | sas_notify_lldd_dev_found(dev); | 568 | if (res) |
567 | } | 569 | goto out_err2; |
570 | |||
571 | res = sas_rphy_add(dev->rphy); | ||
572 | if (res) | ||
573 | goto out_err; | ||
574 | |||
575 | return res; | ||
576 | |||
577 | out_err: | ||
578 | sas_notify_lldd_dev_gone(dev); | ||
579 | out_err2: | ||
568 | return res; | 580 | return res; |
569 | } | 581 | } |
570 | 582 | ||
@@ -580,21 +592,17 @@ int sas_discover_end_dev(struct domain_device *dev) | |||
580 | 592 | ||
581 | res = sas_notify_lldd_dev_found(dev); | 593 | res = sas_notify_lldd_dev_found(dev); |
582 | if (res) | 594 | if (res) |
583 | return res; | 595 | goto out_err2; |
584 | 596 | ||
585 | res = sas_rphy_add(dev->rphy); | 597 | res = sas_rphy_add(dev->rphy); |
586 | if (res) | 598 | if (res) |
587 | goto out_err; | 599 | goto out_err; |
588 | 600 | ||
589 | /* do this to get the end device port attributes which will have | ||
590 | * been scanned in sas_rphy_add */ | ||
591 | sas_notify_lldd_dev_gone(dev); | ||
592 | sas_notify_lldd_dev_found(dev); | ||
593 | |||
594 | return 0; | 601 | return 0; |
595 | 602 | ||
596 | out_err: | 603 | out_err: |
597 | sas_notify_lldd_dev_gone(dev); | 604 | sas_notify_lldd_dev_gone(dev); |
605 | out_err2: | ||
598 | return res; | 606 | return res; |
599 | } | 607 | } |
600 | 608 | ||
@@ -649,6 +657,7 @@ void sas_unregister_domain_devices(struct asd_sas_port *port) | |||
649 | */ | 657 | */ |
650 | static void sas_discover_domain(struct work_struct *work) | 658 | static void sas_discover_domain(struct work_struct *work) |
651 | { | 659 | { |
660 | struct domain_device *dev; | ||
652 | int error = 0; | 661 | int error = 0; |
653 | struct sas_discovery_event *ev = | 662 | struct sas_discovery_event *ev = |
654 | container_of(work, struct sas_discovery_event, work); | 663 | container_of(work, struct sas_discovery_event, work); |
@@ -658,35 +667,42 @@ static void sas_discover_domain(struct work_struct *work) | |||
658 | &port->disc.pending); | 667 | &port->disc.pending); |
659 | 668 | ||
660 | if (port->port_dev) | 669 | if (port->port_dev) |
661 | return ; | 670 | return; |
662 | else { | 671 | |
663 | error = sas_get_port_device(port); | 672 | error = sas_get_port_device(port); |
664 | if (error) | 673 | if (error) |
665 | return; | 674 | return; |
666 | } | 675 | dev = port->port_dev; |
667 | 676 | ||
668 | SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, | 677 | SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, |
669 | current->pid); | 678 | current->pid); |
670 | 679 | ||
671 | switch (port->port_dev->dev_type) { | 680 | switch (dev->dev_type) { |
672 | case SAS_END_DEV: | 681 | case SAS_END_DEV: |
673 | error = sas_discover_end_dev(port->port_dev); | 682 | error = sas_discover_end_dev(dev); |
674 | break; | 683 | break; |
675 | case EDGE_DEV: | 684 | case EDGE_DEV: |
676 | case FANOUT_DEV: | 685 | case FANOUT_DEV: |
677 | error = sas_discover_root_expander(port->port_dev); | 686 | error = sas_discover_root_expander(dev); |
678 | break; | 687 | break; |
679 | case SATA_DEV: | 688 | case SATA_DEV: |
680 | case SATA_PM: | 689 | case SATA_PM: |
681 | error = sas_discover_sata(port->port_dev); | 690 | error = sas_discover_sata(dev); |
682 | break; | 691 | break; |
683 | default: | 692 | default: |
684 | SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type); | 693 | SAS_DPRINTK("unhandled device %d\n", dev->dev_type); |
685 | break; | 694 | break; |
686 | } | 695 | } |
687 | 696 | ||
688 | if (error) { | 697 | if (error) { |
689 | kfree(port->port_dev); /* not kobject_register-ed yet */ | 698 | sas_rphy_free(dev->rphy); |
699 | dev->rphy = NULL; | ||
700 | |||
701 | spin_lock(&port->dev_list_lock); | ||
702 | list_del_init(&dev->dev_list_node); | ||
703 | spin_unlock(&port->dev_list_lock); | ||
704 | |||
705 | kfree(dev); /* not kobject_register-ed yet */ | ||
690 | port->port_dev = NULL; | 706 | port->port_dev = NULL; |
691 | } | 707 | } |
692 | 708 | ||
@@ -726,7 +742,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) | |||
726 | BUG_ON(ev >= DISC_NUM_EVENTS); | 742 | BUG_ON(ev >= DISC_NUM_EVENTS); |
727 | 743 | ||
728 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, | 744 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, |
729 | &disc->disc_work[ev].work, port->ha->core.shost); | 745 | &disc->disc_work[ev].work, port->ha); |
730 | 746 | ||
731 | return 0; | 747 | return 0; |
732 | } | 748 | } |
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index d83392ee6823..9db30fb5caf2 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c | |||
@@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event) | |||
31 | BUG_ON(event >= HA_NUM_EVENTS); | 31 | BUG_ON(event >= HA_NUM_EVENTS); |
32 | 32 | ||
33 | sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, | 33 | sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, |
34 | &sas_ha->ha_events[event].work, sas_ha->core.shost); | 34 | &sas_ha->ha_events[event].work, sas_ha); |
35 | } | 35 | } |
36 | 36 | ||
37 | static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) | 37 | static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) |
@@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) | |||
41 | BUG_ON(event >= PORT_NUM_EVENTS); | 41 | BUG_ON(event >= PORT_NUM_EVENTS); |
42 | 42 | ||
43 | sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, | 43 | sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, |
44 | &phy->port_events[event].work, ha->core.shost); | 44 | &phy->port_events[event].work, ha); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) | 47 | static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) |
@@ -51,7 +51,7 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) | |||
51 | BUG_ON(event >= PHY_NUM_EVENTS); | 51 | BUG_ON(event >= PHY_NUM_EVENTS); |
52 | 52 | ||
53 | sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, | 53 | sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, |
54 | &phy->phy_events[event].work, ha->core.shost); | 54 | &phy->phy_events[event].work, ha); |
55 | } | 55 | } |
56 | 56 | ||
57 | int sas_init_events(struct sas_ha_struct *sas_ha) | 57 | int sas_init_events(struct sas_ha_struct *sas_ha) |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index d31e6fa466f7..dc70c180e115 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -667,8 +667,9 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
667 | return child; | 667 | return child; |
668 | 668 | ||
669 | out_list_del: | 669 | out_list_del: |
670 | sas_rphy_free(child->rphy); | ||
671 | child->rphy = NULL; | ||
670 | list_del(&child->dev_list_node); | 672 | list_del(&child->dev_list_node); |
671 | sas_rphy_free(rphy); | ||
672 | out_free: | 673 | out_free: |
673 | sas_port_delete(phy->port); | 674 | sas_port_delete(phy->port); |
674 | out_err: | 675 | out_err: |
@@ -677,6 +678,29 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
677 | return NULL; | 678 | return NULL; |
678 | } | 679 | } |
679 | 680 | ||
681 | /* See if this phy is part of a wide port */ | ||
682 | static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) | ||
683 | { | ||
684 | struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; | ||
685 | int i; | ||
686 | |||
687 | for (i = 0; i < parent->ex_dev.num_phys; i++) { | ||
688 | struct ex_phy *ephy = &parent->ex_dev.ex_phy[i]; | ||
689 | |||
690 | if (ephy == phy) | ||
691 | continue; | ||
692 | |||
693 | if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr, | ||
694 | SAS_ADDR_SIZE) && ephy->port) { | ||
695 | sas_port_add_phy(ephy->port, phy->phy); | ||
696 | phy->phy_state = PHY_DEVICE_DISCOVERED; | ||
697 | return 0; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | return -ENODEV; | ||
702 | } | ||
703 | |||
680 | static struct domain_device *sas_ex_discover_expander( | 704 | static struct domain_device *sas_ex_discover_expander( |
681 | struct domain_device *parent, int phy_id) | 705 | struct domain_device *parent, int phy_id) |
682 | { | 706 | { |
@@ -809,6 +833,13 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
809 | return res; | 833 | return res; |
810 | } | 834 | } |
811 | 835 | ||
836 | res = sas_ex_join_wide_port(dev, phy_id); | ||
837 | if (!res) { | ||
838 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", | ||
839 | phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); | ||
840 | return res; | ||
841 | } | ||
842 | |||
812 | switch (ex_phy->attached_dev_type) { | 843 | switch (ex_phy->attached_dev_type) { |
813 | case SAS_END_DEV: | 844 | case SAS_END_DEV: |
814 | child = sas_ex_discover_end_dev(dev, phy_id); | 845 | child = sas_ex_discover_end_dev(dev, phy_id); |
@@ -1431,14 +1462,23 @@ int sas_discover_root_expander(struct domain_device *dev) | |||
1431 | int res; | 1462 | int res; |
1432 | struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); | 1463 | struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); |
1433 | 1464 | ||
1434 | sas_rphy_add(dev->rphy); | 1465 | res = sas_rphy_add(dev->rphy); |
1466 | if (res) | ||
1467 | goto out_err; | ||
1435 | 1468 | ||
1436 | ex->level = dev->port->disc.max_level; /* 0 */ | 1469 | ex->level = dev->port->disc.max_level; /* 0 */ |
1437 | res = sas_discover_expander(dev); | 1470 | res = sas_discover_expander(dev); |
1438 | if (!res) | 1471 | if (res) |
1439 | sas_ex_bfs_disc(dev->port); | 1472 | goto out_err2; |
1473 | |||
1474 | sas_ex_bfs_disc(dev->port); | ||
1440 | 1475 | ||
1441 | return res; | 1476 | return res; |
1477 | |||
1478 | out_err2: | ||
1479 | sas_rphy_remove(dev->rphy); | ||
1480 | out_err: | ||
1481 | return res; | ||
1442 | } | 1482 | } |
1443 | 1483 | ||
1444 | /* ---------- Domain revalidation ---------- */ | 1484 | /* ---------- Domain revalidation ---------- */ |
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 2f0c07fc3f48..965698c8b7bf 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -87,6 +87,9 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) | |||
87 | else if (sas_ha->lldd_queue_size == -1) | 87 | else if (sas_ha->lldd_queue_size == -1) |
88 | sas_ha->lldd_queue_size = 128; /* Sanity */ | 88 | sas_ha->lldd_queue_size = 128; /* Sanity */ |
89 | 89 | ||
90 | sas_ha->state = SAS_HA_REGISTERED; | ||
91 | spin_lock_init(&sas_ha->state_lock); | ||
92 | |||
90 | error = sas_register_phys(sas_ha); | 93 | error = sas_register_phys(sas_ha); |
91 | if (error) { | 94 | if (error) { |
92 | printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); | 95 | printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); |
@@ -127,12 +130,22 @@ Undo_phys: | |||
127 | 130 | ||
128 | int sas_unregister_ha(struct sas_ha_struct *sas_ha) | 131 | int sas_unregister_ha(struct sas_ha_struct *sas_ha) |
129 | { | 132 | { |
133 | unsigned long flags; | ||
134 | |||
135 | /* Set the state to unregistered to avoid further | ||
136 | * events to be queued */ | ||
137 | spin_lock_irqsave(&sas_ha->state_lock, flags); | ||
138 | sas_ha->state = SAS_HA_UNREGISTERED; | ||
139 | spin_unlock_irqrestore(&sas_ha->state_lock, flags); | ||
140 | scsi_flush_work(sas_ha->core.shost); | ||
141 | |||
142 | sas_unregister_ports(sas_ha); | ||
143 | |||
130 | if (sas_ha->lldd_max_execute_num > 1) { | 144 | if (sas_ha->lldd_max_execute_num > 1) { |
131 | sas_shutdown_queue(sas_ha); | 145 | sas_shutdown_queue(sas_ha); |
146 | sas_ha->lldd_max_execute_num = 1; | ||
132 | } | 147 | } |
133 | 148 | ||
134 | sas_unregister_ports(sas_ha); | ||
135 | |||
136 | return 0; | 149 | return 0; |
137 | } | 150 | } |
138 | 151 | ||
@@ -146,6 +159,36 @@ static int sas_get_linkerrors(struct sas_phy *phy) | |||
146 | return sas_smp_get_phy_events(phy); | 159 | return sas_smp_get_phy_events(phy); |
147 | } | 160 | } |
148 | 161 | ||
162 | int sas_phy_enable(struct sas_phy *phy, int enable) | ||
163 | { | ||
164 | int ret; | ||
165 | enum phy_func command; | ||
166 | |||
167 | if (enable) | ||
168 | command = PHY_FUNC_LINK_RESET; | ||
169 | else | ||
170 | command = PHY_FUNC_DISABLE; | ||
171 | |||
172 | if (scsi_is_sas_phy_local(phy)) { | ||
173 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
174 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | ||
175 | struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; | ||
176 | struct sas_internal *i = | ||
177 | to_sas_internal(sas_ha->core.shost->transportt); | ||
178 | |||
179 | if (!enable) { | ||
180 | sas_phy_disconnected(asd_phy); | ||
181 | sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL); | ||
182 | } | ||
183 | ret = i->dft->lldd_control_phy(asd_phy, command, NULL); | ||
184 | } else { | ||
185 | struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); | ||
186 | struct domain_device *ddev = sas_find_dev_by_rphy(rphy); | ||
187 | ret = sas_smp_phy_control(ddev, phy->number, command, NULL); | ||
188 | } | ||
189 | return ret; | ||
190 | } | ||
191 | |||
149 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) | 192 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) |
150 | { | 193 | { |
151 | int ret; | 194 | int ret; |
@@ -172,8 +215,8 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset) | |||
172 | return ret; | 215 | return ret; |
173 | } | 216 | } |
174 | 217 | ||
175 | static int sas_set_phy_speed(struct sas_phy *phy, | 218 | int sas_set_phy_speed(struct sas_phy *phy, |
176 | struct sas_phy_linkrates *rates) | 219 | struct sas_phy_linkrates *rates) |
177 | { | 220 | { |
178 | int ret; | 221 | int ret; |
179 | 222 | ||
@@ -212,6 +255,7 @@ static int sas_set_phy_speed(struct sas_phy *phy, | |||
212 | } | 255 | } |
213 | 256 | ||
214 | static struct sas_function_template sft = { | 257 | static struct sas_function_template sft = { |
258 | .phy_enable = sas_phy_enable, | ||
215 | .phy_reset = sas_phy_reset, | 259 | .phy_reset = sas_phy_reset, |
216 | .set_phy_speed = sas_set_phy_speed, | 260 | .set_phy_speed = sas_set_phy_speed, |
217 | .get_linkerrors = sas_get_linkerrors, | 261 | .get_linkerrors = sas_get_linkerrors, |
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 137d7e496b6d..a78638df2018 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h | |||
@@ -80,7 +80,7 @@ void sas_hae_reset(struct work_struct *work); | |||
80 | static inline void sas_queue_event(int event, spinlock_t *lock, | 80 | static inline void sas_queue_event(int event, spinlock_t *lock, |
81 | unsigned long *pending, | 81 | unsigned long *pending, |
82 | struct work_struct *work, | 82 | struct work_struct *work, |
83 | struct Scsi_Host *shost) | 83 | struct sas_ha_struct *sas_ha) |
84 | { | 84 | { |
85 | unsigned long flags; | 85 | unsigned long flags; |
86 | 86 | ||
@@ -91,7 +91,12 @@ static inline void sas_queue_event(int event, spinlock_t *lock, | |||
91 | } | 91 | } |
92 | __set_bit(event, pending); | 92 | __set_bit(event, pending); |
93 | spin_unlock_irqrestore(lock, flags); | 93 | spin_unlock_irqrestore(lock, flags); |
94 | scsi_queue_work(shost, work); | 94 | |
95 | spin_lock_irqsave(&sas_ha->state_lock, flags); | ||
96 | if (sas_ha->state != SAS_HA_UNREGISTERED) { | ||
97 | scsi_queue_work(sas_ha->core.shost, work); | ||
98 | } | ||
99 | spin_unlock_irqrestore(&sas_ha->state_lock, flags); | ||
95 | } | 100 | } |
96 | 101 | ||
97 | static inline void sas_begin_event(int event, spinlock_t *lock, | 102 | static inline void sas_begin_event(int event, spinlock_t *lock, |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 971c37ceecb4..e1e2d085c920 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -42,10 +42,11 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
42 | struct asd_sas_port *port = phy->port; | 42 | struct asd_sas_port *port = phy->port; |
43 | struct sas_internal *si = | 43 | struct sas_internal *si = |
44 | to_sas_internal(sas_ha->core.shost->transportt); | 44 | to_sas_internal(sas_ha->core.shost->transportt); |
45 | unsigned long flags; | ||
45 | 46 | ||
46 | if (port) { | 47 | if (port) { |
47 | if (memcmp(port->attached_sas_addr, phy->attached_sas_addr, | 48 | if (memcmp(port->attached_sas_addr, phy->attached_sas_addr, |
48 | SAS_ADDR_SIZE) == 0) | 49 | SAS_ADDR_SIZE) != 0) |
49 | sas_deform_port(phy); | 50 | sas_deform_port(phy); |
50 | else { | 51 | else { |
51 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", | 52 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", |
@@ -56,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | /* find a port */ | 59 | /* find a port */ |
59 | spin_lock(&sas_ha->phy_port_lock); | 60 | spin_lock_irqsave(&sas_ha->phy_port_lock, flags); |
60 | for (i = 0; i < sas_ha->num_phys; i++) { | 61 | for (i = 0; i < sas_ha->num_phys; i++) { |
61 | port = sas_ha->sas_port[i]; | 62 | port = sas_ha->sas_port[i]; |
62 | spin_lock(&port->phy_list_lock); | 63 | spin_lock(&port->phy_list_lock); |
@@ -78,7 +79,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
78 | if (i >= sas_ha->num_phys) { | 79 | if (i >= sas_ha->num_phys) { |
79 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", | 80 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", |
80 | __FUNCTION__); | 81 | __FUNCTION__); |
81 | spin_unlock(&sas_ha->phy_port_lock); | 82 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); |
82 | return; | 83 | return; |
83 | } | 84 | } |
84 | 85 | ||
@@ -105,7 +106,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
105 | } else | 106 | } else |
106 | port->linkrate = max(port->linkrate, phy->linkrate); | 107 | port->linkrate = max(port->linkrate, phy->linkrate); |
107 | spin_unlock(&port->phy_list_lock); | 108 | spin_unlock(&port->phy_list_lock); |
108 | spin_unlock(&sas_ha->phy_port_lock); | 109 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); |
109 | 110 | ||
110 | if (!port->port) { | 111 | if (!port->port) { |
111 | port->port = sas_port_alloc(phy->phy->dev.parent, port->id); | 112 | port->port = sas_port_alloc(phy->phy->dev.parent, port->id); |
@@ -137,6 +138,7 @@ void sas_deform_port(struct asd_sas_phy *phy) | |||
137 | struct asd_sas_port *port = phy->port; | 138 | struct asd_sas_port *port = phy->port; |
138 | struct sas_internal *si = | 139 | struct sas_internal *si = |
139 | to_sas_internal(sas_ha->core.shost->transportt); | 140 | to_sas_internal(sas_ha->core.shost->transportt); |
141 | unsigned long flags; | ||
140 | 142 | ||
141 | if (!port) | 143 | if (!port) |
142 | return; /* done by a phy event */ | 144 | return; /* done by a phy event */ |
@@ -155,7 +157,7 @@ void sas_deform_port(struct asd_sas_phy *phy) | |||
155 | if (si->dft->lldd_port_deformed) | 157 | if (si->dft->lldd_port_deformed) |
156 | si->dft->lldd_port_deformed(phy); | 158 | si->dft->lldd_port_deformed(phy); |
157 | 159 | ||
158 | spin_lock(&sas_ha->phy_port_lock); | 160 | spin_lock_irqsave(&sas_ha->phy_port_lock, flags); |
159 | spin_lock(&port->phy_list_lock); | 161 | spin_lock(&port->phy_list_lock); |
160 | 162 | ||
161 | list_del_init(&phy->port_phy_el); | 163 | list_del_init(&phy->port_phy_el); |
@@ -174,7 +176,7 @@ void sas_deform_port(struct asd_sas_phy *phy) | |||
174 | port->phy_mask = 0; | 176 | port->phy_mask = 0; |
175 | } | 177 | } |
176 | spin_unlock(&port->phy_list_lock); | 178 | spin_unlock(&port->phy_list_lock); |
177 | spin_unlock(&sas_ha->phy_port_lock); | 179 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); |
178 | 180 | ||
179 | return; | 181 | return; |
180 | } | 182 | } |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 22672d54aa27..897a5e2c55e4 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <scsi/scsi_transport_sas.h> | 34 | #include <scsi/scsi_transport_sas.h> |
35 | #include "../scsi_sas_internal.h" | 35 | #include "../scsi_sas_internal.h" |
36 | #include "../scsi_transport_api.h" | 36 | #include "../scsi_transport_api.h" |
37 | #include "../scsi_priv.h" | ||
37 | 38 | ||
38 | #include <linux/err.h> | 39 | #include <linux/err.h> |
39 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
@@ -130,7 +131,7 @@ static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd) | |||
130 | if (cmd->request && blk_rq_tagged(cmd->request)) { | 131 | if (cmd->request && blk_rq_tagged(cmd->request)) { |
131 | if (cmd->device->ordered_tags && | 132 | if (cmd->device->ordered_tags && |
132 | (cmd->request->cmd_flags & REQ_HARDBARRIER)) | 133 | (cmd->request->cmd_flags & REQ_HARDBARRIER)) |
133 | ta = TASK_ATTR_HOQ; | 134 | ta = TASK_ATTR_ORDERED; |
134 | } | 135 | } |
135 | return ta; | 136 | return ta; |
136 | } | 137 | } |
@@ -281,6 +282,7 @@ enum task_disposition { | |||
281 | TASK_IS_ABORTED, | 282 | TASK_IS_ABORTED, |
282 | TASK_IS_AT_LU, | 283 | TASK_IS_AT_LU, |
283 | TASK_IS_NOT_AT_LU, | 284 | TASK_IS_NOT_AT_LU, |
285 | TASK_ABORT_FAILED, | ||
284 | }; | 286 | }; |
285 | 287 | ||
286 | static enum task_disposition sas_scsi_find_task(struct sas_task *task) | 288 | static enum task_disposition sas_scsi_find_task(struct sas_task *task) |
@@ -310,15 +312,6 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
310 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 312 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
311 | } | 313 | } |
312 | 314 | ||
313 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
314 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | ||
315 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
316 | SAS_DPRINTK("%s: task 0x%p already aborted\n", | ||
317 | __FUNCTION__, task); | ||
318 | return TASK_IS_ABORTED; | ||
319 | } | ||
320 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
321 | |||
322 | for (i = 0; i < 5; i++) { | 315 | for (i = 0; i < 5; i++) { |
323 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); | 316 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); |
324 | res = si->dft->lldd_abort_task(task); | 317 | res = si->dft->lldd_abort_task(task); |
@@ -340,15 +333,21 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
340 | SAS_DPRINTK("%s: querying task 0x%p\n", | 333 | SAS_DPRINTK("%s: querying task 0x%p\n", |
341 | __FUNCTION__, task); | 334 | __FUNCTION__, task); |
342 | res = si->dft->lldd_query_task(task); | 335 | res = si->dft->lldd_query_task(task); |
343 | if (res == TMF_RESP_FUNC_SUCC) { | 336 | switch (res) { |
337 | case TMF_RESP_FUNC_SUCC: | ||
344 | SAS_DPRINTK("%s: task 0x%p at LU\n", | 338 | SAS_DPRINTK("%s: task 0x%p at LU\n", |
345 | __FUNCTION__, task); | 339 | __FUNCTION__, task); |
346 | return TASK_IS_AT_LU; | 340 | return TASK_IS_AT_LU; |
347 | } else if (res == TMF_RESP_FUNC_COMPLETE) { | 341 | case TMF_RESP_FUNC_COMPLETE: |
348 | SAS_DPRINTK("%s: task 0x%p not at LU\n", | 342 | SAS_DPRINTK("%s: task 0x%p not at LU\n", |
349 | __FUNCTION__, task); | 343 | __FUNCTION__, task); |
350 | return TASK_IS_NOT_AT_LU; | 344 | return TASK_IS_NOT_AT_LU; |
351 | } | 345 | case TMF_RESP_FUNC_FAILED: |
346 | SAS_DPRINTK("%s: task 0x%p failed to abort\n", | ||
347 | __FUNCTION__, task); | ||
348 | return TASK_ABORT_FAILED; | ||
349 | } | ||
350 | |||
352 | } | 351 | } |
353 | } | 352 | } |
354 | return res; | 353 | return res; |
@@ -398,35 +397,113 @@ static int sas_recover_I_T(struct domain_device *dev) | |||
398 | return res; | 397 | return res; |
399 | } | 398 | } |
400 | 399 | ||
401 | void sas_scsi_recover_host(struct Scsi_Host *shost) | 400 | /* Find the sas_phy that's attached to this device */ |
401 | struct sas_phy *find_local_sas_phy(struct domain_device *dev) | ||
402 | { | ||
403 | struct domain_device *pdev = dev->parent; | ||
404 | struct ex_phy *exphy = NULL; | ||
405 | int i; | ||
406 | |||
407 | /* Directly attached device */ | ||
408 | if (!pdev) | ||
409 | return dev->port->phy; | ||
410 | |||
411 | /* Otherwise look in the expander */ | ||
412 | for (i = 0; i < pdev->ex_dev.num_phys; i++) | ||
413 | if (!memcmp(dev->sas_addr, | ||
414 | pdev->ex_dev.ex_phy[i].attached_sas_addr, | ||
415 | SAS_ADDR_SIZE)) { | ||
416 | exphy = &pdev->ex_dev.ex_phy[i]; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | BUG_ON(!exphy); | ||
421 | return exphy->phy; | ||
422 | } | ||
423 | |||
424 | /* Attempt to send a LUN reset message to a device */ | ||
425 | int sas_eh_device_reset_handler(struct scsi_cmnd *cmd) | ||
426 | { | ||
427 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
428 | struct sas_internal *i = | ||
429 | to_sas_internal(dev->port->ha->core.shost->transportt); | ||
430 | struct scsi_lun lun; | ||
431 | int res; | ||
432 | |||
433 | int_to_scsilun(cmd->device->lun, &lun); | ||
434 | |||
435 | if (!i->dft->lldd_lu_reset) | ||
436 | return FAILED; | ||
437 | |||
438 | res = i->dft->lldd_lu_reset(dev, lun.scsi_lun); | ||
439 | if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE) | ||
440 | return SUCCESS; | ||
441 | |||
442 | return FAILED; | ||
443 | } | ||
444 | |||
445 | /* Attempt to send a phy (bus) reset */ | ||
446 | int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd) | ||
447 | { | ||
448 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
449 | struct sas_phy *phy = find_local_sas_phy(dev); | ||
450 | int res; | ||
451 | |||
452 | res = sas_phy_reset(phy, 1); | ||
453 | if (res) | ||
454 | SAS_DPRINTK("Bus reset of %s failed 0x%x\n", | ||
455 | phy->dev.kobj.k_name, | ||
456 | res); | ||
457 | if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE) | ||
458 | return SUCCESS; | ||
459 | |||
460 | return FAILED; | ||
461 | } | ||
462 | |||
463 | /* Try to reset a device */ | ||
464 | static int try_to_reset_cmd_device(struct Scsi_Host *shost, | ||
465 | struct scsi_cmnd *cmd) | ||
466 | { | ||
467 | int res; | ||
468 | |||
469 | if (!shost->hostt->eh_device_reset_handler) | ||
470 | goto try_bus_reset; | ||
471 | |||
472 | res = shost->hostt->eh_device_reset_handler(cmd); | ||
473 | if (res == SUCCESS) | ||
474 | return res; | ||
475 | |||
476 | try_bus_reset: | ||
477 | if (shost->hostt->eh_bus_reset_handler) | ||
478 | return shost->hostt->eh_bus_reset_handler(cmd); | ||
479 | |||
480 | return FAILED; | ||
481 | } | ||
482 | |||
483 | static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, | ||
484 | struct list_head *work_q, | ||
485 | struct list_head *done_q) | ||
402 | { | 486 | { |
403 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | ||
404 | unsigned long flags; | ||
405 | LIST_HEAD(error_q); | ||
406 | struct scsi_cmnd *cmd, *n; | 487 | struct scsi_cmnd *cmd, *n; |
407 | enum task_disposition res = TASK_IS_DONE; | 488 | enum task_disposition res = TASK_IS_DONE; |
408 | int tmf_resp; | 489 | int tmf_resp, need_reset; |
409 | struct sas_internal *i = to_sas_internal(shost->transportt); | 490 | struct sas_internal *i = to_sas_internal(shost->transportt); |
491 | unsigned long flags; | ||
492 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | ||
410 | 493 | ||
411 | spin_lock_irqsave(shost->host_lock, flags); | ||
412 | list_splice_init(&shost->eh_cmd_q, &error_q); | ||
413 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
414 | |||
415 | SAS_DPRINTK("Enter %s\n", __FUNCTION__); | ||
416 | |||
417 | /* All tasks on this list were marked SAS_TASK_STATE_ABORTED | ||
418 | * by sas_scsi_timed_out() callback. | ||
419 | */ | ||
420 | Again: | 494 | Again: |
421 | SAS_DPRINTK("going over list...\n"); | 495 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { |
422 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { | ||
423 | struct sas_task *task = TO_SAS_TASK(cmd); | 496 | struct sas_task *task = TO_SAS_TASK(cmd); |
424 | list_del_init(&cmd->eh_entry); | ||
425 | 497 | ||
426 | if (!task) { | 498 | if (!task) |
427 | SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__); | ||
428 | continue; | 499 | continue; |
429 | } | 500 | |
501 | list_del_init(&cmd->eh_entry); | ||
502 | |||
503 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
504 | need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET; | ||
505 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
506 | |||
430 | SAS_DPRINTK("trying to find task 0x%p\n", task); | 507 | SAS_DPRINTK("trying to find task 0x%p\n", task); |
431 | res = sas_scsi_find_task(task); | 508 | res = sas_scsi_find_task(task); |
432 | 509 | ||
@@ -437,11 +514,15 @@ Again: | |||
437 | SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, | 514 | SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, |
438 | task); | 515 | task); |
439 | task->task_done(task); | 516 | task->task_done(task); |
517 | if (need_reset) | ||
518 | try_to_reset_cmd_device(shost, cmd); | ||
440 | continue; | 519 | continue; |
441 | case TASK_IS_ABORTED: | 520 | case TASK_IS_ABORTED: |
442 | SAS_DPRINTK("%s: task 0x%p is aborted\n", | 521 | SAS_DPRINTK("%s: task 0x%p is aborted\n", |
443 | __FUNCTION__, task); | 522 | __FUNCTION__, task); |
444 | task->task_done(task); | 523 | task->task_done(task); |
524 | if (need_reset) | ||
525 | try_to_reset_cmd_device(shost, cmd); | ||
445 | continue; | 526 | continue; |
446 | case TASK_IS_AT_LU: | 527 | case TASK_IS_AT_LU: |
447 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); | 528 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); |
@@ -452,11 +533,14 @@ Again: | |||
452 | SAS_ADDR(task->dev), | 533 | SAS_ADDR(task->dev), |
453 | cmd->device->lun); | 534 | cmd->device->lun); |
454 | task->task_done(task); | 535 | task->task_done(task); |
455 | sas_scsi_clear_queue_lu(&error_q, cmd); | 536 | if (need_reset) |
537 | try_to_reset_cmd_device(shost, cmd); | ||
538 | sas_scsi_clear_queue_lu(work_q, cmd); | ||
456 | goto Again; | 539 | goto Again; |
457 | } | 540 | } |
458 | /* fallthrough */ | 541 | /* fallthrough */ |
459 | case TASK_IS_NOT_AT_LU: | 542 | case TASK_IS_NOT_AT_LU: |
543 | case TASK_ABORT_FAILED: | ||
460 | SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n", | 544 | SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n", |
461 | task); | 545 | task); |
462 | tmf_resp = sas_recover_I_T(task->dev); | 546 | tmf_resp = sas_recover_I_T(task->dev); |
@@ -464,7 +548,9 @@ Again: | |||
464 | SAS_DPRINTK("I_T %016llx recovered\n", | 548 | SAS_DPRINTK("I_T %016llx recovered\n", |
465 | SAS_ADDR(task->dev->sas_addr)); | 549 | SAS_ADDR(task->dev->sas_addr)); |
466 | task->task_done(task); | 550 | task->task_done(task); |
467 | sas_scsi_clear_queue_I_T(&error_q, task->dev); | 551 | if (need_reset) |
552 | try_to_reset_cmd_device(shost, cmd); | ||
553 | sas_scsi_clear_queue_I_T(work_q, task->dev); | ||
468 | goto Again; | 554 | goto Again; |
469 | } | 555 | } |
470 | /* Hammer time :-) */ | 556 | /* Hammer time :-) */ |
@@ -477,7 +563,9 @@ Again: | |||
477 | SAS_DPRINTK("clear nexus port:%d " | 563 | SAS_DPRINTK("clear nexus port:%d " |
478 | "succeeded\n", port->id); | 564 | "succeeded\n", port->id); |
479 | task->task_done(task); | 565 | task->task_done(task); |
480 | sas_scsi_clear_queue_port(&error_q, | 566 | if (need_reset) |
567 | try_to_reset_cmd_device(shost, cmd); | ||
568 | sas_scsi_clear_queue_port(work_q, | ||
481 | port); | 569 | port); |
482 | goto Again; | 570 | goto Again; |
483 | } | 571 | } |
@@ -489,6 +577,8 @@ Again: | |||
489 | SAS_DPRINTK("clear nexus ha " | 577 | SAS_DPRINTK("clear nexus ha " |
490 | "succeeded\n"); | 578 | "succeeded\n"); |
491 | task->task_done(task); | 579 | task->task_done(task); |
580 | if (need_reset) | ||
581 | try_to_reset_cmd_device(shost, cmd); | ||
492 | goto out; | 582 | goto out; |
493 | } | 583 | } |
494 | } | 584 | } |
@@ -502,20 +592,54 @@ Again: | |||
502 | cmd->device->lun); | 592 | cmd->device->lun); |
503 | 593 | ||
504 | task->task_done(task); | 594 | task->task_done(task); |
595 | if (need_reset) | ||
596 | try_to_reset_cmd_device(shost, cmd); | ||
505 | goto clear_q; | 597 | goto clear_q; |
506 | } | 598 | } |
507 | } | 599 | } |
508 | out: | 600 | out: |
509 | scsi_eh_flush_done_q(&ha->eh_done_q); | 601 | return list_empty(work_q); |
510 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); | ||
511 | return; | ||
512 | clear_q: | 602 | clear_q: |
513 | SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); | 603 | SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); |
514 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { | 604 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { |
515 | struct sas_task *task = TO_SAS_TASK(cmd); | 605 | struct sas_task *task = TO_SAS_TASK(cmd); |
516 | list_del_init(&cmd->eh_entry); | 606 | list_del_init(&cmd->eh_entry); |
517 | task->task_done(task); | 607 | task->task_done(task); |
518 | } | 608 | } |
609 | return list_empty(work_q); | ||
610 | } | ||
611 | |||
612 | void sas_scsi_recover_host(struct Scsi_Host *shost) | ||
613 | { | ||
614 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | ||
615 | unsigned long flags; | ||
616 | LIST_HEAD(eh_work_q); | ||
617 | |||
618 | spin_lock_irqsave(shost->host_lock, flags); | ||
619 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); | ||
620 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
621 | |||
622 | SAS_DPRINTK("Enter %s\n", __FUNCTION__); | ||
623 | /* | ||
624 | * Deal with commands that still have SAS tasks (i.e. they didn't | ||
625 | * complete via the normal sas_task completion mechanism) | ||
626 | */ | ||
627 | if (sas_eh_handle_sas_errors(shost, &eh_work_q, &ha->eh_done_q)) | ||
628 | goto out; | ||
629 | |||
630 | /* | ||
631 | * Now deal with SCSI commands that completed ok but have a an error | ||
632 | * code (and hopefully sense data) attached. This is roughly what | ||
633 | * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any | ||
634 | * command we see here has no sas_task and is thus unknown to the HA. | ||
635 | */ | ||
636 | if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q)) | ||
637 | scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); | ||
638 | |||
639 | out: | ||
640 | scsi_eh_flush_done_q(&ha->eh_done_q); | ||
641 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); | ||
642 | return; | ||
519 | } | 643 | } |
520 | 644 | ||
521 | enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | 645 | enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) |
@@ -524,24 +648,30 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | |||
524 | unsigned long flags; | 648 | unsigned long flags; |
525 | 649 | ||
526 | if (!task) { | 650 | if (!task) { |
527 | SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", | 651 | cmd->timeout_per_command /= 2; |
528 | cmd, task); | 652 | SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n", |
529 | return EH_HANDLED; | 653 | cmd, task, (cmd->timeout_per_command ? |
654 | "EH_RESET_TIMER" : "EH_NOT_HANDLED")); | ||
655 | if (!cmd->timeout_per_command) | ||
656 | return EH_NOT_HANDLED; | ||
657 | return EH_RESET_TIMER; | ||
530 | } | 658 | } |
531 | 659 | ||
532 | spin_lock_irqsave(&task->task_state_lock, flags); | 660 | spin_lock_irqsave(&task->task_state_lock, flags); |
533 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | 661 | BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED); |
534 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
535 | SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: " | ||
536 | "EH_NOT_HANDLED\n", cmd, task); | ||
537 | return EH_NOT_HANDLED; | ||
538 | } | ||
539 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 662 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
540 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 663 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
541 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", | 664 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", |
542 | cmd, task); | 665 | cmd, task); |
543 | return EH_HANDLED; | 666 | return EH_HANDLED; |
544 | } | 667 | } |
668 | if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) { | ||
669 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
670 | SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: " | ||
671 | "EH_RESET_TIMER\n", | ||
672 | cmd, task); | ||
673 | return EH_RESET_TIMER; | ||
674 | } | ||
545 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | 675 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; |
546 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 676 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
547 | 677 | ||
@@ -557,8 +687,9 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) | |||
557 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | 687 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); |
558 | struct domain_device *found_dev = NULL; | 688 | struct domain_device *found_dev = NULL; |
559 | int i; | 689 | int i; |
690 | unsigned long flags; | ||
560 | 691 | ||
561 | spin_lock(&ha->phy_port_lock); | 692 | spin_lock_irqsave(&ha->phy_port_lock, flags); |
562 | for (i = 0; i < ha->num_phys; i++) { | 693 | for (i = 0; i < ha->num_phys; i++) { |
563 | struct asd_sas_port *port = ha->sas_port[i]; | 694 | struct asd_sas_port *port = ha->sas_port[i]; |
564 | struct domain_device *dev; | 695 | struct domain_device *dev; |
@@ -574,7 +705,7 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) | |||
574 | spin_unlock(&port->dev_list_lock); | 705 | spin_unlock(&port->dev_list_lock); |
575 | } | 706 | } |
576 | found: | 707 | found: |
577 | spin_unlock(&ha->phy_port_lock); | 708 | spin_unlock_irqrestore(&ha->phy_port_lock, flags); |
578 | 709 | ||
579 | return found_dev; | 710 | return found_dev; |
580 | } | 711 | } |
@@ -623,6 +754,8 @@ int sas_slave_configure(struct scsi_device *scsi_dev) | |||
623 | scsi_deactivate_tcq(scsi_dev, 1); | 754 | scsi_deactivate_tcq(scsi_dev, 1); |
624 | } | 755 | } |
625 | 756 | ||
757 | scsi_dev->allow_restart = 1; | ||
758 | |||
626 | return 0; | 759 | return 0; |
627 | } | 760 | } |
628 | 761 | ||
@@ -799,46 +932,42 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha) | |||
799 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 932 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
800 | } | 933 | } |
801 | 934 | ||
802 | static int do_sas_task_abort(struct sas_task *task) | 935 | /* |
936 | * Call the LLDD task abort routine directly. This function is intended for | ||
937 | * use by upper layers that need to tell the LLDD to abort a task. | ||
938 | */ | ||
939 | int __sas_task_abort(struct sas_task *task) | ||
803 | { | 940 | { |
804 | struct scsi_cmnd *sc = task->uldd_task; | ||
805 | struct sas_internal *si = | 941 | struct sas_internal *si = |
806 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | 942 | to_sas_internal(task->dev->port->ha->core.shost->transportt); |
807 | unsigned long flags; | 943 | unsigned long flags; |
808 | int res; | 944 | int res; |
809 | 945 | ||
810 | spin_lock_irqsave(&task->task_state_lock, flags); | 946 | spin_lock_irqsave(&task->task_state_lock, flags); |
811 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | 947 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED || |
948 | task->task_state_flags & SAS_TASK_STATE_DONE) { | ||
812 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 949 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
813 | SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__, | 950 | SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__, |
814 | task); | 951 | task); |
815 | return 0; | 952 | return 0; |
816 | } | 953 | } |
817 | 954 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | |
818 | task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED; | ||
819 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
820 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
821 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 955 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
822 | 956 | ||
823 | if (!si->dft->lldd_abort_task) | 957 | if (!si->dft->lldd_abort_task) |
824 | return -ENODEV; | 958 | return -ENODEV; |
825 | 959 | ||
826 | res = si->dft->lldd_abort_task(task); | 960 | res = si->dft->lldd_abort_task(task); |
961 | |||
962 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
827 | if ((task->task_state_flags & SAS_TASK_STATE_DONE) || | 963 | if ((task->task_state_flags & SAS_TASK_STATE_DONE) || |
828 | (res == TMF_RESP_FUNC_COMPLETE)) | 964 | (res == TMF_RESP_FUNC_COMPLETE)) |
829 | { | 965 | { |
830 | /* SMP commands don't have scsi_cmds(?) */ | 966 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
831 | if (!sc) { | 967 | task->task_done(task); |
832 | task->task_done(task); | ||
833 | return 0; | ||
834 | } | ||
835 | scsi_req_abort_cmd(sc); | ||
836 | scsi_schedule_eh(sc->device->host); | ||
837 | return 0; | 968 | return 0; |
838 | } | 969 | } |
839 | 970 | ||
840 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
841 | task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED; | ||
842 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | 971 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) |
843 | task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; | 972 | task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; |
844 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 973 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
@@ -846,17 +975,24 @@ static int do_sas_task_abort(struct sas_task *task) | |||
846 | return -EAGAIN; | 975 | return -EAGAIN; |
847 | } | 976 | } |
848 | 977 | ||
849 | void sas_task_abort(struct work_struct *work) | 978 | /* |
979 | * Tell an upper layer that it needs to initiate an abort for a given task. | ||
980 | * This should only ever be called by an LLDD. | ||
981 | */ | ||
982 | void sas_task_abort(struct sas_task *task) | ||
850 | { | 983 | { |
851 | struct sas_task *task = | 984 | struct scsi_cmnd *sc = task->uldd_task; |
852 | container_of(work, struct sas_task, abort_work); | ||
853 | int i; | ||
854 | 985 | ||
855 | for (i = 0; i < 5; i++) | 986 | /* Escape for libsas internal commands */ |
856 | if (!do_sas_task_abort(task)) | 987 | if (!sc) { |
988 | if (!del_timer(&task->timer)) | ||
857 | return; | 989 | return; |
990 | task->timer.function(task->timer.data); | ||
991 | return; | ||
992 | } | ||
858 | 993 | ||
859 | SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__); | 994 | scsi_req_abort_cmd(sc); |
995 | scsi_schedule_eh(sc->device->host); | ||
860 | } | 996 | } |
861 | 997 | ||
862 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 998 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
@@ -866,5 +1002,9 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy); | |||
866 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); | 1002 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); |
867 | EXPORT_SYMBOL_GPL(sas_change_queue_type); | 1003 | EXPORT_SYMBOL_GPL(sas_change_queue_type); |
868 | EXPORT_SYMBOL_GPL(sas_bios_param); | 1004 | EXPORT_SYMBOL_GPL(sas_bios_param); |
1005 | EXPORT_SYMBOL_GPL(__sas_task_abort); | ||
869 | EXPORT_SYMBOL_GPL(sas_task_abort); | 1006 | EXPORT_SYMBOL_GPL(sas_task_abort); |
870 | EXPORT_SYMBOL_GPL(sas_phy_reset); | 1007 | EXPORT_SYMBOL_GPL(sas_phy_reset); |
1008 | EXPORT_SYMBOL_GPL(sas_phy_enable); | ||
1009 | EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); | ||
1010 | EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler); | ||
diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h index 3052869f51f4..170399ef06f4 100644 --- a/drivers/scsi/megaraid/mbox_defs.h +++ b/drivers/scsi/megaraid/mbox_defs.h | |||
@@ -748,7 +748,7 @@ typedef struct { | |||
748 | 748 | ||
749 | 749 | ||
750 | /** | 750 | /** |
751 | * private_bios_data - bios private data for boot devices | 751 | * struct private_bios_data - bios private data for boot devices |
752 | * @geometry : bits 0-3 - BIOS geometry, 0x0001 - 1GB, 0x0010 - 2GB, | 752 | * @geometry : bits 0-3 - BIOS geometry, 0x0001 - 1GB, 0x0010 - 2GB, |
753 | * 0x1000 - 8GB, Others values are invalid | 753 | * 0x1000 - 8GB, Others values are invalid |
754 | * @unused : bits 4-7 are unused | 754 | * @unused : bits 4-7 are unused |
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h index b50e27e66024..26e1e6c55654 100644 --- a/drivers/scsi/megaraid/mega_common.h +++ b/drivers/scsi/megaraid/mega_common.h | |||
@@ -46,17 +46,17 @@ | |||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * scb_t - scsi command control block | 48 | * scb_t - scsi command control block |
49 | * @param ccb : command control block for individual driver | 49 | * @ccb : command control block for individual driver |
50 | * @param list : list of control blocks | 50 | * @list : list of control blocks |
51 | * @param gp : general purpose field for LLDs | 51 | * @gp : general purpose field for LLDs |
52 | * @param sno : all SCBs have a serial number | 52 | * @sno : all SCBs have a serial number |
53 | * @param scp : associated scsi command | 53 | * @scp : associated scsi command |
54 | * @param state : current state of scb | 54 | * @state : current state of scb |
55 | * @param dma_dir : direction of data transfer | 55 | * @dma_dir : direction of data transfer |
56 | * @param dma_type : transfer with sg list, buffer, or no data transfer | 56 | * @dma_type : transfer with sg list, buffer, or no data transfer |
57 | * @param dev_channel : actual channel on the device | 57 | * @dev_channel : actual channel on the device |
58 | * @param dev_target : actual target on the device | 58 | * @dev_target : actual target on the device |
59 | * @param status : completion status | 59 | * @status : completion status |
60 | * | 60 | * |
61 | * This is our central data structure to issue commands the each driver. | 61 | * This is our central data structure to issue commands the each driver. |
62 | * Driver specific data structures are maintained in the ccb field. | 62 | * Driver specific data structures are maintained in the ccb field. |
@@ -99,42 +99,42 @@ typedef struct { | |||
99 | 99 | ||
100 | /** | 100 | /** |
101 | * struct adapter_t - driver's initialization structure | 101 | * struct adapter_t - driver's initialization structure |
102 | * @param dpc_h : tasklet handle | 102 | * @aram dpc_h : tasklet handle |
103 | * @param pdev : pci configuration pointer for kernel | 103 | * @pdev : pci configuration pointer for kernel |
104 | * @param host : pointer to host structure of mid-layer | 104 | * @host : pointer to host structure of mid-layer |
105 | * @param lock : synchronization lock for mid-layer and driver | 105 | * @lock : synchronization lock for mid-layer and driver |
106 | * @param quiescent : driver is quiescent for now. | 106 | * @quiescent : driver is quiescent for now. |
107 | * @param outstanding_cmds : number of commands pending in the driver | 107 | * @outstanding_cmds : number of commands pending in the driver |
108 | * @param kscb_list : pointer to the bulk of SCBs pointers for IO | 108 | * @kscb_list : pointer to the bulk of SCBs pointers for IO |
109 | * @param kscb_pool : pool of free scbs for IO | 109 | * @kscb_pool : pool of free scbs for IO |
110 | * @param kscb_pool_lock : lock for pool of free scbs | 110 | * @kscb_pool_lock : lock for pool of free scbs |
111 | * @param pend_list : pending commands list | 111 | * @pend_list : pending commands list |
112 | * @param pend_list_lock : exlusion lock for pending commands list | 112 | * @pend_list_lock : exclusion lock for pending commands list |
113 | * @param completed_list : list of completed commands | 113 | * @completed_list : list of completed commands |
114 | * @param completed_list_lock : exclusion lock for list of completed commands | 114 | * @completed_list_lock : exclusion lock for list of completed commands |
115 | * @param sglen : max sg elements supported | 115 | * @sglen : max sg elements supported |
116 | * @param device_ids : to convert kernel device addr to our devices. | 116 | * @device_ids : to convert kernel device addr to our devices. |
117 | * @param raid_device : raid adapter specific pointer | 117 | * @raid_device : raid adapter specific pointer |
118 | * @param max_channel : maximum channel number supported - inclusive | 118 | * @max_channel : maximum channel number supported - inclusive |
119 | * @param max_target : max target supported - inclusive | 119 | * @max_target : max target supported - inclusive |
120 | * @param max_lun : max lun supported - inclusive | 120 | * @max_lun : max lun supported - inclusive |
121 | * @param unique_id : unique identifier for each adapter | 121 | * @unique_id : unique identifier for each adapter |
122 | * @param irq : IRQ for this adapter | 122 | * @irq : IRQ for this adapter |
123 | * @param ito : internal timeout value, (-1) means no timeout | 123 | * @ito : internal timeout value, (-1) means no timeout |
124 | * @param ibuf : buffer to issue internal commands | 124 | * @ibuf : buffer to issue internal commands |
125 | * @param ibuf_dma_h : dma handle for the above buffer | 125 | * @ibuf_dma_h : dma handle for the above buffer |
126 | * @param uscb_list : SCB pointers for user cmds, common mgmt module | 126 | * @uscb_list : SCB pointers for user cmds, common mgmt module |
127 | * @param uscb_pool : pool of SCBs for user commands | 127 | * @uscb_pool : pool of SCBs for user commands |
128 | * @param uscb_pool_lock : exclusion lock for these SCBs | 128 | * @uscb_pool_lock : exclusion lock for these SCBs |
129 | * @param max_cmds : max outstanding commands | 129 | * @max_cmds : max outstanding commands |
130 | * @param fw_version : firmware version | 130 | * @fw_version : firmware version |
131 | * @param bios_version : bios version | 131 | * @bios_version : bios version |
132 | * @param max_cdb_sz : biggest CDB size supported. | 132 | * @max_cdb_sz : biggest CDB size supported. |
133 | * @param ha : is high availability present - clustering | 133 | * @ha : is high availability present - clustering |
134 | * @param init_id : initiator ID, the default value should be 7 | 134 | * @init_id : initiator ID, the default value should be 7 |
135 | * @param max_sectors : max sectors per request | 135 | * @max_sectors : max sectors per request |
136 | * @param cmd_per_lun : max outstanding commands per LUN | 136 | * @cmd_per_lun : max outstanding commands per LUN |
137 | * @param being_detached : set when unloading, no more mgmt calls | 137 | * @being_detached : set when unloading, no more mgmt calls |
138 | * | 138 | * |
139 | * | 139 | * |
140 | * mraid_setup_device_map() can be called anytime after the device map is | 140 | * mraid_setup_device_map() can be called anytime after the device map is |
@@ -211,23 +211,23 @@ typedef struct { | |||
211 | #define SCP2ADAPTER(scp) (adapter_t *)SCSIHOST2ADAP(SCP2HOST(scp)) | 211 | #define SCP2ADAPTER(scp) (adapter_t *)SCSIHOST2ADAP(SCP2HOST(scp)) |
212 | 212 | ||
213 | 213 | ||
214 | /** | ||
215 | * MRAID_GET_DEVICE_MAP - device ids | ||
216 | * @param adp - Adapter's soft state | ||
217 | * @param scp - mid-layer scsi command pointer | ||
218 | * @param p_chan - physical channel on the controller | ||
219 | * @param target - target id of the device or logical drive number | ||
220 | * @param islogical - set if the command is for the logical drive | ||
221 | * | ||
222 | * Macro to retrieve information about device class, logical or physical and | ||
223 | * the corresponding physical channel and target or logical drive number | ||
224 | **/ | ||
225 | #define MRAID_IS_LOGICAL(adp, scp) \ | 214 | #define MRAID_IS_LOGICAL(adp, scp) \ |
226 | (SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0 | 215 | (SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0 |
227 | 216 | ||
228 | #define MRAID_IS_LOGICAL_SDEV(adp, sdev) \ | 217 | #define MRAID_IS_LOGICAL_SDEV(adp, sdev) \ |
229 | (sdev->channel == (adp)->max_channel) ? 1 : 0 | 218 | (sdev->channel == (adp)->max_channel) ? 1 : 0 |
230 | 219 | ||
220 | /** | ||
221 | * MRAID_GET_DEVICE_MAP - device ids | ||
222 | * @adp : adapter's soft state | ||
223 | * @scp : mid-layer scsi command pointer | ||
224 | * @p_chan : physical channel on the controller | ||
225 | * @target : target id of the device or logical drive number | ||
226 | * @islogical : set if the command is for the logical drive | ||
227 | * | ||
228 | * Macro to retrieve information about device class, logical or physical and | ||
229 | * the corresponding physical channel and target or logical drive number | ||
230 | */ | ||
231 | #define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical) \ | 231 | #define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical) \ |
232 | /* \ | 232 | /* \ |
233 | * Is the request coming for the virtual channel \ | 233 | * Is the request coming for the virtual channel \ |
@@ -271,10 +271,10 @@ typedef struct { | |||
271 | #define ASSERT(expression) | 271 | #define ASSERT(expression) |
272 | #endif | 272 | #endif |
273 | 273 | ||
274 | /* | 274 | /** |
275 | * struct mraid_pci_blk - structure holds DMA memory block info | 275 | * struct mraid_pci_blk - structure holds DMA memory block info |
276 | * @param vaddr : virtual address to a memory block | 276 | * @vaddr : virtual address to a memory block |
277 | * @param dma_addr : DMA handle to a memory block | 277 | * @dma_addr : DMA handle to a memory block |
278 | * | 278 | * |
279 | * This structure is filled up for the caller. It is the responsibilty of the | 279 | * This structure is filled up for the caller. It is the responsibilty of the |
280 | * caller to allocate this array big enough to store addresses for all | 280 | * caller to allocate this array big enough to store addresses for all |
diff --git a/drivers/scsi/megaraid/megaraid_ioctl.h b/drivers/scsi/megaraid/megaraid_ioctl.h index b8aa34202ec3..706fa05a187a 100644 --- a/drivers/scsi/megaraid/megaraid_ioctl.h +++ b/drivers/scsi/megaraid/megaraid_ioctl.h | |||
@@ -22,23 +22,23 @@ | |||
22 | 22 | ||
23 | #include "mbox_defs.h" | 23 | #include "mbox_defs.h" |
24 | 24 | ||
25 | /* | ||
26 | * console messages debug levels | ||
27 | */ | ||
28 | #define CL_ANN 0 /* print unconditionally, announcements */ | ||
29 | #define CL_DLEVEL1 1 /* debug level 1, informative */ | ||
30 | #define CL_DLEVEL2 2 /* debug level 2, verbose */ | ||
31 | #define CL_DLEVEL3 3 /* debug level 3, very verbose */ | ||
32 | |||
25 | /** | 33 | /** |
26 | * con_log() - console log routine | 34 | * con_log() - console log routine |
27 | * @param level : indicates the severity of the message. | 35 | * @level : indicates the severity of the message. |
28 | * @fparam mt : format string | 36 | * @fmt : format string |
29 | * | 37 | * |
30 | * con_log displays the error messages on the console based on the current | 38 | * con_log displays the error messages on the console based on the current |
31 | * debug level. Also it attaches the appropriate kernel severity level with | 39 | * debug level. Also it attaches the appropriate kernel severity level with |
32 | * the message. | 40 | * the message. |
33 | * | ||
34 | * | ||
35 | * consolge messages debug levels | ||
36 | */ | 41 | */ |
37 | #define CL_ANN 0 /* print unconditionally, announcements */ | ||
38 | #define CL_DLEVEL1 1 /* debug level 1, informative */ | ||
39 | #define CL_DLEVEL2 2 /* debug level 2, verbose */ | ||
40 | #define CL_DLEVEL3 3 /* debug level 3, very verbose */ | ||
41 | |||
42 | #define con_log(level, fmt) if (LSI_DBGLVL >= level) printk fmt; | 42 | #define con_log(level, fmt) if (LSI_DBGLVL >= level) printk fmt; |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -157,14 +157,14 @@ typedef struct uioc { | |||
157 | /** | 157 | /** |
158 | * struct mraid_hba_info - information about the controller | 158 | * struct mraid_hba_info - information about the controller |
159 | * | 159 | * |
160 | * @param pci_vendor_id : PCI vendor id | 160 | * @pci_vendor_id : PCI vendor id |
161 | * @param pci_device_id : PCI device id | 161 | * @pci_device_id : PCI device id |
162 | * @param subsystem_vendor_id : PCI subsystem vendor id | 162 | * @subsystem_vendor_id : PCI subsystem vendor id |
163 | * @param subsystem_device_id : PCI subsystem device id | 163 | * @subsystem_device_id : PCI subsystem device id |
164 | * @param baseport : base port of hba memory | 164 | * @baseport : base port of hba memory |
165 | * @param pci_bus : PCI bus | 165 | * @pci_bus : PCI bus |
166 | * @param pci_dev_fn : PCI device/function values | 166 | * @pci_dev_fn : PCI device/function values |
167 | * @param irq : interrupt vector for the device | 167 | * @irq : interrupt vector for the device |
168 | * | 168 | * |
169 | * Extended information of 256 bytes about the controller. Align on the single | 169 | * Extended information of 256 bytes about the controller. Align on the single |
170 | * byte boundary so that 32-bit applications can be run on 64-bit platform | 170 | * byte boundary so that 32-bit applications can be run on 64-bit platform |
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 7bac86dda88f..04d0b6918c61 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c | |||
@@ -10,13 +10,13 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * FILE : megaraid_mbox.c | 12 | * FILE : megaraid_mbox.c |
13 | * Version : v2.20.4.9 (Jul 16 2006) | 13 | * Version : v2.20.5.1 (Nov 16 2006) |
14 | * | 14 | * |
15 | * Authors: | 15 | * Authors: |
16 | * Atul Mukker <Atul.Mukker@lsil.com> | 16 | * Atul Mukker <Atul.Mukker@lsi.com> |
17 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> | 17 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsi.com> |
18 | * Manoj Jose <Manoj.Jose@lsil.com> | 18 | * Manoj Jose <Manoj.Jose@lsi.com> |
19 | * Seokmann Ju <Seokmann.Ju@lsil.com> | 19 | * Seokmann Ju |
20 | * | 20 | * |
21 | * List of supported controllers | 21 | * List of supported controllers |
22 | * | 22 | * |
@@ -107,6 +107,7 @@ static int megaraid_mbox_support_random_del(adapter_t *); | |||
107 | static int megaraid_mbox_get_max_sg(adapter_t *); | 107 | static int megaraid_mbox_get_max_sg(adapter_t *); |
108 | static void megaraid_mbox_enum_raid_scsi(adapter_t *); | 108 | static void megaraid_mbox_enum_raid_scsi(adapter_t *); |
109 | static void megaraid_mbox_flush_cache(adapter_t *); | 109 | static void megaraid_mbox_flush_cache(adapter_t *); |
110 | static int megaraid_mbox_fire_sync_cmd(adapter_t *); | ||
110 | 111 | ||
111 | static void megaraid_mbox_display_scb(adapter_t *, scb_t *); | 112 | static void megaraid_mbox_display_scb(adapter_t *, scb_t *); |
112 | static void megaraid_mbox_setup_device_map(adapter_t *); | 113 | static void megaraid_mbox_setup_device_map(adapter_t *); |
@@ -137,7 +138,7 @@ static int wait_till_fw_empty(adapter_t *); | |||
137 | 138 | ||
138 | 139 | ||
139 | 140 | ||
140 | MODULE_AUTHOR("sju@lsil.com"); | 141 | MODULE_AUTHOR("megaraidlinux@lsi.com"); |
141 | MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver"); | 142 | MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver"); |
142 | MODULE_LICENSE("GPL"); | 143 | MODULE_LICENSE("GPL"); |
143 | MODULE_VERSION(MEGARAID_VERSION); | 144 | MODULE_VERSION(MEGARAID_VERSION); |
@@ -146,7 +147,7 @@ MODULE_VERSION(MEGARAID_VERSION); | |||
146 | * ### modules parameters for driver ### | 147 | * ### modules parameters for driver ### |
147 | */ | 148 | */ |
148 | 149 | ||
149 | /** | 150 | /* |
150 | * Set to enable driver to expose unconfigured disk to kernel | 151 | * Set to enable driver to expose unconfigured disk to kernel |
151 | */ | 152 | */ |
152 | static int megaraid_expose_unconf_disks = 0; | 153 | static int megaraid_expose_unconf_disks = 0; |
@@ -154,7 +155,7 @@ module_param_named(unconf_disks, megaraid_expose_unconf_disks, int, 0); | |||
154 | MODULE_PARM_DESC(unconf_disks, | 155 | MODULE_PARM_DESC(unconf_disks, |
155 | "Set to expose unconfigured disks to kernel (default=0)"); | 156 | "Set to expose unconfigured disks to kernel (default=0)"); |
156 | 157 | ||
157 | /** | 158 | /* |
158 | * driver wait time if the adapter's mailbox is busy | 159 | * driver wait time if the adapter's mailbox is busy |
159 | */ | 160 | */ |
160 | static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT; | 161 | static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT; |
@@ -162,7 +163,7 @@ module_param_named(busy_wait, max_mbox_busy_wait, int, 0); | |||
162 | MODULE_PARM_DESC(busy_wait, | 163 | MODULE_PARM_DESC(busy_wait, |
163 | "Max wait for mailbox in microseconds if busy (default=10)"); | 164 | "Max wait for mailbox in microseconds if busy (default=10)"); |
164 | 165 | ||
165 | /** | 166 | /* |
166 | * number of sectors per IO command | 167 | * number of sectors per IO command |
167 | */ | 168 | */ |
168 | static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS; | 169 | static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS; |
@@ -170,7 +171,7 @@ module_param_named(max_sectors, megaraid_max_sectors, int, 0); | |||
170 | MODULE_PARM_DESC(max_sectors, | 171 | MODULE_PARM_DESC(max_sectors, |
171 | "Maximum number of sectors per IO command (default=128)"); | 172 | "Maximum number of sectors per IO command (default=128)"); |
172 | 173 | ||
173 | /** | 174 | /* |
174 | * number of commands per logical unit | 175 | * number of commands per logical unit |
175 | */ | 176 | */ |
176 | static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN; | 177 | static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN; |
@@ -179,7 +180,7 @@ MODULE_PARM_DESC(cmd_per_lun, | |||
179 | "Maximum number of commands per logical unit (default=64)"); | 180 | "Maximum number of commands per logical unit (default=64)"); |
180 | 181 | ||
181 | 182 | ||
182 | /** | 183 | /* |
183 | * Fast driver load option, skip scanning for physical devices during load. | 184 | * Fast driver load option, skip scanning for physical devices during load. |
184 | * This would result in non-disk devices being skipped during driver load | 185 | * This would result in non-disk devices being skipped during driver load |
185 | * time. These can be later added though, using /proc/scsi/scsi | 186 | * time. These can be later added though, using /proc/scsi/scsi |
@@ -190,7 +191,7 @@ MODULE_PARM_DESC(fast_load, | |||
190 | "Faster loading of the driver, skips physical devices! (default=0)"); | 191 | "Faster loading of the driver, skips physical devices! (default=0)"); |
191 | 192 | ||
192 | 193 | ||
193 | /** | 194 | /* |
194 | * mraid_debug level - threshold for amount of information to be displayed by | 195 | * mraid_debug level - threshold for amount of information to be displayed by |
195 | * the driver. This level can be changed through modules parameters, ioctl or | 196 | * the driver. This level can be changed through modules parameters, ioctl or |
196 | * sysfs/proc interface. By default, print the announcement messages only. | 197 | * sysfs/proc interface. By default, print the announcement messages only. |
@@ -337,7 +338,7 @@ static struct device_attribute *megaraid_sdev_attrs[] = { | |||
337 | * | 338 | * |
338 | * Return value: | 339 | * Return value: |
339 | * actual depth set | 340 | * actual depth set |
340 | **/ | 341 | */ |
341 | static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth) | 342 | static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth) |
342 | { | 343 | { |
343 | if (qdepth > MBOX_MAX_SCSI_CMDS) | 344 | if (qdepth > MBOX_MAX_SCSI_CMDS) |
@@ -369,8 +370,8 @@ static struct scsi_host_template megaraid_template_g = { | |||
369 | * megaraid_init - module load hook | 370 | * megaraid_init - module load hook |
370 | * | 371 | * |
371 | * We register ourselves as hotplug enabled module and let PCI subsystem | 372 | * We register ourselves as hotplug enabled module and let PCI subsystem |
372 | * discover our adaters | 373 | * discover our adapters. |
373 | **/ | 374 | */ |
374 | static int __init | 375 | static int __init |
375 | megaraid_init(void) | 376 | megaraid_init(void) |
376 | { | 377 | { |
@@ -405,7 +406,7 @@ megaraid_init(void) | |||
405 | /** | 406 | /** |
406 | * megaraid_exit - driver unload entry point | 407 | * megaraid_exit - driver unload entry point |
407 | * | 408 | * |
408 | * We simply unwrap the megaraid_init routine here | 409 | * We simply unwrap the megaraid_init routine here. |
409 | */ | 410 | */ |
410 | static void __exit | 411 | static void __exit |
411 | megaraid_exit(void) | 412 | megaraid_exit(void) |
@@ -421,12 +422,12 @@ megaraid_exit(void) | |||
421 | 422 | ||
422 | /** | 423 | /** |
423 | * megaraid_probe_one - PCI hotplug entry point | 424 | * megaraid_probe_one - PCI hotplug entry point |
424 | * @param pdev : handle to this controller's PCI configuration space | 425 | * @pdev : handle to this controller's PCI configuration space |
425 | * @param id : pci device id of the class of controllers | 426 | * @id : pci device id of the class of controllers |
426 | * | 427 | * |
427 | * This routine should be called whenever a new adapter is detected by the | 428 | * This routine should be called whenever a new adapter is detected by the |
428 | * PCI hotplug susbsytem. | 429 | * PCI hotplug susbsytem. |
429 | **/ | 430 | */ |
430 | static int __devinit | 431 | static int __devinit |
431 | megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | 432 | megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) |
432 | { | 433 | { |
@@ -542,16 +543,15 @@ out_probe_one: | |||
542 | 543 | ||
543 | 544 | ||
544 | /** | 545 | /** |
545 | * megaraid_detach_one - release the framework resources and call LLD release | 546 | * megaraid_detach_one - release framework resources and call LLD release routine |
546 | * routine | 547 | * @pdev : handle for our PCI cofiguration space |
547 | * @param pdev : handle for our PCI cofiguration space | ||
548 | * | 548 | * |
549 | * This routine is called during driver unload. We free all the allocated | 549 | * This routine is called during driver unload. We free all the allocated |
550 | * resources and call the corresponding LLD so that it can also release all | 550 | * resources and call the corresponding LLD so that it can also release all |
551 | * its resources. | 551 | * its resources. |
552 | * | 552 | * |
553 | * This routine is also called from the PCI hotplug system | 553 | * This routine is also called from the PCI hotplug system. |
554 | **/ | 554 | */ |
555 | static void | 555 | static void |
556 | megaraid_detach_one(struct pci_dev *pdev) | 556 | megaraid_detach_one(struct pci_dev *pdev) |
557 | { | 557 | { |
@@ -615,9 +615,9 @@ megaraid_detach_one(struct pci_dev *pdev) | |||
615 | 615 | ||
616 | /** | 616 | /** |
617 | * megaraid_mbox_shutdown - PCI shutdown for megaraid HBA | 617 | * megaraid_mbox_shutdown - PCI shutdown for megaraid HBA |
618 | * @param device : generice driver model device | 618 | * @pdev : generic driver model device |
619 | * | 619 | * |
620 | * Shutdown notification, perform flush cache | 620 | * Shutdown notification, perform flush cache. |
621 | */ | 621 | */ |
622 | static void | 622 | static void |
623 | megaraid_mbox_shutdown(struct pci_dev *pdev) | 623 | megaraid_mbox_shutdown(struct pci_dev *pdev) |
@@ -643,10 +643,10 @@ megaraid_mbox_shutdown(struct pci_dev *pdev) | |||
643 | 643 | ||
644 | /** | 644 | /** |
645 | * megaraid_io_attach - attach a device with the IO subsystem | 645 | * megaraid_io_attach - attach a device with the IO subsystem |
646 | * @param adapter : controller's soft state | 646 | * @adapter : controller's soft state |
647 | * | 647 | * |
648 | * Attach this device with the IO subsystem | 648 | * Attach this device with the IO subsystem. |
649 | **/ | 649 | */ |
650 | static int | 650 | static int |
651 | megaraid_io_attach(adapter_t *adapter) | 651 | megaraid_io_attach(adapter_t *adapter) |
652 | { | 652 | { |
@@ -695,10 +695,10 @@ megaraid_io_attach(adapter_t *adapter) | |||
695 | 695 | ||
696 | /** | 696 | /** |
697 | * megaraid_io_detach - detach a device from the IO subsystem | 697 | * megaraid_io_detach - detach a device from the IO subsystem |
698 | * @param adapter : controller's soft state | 698 | * @adapter : controller's soft state |
699 | * | 699 | * |
700 | * Detach this device from the IO subsystem | 700 | * Detach this device from the IO subsystem. |
701 | **/ | 701 | */ |
702 | static void | 702 | static void |
703 | megaraid_io_detach(adapter_t *adapter) | 703 | megaraid_io_detach(adapter_t *adapter) |
704 | { | 704 | { |
@@ -722,13 +722,13 @@ megaraid_io_detach(adapter_t *adapter) | |||
722 | 722 | ||
723 | /** | 723 | /** |
724 | * megaraid_init_mbox - initialize controller | 724 | * megaraid_init_mbox - initialize controller |
725 | * @param adapter - our soft state | 725 | * @adapter : our soft state |
726 | * | 726 | * |
727 | * . Allocate 16-byte aligned mailbox memory for firmware handshake | 727 | * - Allocate 16-byte aligned mailbox memory for firmware handshake |
728 | * . Allocate controller's memory resources | 728 | * - Allocate controller's memory resources |
729 | * . Find out all initialization data | 729 | * - Find out all initialization data |
730 | * . Allocate memory required for all the commands | 730 | * - Allocate memory required for all the commands |
731 | * . Use internal library of FW routines, build up complete soft state | 731 | * - Use internal library of FW routines, build up complete soft state |
732 | */ | 732 | */ |
733 | static int __devinit | 733 | static int __devinit |
734 | megaraid_init_mbox(adapter_t *adapter) | 734 | megaraid_init_mbox(adapter_t *adapter) |
@@ -779,33 +779,39 @@ megaraid_init_mbox(adapter_t *adapter) | |||
779 | goto out_release_regions; | 779 | goto out_release_regions; |
780 | } | 780 | } |
781 | 781 | ||
782 | // | 782 | /* initialize the mutual exclusion lock for the mailbox */ |
783 | // Setup the rest of the soft state using the library of FW routines | 783 | spin_lock_init(&raid_dev->mailbox_lock); |
784 | // | ||
785 | 784 | ||
786 | // request IRQ and register the interrupt service routine | 785 | /* allocate memory required for commands */ |
786 | if (megaraid_alloc_cmd_packets(adapter) != 0) | ||
787 | goto out_iounmap; | ||
788 | |||
789 | /* | ||
790 | * Issue SYNC cmd to flush the pending cmds in the adapter | ||
791 | * and initialize its internal state | ||
792 | */ | ||
793 | |||
794 | if (megaraid_mbox_fire_sync_cmd(adapter)) | ||
795 | con_log(CL_ANN, ("megaraid: sync cmd failed\n")); | ||
796 | |||
797 | /* | ||
798 | * Setup the rest of the soft state using the library of | ||
799 | * FW routines | ||
800 | */ | ||
801 | |||
802 | /* request IRQ and register the interrupt service routine */ | ||
787 | if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid", | 803 | if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid", |
788 | adapter)) { | 804 | adapter)) { |
789 | 805 | ||
790 | con_log(CL_ANN, (KERN_WARNING | 806 | con_log(CL_ANN, (KERN_WARNING |
791 | "megaraid: Couldn't register IRQ %d!\n", adapter->irq)); | 807 | "megaraid: Couldn't register IRQ %d!\n", adapter->irq)); |
808 | goto out_alloc_cmds; | ||
792 | 809 | ||
793 | goto out_iounmap; | ||
794 | } | ||
795 | |||
796 | |||
797 | // initialize the mutual exclusion lock for the mailbox | ||
798 | spin_lock_init(&raid_dev->mailbox_lock); | ||
799 | |||
800 | // allocate memory required for commands | ||
801 | if (megaraid_alloc_cmd_packets(adapter) != 0) { | ||
802 | goto out_free_irq; | ||
803 | } | 810 | } |
804 | 811 | ||
805 | // Product info | 812 | // Product info |
806 | if (megaraid_mbox_product_info(adapter) != 0) { | 813 | if (megaraid_mbox_product_info(adapter) != 0) |
807 | goto out_alloc_cmds; | 814 | goto out_free_irq; |
808 | } | ||
809 | 815 | ||
810 | // Do we support extended CDBs | 816 | // Do we support extended CDBs |
811 | adapter->max_cdb_sz = 10; | 817 | adapter->max_cdb_sz = 10; |
@@ -874,9 +880,8 @@ megaraid_init_mbox(adapter_t *adapter) | |||
874 | * Allocate resources required to issue FW calls, when sysfs is | 880 | * Allocate resources required to issue FW calls, when sysfs is |
875 | * accessed | 881 | * accessed |
876 | */ | 882 | */ |
877 | if (megaraid_sysfs_alloc_resources(adapter) != 0) { | 883 | if (megaraid_sysfs_alloc_resources(adapter) != 0) |
878 | goto out_alloc_cmds; | 884 | goto out_free_irq; |
879 | } | ||
880 | 885 | ||
881 | // Set the DMA mask to 64-bit. All supported controllers as capable of | 886 | // Set the DMA mask to 64-bit. All supported controllers as capable of |
882 | // DMA in this range | 887 | // DMA in this range |
@@ -920,10 +925,10 @@ megaraid_init_mbox(adapter_t *adapter) | |||
920 | 925 | ||
921 | out_free_sysfs_res: | 926 | out_free_sysfs_res: |
922 | megaraid_sysfs_free_resources(adapter); | 927 | megaraid_sysfs_free_resources(adapter); |
923 | out_alloc_cmds: | ||
924 | megaraid_free_cmd_packets(adapter); | ||
925 | out_free_irq: | 928 | out_free_irq: |
926 | free_irq(adapter->irq, adapter); | 929 | free_irq(adapter->irq, adapter); |
930 | out_alloc_cmds: | ||
931 | megaraid_free_cmd_packets(adapter); | ||
927 | out_iounmap: | 932 | out_iounmap: |
928 | iounmap(raid_dev->baseaddr); | 933 | iounmap(raid_dev->baseaddr); |
929 | out_release_regions: | 934 | out_release_regions: |
@@ -937,7 +942,7 @@ out_free_raid_dev: | |||
937 | 942 | ||
938 | /** | 943 | /** |
939 | * megaraid_fini_mbox - undo controller initialization | 944 | * megaraid_fini_mbox - undo controller initialization |
940 | * @param adapter : our soft state | 945 | * @adapter : our soft state |
941 | */ | 946 | */ |
942 | static void | 947 | static void |
943 | megaraid_fini_mbox(adapter_t *adapter) | 948 | megaraid_fini_mbox(adapter_t *adapter) |
@@ -967,12 +972,12 @@ megaraid_fini_mbox(adapter_t *adapter) | |||
967 | 972 | ||
968 | /** | 973 | /** |
969 | * megaraid_alloc_cmd_packets - allocate shared mailbox | 974 | * megaraid_alloc_cmd_packets - allocate shared mailbox |
970 | * @param adapter : soft state of the raid controller | 975 | * @adapter : soft state of the raid controller |
971 | * | 976 | * |
972 | * Allocate and align the shared mailbox. This maibox is used to issue | 977 | * Allocate and align the shared mailbox. This maibox is used to issue |
973 | * all the commands. For IO based controllers, the mailbox is also regsitered | 978 | * all the commands. For IO based controllers, the mailbox is also regsitered |
974 | * with the FW. Allocate memory for all commands as well. | 979 | * with the FW. Allocate memory for all commands as well. |
975 | * This is our big allocator | 980 | * This is our big allocator. |
976 | */ | 981 | */ |
977 | static int | 982 | static int |
978 | megaraid_alloc_cmd_packets(adapter_t *adapter) | 983 | megaraid_alloc_cmd_packets(adapter_t *adapter) |
@@ -1132,9 +1137,9 @@ out_free_common_mbox: | |||
1132 | 1137 | ||
1133 | /** | 1138 | /** |
1134 | * megaraid_free_cmd_packets - free memory | 1139 | * megaraid_free_cmd_packets - free memory |
1135 | * @param adapter : soft state of the raid controller | 1140 | * @adapter : soft state of the raid controller |
1136 | * | 1141 | * |
1137 | * Release memory resources allocated for commands | 1142 | * Release memory resources allocated for commands. |
1138 | */ | 1143 | */ |
1139 | static void | 1144 | static void |
1140 | megaraid_free_cmd_packets(adapter_t *adapter) | 1145 | megaraid_free_cmd_packets(adapter_t *adapter) |
@@ -1156,10 +1161,10 @@ megaraid_free_cmd_packets(adapter_t *adapter) | |||
1156 | 1161 | ||
1157 | /** | 1162 | /** |
1158 | * megaraid_mbox_setup_dma_pools - setup dma pool for command packets | 1163 | * megaraid_mbox_setup_dma_pools - setup dma pool for command packets |
1159 | * @param adapter : HBA soft state | 1164 | * @adapter : HBA soft state |
1160 | * | 1165 | * |
1161 | * setup the dma pools for mailbox, passthru and extended passthru structures, | 1166 | * Setup the dma pools for mailbox, passthru and extended passthru structures, |
1162 | * and scatter-gather lists | 1167 | * and scatter-gather lists. |
1163 | */ | 1168 | */ |
1164 | static int | 1169 | static int |
1165 | megaraid_mbox_setup_dma_pools(adapter_t *adapter) | 1170 | megaraid_mbox_setup_dma_pools(adapter_t *adapter) |
@@ -1252,10 +1257,10 @@ fail_setup_dma_pool: | |||
1252 | 1257 | ||
1253 | /** | 1258 | /** |
1254 | * megaraid_mbox_teardown_dma_pools - teardown dma pools for command packets | 1259 | * megaraid_mbox_teardown_dma_pools - teardown dma pools for command packets |
1255 | * @param adapter : HBA soft state | 1260 | * @adapter : HBA soft state |
1256 | * | 1261 | * |
1257 | * teardown the dma pool for mailbox, passthru and extended passthru | 1262 | * Teardown the dma pool for mailbox, passthru and extended passthru |
1258 | * structures, and scatter-gather lists | 1263 | * structures, and scatter-gather lists. |
1259 | */ | 1264 | */ |
1260 | static void | 1265 | static void |
1261 | megaraid_mbox_teardown_dma_pools(adapter_t *adapter) | 1266 | megaraid_mbox_teardown_dma_pools(adapter_t *adapter) |
@@ -1300,10 +1305,11 @@ megaraid_mbox_teardown_dma_pools(adapter_t *adapter) | |||
1300 | /** | 1305 | /** |
1301 | * megaraid_alloc_scb - detach and return a scb from the free list | 1306 | * megaraid_alloc_scb - detach and return a scb from the free list |
1302 | * @adapter : controller's soft state | 1307 | * @adapter : controller's soft state |
1308 | * @scp : pointer to the scsi command to be executed | ||
1303 | * | 1309 | * |
1304 | * return the scb from the head of the free list. NULL if there are none | 1310 | * Return the scb from the head of the free list. %NULL if there are none |
1305 | * available | 1311 | * available. |
1306 | **/ | 1312 | */ |
1307 | static scb_t * | 1313 | static scb_t * |
1308 | megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp) | 1314 | megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp) |
1309 | { | 1315 | { |
@@ -1337,11 +1343,11 @@ megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp) | |||
1337 | * @adapter : controller's soft state | 1343 | * @adapter : controller's soft state |
1338 | * @scb : scb to be freed | 1344 | * @scb : scb to be freed |
1339 | * | 1345 | * |
1340 | * return the scb back to the free list of scbs. The caller must 'flush' the | 1346 | * Return the scb back to the free list of scbs. The caller must 'flush' the |
1341 | * SCB before calling us. E.g., performing pci_unamp and/or pci_sync etc. | 1347 | * SCB before calling us. E.g., performing pci_unamp and/or pci_sync etc. |
1342 | * NOTE NOTE: Make sure the scb is not on any list before calling this | 1348 | * NOTE NOTE: Make sure the scb is not on any list before calling this |
1343 | * routine. | 1349 | * routine. |
1344 | **/ | 1350 | */ |
1345 | static inline void | 1351 | static inline void |
1346 | megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb) | 1352 | megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb) |
1347 | { | 1353 | { |
@@ -1362,10 +1368,10 @@ megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb) | |||
1362 | 1368 | ||
1363 | /** | 1369 | /** |
1364 | * megaraid_mbox_mksgl - make the scatter-gather list | 1370 | * megaraid_mbox_mksgl - make the scatter-gather list |
1365 | * @adapter - controller's soft state | 1371 | * @adapter : controller's soft state |
1366 | * @scb - scsi control block | 1372 | * @scb : scsi control block |
1367 | * | 1373 | * |
1368 | * prepare the scatter-gather list | 1374 | * Prepare the scatter-gather list. |
1369 | */ | 1375 | */ |
1370 | static int | 1376 | static int |
1371 | megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) | 1377 | megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) |
@@ -1435,10 +1441,10 @@ megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) | |||
1435 | 1441 | ||
1436 | /** | 1442 | /** |
1437 | * mbox_post_cmd - issue a mailbox command | 1443 | * mbox_post_cmd - issue a mailbox command |
1438 | * @adapter - controller's soft state | 1444 | * @adapter : controller's soft state |
1439 | * @scb - command to be issued | 1445 | * @scb : command to be issued |
1440 | * | 1446 | * |
1441 | * post the command to the controller if mailbox is availble. | 1447 | * Post the command to the controller if mailbox is available. |
1442 | */ | 1448 | */ |
1443 | static int | 1449 | static int |
1444 | mbox_post_cmd(adapter_t *adapter, scb_t *scb) | 1450 | mbox_post_cmd(adapter_t *adapter, scb_t *scb) |
@@ -1518,7 +1524,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) | |||
1518 | * Queue entry point for mailbox based controllers. | 1524 | * Queue entry point for mailbox based controllers. |
1519 | */ | 1525 | */ |
1520 | static int | 1526 | static int |
1521 | megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *)) | 1527 | megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) |
1522 | { | 1528 | { |
1523 | adapter_t *adapter; | 1529 | adapter_t *adapter; |
1524 | scb_t *scb; | 1530 | scb_t *scb; |
@@ -1548,15 +1554,15 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *)) | |||
1548 | } | 1554 | } |
1549 | 1555 | ||
1550 | /** | 1556 | /** |
1551 | * megaraid_mbox_build_cmd - transform the mid-layer scsi command to megaraid | 1557 | * megaraid_mbox_build_cmd - transform the mid-layer scsi commands |
1552 | * firmware lingua | 1558 | * @adapter : controller's soft state |
1553 | * @adapter - controller's soft state | 1559 | * @scp : mid-layer scsi command pointer |
1554 | * @scp - mid-layer scsi command pointer | 1560 | * @busy : set if request could not be completed because of lack of |
1555 | * @busy - set if request could not be completed because of lack of | ||
1556 | * resources | 1561 | * resources |
1557 | * | 1562 | * |
1558 | * convert the command issued by mid-layer to format understood by megaraid | 1563 | * Transform the mid-layer scsi command to megaraid firmware lingua. |
1559 | * firmware. We also complete certain command without sending them to firmware | 1564 | * Convert the command issued by mid-layer to format understood by megaraid |
1565 | * firmware. We also complete certain commands without sending them to firmware. | ||
1560 | */ | 1566 | */ |
1561 | static scb_t * | 1567 | static scb_t * |
1562 | megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) | 1568 | megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) |
@@ -1937,9 +1943,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) | |||
1937 | /** | 1943 | /** |
1938 | * megaraid_mbox_runpendq - execute commands queued in the pending queue | 1944 | * megaraid_mbox_runpendq - execute commands queued in the pending queue |
1939 | * @adapter : controller's soft state | 1945 | * @adapter : controller's soft state |
1940 | * @scb : SCB to be queued in the pending list | 1946 | * @scb_q : SCB to be queued in the pending list |
1941 | * | 1947 | * |
1942 | * scan the pending list for commands which are not yet issued and try to | 1948 | * Scan the pending list for commands which are not yet issued and try to |
1943 | * post to the controller. The SCB can be a null pointer, which would indicate | 1949 | * post to the controller. The SCB can be a null pointer, which would indicate |
1944 | * no SCB to be queue, just try to execute the ones in the pending list. | 1950 | * no SCB to be queue, just try to execute the ones in the pending list. |
1945 | * | 1951 | * |
@@ -2012,11 +2018,11 @@ megaraid_mbox_runpendq(adapter_t *adapter, scb_t *scb_q) | |||
2012 | 2018 | ||
2013 | /** | 2019 | /** |
2014 | * megaraid_mbox_prepare_pthru - prepare a command for physical devices | 2020 | * megaraid_mbox_prepare_pthru - prepare a command for physical devices |
2015 | * @adapter - pointer to controller's soft state | 2021 | * @adapter : pointer to controller's soft state |
2016 | * @scb - scsi control block | 2022 | * @scb : scsi control block |
2017 | * @scp - scsi command from the mid-layer | 2023 | * @scp : scsi command from the mid-layer |
2018 | * | 2024 | * |
2019 | * prepare a command for the scsi physical devices | 2025 | * Prepare a command for the scsi physical devices. |
2020 | */ | 2026 | */ |
2021 | static void | 2027 | static void |
2022 | megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, | 2028 | megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, |
@@ -2060,12 +2066,12 @@ megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, | |||
2060 | 2066 | ||
2061 | /** | 2067 | /** |
2062 | * megaraid_mbox_prepare_epthru - prepare a command for physical devices | 2068 | * megaraid_mbox_prepare_epthru - prepare a command for physical devices |
2063 | * @adapter - pointer to controller's soft state | 2069 | * @adapter : pointer to controller's soft state |
2064 | * @scb - scsi control block | 2070 | * @scb : scsi control block |
2065 | * @scp - scsi command from the mid-layer | 2071 | * @scp : scsi command from the mid-layer |
2066 | * | 2072 | * |
2067 | * prepare a command for the scsi physical devices. This rountine prepares | 2073 | * Prepare a command for the scsi physical devices. This rountine prepares |
2068 | * commands for devices which can take extended CDBs (>10 bytes) | 2074 | * commands for devices which can take extended CDBs (>10 bytes). |
2069 | */ | 2075 | */ |
2070 | static void | 2076 | static void |
2071 | megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb, | 2077 | megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb, |
@@ -2109,9 +2115,9 @@ megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb, | |||
2109 | 2115 | ||
2110 | /** | 2116 | /** |
2111 | * megaraid_ack_sequence - interrupt ack sequence for memory mapped HBAs | 2117 | * megaraid_ack_sequence - interrupt ack sequence for memory mapped HBAs |
2112 | * @adapter - controller's soft state | 2118 | * @adapter : controller's soft state |
2113 | * | 2119 | * |
2114 | * Interrupt ackrowledgement sequence for memory mapped HBAs. Find out the | 2120 | * Interrupt acknowledgement sequence for memory mapped HBAs. Find out the |
2115 | * completed command and put them on the completed list for later processing. | 2121 | * completed command and put them on the completed list for later processing. |
2116 | * | 2122 | * |
2117 | * Returns: 1 if the interrupt is valid, 0 otherwise | 2123 | * Returns: 1 if the interrupt is valid, 0 otherwise |
@@ -2224,9 +2230,8 @@ megaraid_ack_sequence(adapter_t *adapter) | |||
2224 | 2230 | ||
2225 | /** | 2231 | /** |
2226 | * megaraid_isr - isr for memory based mailbox based controllers | 2232 | * megaraid_isr - isr for memory based mailbox based controllers |
2227 | * @irq - irq | 2233 | * @irq : irq |
2228 | * @devp - pointer to our soft state | 2234 | * @devp : pointer to our soft state |
2229 | * @regs - unused | ||
2230 | * | 2235 | * |
2231 | * Interrupt service routine for memory-mapped mailbox controllers. | 2236 | * Interrupt service routine for memory-mapped mailbox controllers. |
2232 | */ | 2237 | */ |
@@ -2671,7 +2676,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp) | |||
2671 | * the FW is still live, in which case the outstanding commands counter mut go | 2676 | * the FW is still live, in which case the outstanding commands counter mut go |
2672 | * down to 0. If that happens, also issue the reservation reset command to | 2677 | * down to 0. If that happens, also issue the reservation reset command to |
2673 | * relinquish (possible) reservations on the logical drives connected to this | 2678 | * relinquish (possible) reservations on the logical drives connected to this |
2674 | * host | 2679 | * host. |
2675 | **/ | 2680 | **/ |
2676 | static int | 2681 | static int |
2677 | megaraid_reset_handler(struct scsi_cmnd *scp) | 2682 | megaraid_reset_handler(struct scsi_cmnd *scp) |
@@ -2823,11 +2828,11 @@ megaraid_reset_handler(struct scsi_cmnd *scp) | |||
2823 | 2828 | ||
2824 | /** | 2829 | /** |
2825 | * mbox_post_sync_cmd() - blocking command to the mailbox based controllers | 2830 | * mbox_post_sync_cmd() - blocking command to the mailbox based controllers |
2826 | * @adapter - controller's soft state | 2831 | * @adapter : controller's soft state |
2827 | * @raw_mbox - the mailbox | 2832 | * @raw_mbox : the mailbox |
2828 | * | 2833 | * |
2829 | * Issue a scb in synchronous and non-interrupt mode for mailbox based | 2834 | * Issue a scb in synchronous and non-interrupt mode for mailbox based |
2830 | * controllers | 2835 | * controllers. |
2831 | */ | 2836 | */ |
2832 | static int | 2837 | static int |
2833 | mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[]) | 2838 | mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[]) |
@@ -2955,12 +2960,12 @@ blocked_mailbox: | |||
2955 | 2960 | ||
2956 | /** | 2961 | /** |
2957 | * mbox_post_sync_cmd_fast - blocking command to the mailbox based controllers | 2962 | * mbox_post_sync_cmd_fast - blocking command to the mailbox based controllers |
2958 | * @adapter - controller's soft state | 2963 | * @adapter : controller's soft state |
2959 | * @raw_mbox - the mailbox | 2964 | * @raw_mbox : the mailbox |
2960 | * | 2965 | * |
2961 | * Issue a scb in synchronous and non-interrupt mode for mailbox based | 2966 | * Issue a scb in synchronous and non-interrupt mode for mailbox based |
2962 | * controllers. This is a faster version of the synchronous command and | 2967 | * controllers. This is a faster version of the synchronous command and |
2963 | * therefore can be called in interrupt-context as well | 2968 | * therefore can be called in interrupt-context as well. |
2964 | */ | 2969 | */ |
2965 | static int | 2970 | static int |
2966 | mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) | 2971 | mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) |
@@ -3008,10 +3013,10 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) | |||
3008 | 3013 | ||
3009 | /** | 3014 | /** |
3010 | * megaraid_busywait_mbox() - Wait until the controller's mailbox is available | 3015 | * megaraid_busywait_mbox() - Wait until the controller's mailbox is available |
3011 | * @raid_dev - RAID device (HBA) soft state | 3016 | * @raid_dev : RAID device (HBA) soft state |
3012 | * | 3017 | * |
3013 | * wait until the controller's mailbox is available to accept more commands. | 3018 | * Wait until the controller's mailbox is available to accept more commands. |
3014 | * wait for at most 1 second | 3019 | * Wait for at most 1 second. |
3015 | */ | 3020 | */ |
3016 | static int | 3021 | static int |
3017 | megaraid_busywait_mbox(mraid_device_t *raid_dev) | 3022 | megaraid_busywait_mbox(mraid_device_t *raid_dev) |
@@ -3032,9 +3037,9 @@ megaraid_busywait_mbox(mraid_device_t *raid_dev) | |||
3032 | 3037 | ||
3033 | /** | 3038 | /** |
3034 | * megaraid_mbox_product_info - some static information about the controller | 3039 | * megaraid_mbox_product_info - some static information about the controller |
3035 | * @adapter - our soft state | 3040 | * @adapter : our soft state |
3036 | * | 3041 | * |
3037 | * issue commands to the controller to grab some parameters required by our | 3042 | * Issue commands to the controller to grab some parameters required by our |
3038 | * caller. | 3043 | * caller. |
3039 | */ | 3044 | */ |
3040 | static int | 3045 | static int |
@@ -3157,10 +3162,10 @@ megaraid_mbox_product_info(adapter_t *adapter) | |||
3157 | 3162 | ||
3158 | /** | 3163 | /** |
3159 | * megaraid_mbox_extended_cdb - check for support for extended CDBs | 3164 | * megaraid_mbox_extended_cdb - check for support for extended CDBs |
3160 | * @adapter - soft state for the controller | 3165 | * @adapter : soft state for the controller |
3161 | * | 3166 | * |
3162 | * this routine check whether the controller in question supports extended | 3167 | * This routine check whether the controller in question supports extended |
3163 | * ( > 10 bytes ) CDBs | 3168 | * ( > 10 bytes ) CDBs. |
3164 | */ | 3169 | */ |
3165 | static int | 3170 | static int |
3166 | megaraid_mbox_extended_cdb(adapter_t *adapter) | 3171 | megaraid_mbox_extended_cdb(adapter_t *adapter) |
@@ -3193,8 +3198,8 @@ megaraid_mbox_extended_cdb(adapter_t *adapter) | |||
3193 | 3198 | ||
3194 | /** | 3199 | /** |
3195 | * megaraid_mbox_support_ha - Do we support clustering | 3200 | * megaraid_mbox_support_ha - Do we support clustering |
3196 | * @adapter - soft state for the controller | 3201 | * @adapter : soft state for the controller |
3197 | * @init_id - ID of the initiator | 3202 | * @init_id : ID of the initiator |
3198 | * | 3203 | * |
3199 | * Determine if the firmware supports clustering and the ID of the initiator. | 3204 | * Determine if the firmware supports clustering and the ID of the initiator. |
3200 | */ | 3205 | */ |
@@ -3236,9 +3241,9 @@ megaraid_mbox_support_ha(adapter_t *adapter, uint16_t *init_id) | |||
3236 | 3241 | ||
3237 | /** | 3242 | /** |
3238 | * megaraid_mbox_support_random_del - Do we support random deletion | 3243 | * megaraid_mbox_support_random_del - Do we support random deletion |
3239 | * @adapter - soft state for the controller | 3244 | * @adapter : soft state for the controller |
3240 | * | 3245 | * |
3241 | * Determine if the firmware supports random deletion | 3246 | * Determine if the firmware supports random deletion. |
3242 | * Return: 1 is operation supported, 0 otherwise | 3247 | * Return: 1 is operation supported, 0 otherwise |
3243 | */ | 3248 | */ |
3244 | static int | 3249 | static int |
@@ -3271,10 +3276,10 @@ megaraid_mbox_support_random_del(adapter_t *adapter) | |||
3271 | 3276 | ||
3272 | /** | 3277 | /** |
3273 | * megaraid_mbox_get_max_sg - maximum sg elements supported by the firmware | 3278 | * megaraid_mbox_get_max_sg - maximum sg elements supported by the firmware |
3274 | * @adapter - soft state for the controller | 3279 | * @adapter : soft state for the controller |
3275 | * | 3280 | * |
3276 | * Find out the maximum number of scatter-gather elements supported by the | 3281 | * Find out the maximum number of scatter-gather elements supported by the |
3277 | * firmware | 3282 | * firmware. |
3278 | */ | 3283 | */ |
3279 | static int | 3284 | static int |
3280 | megaraid_mbox_get_max_sg(adapter_t *adapter) | 3285 | megaraid_mbox_get_max_sg(adapter_t *adapter) |
@@ -3311,10 +3316,10 @@ megaraid_mbox_get_max_sg(adapter_t *adapter) | |||
3311 | 3316 | ||
3312 | /** | 3317 | /** |
3313 | * megaraid_mbox_enum_raid_scsi - enumerate the RAID and SCSI channels | 3318 | * megaraid_mbox_enum_raid_scsi - enumerate the RAID and SCSI channels |
3314 | * @adapter - soft state for the controller | 3319 | * @adapter : soft state for the controller |
3315 | * | 3320 | * |
3316 | * Enumerate the RAID and SCSI channels for ROMB platoforms so that channels | 3321 | * Enumerate the RAID and SCSI channels for ROMB platforms so that channels |
3317 | * can be exported as regular SCSI channels | 3322 | * can be exported as regular SCSI channels. |
3318 | */ | 3323 | */ |
3319 | static void | 3324 | static void |
3320 | megaraid_mbox_enum_raid_scsi(adapter_t *adapter) | 3325 | megaraid_mbox_enum_raid_scsi(adapter_t *adapter) |
@@ -3348,9 +3353,9 @@ megaraid_mbox_enum_raid_scsi(adapter_t *adapter) | |||
3348 | 3353 | ||
3349 | /** | 3354 | /** |
3350 | * megaraid_mbox_flush_cache - flush adapter and disks cache | 3355 | * megaraid_mbox_flush_cache - flush adapter and disks cache |
3351 | * @param adapter : soft state for the controller | 3356 | * @adapter : soft state for the controller |
3352 | * | 3357 | * |
3353 | * Flush adapter cache followed by disks cache | 3358 | * Flush adapter cache followed by disks cache. |
3354 | */ | 3359 | */ |
3355 | static void | 3360 | static void |
3356 | megaraid_mbox_flush_cache(adapter_t *adapter) | 3361 | megaraid_mbox_flush_cache(adapter_t *adapter) |
@@ -3380,13 +3385,91 @@ megaraid_mbox_flush_cache(adapter_t *adapter) | |||
3380 | 3385 | ||
3381 | 3386 | ||
3382 | /** | 3387 | /** |
3388 | * megaraid_mbox_fire_sync_cmd - fire the sync cmd | ||
3389 | * @adapter : soft state for the controller | ||
3390 | * | ||
3391 | * Clears the pending cmds in FW and reinits its RAID structs. | ||
3392 | */ | ||
3393 | static int | ||
3394 | megaraid_mbox_fire_sync_cmd(adapter_t *adapter) | ||
3395 | { | ||
3396 | mbox_t *mbox; | ||
3397 | uint8_t raw_mbox[sizeof(mbox_t)]; | ||
3398 | mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); | ||
3399 | mbox64_t *mbox64; | ||
3400 | int status = 0; | ||
3401 | int i; | ||
3402 | uint32_t dword; | ||
3403 | |||
3404 | mbox = (mbox_t *)raw_mbox; | ||
3405 | |||
3406 | memset((caddr_t)raw_mbox, 0, sizeof(mbox_t)); | ||
3407 | |||
3408 | raw_mbox[0] = 0xFF; | ||
3409 | |||
3410 | mbox64 = raid_dev->mbox64; | ||
3411 | mbox = raid_dev->mbox; | ||
3412 | |||
3413 | /* Wait until mailbox is free */ | ||
3414 | if (megaraid_busywait_mbox(raid_dev) != 0) { | ||
3415 | status = 1; | ||
3416 | goto blocked_mailbox; | ||
3417 | } | ||
3418 | |||
3419 | /* Copy mailbox data into host structure */ | ||
3420 | memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16); | ||
3421 | mbox->cmdid = 0xFE; | ||
3422 | mbox->busy = 1; | ||
3423 | mbox->poll = 0; | ||
3424 | mbox->ack = 0; | ||
3425 | mbox->numstatus = 0; | ||
3426 | mbox->status = 0; | ||
3427 | |||
3428 | wmb(); | ||
3429 | WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); | ||
3430 | |||
3431 | /* Wait for maximum 1 min for status to post. | ||
3432 | * If the Firmware SUPPORTS the ABOVE COMMAND, | ||
3433 | * mbox->cmd will be set to 0 | ||
3434 | * else | ||
3435 | * the firmware will reject the command with | ||
3436 | * mbox->numstatus set to 1 | ||
3437 | */ | ||
3438 | |||
3439 | i = 0; | ||
3440 | status = 0; | ||
3441 | while (!mbox->numstatus && mbox->cmd == 0xFF) { | ||
3442 | rmb(); | ||
3443 | msleep(1); | ||
3444 | i++; | ||
3445 | if (i > 1000 * 60) { | ||
3446 | status = 1; | ||
3447 | break; | ||
3448 | } | ||
3449 | } | ||
3450 | if (mbox->numstatus == 1) | ||
3451 | status = 1; /*cmd not supported*/ | ||
3452 | |||
3453 | /* Check for interrupt line */ | ||
3454 | dword = RDOUTDOOR(raid_dev); | ||
3455 | WROUTDOOR(raid_dev, dword); | ||
3456 | WRINDOOR(raid_dev,2); | ||
3457 | |||
3458 | return status; | ||
3459 | |||
3460 | blocked_mailbox: | ||
3461 | con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n")); | ||
3462 | return status; | ||
3463 | } | ||
3464 | |||
3465 | /** | ||
3383 | * megaraid_mbox_display_scb - display SCB information, mostly debug purposes | 3466 | * megaraid_mbox_display_scb - display SCB information, mostly debug purposes |
3384 | * @param adapter : controllers' soft state | 3467 | * @adapter : controller's soft state |
3385 | * @param scb : SCB to be displayed | 3468 | * @scb : SCB to be displayed |
3386 | * @param level : debug level for console print | 3469 | * @level : debug level for console print |
3387 | * | 3470 | * |
3388 | * Diplay information about the given SCB iff the current debug level is | 3471 | * Diplay information about the given SCB iff the current debug level is |
3389 | * verbose | 3472 | * verbose. |
3390 | */ | 3473 | */ |
3391 | static void | 3474 | static void |
3392 | megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) | 3475 | megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) |
@@ -3434,7 +3517,7 @@ megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) | |||
3434 | * scsi addresses and megaraid scsi and logical drive addresses. We export | 3517 | * scsi addresses and megaraid scsi and logical drive addresses. We export |
3435 | * scsi devices on their actual addresses, whereas the logical drives are | 3518 | * scsi devices on their actual addresses, whereas the logical drives are |
3436 | * exported on a virtual scsi channel. | 3519 | * exported on a virtual scsi channel. |
3437 | **/ | 3520 | */ |
3438 | static void | 3521 | static void |
3439 | megaraid_mbox_setup_device_map(adapter_t *adapter) | 3522 | megaraid_mbox_setup_device_map(adapter_t *adapter) |
3440 | { | 3523 | { |
@@ -3472,7 +3555,7 @@ megaraid_mbox_setup_device_map(adapter_t *adapter) | |||
3472 | 3555 | ||
3473 | /** | 3556 | /** |
3474 | * megaraid_cmm_register - register with the mangement module | 3557 | * megaraid_cmm_register - register with the mangement module |
3475 | * @param adapter : HBA soft state | 3558 | * @adapter : HBA soft state |
3476 | * | 3559 | * |
3477 | * Register with the management module, which allows applications to issue | 3560 | * Register with the management module, which allows applications to issue |
3478 | * ioctl calls to the drivers. This interface is used by the management module | 3561 | * ioctl calls to the drivers. This interface is used by the management module |
@@ -3562,11 +3645,11 @@ megaraid_cmm_register(adapter_t *adapter) | |||
3562 | 3645 | ||
3563 | /** | 3646 | /** |
3564 | * megaraid_cmm_unregister - un-register with the mangement module | 3647 | * megaraid_cmm_unregister - un-register with the mangement module |
3565 | * @param adapter : HBA soft state | 3648 | * @adapter : HBA soft state |
3566 | * | 3649 | * |
3567 | * Un-register with the management module. | 3650 | * Un-register with the management module. |
3568 | * FIXME: mgmt module must return failure for unregister if it has pending | 3651 | * FIXME: mgmt module must return failure for unregister if it has pending |
3569 | * commands in LLD | 3652 | * commands in LLD. |
3570 | */ | 3653 | */ |
3571 | static int | 3654 | static int |
3572 | megaraid_cmm_unregister(adapter_t *adapter) | 3655 | megaraid_cmm_unregister(adapter_t *adapter) |
@@ -3579,9 +3662,9 @@ megaraid_cmm_unregister(adapter_t *adapter) | |||
3579 | 3662 | ||
3580 | /** | 3663 | /** |
3581 | * megaraid_mbox_mm_handler - interface for CMM to issue commands to LLD | 3664 | * megaraid_mbox_mm_handler - interface for CMM to issue commands to LLD |
3582 | * @param drvr_data : LLD specific data | 3665 | * @drvr_data : LLD specific data |
3583 | * @param kioc : CMM interface packet | 3666 | * @kioc : CMM interface packet |
3584 | * @param action : command action | 3667 | * @action : command action |
3585 | * | 3668 | * |
3586 | * This routine is invoked whenever the Common Mangement Module (CMM) has a | 3669 | * This routine is invoked whenever the Common Mangement Module (CMM) has a |
3587 | * command for us. The 'action' parameter specifies if this is a new command | 3670 | * command for us. The 'action' parameter specifies if this is a new command |
@@ -3634,8 +3717,8 @@ megaraid_mbox_mm_handler(unsigned long drvr_data, uioc_t *kioc, uint32_t action) | |||
3634 | 3717 | ||
3635 | /** | 3718 | /** |
3636 | * megaraid_mbox_mm_command - issues commands routed through CMM | 3719 | * megaraid_mbox_mm_command - issues commands routed through CMM |
3637 | * @param adapter : HBA soft state | 3720 | * @adapter : HBA soft state |
3638 | * @param kioc : management command packet | 3721 | * @kioc : management command packet |
3639 | * | 3722 | * |
3640 | * Issues commands, which are routed through the management module. | 3723 | * Issues commands, which are routed through the management module. |
3641 | */ | 3724 | */ |
@@ -3804,8 +3887,8 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb) | |||
3804 | 3887 | ||
3805 | /** | 3888 | /** |
3806 | * gather_hbainfo - HBA characteristics for the applications | 3889 | * gather_hbainfo - HBA characteristics for the applications |
3807 | * @param adapter : HBA soft state | 3890 | * @adapter : HBA soft state |
3808 | * @param hinfo : pointer to the caller's host info strucuture | 3891 | * @hinfo : pointer to the caller's host info strucuture |
3809 | */ | 3892 | */ |
3810 | static int | 3893 | static int |
3811 | gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo) | 3894 | gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo) |
@@ -3839,16 +3922,15 @@ gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo) | |||
3839 | 3922 | ||
3840 | /** | 3923 | /** |
3841 | * megaraid_sysfs_alloc_resources - allocate sysfs related resources | 3924 | * megaraid_sysfs_alloc_resources - allocate sysfs related resources |
3925 | * @adapter : controller's soft state | ||
3842 | * | 3926 | * |
3843 | * Allocate packets required to issue FW calls whenever the sysfs attributes | 3927 | * Allocate packets required to issue FW calls whenever the sysfs attributes |
3844 | * are read. These attributes would require up-to-date information from the | 3928 | * are read. These attributes would require up-to-date information from the |
3845 | * FW. Also set up resources for mutual exclusion to share these resources and | 3929 | * FW. Also set up resources for mutual exclusion to share these resources and |
3846 | * the wait queue. | 3930 | * the wait queue. |
3847 | * | 3931 | * |
3848 | * @param adapter : controller's soft state | 3932 | * Return 0 on success. |
3849 | * | 3933 | * Return -ERROR_CODE on failure. |
3850 | * @return 0 on success | ||
3851 | * @return -ERROR_CODE on failure | ||
3852 | */ | 3934 | */ |
3853 | static int | 3935 | static int |
3854 | megaraid_sysfs_alloc_resources(adapter_t *adapter) | 3936 | megaraid_sysfs_alloc_resources(adapter_t *adapter) |
@@ -3885,10 +3967,9 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) | |||
3885 | 3967 | ||
3886 | /** | 3968 | /** |
3887 | * megaraid_sysfs_free_resources - free sysfs related resources | 3969 | * megaraid_sysfs_free_resources - free sysfs related resources |
3970 | * @adapter : controller's soft state | ||
3888 | * | 3971 | * |
3889 | * Free packets allocated for sysfs FW commands | 3972 | * Free packets allocated for sysfs FW commands |
3890 | * | ||
3891 | * @param adapter : controller's soft state | ||
3892 | */ | 3973 | */ |
3893 | static void | 3974 | static void |
3894 | megaraid_sysfs_free_resources(adapter_t *adapter) | 3975 | megaraid_sysfs_free_resources(adapter_t *adapter) |
@@ -3907,10 +3988,9 @@ megaraid_sysfs_free_resources(adapter_t *adapter) | |||
3907 | 3988 | ||
3908 | /** | 3989 | /** |
3909 | * megaraid_sysfs_get_ldmap_done - callback for get ldmap | 3990 | * megaraid_sysfs_get_ldmap_done - callback for get ldmap |
3991 | * @uioc : completed packet | ||
3910 | * | 3992 | * |
3911 | * Callback routine called in the ISR/tasklet context for get ldmap call | 3993 | * Callback routine called in the ISR/tasklet context for get ldmap call |
3912 | * | ||
3913 | * @param uioc : completed packet | ||
3914 | */ | 3994 | */ |
3915 | static void | 3995 | static void |
3916 | megaraid_sysfs_get_ldmap_done(uioc_t *uioc) | 3996 | megaraid_sysfs_get_ldmap_done(uioc_t *uioc) |
@@ -3926,12 +4006,11 @@ megaraid_sysfs_get_ldmap_done(uioc_t *uioc) | |||
3926 | 4006 | ||
3927 | /** | 4007 | /** |
3928 | * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap | 4008 | * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap |
4009 | * @data : timed out packet | ||
3929 | * | 4010 | * |
3930 | * Timeout routine to recover and return to application, in case the adapter | 4011 | * Timeout routine to recover and return to application, in case the adapter |
3931 | * has stopped responding. A timeout of 60 seconds for this command seem like | 4012 | * has stopped responding. A timeout of 60 seconds for this command seems like |
3932 | * a good value | 4013 | * a good value. |
3933 | * | ||
3934 | * @param uioc : timed out packet | ||
3935 | */ | 4014 | */ |
3936 | static void | 4015 | static void |
3937 | megaraid_sysfs_get_ldmap_timeout(unsigned long data) | 4016 | megaraid_sysfs_get_ldmap_timeout(unsigned long data) |
@@ -3948,6 +4027,7 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data) | |||
3948 | 4027 | ||
3949 | /** | 4028 | /** |
3950 | * megaraid_sysfs_get_ldmap - get update logical drive map | 4029 | * megaraid_sysfs_get_ldmap - get update logical drive map |
4030 | * @adapter : controller's soft state | ||
3951 | * | 4031 | * |
3952 | * This routine will be called whenever user reads the logical drive | 4032 | * This routine will be called whenever user reads the logical drive |
3953 | * attributes, go get the current logical drive mapping table from the | 4033 | * attributes, go get the current logical drive mapping table from the |
@@ -3959,10 +4039,8 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data) | |||
3959 | * standalone libary. For now, this should suffice since there is no other | 4039 | * standalone libary. For now, this should suffice since there is no other |
3960 | * user of this interface. | 4040 | * user of this interface. |
3961 | * | 4041 | * |
3962 | * @param adapter : controller's soft state | 4042 | * Return 0 on success. |
3963 | * | 4043 | * Return -1 on failure. |
3964 | * @return 0 on success | ||
3965 | * @return -1 on failure | ||
3966 | */ | 4044 | */ |
3967 | static int | 4045 | static int |
3968 | megaraid_sysfs_get_ldmap(adapter_t *adapter) | 4046 | megaraid_sysfs_get_ldmap(adapter_t *adapter) |
@@ -4064,13 +4142,12 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) | |||
4064 | 4142 | ||
4065 | /** | 4143 | /** |
4066 | * megaraid_sysfs_show_app_hndl - display application handle for this adapter | 4144 | * megaraid_sysfs_show_app_hndl - display application handle for this adapter |
4145 | * @cdev : class device object representation for the host | ||
4146 | * @buf : buffer to send data to | ||
4067 | * | 4147 | * |
4068 | * Display the handle used by the applications while executing management | 4148 | * Display the handle used by the applications while executing management |
4069 | * tasks on the adapter. We invoke a management module API to get the adapter | 4149 | * tasks on the adapter. We invoke a management module API to get the adapter |
4070 | * handle, since we do not interface with applications directly. | 4150 | * handle, since we do not interface with applications directly. |
4071 | * | ||
4072 | * @param cdev : class device object representation for the host | ||
4073 | * @param buf : buffer to send data to | ||
4074 | */ | 4151 | */ |
4075 | static ssize_t | 4152 | static ssize_t |
4076 | megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf) | 4153 | megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf) |
@@ -4087,16 +4164,18 @@ megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf) | |||
4087 | 4164 | ||
4088 | /** | 4165 | /** |
4089 | * megaraid_sysfs_show_ldnum - display the logical drive number for this device | 4166 | * megaraid_sysfs_show_ldnum - display the logical drive number for this device |
4167 | * @dev : device object representation for the scsi device | ||
4168 | * @attr : device attribute to show | ||
4169 | * @buf : buffer to send data to | ||
4090 | * | 4170 | * |
4091 | * Display the logical drive number for the device in question, if it a valid | 4171 | * Display the logical drive number for the device in question, if it a valid |
4092 | * logical drive. For physical devices, "-1" is returned | 4172 | * logical drive. For physical devices, "-1" is returned. |
4093 | * The logical drive number is displayed in following format | 4173 | * |
4174 | * The logical drive number is displayed in following format: | ||
4094 | * | 4175 | * |
4095 | * <SCSI ID> <LD NUM> <LD STICKY ID> <APP ADAPTER HANDLE> | 4176 | * <SCSI ID> <LD NUM> <LD STICKY ID> <APP ADAPTER HANDLE> |
4096 | * <int> <int> <int> <int> | ||
4097 | * | 4177 | * |
4098 | * @param dev : device object representation for the scsi device | 4178 | * <int> <int> <int> <int> |
4099 | * @param buf : buffer to send data to | ||
4100 | */ | 4179 | */ |
4101 | static ssize_t | 4180 | static ssize_t |
4102 | megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf) | 4181 | megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf) |
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h index 2b5a3285f799..9de803cebd4b 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.h +++ b/drivers/scsi/megaraid/megaraid_mbox.h | |||
@@ -21,8 +21,8 @@ | |||
21 | #include "megaraid_ioctl.h" | 21 | #include "megaraid_ioctl.h" |
22 | 22 | ||
23 | 23 | ||
24 | #define MEGARAID_VERSION "2.20.4.9" | 24 | #define MEGARAID_VERSION "2.20.5.1" |
25 | #define MEGARAID_EXT_VERSION "(Release Date: Sun Jul 16 12:27:22 EST 2006)" | 25 | #define MEGARAID_EXT_VERSION "(Release Date: Thu Nov 16 15:32:35 EST 2006)" |
26 | 26 | ||
27 | 27 | ||
28 | /* | 28 | /* |
@@ -146,27 +146,27 @@ typedef struct { | |||
146 | 146 | ||
147 | /** | 147 | /** |
148 | * mraid_device_t - adapter soft state structure for mailbox controllers | 148 | * mraid_device_t - adapter soft state structure for mailbox controllers |
149 | * @param una_mbox64 : 64-bit mbox - unaligned | 149 | * @una_mbox64 : 64-bit mbox - unaligned |
150 | * @param una_mbox64_dma : mbox dma addr - unaligned | 150 | * @una_mbox64_dma : mbox dma addr - unaligned |
151 | * @param mbox : 32-bit mbox - aligned | 151 | * @mbox : 32-bit mbox - aligned |
152 | * @param mbox64 : 64-bit mbox - aligned | 152 | * @mbox64 : 64-bit mbox - aligned |
153 | * @param mbox_dma : mbox dma addr - aligned | 153 | * @mbox_dma : mbox dma addr - aligned |
154 | * @param mailbox_lock : exclusion lock for the mailbox | 154 | * @mailbox_lock : exclusion lock for the mailbox |
155 | * @param baseport : base port of hba memory | 155 | * @baseport : base port of hba memory |
156 | * @param baseaddr : mapped addr of hba memory | 156 | * @baseaddr : mapped addr of hba memory |
157 | * @param mbox_pool : pool of mailboxes | 157 | * @mbox_pool : pool of mailboxes |
158 | * @param mbox_pool_handle : handle for the mailbox pool memory | 158 | * @mbox_pool_handle : handle for the mailbox pool memory |
159 | * @param epthru_pool : a pool for extended passthru commands | 159 | * @epthru_pool : a pool for extended passthru commands |
160 | * @param epthru_pool_handle : handle to the pool above | 160 | * @epthru_pool_handle : handle to the pool above |
161 | * @param sg_pool : pool of scatter-gather lists for this driver | 161 | * @sg_pool : pool of scatter-gather lists for this driver |
162 | * @param sg_pool_handle : handle to the pool above | 162 | * @sg_pool_handle : handle to the pool above |
163 | * @param ccb_list : list of our command control blocks | 163 | * @ccb_list : list of our command control blocks |
164 | * @param uccb_list : list of cmd control blocks for mgmt module | 164 | * @uccb_list : list of cmd control blocks for mgmt module |
165 | * @param umbox64 : array of mailbox for user commands (cmm) | 165 | * @umbox64 : array of mailbox for user commands (cmm) |
166 | * @param pdrv_state : array for state of each physical drive. | 166 | * @pdrv_state : array for state of each physical drive. |
167 | * @param last_disp : flag used to show device scanning | 167 | * @last_disp : flag used to show device scanning |
168 | * @param hw_error : set if FW not responding | 168 | * @hw_error : set if FW not responding |
169 | * @param fast_load : If set, skip physical device scanning | 169 | * @fast_load : If set, skip physical device scanning |
170 | * @channel_class : channel class, RAID or SCSI | 170 | * @channel_class : channel class, RAID or SCSI |
171 | * @sysfs_sem : semaphore to serialize access to sysfs res. | 171 | * @sysfs_sem : semaphore to serialize access to sysfs res. |
172 | * @sysfs_uioc : management packet to issue FW calls from sysfs | 172 | * @sysfs_uioc : management packet to issue FW calls from sysfs |
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index d85b9a8f1b8d..c1ff20c4747d 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c | |||
@@ -78,10 +78,10 @@ static struct file_operations lsi_fops = { | |||
78 | 78 | ||
79 | /** | 79 | /** |
80 | * mraid_mm_open - open routine for char node interface | 80 | * mraid_mm_open - open routine for char node interface |
81 | * @inod : unused | 81 | * @inode : unused |
82 | * @filep : unused | 82 | * @filep : unused |
83 | * | 83 | * |
84 | * allow ioctl operations by apps only if they superuser privilege | 84 | * Allow ioctl operations by apps only if they have superuser privilege. |
85 | */ | 85 | */ |
86 | static int | 86 | static int |
87 | mraid_mm_open(struct inode *inode, struct file *filep) | 87 | mraid_mm_open(struct inode *inode, struct file *filep) |
@@ -214,7 +214,9 @@ mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, | |||
214 | /** | 214 | /** |
215 | * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet | 215 | * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet |
216 | * @umimd : User space mimd_t ioctl packet | 216 | * @umimd : User space mimd_t ioctl packet |
217 | * @adapter : pointer to the adapter (OUT) | 217 | * @rval : returned success/error status |
218 | * | ||
219 | * The function return value is a pointer to the located @adapter. | ||
218 | */ | 220 | */ |
219 | static mraid_mmadp_t * | 221 | static mraid_mmadp_t * |
220 | mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) | 222 | mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) |
@@ -252,11 +254,11 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) | |||
252 | return adapter; | 254 | return adapter; |
253 | } | 255 | } |
254 | 256 | ||
255 | /* | 257 | /** |
256 | * handle_drvrcmd - This routine checks if the opcode is a driver | 258 | * handle_drvrcmd - Checks if the opcode is a driver cmd and if it is, handles it. |
257 | * cmd and if it is, handles it. | ||
258 | * @arg : packet sent by the user app | 259 | * @arg : packet sent by the user app |
259 | * @old_ioctl : mimd if 1; uioc otherwise | 260 | * @old_ioctl : mimd if 1; uioc otherwise |
261 | * @rval : pointer for command's returned value (not function status) | ||
260 | */ | 262 | */ |
261 | static int | 263 | static int |
262 | handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval) | 264 | handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval) |
@@ -322,8 +324,8 @@ old_packet: | |||
322 | 324 | ||
323 | /** | 325 | /** |
324 | * mimd_to_kioc - Converter from old to new ioctl format | 326 | * mimd_to_kioc - Converter from old to new ioctl format |
325 | * | ||
326 | * @umimd : user space old MIMD IOCTL | 327 | * @umimd : user space old MIMD IOCTL |
328 | * @adp : adapter softstate | ||
327 | * @kioc : kernel space new format IOCTL | 329 | * @kioc : kernel space new format IOCTL |
328 | * | 330 | * |
329 | * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The | 331 | * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The |
@@ -474,7 +476,6 @@ mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc) | |||
474 | 476 | ||
475 | /** | 477 | /** |
476 | * mraid_mm_attch_buf - Attach a free dma buffer for required size | 478 | * mraid_mm_attch_buf - Attach a free dma buffer for required size |
477 | * | ||
478 | * @adp : Adapter softstate | 479 | * @adp : Adapter softstate |
479 | * @kioc : kioc that the buffer needs to be attached to | 480 | * @kioc : kioc that the buffer needs to be attached to |
480 | * @xferlen : required length for buffer | 481 | * @xferlen : required length for buffer |
@@ -607,7 +608,6 @@ mraid_mm_alloc_kioc(mraid_mmadp_t *adp) | |||
607 | 608 | ||
608 | /** | 609 | /** |
609 | * mraid_mm_dealloc_kioc - Return kioc to free pool | 610 | * mraid_mm_dealloc_kioc - Return kioc to free pool |
610 | * | ||
611 | * @adp : Adapter softstate | 611 | * @adp : Adapter softstate |
612 | * @kioc : uioc_t node to be returned to free pool | 612 | * @kioc : uioc_t node to be returned to free pool |
613 | */ | 613 | */ |
@@ -652,7 +652,6 @@ mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc) | |||
652 | 652 | ||
653 | /** | 653 | /** |
654 | * lld_ioctl - Routine to issue ioctl to low level drvr | 654 | * lld_ioctl - Routine to issue ioctl to low level drvr |
655 | * | ||
656 | * @adp : The adapter handle | 655 | * @adp : The adapter handle |
657 | * @kioc : The ioctl packet with kernel addresses | 656 | * @kioc : The ioctl packet with kernel addresses |
658 | */ | 657 | */ |
@@ -705,7 +704,6 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc) | |||
705 | 704 | ||
706 | /** | 705 | /** |
707 | * ioctl_done - callback from the low level driver | 706 | * ioctl_done - callback from the low level driver |
708 | * | ||
709 | * @kioc : completed ioctl packet | 707 | * @kioc : completed ioctl packet |
710 | */ | 708 | */ |
711 | static void | 709 | static void |
@@ -756,9 +754,8 @@ ioctl_done(uioc_t *kioc) | |||
756 | } | 754 | } |
757 | 755 | ||
758 | 756 | ||
759 | /* | 757 | /** |
760 | * lld_timedout : callback from the expired timer | 758 | * lld_timedout - callback from the expired timer |
761 | * | ||
762 | * @ptr : ioctl packet that timed out | 759 | * @ptr : ioctl packet that timed out |
763 | */ | 760 | */ |
764 | static void | 761 | static void |
@@ -776,8 +773,7 @@ lld_timedout(unsigned long ptr) | |||
776 | 773 | ||
777 | 774 | ||
778 | /** | 775 | /** |
779 | * kioc_to_mimd : Converter from new back to old format | 776 | * kioc_to_mimd - Converter from new back to old format |
780 | * | ||
781 | * @kioc : Kernel space IOCTL packet (successfully issued) | 777 | * @kioc : Kernel space IOCTL packet (successfully issued) |
782 | * @mimd : User space MIMD packet | 778 | * @mimd : User space MIMD packet |
783 | */ | 779 | */ |
@@ -855,7 +851,6 @@ kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd) | |||
855 | 851 | ||
856 | /** | 852 | /** |
857 | * hinfo_to_cinfo - Convert new format hba info into old format | 853 | * hinfo_to_cinfo - Convert new format hba info into old format |
858 | * | ||
859 | * @hinfo : New format, more comprehensive adapter info | 854 | * @hinfo : New format, more comprehensive adapter info |
860 | * @cinfo : Old format adapter info to support mimd_t apps | 855 | * @cinfo : Old format adapter info to support mimd_t apps |
861 | */ | 856 | */ |
@@ -878,10 +873,9 @@ hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo) | |||
878 | } | 873 | } |
879 | 874 | ||
880 | 875 | ||
881 | /* | 876 | /** |
882 | * mraid_mm_register_adp - Registration routine for low level drvrs | 877 | * mraid_mm_register_adp - Registration routine for low level drivers |
883 | * | 878 | * @lld_adp : Adapter objejct |
884 | * @adp : Adapter objejct | ||
885 | */ | 879 | */ |
886 | int | 880 | int |
887 | mraid_mm_register_adp(mraid_mmadp_t *lld_adp) | 881 | mraid_mm_register_adp(mraid_mmadp_t *lld_adp) |
@@ -1007,15 +1001,14 @@ memalloc_error: | |||
1007 | 1001 | ||
1008 | /** | 1002 | /** |
1009 | * mraid_mm_adapter_app_handle - return the application handle for this adapter | 1003 | * mraid_mm_adapter_app_handle - return the application handle for this adapter |
1004 | * @unique_id : adapter unique identifier | ||
1010 | * | 1005 | * |
1011 | * For the given driver data, locate the adadpter in our global list and | 1006 | * For the given driver data, locate the adapter in our global list and |
1012 | * return the corresponding handle, which is also used by applications to | 1007 | * return the corresponding handle, which is also used by applications to |
1013 | * uniquely identify an adapter. | 1008 | * uniquely identify an adapter. |
1014 | * | 1009 | * |
1015 | * @param unique_id : adapter unique identifier | 1010 | * Return adapter handle if found in the list. |
1016 | * | 1011 | * Return 0 if adapter could not be located, should never happen though. |
1017 | * @return adapter handle if found in the list | ||
1018 | * @return 0 if adapter could not be located, should never happen though | ||
1019 | */ | 1012 | */ |
1020 | uint32_t | 1013 | uint32_t |
1021 | mraid_mm_adapter_app_handle(uint32_t unique_id) | 1014 | mraid_mm_adapter_app_handle(uint32_t unique_id) |
@@ -1040,7 +1033,6 @@ mraid_mm_adapter_app_handle(uint32_t unique_id) | |||
1040 | 1033 | ||
1041 | /** | 1034 | /** |
1042 | * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter | 1035 | * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter |
1043 | * | ||
1044 | * @adp : Adapter softstate | 1036 | * @adp : Adapter softstate |
1045 | * | 1037 | * |
1046 | * We maintain a pool of dma buffers per each adapter. Each pool has one | 1038 | * We maintain a pool of dma buffers per each adapter. Each pool has one |
@@ -1093,11 +1085,11 @@ dma_pool_setup_error: | |||
1093 | } | 1085 | } |
1094 | 1086 | ||
1095 | 1087 | ||
1096 | /* | 1088 | /** |
1097 | * mraid_mm_unregister_adp - Unregister routine for low level drivers | 1089 | * mraid_mm_unregister_adp - Unregister routine for low level drivers |
1098 | * Assume no outstanding ioctls to llds. | ||
1099 | * | ||
1100 | * @unique_id : UID of the adpater | 1090 | * @unique_id : UID of the adpater |
1091 | * | ||
1092 | * Assumes no outstanding ioctls to llds. | ||
1101 | */ | 1093 | */ |
1102 | int | 1094 | int |
1103 | mraid_mm_unregister_adp(uint32_t unique_id) | 1095 | mraid_mm_unregister_adp(uint32_t unique_id) |
@@ -1131,7 +1123,6 @@ mraid_mm_unregister_adp(uint32_t unique_id) | |||
1131 | 1123 | ||
1132 | /** | 1124 | /** |
1133 | * mraid_mm_free_adp_resources - Free adapter softstate | 1125 | * mraid_mm_free_adp_resources - Free adapter softstate |
1134 | * | ||
1135 | * @adp : Adapter softstate | 1126 | * @adp : Adapter softstate |
1136 | */ | 1127 | */ |
1137 | static void | 1128 | static void |
@@ -1162,7 +1153,6 @@ mraid_mm_free_adp_resources(mraid_mmadp_t *adp) | |||
1162 | 1153 | ||
1163 | /** | 1154 | /** |
1164 | * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers | 1155 | * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers |
1165 | * | ||
1166 | * @adp : Adapter softstate | 1156 | * @adp : Adapter softstate |
1167 | */ | 1157 | */ |
1168 | static void | 1158 | static void |
@@ -1190,7 +1180,7 @@ mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp) | |||
1190 | } | 1180 | } |
1191 | 1181 | ||
1192 | /** | 1182 | /** |
1193 | * mraid_mm_init : Module entry point | 1183 | * mraid_mm_init - Module entry point |
1194 | */ | 1184 | */ |
1195 | static int __init | 1185 | static int __init |
1196 | mraid_mm_init(void) | 1186 | mraid_mm_init(void) |
@@ -1214,10 +1204,13 @@ mraid_mm_init(void) | |||
1214 | } | 1204 | } |
1215 | 1205 | ||
1216 | 1206 | ||
1207 | #ifdef CONFIG_COMPAT | ||
1217 | /** | 1208 | /** |
1218 | * mraid_mm_compat_ioctl : 32bit to 64bit ioctl conversion routine | 1209 | * mraid_mm_compat_ioctl - 32bit to 64bit ioctl conversion routine |
1210 | * @filep : file operations pointer (ignored) | ||
1211 | * @cmd : ioctl command | ||
1212 | * @arg : user ioctl packet | ||
1219 | */ | 1213 | */ |
1220 | #ifdef CONFIG_COMPAT | ||
1221 | static long | 1214 | static long |
1222 | mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, | 1215 | mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, |
1223 | unsigned long arg) | 1216 | unsigned long arg) |
@@ -1231,7 +1224,7 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, | |||
1231 | #endif | 1224 | #endif |
1232 | 1225 | ||
1233 | /** | 1226 | /** |
1234 | * mraid_mm_exit : Module exit point | 1227 | * mraid_mm_exit - Module exit point |
1235 | */ | 1228 | */ |
1236 | static void __exit | 1229 | static void __exit |
1237 | mraid_mm_exit(void) | 1230 | mraid_mm_exit(void) |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 55eddcf8eb15..cacb3ad92527 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #ifndef LSI_MEGARAID_SAS_H | 15 | #ifndef LSI_MEGARAID_SAS_H |
16 | #define LSI_MEGARAID_SAS_H | 16 | #define LSI_MEGARAID_SAS_H |
17 | 17 | ||
18 | /** | 18 | /* |
19 | * MegaRAID SAS Driver meta data | 19 | * MegaRAID SAS Driver meta data |
20 | */ | 20 | */ |
21 | #define MEGASAS_VERSION "00.00.03.05" | 21 | #define MEGASAS_VERSION "00.00.03.05" |
@@ -40,7 +40,7 @@ | |||
40 | * "message frames" | 40 | * "message frames" |
41 | */ | 41 | */ |
42 | 42 | ||
43 | /** | 43 | /* |
44 | * FW posts its state in upper 4 bits of outbound_msg_0 register | 44 | * FW posts its state in upper 4 bits of outbound_msg_0 register |
45 | */ | 45 | */ |
46 | #define MFI_STATE_MASK 0xF0000000 | 46 | #define MFI_STATE_MASK 0xF0000000 |
@@ -58,7 +58,7 @@ | |||
58 | 58 | ||
59 | #define MEGAMFI_FRAME_SIZE 64 | 59 | #define MEGAMFI_FRAME_SIZE 64 |
60 | 60 | ||
61 | /** | 61 | /* |
62 | * During FW init, clear pending cmds & reset state using inbound_msg_0 | 62 | * During FW init, clear pending cmds & reset state using inbound_msg_0 |
63 | * | 63 | * |
64 | * ABORT : Abort all pending cmds | 64 | * ABORT : Abort all pending cmds |
@@ -78,7 +78,7 @@ | |||
78 | MFI_INIT_MFIMODE| \ | 78 | MFI_INIT_MFIMODE| \ |
79 | MFI_INIT_ABORT | 79 | MFI_INIT_ABORT |
80 | 80 | ||
81 | /** | 81 | /* |
82 | * MFI frame flags | 82 | * MFI frame flags |
83 | */ | 83 | */ |
84 | #define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000 | 84 | #define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000 |
@@ -92,12 +92,12 @@ | |||
92 | #define MFI_FRAME_DIR_READ 0x0010 | 92 | #define MFI_FRAME_DIR_READ 0x0010 |
93 | #define MFI_FRAME_DIR_BOTH 0x0018 | 93 | #define MFI_FRAME_DIR_BOTH 0x0018 |
94 | 94 | ||
95 | /** | 95 | /* |
96 | * Definition for cmd_status | 96 | * Definition for cmd_status |
97 | */ | 97 | */ |
98 | #define MFI_CMD_STATUS_POLL_MODE 0xFF | 98 | #define MFI_CMD_STATUS_POLL_MODE 0xFF |
99 | 99 | ||
100 | /** | 100 | /* |
101 | * MFI command opcodes | 101 | * MFI command opcodes |
102 | */ | 102 | */ |
103 | #define MFI_CMD_INIT 0x00 | 103 | #define MFI_CMD_INIT 0x00 |
@@ -128,7 +128,7 @@ | |||
128 | #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100 | 128 | #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100 |
129 | #define MR_DCMD_CLUSTER_RESET_LD 0x08010200 | 129 | #define MR_DCMD_CLUSTER_RESET_LD 0x08010200 |
130 | 130 | ||
131 | /** | 131 | /* |
132 | * MFI command completion codes | 132 | * MFI command completion codes |
133 | */ | 133 | */ |
134 | enum MFI_STAT { | 134 | enum MFI_STAT { |
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 625ca97da52d..9102cbdf1359 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -290,7 +290,6 @@ typedef struct _nsp_hw_data { | |||
290 | #endif | 290 | #endif |
291 | } nsp_hw_data; | 291 | } nsp_hw_data; |
292 | 292 | ||
293 | |||
294 | /**************************************************************************** | 293 | /**************************************************************************** |
295 | * | 294 | * |
296 | */ | 295 | */ |
@@ -302,22 +301,13 @@ static int nsp_cs_config (struct pcmcia_device *link); | |||
302 | 301 | ||
303 | /* Linux SCSI subsystem specific functions */ | 302 | /* Linux SCSI subsystem specific functions */ |
304 | static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); | 303 | static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); |
305 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) | ||
306 | static int nsp_detect_old (struct scsi_host_template *sht); | ||
307 | static int nsp_release_old(struct Scsi_Host *shpnt); | ||
308 | #endif | ||
309 | static const char *nsp_info (struct Scsi_Host *shpnt); | 304 | static const char *nsp_info (struct Scsi_Host *shpnt); |
310 | static int nsp_proc_info ( | 305 | static int nsp_proc_info ( |
311 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
312 | struct Scsi_Host *host, | 306 | struct Scsi_Host *host, |
313 | #endif | ||
314 | char *buffer, | 307 | char *buffer, |
315 | char **start, | 308 | char **start, |
316 | off_t offset, | 309 | off_t offset, |
317 | int length, | 310 | int length, |
318 | #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
319 | int hostno, | ||
320 | #endif | ||
321 | int inout); | 311 | int inout); |
322 | static int nsp_queuecommand(struct scsi_cmnd *SCpnt, | 312 | static int nsp_queuecommand(struct scsi_cmnd *SCpnt, |
323 | void (* done)(struct scsi_cmnd *SCpnt)); | 313 | void (* done)(struct scsi_cmnd *SCpnt)); |
@@ -356,7 +346,6 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); | |||
356 | static int __init nsp_cs_init(void); | 346 | static int __init nsp_cs_init(void); |
357 | static void __exit nsp_cs_exit(void); | 347 | static void __exit nsp_cs_exit(void); |
358 | 348 | ||
359 | |||
360 | /* Debug */ | 349 | /* Debug */ |
361 | #ifdef NSP_DEBUG | 350 | #ifdef NSP_DEBUG |
362 | static void show_command (struct scsi_cmnd *SCpnt); | 351 | static void show_command (struct scsi_cmnd *SCpnt); |
@@ -401,7 +390,6 @@ enum _burst_mode { | |||
401 | BURST_MEM32 = 2, | 390 | BURST_MEM32 = 2, |
402 | }; | 391 | }; |
403 | 392 | ||
404 | |||
405 | /************************************************************************** | 393 | /************************************************************************** |
406 | * SCSI messaage | 394 | * SCSI messaage |
407 | */ | 395 | */ |
@@ -413,62 +401,8 @@ enum _burst_mode { | |||
413 | 401 | ||
414 | #define MSG_EXT_SDTR 0x01 | 402 | #define MSG_EXT_SDTR 0x01 |
415 | 403 | ||
416 | |||
417 | /************************************************************************** | ||
418 | * Compatibility functions | ||
419 | */ | ||
420 | |||
421 | /* for Kernel 2.4 */ | ||
422 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) | ||
423 | # define scsi_register_host(template) scsi_register_module(MODULE_SCSI_HA, template) | ||
424 | # define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template) | ||
425 | # define scsi_host_put(host) scsi_unregister(host) | ||
426 | |||
427 | typedef void irqreturn_t; | ||
428 | # define IRQ_NONE /* */ | ||
429 | # define IRQ_HANDLED /* */ | ||
430 | # define IRQ_RETVAL(x) /* */ | ||
431 | |||
432 | /* This is ad-hoc version of scsi_host_get_next() */ | ||
433 | static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host) | ||
434 | { | ||
435 | if (host == NULL) { | ||
436 | return scsi_hostlist; | ||
437 | } else { | ||
438 | return host->next; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | /* This is ad-hoc version of scsi_host_hn_get() */ | ||
443 | static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno) | ||
444 | { | ||
445 | struct Scsi_Host *host; | ||
446 | |||
447 | for (host = scsi_host_get_next(NULL); host != NULL; | ||
448 | host = scsi_host_get_next(host)) { | ||
449 | if (host->host_no == hostno) { | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | |||
454 | return host; | ||
455 | } | ||
456 | |||
457 | static void cs_error(struct pcmcia_device *handle, int func, int ret) | ||
458 | { | ||
459 | error_info_t err = { func, ret }; | ||
460 | pcmcia_report_error(handle, &err); | ||
461 | } | ||
462 | |||
463 | /* scatter-gather table */ | ||
464 | # define BUFFER_ADDR (SCpnt->SCp.buffer->address) | ||
465 | #endif | ||
466 | |||
467 | /* for Kernel 2.6 */ | ||
468 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) | ||
469 | /* scatter-gather table */ | 404 | /* scatter-gather table */ |
470 | # define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset)) | 405 | # define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset)) |
471 | #endif | ||
472 | 406 | ||
473 | #endif /*__nsp_cs__*/ | 407 | #endif /*__nsp_cs__*/ |
474 | /* end */ | 408 | /* end */ |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 7b18a6c7b7eb..8081b637d97e 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -140,6 +140,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off, | |||
140 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); | 140 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); |
141 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 141 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
142 | 142 | ||
143 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
144 | |||
143 | return (count); | 145 | return (count); |
144 | } | 146 | } |
145 | 147 | ||
@@ -653,6 +655,43 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf, | |||
653 | return count; | 655 | return count; |
654 | } | 656 | } |
655 | 657 | ||
658 | static ssize_t | ||
659 | qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) | ||
660 | { | ||
661 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
662 | |||
663 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], | ||
664 | ha->bios_revision[0]); | ||
665 | } | ||
666 | |||
667 | static ssize_t | ||
668 | qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) | ||
669 | { | ||
670 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
671 | |||
672 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], | ||
673 | ha->efi_revision[0]); | ||
674 | } | ||
675 | |||
676 | static ssize_t | ||
677 | qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) | ||
678 | { | ||
679 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
680 | |||
681 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], | ||
682 | ha->fcode_revision[0]); | ||
683 | } | ||
684 | |||
685 | static ssize_t | ||
686 | qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf) | ||
687 | { | ||
688 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
689 | |||
690 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", | ||
691 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], | ||
692 | ha->fw_revision[3]); | ||
693 | } | ||
694 | |||
656 | static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, | 695 | static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, |
657 | NULL); | 696 | NULL); |
658 | static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); | 697 | static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
@@ -669,6 +708,14 @@ static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, | |||
669 | qla2x00_zio_timer_store); | 708 | qla2x00_zio_timer_store); |
670 | static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, | 709 | static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, |
671 | qla2x00_beacon_store); | 710 | qla2x00_beacon_store); |
711 | static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO, | ||
712 | qla2x00_optrom_bios_version_show, NULL); | ||
713 | static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO, | ||
714 | qla2x00_optrom_efi_version_show, NULL); | ||
715 | static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO, | ||
716 | qla2x00_optrom_fcode_version_show, NULL); | ||
717 | static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO, | ||
718 | qla2x00_optrom_fw_version_show, NULL); | ||
672 | 719 | ||
673 | struct class_device_attribute *qla2x00_host_attrs[] = { | 720 | struct class_device_attribute *qla2x00_host_attrs[] = { |
674 | &class_device_attr_driver_version, | 721 | &class_device_attr_driver_version, |
@@ -683,6 +730,10 @@ struct class_device_attribute *qla2x00_host_attrs[] = { | |||
683 | &class_device_attr_zio, | 730 | &class_device_attr_zio, |
684 | &class_device_attr_zio_timer, | 731 | &class_device_attr_zio_timer, |
685 | &class_device_attr_beacon, | 732 | &class_device_attr_beacon, |
733 | &class_device_attr_optrom_bios_version, | ||
734 | &class_device_attr_optrom_efi_version, | ||
735 | &class_device_attr_optrom_fcode_version, | ||
736 | &class_device_attr_optrom_fw_version, | ||
686 | NULL, | 737 | NULL, |
687 | }; | 738 | }; |
688 | 739 | ||
@@ -836,21 +887,24 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
836 | link_stat_t stat_buf; | 887 | link_stat_t stat_buf; |
837 | struct fc_host_statistics *pfc_host_stat; | 888 | struct fc_host_statistics *pfc_host_stat; |
838 | 889 | ||
890 | rval = QLA_FUNCTION_FAILED; | ||
839 | pfc_host_stat = &ha->fc_host_stat; | 891 | pfc_host_stat = &ha->fc_host_stat; |
840 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 892 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
841 | 893 | ||
842 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 894 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
843 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, | 895 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, |
844 | sizeof(stat_buf) / 4, mb_stat); | 896 | sizeof(stat_buf) / 4, mb_stat); |
845 | } else { | 897 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && |
898 | !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) && | ||
899 | !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) && | ||
900 | !ha->dpc_active) { | ||
901 | /* Must be in a 'READY' state for statistics retrieval. */ | ||
846 | rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, | 902 | rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, |
847 | mb_stat); | 903 | mb_stat); |
848 | } | 904 | } |
849 | if (rval != 0) { | 905 | |
850 | qla_printk(KERN_WARNING, ha, | 906 | if (rval != QLA_SUCCESS) |
851 | "Unable to retrieve host statistics (%d).\n", mb_stat[0]); | 907 | goto done; |
852 | return pfc_host_stat; | ||
853 | } | ||
854 | 908 | ||
855 | pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; | 909 | pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; |
856 | pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; | 910 | pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; |
@@ -858,7 +912,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
858 | pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; | 912 | pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; |
859 | pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; | 913 | pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; |
860 | pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; | 914 | pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; |
861 | 915 | done: | |
862 | return pfc_host_stat; | 916 | return pfc_host_stat; |
863 | } | 917 | } |
864 | 918 | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 2c10130d9e03..05f4f2a378eb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2045,6 +2045,29 @@ struct isp_operations { | |||
2045 | uint32_t, uint32_t); | 2045 | uint32_t, uint32_t); |
2046 | int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t, | 2046 | int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t, |
2047 | uint32_t); | 2047 | uint32_t); |
2048 | |||
2049 | int (*get_flash_version) (struct scsi_qla_host *, void *); | ||
2050 | }; | ||
2051 | |||
2052 | /* MSI-X Support *************************************************************/ | ||
2053 | |||
2054 | #define QLA_MSIX_CHIP_REV_24XX 3 | ||
2055 | #define QLA_MSIX_FW_MODE(m) (((m) & (BIT_7|BIT_8|BIT_9)) >> 7) | ||
2056 | #define QLA_MSIX_FW_MODE_1(m) (QLA_MSIX_FW_MODE(m) == 1) | ||
2057 | |||
2058 | #define QLA_MSIX_DEFAULT 0x00 | ||
2059 | #define QLA_MSIX_RSP_Q 0x01 | ||
2060 | |||
2061 | #define QLA_MSIX_ENTRIES 2 | ||
2062 | #define QLA_MIDX_DEFAULT 0 | ||
2063 | #define QLA_MIDX_RSP_Q 1 | ||
2064 | |||
2065 | struct scsi_qla_host; | ||
2066 | |||
2067 | struct qla_msix_entry { | ||
2068 | int have_irq; | ||
2069 | uint16_t msix_vector; | ||
2070 | uint16_t msix_entry; | ||
2048 | }; | 2071 | }; |
2049 | 2072 | ||
2050 | /* | 2073 | /* |
@@ -2077,6 +2100,7 @@ typedef struct scsi_qla_host { | |||
2077 | uint32_t enable_lip_full_login :1; | 2100 | uint32_t enable_lip_full_login :1; |
2078 | uint32_t enable_target_reset :1; | 2101 | uint32_t enable_target_reset :1; |
2079 | uint32_t enable_led_scheme :1; | 2102 | uint32_t enable_led_scheme :1; |
2103 | uint32_t inta_enabled :1; | ||
2080 | uint32_t msi_enabled :1; | 2104 | uint32_t msi_enabled :1; |
2081 | uint32_t msix_enabled :1; | 2105 | uint32_t msix_enabled :1; |
2082 | uint32_t disable_serdes :1; | 2106 | uint32_t disable_serdes :1; |
@@ -2316,8 +2340,6 @@ typedef struct scsi_qla_host { | |||
2316 | #define MBX_INTR_WAIT 2 | 2340 | #define MBX_INTR_WAIT 2 |
2317 | #define MBX_UPDATE_FLASH_ACTIVE 3 | 2341 | #define MBX_UPDATE_FLASH_ACTIVE 3 |
2318 | 2342 | ||
2319 | spinlock_t mbx_reg_lock; /* Mbx Cmd Register Lock */ | ||
2320 | |||
2321 | struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ | 2343 | struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ |
2322 | struct semaphore mbx_intr_sem; /* Used for completion notification */ | 2344 | struct semaphore mbx_intr_sem; /* Used for completion notification */ |
2323 | 2345 | ||
@@ -2358,6 +2380,7 @@ typedef struct scsi_qla_host { | |||
2358 | 2380 | ||
2359 | uint8_t host_str[16]; | 2381 | uint8_t host_str[16]; |
2360 | uint32_t pci_attr; | 2382 | uint32_t pci_attr; |
2383 | uint16_t chip_revision; | ||
2361 | 2384 | ||
2362 | uint16_t product_id[4]; | 2385 | uint16_t product_id[4]; |
2363 | 2386 | ||
@@ -2379,6 +2402,15 @@ typedef struct scsi_qla_host { | |||
2379 | #define QLA_SREADING 1 | 2402 | #define QLA_SREADING 1 |
2380 | #define QLA_SWRITING 2 | 2403 | #define QLA_SWRITING 2 |
2381 | 2404 | ||
2405 | /* PCI expansion ROM image information. */ | ||
2406 | #define ROM_CODE_TYPE_BIOS 0 | ||
2407 | #define ROM_CODE_TYPE_FCODE 1 | ||
2408 | #define ROM_CODE_TYPE_EFI 3 | ||
2409 | uint8_t bios_revision[2]; | ||
2410 | uint8_t efi_revision[2]; | ||
2411 | uint8_t fcode_revision[16]; | ||
2412 | uint32_t fw_revision[4]; | ||
2413 | |||
2382 | /* Needed for BEACON */ | 2414 | /* Needed for BEACON */ |
2383 | uint16_t beacon_blink_led; | 2415 | uint16_t beacon_blink_led; |
2384 | uint8_t beacon_color_state; | 2416 | uint8_t beacon_color_state; |
@@ -2391,6 +2423,8 @@ typedef struct scsi_qla_host { | |||
2391 | uint16_t zio_mode; | 2423 | uint16_t zio_mode; |
2392 | uint16_t zio_timer; | 2424 | uint16_t zio_timer; |
2393 | struct fc_host_statistics fc_host_stat; | 2425 | struct fc_host_statistics fc_host_stat; |
2426 | |||
2427 | struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES]; | ||
2394 | } scsi_qla_host_t; | 2428 | } scsi_qla_host_t; |
2395 | 2429 | ||
2396 | 2430 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e4dd12f4b80e..74544ae4b0e2 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -224,6 +224,9 @@ extern irqreturn_t qla24xx_intr_handler(int, void *); | |||
224 | extern void qla2x00_process_response_queue(struct scsi_qla_host *); | 224 | extern void qla2x00_process_response_queue(struct scsi_qla_host *); |
225 | extern void qla24xx_process_response_queue(struct scsi_qla_host *); | 225 | extern void qla24xx_process_response_queue(struct scsi_qla_host *); |
226 | 226 | ||
227 | extern int qla2x00_request_irqs(scsi_qla_host_t *); | ||
228 | extern void qla2x00_free_irqs(scsi_qla_host_t *); | ||
229 | |||
227 | /* | 230 | /* |
228 | * Global Function Prototypes in qla_sup.c source file. | 231 | * Global Function Prototypes in qla_sup.c source file. |
229 | */ | 232 | */ |
@@ -259,6 +262,9 @@ extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
259 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 262 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, |
260 | uint32_t, uint32_t); | 263 | uint32_t, uint32_t); |
261 | 264 | ||
265 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | ||
266 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | ||
267 | |||
262 | /* | 268 | /* |
263 | * Global Function Prototypes in qla_dbg.c source file. | 269 | * Global Function Prototypes in qla_dbg.c source file. |
264 | */ | 270 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b3dac26ddba3..98c01cd5e1a8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -65,7 +65,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
65 | ha->flags.reset_active = 0; | 65 | ha->flags.reset_active = 0; |
66 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 66 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); |
67 | atomic_set(&ha->loop_state, LOOP_DOWN); | 67 | atomic_set(&ha->loop_state, LOOP_DOWN); |
68 | ha->device_flags = 0; | 68 | ha->device_flags = DFLG_NO_CABLE; |
69 | ha->dpc_flags = 0; | 69 | ha->dpc_flags = 0; |
70 | ha->flags.management_server_logged_in = 0; | 70 | ha->flags.management_server_logged_in = 0; |
71 | ha->marker_needed = 0; | 71 | ha->marker_needed = 0; |
@@ -77,16 +77,23 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
77 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); | 77 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); |
78 | rval = ha->isp_ops.pci_config(ha); | 78 | rval = ha->isp_ops.pci_config(ha); |
79 | if (rval) { | 79 | if (rval) { |
80 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space=n", | 80 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n", |
81 | ha->host_no)); | 81 | ha->host_no)); |
82 | return (rval); | 82 | return (rval); |
83 | } | 83 | } |
84 | 84 | ||
85 | ha->isp_ops.reset_chip(ha); | 85 | ha->isp_ops.reset_chip(ha); |
86 | 86 | ||
87 | ha->isp_ops.get_flash_version(ha, ha->request_ring); | ||
88 | |||
87 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); | 89 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); |
88 | 90 | ||
89 | ha->isp_ops.nvram_config(ha); | 91 | rval = ha->isp_ops.nvram_config(ha); |
92 | if (rval) { | ||
93 | DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n", | ||
94 | ha->host_no)); | ||
95 | return rval; | ||
96 | } | ||
90 | 97 | ||
91 | if (ha->flags.disable_serdes) { | 98 | if (ha->flags.disable_serdes) { |
92 | /* Mask HBA via NVRAM settings? */ | 99 | /* Mask HBA via NVRAM settings? */ |
@@ -293,6 +300,8 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
293 | d &= ~PCI_ROM_ADDRESS_ENABLE; | 300 | d &= ~PCI_ROM_ADDRESS_ENABLE; |
294 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | 301 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); |
295 | 302 | ||
303 | pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->chip_revision); | ||
304 | |||
296 | /* Get PCI bus information. */ | 305 | /* Get PCI bus information. */ |
297 | spin_lock_irqsave(&ha->hardware_lock, flags); | 306 | spin_lock_irqsave(&ha->hardware_lock, flags); |
298 | ha->pci_attr = RD_REG_DWORD(®->ctrl_status); | 307 | ha->pci_attr = RD_REG_DWORD(®->ctrl_status); |
@@ -1351,6 +1360,39 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) | |||
1351 | return(rval); | 1360 | return(rval); |
1352 | } | 1361 | } |
1353 | 1362 | ||
1363 | static inline void | ||
1364 | qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *def) | ||
1365 | { | ||
1366 | char *st, *en; | ||
1367 | uint16_t index; | ||
1368 | |||
1369 | if (memcmp(model, BINZERO, len) != 0) { | ||
1370 | strncpy(ha->model_number, model, len); | ||
1371 | st = en = ha->model_number; | ||
1372 | en += len - 1; | ||
1373 | while (en > st) { | ||
1374 | if (*en != 0x20 && *en != 0x00) | ||
1375 | break; | ||
1376 | *en-- = '\0'; | ||
1377 | } | ||
1378 | |||
1379 | index = (ha->pdev->subsystem_device & 0xff); | ||
1380 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1381 | index < QLA_MODEL_NAMES) | ||
1382 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
1383 | } else { | ||
1384 | index = (ha->pdev->subsystem_device & 0xff); | ||
1385 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | ||
1386 | index < QLA_MODEL_NAMES) { | ||
1387 | strcpy(ha->model_number, | ||
1388 | qla2x00_model_name[index * 2]); | ||
1389 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
1390 | } else { | ||
1391 | strcpy(ha->model_number, def); | ||
1392 | } | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1354 | /* | 1396 | /* |
1355 | * NVRAM configuration for ISP 2xxx | 1397 | * NVRAM configuration for ISP 2xxx |
1356 | * | 1398 | * |
@@ -1367,7 +1409,6 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) | |||
1367 | int | 1409 | int |
1368 | qla2x00_nvram_config(scsi_qla_host_t *ha) | 1410 | qla2x00_nvram_config(scsi_qla_host_t *ha) |
1369 | { | 1411 | { |
1370 | int rval; | ||
1371 | uint8_t chksum = 0; | 1412 | uint8_t chksum = 0; |
1372 | uint16_t cnt; | 1413 | uint16_t cnt; |
1373 | uint8_t *dptr1, *dptr2; | 1414 | uint8_t *dptr1, *dptr2; |
@@ -1376,8 +1417,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1376 | uint8_t *ptr = (uint8_t *)ha->request_ring; | 1417 | uint8_t *ptr = (uint8_t *)ha->request_ring; |
1377 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 1418 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1378 | 1419 | ||
1379 | rval = QLA_SUCCESS; | ||
1380 | |||
1381 | /* Determine NVRAM starting address. */ | 1420 | /* Determine NVRAM starting address. */ |
1382 | ha->nvram_size = sizeof(nvram_t); | 1421 | ha->nvram_size = sizeof(nvram_t); |
1383 | ha->nvram_base = 0; | 1422 | ha->nvram_base = 0; |
@@ -1401,55 +1440,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1401 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " | 1440 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " |
1402 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], | 1441 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], |
1403 | nv->nvram_version); | 1442 | nv->nvram_version); |
1404 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 1443 | return QLA_FUNCTION_FAILED; |
1405 | "invalid -- WWPN) defaults.\n"); | ||
1406 | |||
1407 | /* | ||
1408 | * Set default initialization control block. | ||
1409 | */ | ||
1410 | memset(nv, 0, ha->nvram_size); | ||
1411 | nv->parameter_block_version = ICB_VERSION; | ||
1412 | |||
1413 | if (IS_QLA23XX(ha)) { | ||
1414 | nv->firmware_options[0] = BIT_2 | BIT_1; | ||
1415 | nv->firmware_options[1] = BIT_7 | BIT_5; | ||
1416 | nv->add_firmware_options[0] = BIT_5; | ||
1417 | nv->add_firmware_options[1] = BIT_5 | BIT_4; | ||
1418 | nv->frame_payload_size = __constant_cpu_to_le16(2048); | ||
1419 | nv->special_options[1] = BIT_7; | ||
1420 | } else if (IS_QLA2200(ha)) { | ||
1421 | nv->firmware_options[0] = BIT_2 | BIT_1; | ||
1422 | nv->firmware_options[1] = BIT_7 | BIT_5; | ||
1423 | nv->add_firmware_options[0] = BIT_5; | ||
1424 | nv->add_firmware_options[1] = BIT_5 | BIT_4; | ||
1425 | nv->frame_payload_size = __constant_cpu_to_le16(1024); | ||
1426 | } else if (IS_QLA2100(ha)) { | ||
1427 | nv->firmware_options[0] = BIT_3 | BIT_1; | ||
1428 | nv->firmware_options[1] = BIT_5; | ||
1429 | nv->frame_payload_size = __constant_cpu_to_le16(1024); | ||
1430 | } | ||
1431 | |||
1432 | nv->max_iocb_allocation = __constant_cpu_to_le16(256); | ||
1433 | nv->execution_throttle = __constant_cpu_to_le16(16); | ||
1434 | nv->retry_count = 8; | ||
1435 | nv->retry_delay = 1; | ||
1436 | |||
1437 | nv->port_name[0] = 33; | ||
1438 | nv->port_name[3] = 224; | ||
1439 | nv->port_name[4] = 139; | ||
1440 | |||
1441 | nv->login_timeout = 4; | ||
1442 | |||
1443 | /* | ||
1444 | * Set default host adapter parameters | ||
1445 | */ | ||
1446 | nv->host_p[1] = BIT_2; | ||
1447 | nv->reset_delay = 5; | ||
1448 | nv->port_down_retry_count = 8; | ||
1449 | nv->max_luns_per_target = __constant_cpu_to_le16(8); | ||
1450 | nv->link_down_timeout = 60; | ||
1451 | |||
1452 | rval = 1; | ||
1453 | } | 1444 | } |
1454 | 1445 | ||
1455 | #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) | 1446 | #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) |
@@ -1489,33 +1480,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1489 | strcpy(ha->model_number, "QLA2300"); | 1480 | strcpy(ha->model_number, "QLA2300"); |
1490 | } | 1481 | } |
1491 | } else { | 1482 | } else { |
1492 | if (rval == 0 && | 1483 | qla2x00_set_model_info(ha, nv->model_number, |
1493 | memcmp(nv->model_number, BINZERO, | 1484 | sizeof(nv->model_number), "QLA23xx"); |
1494 | sizeof(nv->model_number)) != 0) { | ||
1495 | char *st, *en; | ||
1496 | |||
1497 | strncpy(ha->model_number, nv->model_number, | ||
1498 | sizeof(nv->model_number)); | ||
1499 | st = en = ha->model_number; | ||
1500 | en += sizeof(nv->model_number) - 1; | ||
1501 | while (en > st) { | ||
1502 | if (*en != 0x20 && *en != 0x00) | ||
1503 | break; | ||
1504 | *en-- = '\0'; | ||
1505 | } | ||
1506 | } else { | ||
1507 | uint16_t index; | ||
1508 | |||
1509 | index = (ha->pdev->subsystem_device & 0xff); | ||
1510 | if (index < QLA_MODEL_NAMES) { | ||
1511 | strcpy(ha->model_number, | ||
1512 | qla2x00_model_name[index * 2]); | ||
1513 | ha->model_desc = | ||
1514 | qla2x00_model_name[index * 2 + 1]; | ||
1515 | } else { | ||
1516 | strcpy(ha->model_number, "QLA23xx"); | ||
1517 | } | ||
1518 | } | ||
1519 | } | 1485 | } |
1520 | } else if (IS_QLA2200(ha)) { | 1486 | } else if (IS_QLA2200(ha)) { |
1521 | nv->firmware_options[0] |= BIT_2; | 1487 | nv->firmware_options[0] |= BIT_2; |
@@ -1687,11 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1687 | } | 1653 | } |
1688 | } | 1654 | } |
1689 | 1655 | ||
1690 | if (rval) { | 1656 | return QLA_SUCCESS; |
1691 | DEBUG2_3(printk(KERN_WARNING | ||
1692 | "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); | ||
1693 | } | ||
1694 | return (rval); | ||
1695 | } | 1657 | } |
1696 | 1658 | ||
1697 | static void | 1659 | static void |
@@ -3107,7 +3069,11 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3107 | } | 3069 | } |
3108 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3070 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3109 | 3071 | ||
3110 | ha->isp_ops.nvram_config(ha); | 3072 | ha->isp_ops.get_flash_version(ha, ha->request_ring); |
3073 | |||
3074 | rval = ha->isp_ops.nvram_config(ha); | ||
3075 | if (rval) | ||
3076 | goto isp_abort_retry; | ||
3111 | 3077 | ||
3112 | if (!qla2x00_restart_isp(ha)) { | 3078 | if (!qla2x00_restart_isp(ha)) { |
3113 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3079 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
@@ -3137,6 +3103,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3137 | } | 3103 | } |
3138 | } | 3104 | } |
3139 | } else { /* failed the ISP abort */ | 3105 | } else { /* failed the ISP abort */ |
3106 | isp_abort_retry: | ||
3140 | ha->flags.online = 1; | 3107 | ha->flags.online = 1; |
3141 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { | 3108 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { |
3142 | if (ha->isp_abort_cnt == 0) { | 3109 | if (ha->isp_abort_cnt == 0) { |
@@ -3326,7 +3293,6 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) | |||
3326 | int | 3293 | int |
3327 | qla24xx_nvram_config(scsi_qla_host_t *ha) | 3294 | qla24xx_nvram_config(scsi_qla_host_t *ha) |
3328 | { | 3295 | { |
3329 | int rval; | ||
3330 | struct init_cb_24xx *icb; | 3296 | struct init_cb_24xx *icb; |
3331 | struct nvram_24xx *nv; | 3297 | struct nvram_24xx *nv; |
3332 | uint32_t *dptr; | 3298 | uint32_t *dptr; |
@@ -3334,7 +3300,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3334 | uint32_t chksum; | 3300 | uint32_t chksum; |
3335 | uint16_t cnt; | 3301 | uint16_t cnt; |
3336 | 3302 | ||
3337 | rval = QLA_SUCCESS; | ||
3338 | icb = (struct init_cb_24xx *)ha->init_cb; | 3303 | icb = (struct init_cb_24xx *)ha->init_cb; |
3339 | nv = (struct nvram_24xx *)ha->request_ring; | 3304 | nv = (struct nvram_24xx *)ha->request_ring; |
3340 | 3305 | ||
@@ -3367,51 +3332,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3367 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " | 3332 | qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " |
3368 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], | 3333 | "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], |
3369 | le16_to_cpu(nv->nvram_version)); | 3334 | le16_to_cpu(nv->nvram_version)); |
3370 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 3335 | return QLA_FUNCTION_FAILED; |
3371 | "invalid -- WWPN) defaults.\n"); | ||
3372 | |||
3373 | /* | ||
3374 | * Set default initialization control block. | ||
3375 | */ | ||
3376 | memset(nv, 0, ha->nvram_size); | ||
3377 | nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION); | ||
3378 | nv->version = __constant_cpu_to_le16(ICB_VERSION); | ||
3379 | nv->frame_payload_size = __constant_cpu_to_le16(2048); | ||
3380 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); | ||
3381 | nv->exchange_count = __constant_cpu_to_le16(0); | ||
3382 | nv->hard_address = __constant_cpu_to_le16(124); | ||
3383 | nv->port_name[0] = 0x21; | ||
3384 | nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); | ||
3385 | nv->port_name[2] = 0x00; | ||
3386 | nv->port_name[3] = 0xe0; | ||
3387 | nv->port_name[4] = 0x8b; | ||
3388 | nv->port_name[5] = 0x1c; | ||
3389 | nv->port_name[6] = 0x55; | ||
3390 | nv->port_name[7] = 0x86; | ||
3391 | nv->node_name[0] = 0x20; | ||
3392 | nv->node_name[1] = 0x00; | ||
3393 | nv->node_name[2] = 0x00; | ||
3394 | nv->node_name[3] = 0xe0; | ||
3395 | nv->node_name[4] = 0x8b; | ||
3396 | nv->node_name[5] = 0x1c; | ||
3397 | nv->node_name[6] = 0x55; | ||
3398 | nv->node_name[7] = 0x86; | ||
3399 | nv->login_retry_count = __constant_cpu_to_le16(8); | ||
3400 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); | ||
3401 | nv->login_timeout = __constant_cpu_to_le16(0); | ||
3402 | nv->firmware_options_1 = | ||
3403 | __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1); | ||
3404 | nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4); | ||
3405 | nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); | ||
3406 | nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13); | ||
3407 | nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10); | ||
3408 | nv->efi_parameters = __constant_cpu_to_le32(0); | ||
3409 | nv->reset_delay = 5; | ||
3410 | nv->max_luns_per_target = __constant_cpu_to_le16(128); | ||
3411 | nv->port_down_retry_count = __constant_cpu_to_le16(30); | ||
3412 | nv->link_down_timeout = __constant_cpu_to_le16(30); | ||
3413 | |||
3414 | rval = 1; | ||
3415 | } | 3336 | } |
3416 | 3337 | ||
3417 | /* Reset Initialization control block */ | 3338 | /* Reset Initialization control block */ |
@@ -3438,25 +3359,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3438 | /* | 3359 | /* |
3439 | * Setup driver NVRAM options. | 3360 | * Setup driver NVRAM options. |
3440 | */ | 3361 | */ |
3441 | if (memcmp(nv->model_name, BINZERO, sizeof(nv->model_name)) != 0) { | 3362 | qla2x00_set_model_info(ha, nv->model_name, sizeof(nv->model_name), |
3442 | char *st, *en; | 3363 | "QLA2462"); |
3443 | uint16_t index; | ||
3444 | |||
3445 | strncpy(ha->model_number, nv->model_name, | ||
3446 | sizeof(nv->model_name)); | ||
3447 | st = en = ha->model_number; | ||
3448 | en += sizeof(nv->model_name) - 1; | ||
3449 | while (en > st) { | ||
3450 | if (*en != 0x20 && *en != 0x00) | ||
3451 | break; | ||
3452 | *en-- = '\0'; | ||
3453 | } | ||
3454 | |||
3455 | index = (ha->pdev->subsystem_device & 0xff); | ||
3456 | if (index < QLA_MODEL_NAMES) | ||
3457 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | ||
3458 | } else | ||
3459 | strcpy(ha->model_number, "QLA2462"); | ||
3460 | 3364 | ||
3461 | /* Use alternate WWN? */ | 3365 | /* Use alternate WWN? */ |
3462 | if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { | 3366 | if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { |
@@ -3575,11 +3479,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3575 | ha->flags.process_response_queue = 1; | 3479 | ha->flags.process_response_queue = 1; |
3576 | } | 3480 | } |
3577 | 3481 | ||
3578 | if (rval) { | 3482 | return QLA_SUCCESS; |
3579 | DEBUG2_3(printk(KERN_WARNING | ||
3580 | "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); | ||
3581 | } | ||
3582 | return (rval); | ||
3583 | } | 3483 | } |
3584 | 3484 | ||
3585 | static int | 3485 | static int |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 39fd17b05be5..d4885616cd39 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -86,12 +86,8 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
86 | 86 | ||
87 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 87 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
88 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 88 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
89 | spin_lock_irqsave(&ha->mbx_reg_lock, flags); | ||
90 | |||
91 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 89 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
92 | up(&ha->mbx_intr_sem); | 90 | up(&ha->mbx_intr_sem); |
93 | |||
94 | spin_unlock_irqrestore(&ha->mbx_reg_lock, flags); | ||
95 | } | 91 | } |
96 | 92 | ||
97 | return (IRQ_HANDLED); | 93 | return (IRQ_HANDLED); |
@@ -199,12 +195,8 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
199 | 195 | ||
200 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 196 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
201 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 197 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
202 | spin_lock_irqsave(&ha->mbx_reg_lock, flags); | ||
203 | |||
204 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 198 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
205 | up(&ha->mbx_intr_sem); | 199 | up(&ha->mbx_intr_sem); |
206 | |||
207 | spin_unlock_irqrestore(&ha->mbx_reg_lock, flags); | ||
208 | } | 200 | } |
209 | 201 | ||
210 | return (IRQ_HANDLED); | 202 | return (IRQ_HANDLED); |
@@ -654,10 +646,8 @@ qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) | |||
654 | fcport->last_queue_full + ql2xqfullrampup * HZ)) | 646 | fcport->last_queue_full + ql2xqfullrampup * HZ)) |
655 | return; | 647 | return; |
656 | 648 | ||
657 | spin_unlock_irq(&ha->hardware_lock); | ||
658 | starget_for_each_device(sdev->sdev_target, fcport, | 649 | starget_for_each_device(sdev->sdev_target, fcport, |
659 | qla2x00_adjust_sdev_qdepth_up); | 650 | qla2x00_adjust_sdev_qdepth_up); |
660 | spin_lock_irq(&ha->hardware_lock); | ||
661 | } | 651 | } |
662 | 652 | ||
663 | /** | 653 | /** |
@@ -927,10 +917,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
927 | 917 | ||
928 | /* Adjust queue depth for all luns on the port. */ | 918 | /* Adjust queue depth for all luns on the port. */ |
929 | fcport->last_queue_full = jiffies; | 919 | fcport->last_queue_full = jiffies; |
930 | spin_unlock_irq(&ha->hardware_lock); | ||
931 | starget_for_each_device(cp->device->sdev_target, | 920 | starget_for_each_device(cp->device->sdev_target, |
932 | fcport, qla2x00_adjust_sdev_qdepth_down); | 921 | fcport, qla2x00_adjust_sdev_qdepth_down); |
933 | spin_lock_irq(&ha->hardware_lock); | ||
934 | break; | 922 | break; |
935 | } | 923 | } |
936 | if (lscsi_status != SS_CHECK_CONDITION) | 924 | if (lscsi_status != SS_CHECK_CONDITION) |
@@ -995,6 +983,22 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
995 | if (lscsi_status != 0) { | 983 | if (lscsi_status != 0) { |
996 | cp->result = DID_OK << 16 | lscsi_status; | 984 | cp->result = DID_OK << 16 | lscsi_status; |
997 | 985 | ||
986 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { | ||
987 | DEBUG2(printk(KERN_INFO | ||
988 | "scsi(%ld): QUEUE FULL status detected " | ||
989 | "0x%x-0x%x.\n", ha->host_no, comp_status, | ||
990 | scsi_status)); | ||
991 | |||
992 | /* | ||
993 | * Adjust queue depth for all luns on the | ||
994 | * port. | ||
995 | */ | ||
996 | fcport->last_queue_full = jiffies; | ||
997 | starget_for_each_device( | ||
998 | cp->device->sdev_target, fcport, | ||
999 | qla2x00_adjust_sdev_qdepth_down); | ||
1000 | break; | ||
1001 | } | ||
998 | if (lscsi_status != SS_CHECK_CONDITION) | 1002 | if (lscsi_status != SS_CHECK_CONDITION) |
999 | break; | 1003 | break; |
1000 | 1004 | ||
@@ -1482,12 +1486,8 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1482 | 1486 | ||
1483 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1487 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1484 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1488 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
1485 | spin_lock_irqsave(&ha->mbx_reg_lock, flags); | ||
1486 | |||
1487 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 1489 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
1488 | up(&ha->mbx_intr_sem); | 1490 | up(&ha->mbx_intr_sem); |
1489 | |||
1490 | spin_unlock_irqrestore(&ha->mbx_reg_lock, flags); | ||
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | return IRQ_HANDLED; | 1493 | return IRQ_HANDLED; |
@@ -1536,3 +1536,216 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | |||
1536 | qla2x00_sp_compl(ha, sp); | 1536 | qla2x00_sp_compl(ha, sp); |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | static irqreturn_t | ||
1540 | qla24xx_msix_rsp_q(int irq, void *dev_id) | ||
1541 | { | ||
1542 | scsi_qla_host_t *ha; | ||
1543 | struct device_reg_24xx __iomem *reg; | ||
1544 | unsigned long flags; | ||
1545 | |||
1546 | ha = dev_id; | ||
1547 | reg = &ha->iobase->isp24; | ||
1548 | |||
1549 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1550 | |||
1551 | qla24xx_process_response_queue(ha); | ||
1552 | |||
1553 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1554 | RD_REG_DWORD_RELAXED(®->hccr); | ||
1555 | |||
1556 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1557 | |||
1558 | return IRQ_HANDLED; | ||
1559 | } | ||
1560 | |||
1561 | static irqreturn_t | ||
1562 | qla24xx_msix_default(int irq, void *dev_id) | ||
1563 | { | ||
1564 | scsi_qla_host_t *ha; | ||
1565 | struct device_reg_24xx __iomem *reg; | ||
1566 | int status; | ||
1567 | unsigned long flags; | ||
1568 | unsigned long iter; | ||
1569 | uint32_t stat; | ||
1570 | uint32_t hccr; | ||
1571 | uint16_t mb[4]; | ||
1572 | |||
1573 | ha = dev_id; | ||
1574 | reg = &ha->iobase->isp24; | ||
1575 | status = 0; | ||
1576 | |||
1577 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1578 | for (iter = 50; iter--; ) { | ||
1579 | stat = RD_REG_DWORD(®->host_status); | ||
1580 | if (stat & HSRX_RISC_PAUSED) { | ||
1581 | hccr = RD_REG_DWORD(®->hccr); | ||
1582 | |||
1583 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | ||
1584 | "Dumping firmware!\n", hccr); | ||
1585 | ha->isp_ops.fw_dump(ha, 1); | ||
1586 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1587 | break; | ||
1588 | } else if ((stat & HSRX_RISC_INT) == 0) | ||
1589 | break; | ||
1590 | |||
1591 | switch (stat & 0xff) { | ||
1592 | case 0x1: | ||
1593 | case 0x2: | ||
1594 | case 0x10: | ||
1595 | case 0x11: | ||
1596 | qla24xx_mbx_completion(ha, MSW(stat)); | ||
1597 | status |= MBX_INTERRUPT; | ||
1598 | |||
1599 | break; | ||
1600 | case 0x12: | ||
1601 | mb[0] = MSW(stat); | ||
1602 | mb[1] = RD_REG_WORD(®->mailbox1); | ||
1603 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
1604 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
1605 | qla2x00_async_event(ha, mb); | ||
1606 | break; | ||
1607 | case 0x13: | ||
1608 | qla24xx_process_response_queue(ha); | ||
1609 | break; | ||
1610 | default: | ||
1611 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | ||
1612 | "(%d).\n", | ||
1613 | ha->host_no, stat & 0xff)); | ||
1614 | break; | ||
1615 | } | ||
1616 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1617 | RD_REG_DWORD_RELAXED(®->hccr); | ||
1618 | } | ||
1619 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1620 | |||
1621 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | ||
1622 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | ||
1623 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
1624 | up(&ha->mbx_intr_sem); | ||
1625 | } | ||
1626 | |||
1627 | return IRQ_HANDLED; | ||
1628 | } | ||
1629 | |||
1630 | /* Interrupt handling helpers. */ | ||
1631 | |||
1632 | struct qla_init_msix_entry { | ||
1633 | uint16_t entry; | ||
1634 | uint16_t index; | ||
1635 | const char *name; | ||
1636 | irqreturn_t (*handler)(int, void *); | ||
1637 | }; | ||
1638 | |||
1639 | static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = { | ||
1640 | { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT, | ||
1641 | "qla2xxx (default)", qla24xx_msix_default }, | ||
1642 | |||
1643 | { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q, | ||
1644 | "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, | ||
1645 | }; | ||
1646 | |||
1647 | static void | ||
1648 | qla24xx_disable_msix(scsi_qla_host_t *ha) | ||
1649 | { | ||
1650 | int i; | ||
1651 | struct qla_msix_entry *qentry; | ||
1652 | |||
1653 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) { | ||
1654 | qentry = &ha->msix_entries[imsix_entries[i].index]; | ||
1655 | if (qentry->have_irq) | ||
1656 | free_irq(qentry->msix_vector, ha); | ||
1657 | } | ||
1658 | pci_disable_msix(ha->pdev); | ||
1659 | } | ||
1660 | |||
1661 | static int | ||
1662 | qla24xx_enable_msix(scsi_qla_host_t *ha) | ||
1663 | { | ||
1664 | int i, ret; | ||
1665 | struct msix_entry entries[QLA_MSIX_ENTRIES]; | ||
1666 | struct qla_msix_entry *qentry; | ||
1667 | |||
1668 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) | ||
1669 | entries[i].entry = imsix_entries[i].entry; | ||
1670 | |||
1671 | ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries)); | ||
1672 | if (ret) { | ||
1673 | qla_printk(KERN_WARNING, ha, | ||
1674 | "MSI-X: Failed to enable support -- %d/%d\n", | ||
1675 | QLA_MSIX_ENTRIES, ret); | ||
1676 | goto msix_out; | ||
1677 | } | ||
1678 | ha->flags.msix_enabled = 1; | ||
1679 | |||
1680 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) { | ||
1681 | qentry = &ha->msix_entries[imsix_entries[i].index]; | ||
1682 | qentry->msix_vector = entries[i].vector; | ||
1683 | qentry->msix_entry = entries[i].entry; | ||
1684 | qentry->have_irq = 0; | ||
1685 | ret = request_irq(qentry->msix_vector, | ||
1686 | imsix_entries[i].handler, 0, imsix_entries[i].name, ha); | ||
1687 | if (ret) { | ||
1688 | qla_printk(KERN_WARNING, ha, | ||
1689 | "MSI-X: Unable to register handler -- %x/%d.\n", | ||
1690 | imsix_entries[i].index, ret); | ||
1691 | qla24xx_disable_msix(ha); | ||
1692 | goto msix_out; | ||
1693 | } | ||
1694 | qentry->have_irq = 1; | ||
1695 | } | ||
1696 | |||
1697 | msix_out: | ||
1698 | return ret; | ||
1699 | } | ||
1700 | |||
1701 | int | ||
1702 | qla2x00_request_irqs(scsi_qla_host_t *ha) | ||
1703 | { | ||
1704 | int ret; | ||
1705 | |||
1706 | /* If possible, enable MSI-X. */ | ||
1707 | if (!IS_QLA2432(ha)) | ||
1708 | goto skip_msix; | ||
1709 | |||
1710 | if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | ||
1711 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) { | ||
1712 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
1713 | "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", | ||
1714 | ha->chip_revision, ha->fw_attributes)); | ||
1715 | |||
1716 | goto skip_msix; | ||
1717 | } | ||
1718 | |||
1719 | ret = qla24xx_enable_msix(ha); | ||
1720 | if (!ret) { | ||
1721 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
1722 | "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision, | ||
1723 | ha->fw_attributes)); | ||
1724 | return ret; | ||
1725 | } | ||
1726 | qla_printk(KERN_WARNING, ha, | ||
1727 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | ||
1728 | skip_msix: | ||
1729 | ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler, | ||
1730 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); | ||
1731 | if (!ret) { | ||
1732 | ha->flags.inta_enabled = 1; | ||
1733 | ha->host->irq = ha->pdev->irq; | ||
1734 | } else { | ||
1735 | qla_printk(KERN_WARNING, ha, | ||
1736 | "Failed to reserve interrupt %d already in use.\n", | ||
1737 | ha->pdev->irq); | ||
1738 | } | ||
1739 | |||
1740 | return ret; | ||
1741 | } | ||
1742 | |||
1743 | void | ||
1744 | qla2x00_free_irqs(scsi_qla_host_t *ha) | ||
1745 | { | ||
1746 | |||
1747 | if (ha->flags.msix_enabled) | ||
1748 | qla24xx_disable_msix(ha); | ||
1749 | else if (ha->flags.inta_enabled) | ||
1750 | free_irq(ha->host->irq, ha); | ||
1751 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 077e5789beeb..83376f6ac3db 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -55,7 +55,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
55 | uint16_t __iomem *optr; | 55 | uint16_t __iomem *optr; |
56 | uint32_t cnt; | 56 | uint32_t cnt; |
57 | uint32_t mboxes; | 57 | uint32_t mboxes; |
58 | unsigned long mbx_flags = 0; | ||
59 | unsigned long wait_time; | 58 | unsigned long wait_time; |
60 | 59 | ||
61 | rval = QLA_SUCCESS; | 60 | rval = QLA_SUCCESS; |
@@ -81,10 +80,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
81 | /* Save mailbox command for debug */ | 80 | /* Save mailbox command for debug */ |
82 | ha->mcp = mcp; | 81 | ha->mcp = mcp; |
83 | 82 | ||
84 | /* Try to get mailbox register access */ | ||
85 | if (!abort_active) | ||
86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); | ||
87 | |||
88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", | 83 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", |
89 | ha->host_no, mcp->mb[0])); | 84 | ha->host_no, mcp->mb[0])); |
90 | 85 | ||
@@ -161,9 +156,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
161 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); | 156 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); |
162 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 157 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
163 | 158 | ||
164 | if (!abort_active) | ||
165 | spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); | ||
166 | |||
167 | /* Wait for either the timer to expire | 159 | /* Wait for either the timer to expire |
168 | * or the mbox completion interrupt | 160 | * or the mbox completion interrupt |
169 | */ | 161 | */ |
@@ -184,8 +176,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
184 | else | 176 | else |
185 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); | 177 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); |
186 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 178 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
187 | if (!abort_active) | ||
188 | spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); | ||
189 | 179 | ||
190 | wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ | 180 | wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ |
191 | while (!ha->flags.mbox_int) { | 181 | while (!ha->flags.mbox_int) { |
@@ -201,9 +191,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
201 | } /* while */ | 191 | } /* while */ |
202 | } | 192 | } |
203 | 193 | ||
204 | if (!abort_active) | ||
205 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); | ||
206 | |||
207 | /* Check whether we timed out */ | 194 | /* Check whether we timed out */ |
208 | if (ha->flags.mbox_int) { | 195 | if (ha->flags.mbox_int) { |
209 | uint16_t *iptr2; | 196 | uint16_t *iptr2; |
@@ -256,9 +243,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
256 | rval = QLA_FUNCTION_TIMEOUT; | 243 | rval = QLA_FUNCTION_TIMEOUT; |
257 | } | 244 | } |
258 | 245 | ||
259 | if (!abort_active) | ||
260 | spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); | ||
261 | |||
262 | ha->flags.mbox_busy = 0; | 246 | ha->flags.mbox_busy = 0; |
263 | 247 | ||
264 | /* Clean up */ | 248 | /* Clean up */ |
@@ -1713,7 +1697,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1713 | lg->entry_count = 1; | 1697 | lg->entry_count = 1; |
1714 | lg->nport_handle = cpu_to_le16(loop_id); | 1698 | lg->nport_handle = cpu_to_le16(loop_id); |
1715 | lg->control_flags = | 1699 | lg->control_flags = |
1716 | __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_EXPL_LOGO); | 1700 | __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); |
1717 | lg->port_id[0] = al_pa; | 1701 | lg->port_id[0] = al_pa; |
1718 | lg->port_id[1] = area; | 1702 | lg->port_id[1] = area; |
1719 | lg->port_id[2] = domain; | 1703 | lg->port_id[2] = domain; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d6445ae841ba..68f5d24b938b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1485,6 +1485,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1485 | ha->isp_ops.fw_dump = qla2100_fw_dump; | 1485 | ha->isp_ops.fw_dump = qla2100_fw_dump; |
1486 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | 1486 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; |
1487 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | 1487 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; |
1488 | ha->isp_ops.get_flash_version = qla2x00_get_flash_version; | ||
1488 | if (IS_QLA2100(ha)) { | 1489 | if (IS_QLA2100(ha)) { |
1489 | host->max_id = MAX_TARGETS_2100; | 1490 | host->max_id = MAX_TARGETS_2100; |
1490 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; | 1491 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; |
@@ -1550,6 +1551,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1550 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | 1551 | ha->isp_ops.beacon_on = qla24xx_beacon_on; |
1551 | ha->isp_ops.beacon_off = qla24xx_beacon_off; | 1552 | ha->isp_ops.beacon_off = qla24xx_beacon_off; |
1552 | ha->isp_ops.beacon_blink = qla24xx_beacon_blink; | 1553 | ha->isp_ops.beacon_blink = qla24xx_beacon_blink; |
1554 | ha->isp_ops.get_flash_version = qla24xx_get_flash_version; | ||
1553 | ha->gid_list_info_size = 8; | 1555 | ha->gid_list_info_size = 8; |
1554 | ha->optrom_size = OPTROM_SIZE_24XX; | 1556 | ha->optrom_size = OPTROM_SIZE_24XX; |
1555 | } | 1557 | } |
@@ -1564,14 +1566,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1564 | INIT_LIST_HEAD(&ha->list); | 1566 | INIT_LIST_HEAD(&ha->list); |
1565 | INIT_LIST_HEAD(&ha->fcports); | 1567 | INIT_LIST_HEAD(&ha->fcports); |
1566 | 1568 | ||
1567 | /* | ||
1568 | * These locks are used to prevent more than one CPU | ||
1569 | * from modifying the queue at the same time. The | ||
1570 | * higher level "host_lock" will reduce most | ||
1571 | * contention for these locks. | ||
1572 | */ | ||
1573 | spin_lock_init(&ha->mbx_reg_lock); | ||
1574 | |||
1575 | qla2x00_config_dma_addressing(ha); | 1569 | qla2x00_config_dma_addressing(ha); |
1576 | if (qla2x00_mem_alloc(ha)) { | 1570 | if (qla2x00_mem_alloc(ha)) { |
1577 | qla_printk(KERN_WARNING, ha, | 1571 | qla_printk(KERN_WARNING, ha, |
@@ -1615,15 +1609,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1615 | host->max_lun = MAX_LUNS; | 1609 | host->max_lun = MAX_LUNS; |
1616 | host->transportt = qla2xxx_transport_template; | 1610 | host->transportt = qla2xxx_transport_template; |
1617 | 1611 | ||
1618 | ret = request_irq(pdev->irq, ha->isp_ops.intr_handler, | 1612 | ret = qla2x00_request_irqs(ha); |
1619 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); | 1613 | if (ret) |
1620 | if (ret) { | ||
1621 | qla_printk(KERN_WARNING, ha, | ||
1622 | "Failed to reserve interrupt %d already in use.\n", | ||
1623 | pdev->irq); | ||
1624 | goto probe_failed; | 1614 | goto probe_failed; |
1625 | } | ||
1626 | host->irq = pdev->irq; | ||
1627 | 1615 | ||
1628 | /* Initialized the timer */ | 1616 | /* Initialized the timer */ |
1629 | qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL); | 1617 | qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL); |
@@ -1753,9 +1741,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1753 | 1741 | ||
1754 | qla2x00_mem_free(ha); | 1742 | qla2x00_mem_free(ha); |
1755 | 1743 | ||
1756 | /* Detach interrupts */ | 1744 | qla2x00_free_irqs(ha); |
1757 | if (ha->host->irq) | ||
1758 | free_irq(ha->host->irq, ha); | ||
1759 | 1745 | ||
1760 | /* release io space registers */ | 1746 | /* release io space registers */ |
1761 | if (ha->iobase) | 1747 | if (ha->iobase) |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 15390ad87456..ff1dd4175a7f 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -611,7 +611,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
611 | flash_conf_to_access_addr(0x0339), | 611 | flash_conf_to_access_addr(0x0339), |
612 | (fdata & 0xff00) | ((fdata << 16) & | 612 | (fdata & 0xff00) | ((fdata << 16) & |
613 | 0xff0000) | ((fdata >> 16) & 0xff)); | 613 | 0xff0000) | ((fdata >> 16) & 0xff)); |
614 | fdata = (faddr & sec_mask) << 2; | ||
615 | ret = qla24xx_write_flash_dword(ha, conf_addr, | 614 | ret = qla24xx_write_flash_dword(ha, conf_addr, |
616 | (fdata & 0xff00) |((fdata << 16) & | 615 | (fdata & 0xff00) |((fdata << 16) & |
617 | 0xff0000) | ((fdata >> 16) & 0xff)); | 616 | 0xff0000) | ((fdata >> 16) & 0xff)); |
@@ -1383,6 +1382,29 @@ qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
1383 | qla2x00_write_flash_byte(ha, 0x5555, 0xf0); | 1382 | qla2x00_write_flash_byte(ha, 0x5555, 0xf0); |
1384 | } | 1383 | } |
1385 | 1384 | ||
1385 | static void | ||
1386 | qla2x00_read_flash_data(scsi_qla_host_t *ha, uint8_t *tmp_buf, uint32_t saddr, | ||
1387 | uint32_t length) | ||
1388 | { | ||
1389 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1390 | uint32_t midpoint, ilength; | ||
1391 | uint8_t data; | ||
1392 | |||
1393 | midpoint = length / 2; | ||
1394 | |||
1395 | WRT_REG_WORD(®->nvram, 0); | ||
1396 | RD_REG_WORD(®->nvram); | ||
1397 | for (ilength = 0; ilength < length; saddr++, ilength++, tmp_buf++) { | ||
1398 | if (ilength == midpoint) { | ||
1399 | WRT_REG_WORD(®->nvram, NVR_SELECT); | ||
1400 | RD_REG_WORD(®->nvram); | ||
1401 | } | ||
1402 | data = qla2x00_read_flash_byte(ha, saddr); | ||
1403 | if (saddr % 100) | ||
1404 | udelay(10); | ||
1405 | *tmp_buf = data; | ||
1406 | } | ||
1407 | } | ||
1386 | 1408 | ||
1387 | static inline void | 1409 | static inline void |
1388 | qla2x00_suspend_hba(struct scsi_qla_host *ha) | 1410 | qla2x00_suspend_hba(struct scsi_qla_host *ha) |
@@ -1722,3 +1744,327 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1722 | 1744 | ||
1723 | return rval; | 1745 | return rval; |
1724 | } | 1746 | } |
1747 | |||
1748 | /** | ||
1749 | * qla2x00_get_fcode_version() - Determine an FCODE image's version. | ||
1750 | * @ha: HA context | ||
1751 | * @pcids: Pointer to the FCODE PCI data structure | ||
1752 | * | ||
1753 | * The process of retrieving the FCODE version information is at best | ||
1754 | * described as interesting. | ||
1755 | * | ||
1756 | * Within the first 100h bytes of the image an ASCII string is present | ||
1757 | * which contains several pieces of information including the FCODE | ||
1758 | * version. Unfortunately it seems the only reliable way to retrieve | ||
1759 | * the version is by scanning for another sentinel within the string, | ||
1760 | * the FCODE build date: | ||
1761 | * | ||
1762 | * ... 2.00.02 10/17/02 ... | ||
1763 | * | ||
1764 | * Returns QLA_SUCCESS on successful retrieval of version. | ||
1765 | */ | ||
1766 | static void | ||
1767 | qla2x00_get_fcode_version(scsi_qla_host_t *ha, uint32_t pcids) | ||
1768 | { | ||
1769 | int ret = QLA_FUNCTION_FAILED; | ||
1770 | uint32_t istart, iend, iter, vend; | ||
1771 | uint8_t do_next, rbyte, *vbyte; | ||
1772 | |||
1773 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | ||
1774 | |||
1775 | /* Skip the PCI data structure. */ | ||
1776 | istart = pcids + | ||
1777 | ((qla2x00_read_flash_byte(ha, pcids + 0x0B) << 8) | | ||
1778 | qla2x00_read_flash_byte(ha, pcids + 0x0A)); | ||
1779 | iend = istart + 0x100; | ||
1780 | do { | ||
1781 | /* Scan for the sentinel date string...eeewww. */ | ||
1782 | do_next = 0; | ||
1783 | iter = istart; | ||
1784 | while ((iter < iend) && !do_next) { | ||
1785 | iter++; | ||
1786 | if (qla2x00_read_flash_byte(ha, iter) == '/') { | ||
1787 | if (qla2x00_read_flash_byte(ha, iter + 2) == | ||
1788 | '/') | ||
1789 | do_next++; | ||
1790 | else if (qla2x00_read_flash_byte(ha, | ||
1791 | iter + 3) == '/') | ||
1792 | do_next++; | ||
1793 | } | ||
1794 | } | ||
1795 | if (!do_next) | ||
1796 | break; | ||
1797 | |||
1798 | /* Backtrack to previous ' ' (space). */ | ||
1799 | do_next = 0; | ||
1800 | while ((iter > istart) && !do_next) { | ||
1801 | iter--; | ||
1802 | if (qla2x00_read_flash_byte(ha, iter) == ' ') | ||
1803 | do_next++; | ||
1804 | } | ||
1805 | if (!do_next) | ||
1806 | break; | ||
1807 | |||
1808 | /* | ||
1809 | * Mark end of version tag, and find previous ' ' (space) or | ||
1810 | * string length (recent FCODE images -- major hack ahead!!!). | ||
1811 | */ | ||
1812 | vend = iter - 1; | ||
1813 | do_next = 0; | ||
1814 | while ((iter > istart) && !do_next) { | ||
1815 | iter--; | ||
1816 | rbyte = qla2x00_read_flash_byte(ha, iter); | ||
1817 | if (rbyte == ' ' || rbyte == 0xd || rbyte == 0x10) | ||
1818 | do_next++; | ||
1819 | } | ||
1820 | if (!do_next) | ||
1821 | break; | ||
1822 | |||
1823 | /* Mark beginning of version tag, and copy data. */ | ||
1824 | iter++; | ||
1825 | if ((vend - iter) && | ||
1826 | ((vend - iter) < sizeof(ha->fcode_revision))) { | ||
1827 | vbyte = ha->fcode_revision; | ||
1828 | while (iter <= vend) { | ||
1829 | *vbyte++ = qla2x00_read_flash_byte(ha, iter); | ||
1830 | iter++; | ||
1831 | } | ||
1832 | ret = QLA_SUCCESS; | ||
1833 | } | ||
1834 | } while (0); | ||
1835 | |||
1836 | if (ret != QLA_SUCCESS) | ||
1837 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | ||
1838 | } | ||
1839 | |||
1840 | int | ||
1841 | qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | ||
1842 | { | ||
1843 | int ret = QLA_SUCCESS; | ||
1844 | uint8_t code_type, last_image; | ||
1845 | uint32_t pcihdr, pcids; | ||
1846 | uint8_t *dbyte; | ||
1847 | uint16_t *dcode; | ||
1848 | |||
1849 | if (!ha->pio_address || !mbuf) | ||
1850 | return QLA_FUNCTION_FAILED; | ||
1851 | |||
1852 | memset(ha->bios_revision, 0, sizeof(ha->bios_revision)); | ||
1853 | memset(ha->efi_revision, 0, sizeof(ha->efi_revision)); | ||
1854 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | ||
1855 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | ||
1856 | |||
1857 | qla2x00_flash_enable(ha); | ||
1858 | |||
1859 | /* Begin with first PCI expansion ROM header. */ | ||
1860 | pcihdr = 0; | ||
1861 | last_image = 1; | ||
1862 | do { | ||
1863 | /* Verify PCI expansion ROM header. */ | ||
1864 | if (qla2x00_read_flash_byte(ha, pcihdr) != 0x55 || | ||
1865 | qla2x00_read_flash_byte(ha, pcihdr + 0x01) != 0xaa) { | ||
1866 | /* No signature */ | ||
1867 | DEBUG2(printk("scsi(%ld): No matching ROM " | ||
1868 | "signature.\n", ha->host_no)); | ||
1869 | ret = QLA_FUNCTION_FAILED; | ||
1870 | break; | ||
1871 | } | ||
1872 | |||
1873 | /* Locate PCI data structure. */ | ||
1874 | pcids = pcihdr + | ||
1875 | ((qla2x00_read_flash_byte(ha, pcihdr + 0x19) << 8) | | ||
1876 | qla2x00_read_flash_byte(ha, pcihdr + 0x18)); | ||
1877 | |||
1878 | /* Validate signature of PCI data structure. */ | ||
1879 | if (qla2x00_read_flash_byte(ha, pcids) != 'P' || | ||
1880 | qla2x00_read_flash_byte(ha, pcids + 0x1) != 'C' || | ||
1881 | qla2x00_read_flash_byte(ha, pcids + 0x2) != 'I' || | ||
1882 | qla2x00_read_flash_byte(ha, pcids + 0x3) != 'R') { | ||
1883 | /* Incorrect header. */ | ||
1884 | DEBUG2(printk("%s(): PCI data struct not found " | ||
1885 | "pcir_adr=%x.\n", __func__, pcids)); | ||
1886 | ret = QLA_FUNCTION_FAILED; | ||
1887 | break; | ||
1888 | } | ||
1889 | |||
1890 | /* Read version */ | ||
1891 | code_type = qla2x00_read_flash_byte(ha, pcids + 0x14); | ||
1892 | switch (code_type) { | ||
1893 | case ROM_CODE_TYPE_BIOS: | ||
1894 | /* Intel x86, PC-AT compatible. */ | ||
1895 | ha->bios_revision[0] = | ||
1896 | qla2x00_read_flash_byte(ha, pcids + 0x12); | ||
1897 | ha->bios_revision[1] = | ||
1898 | qla2x00_read_flash_byte(ha, pcids + 0x13); | ||
1899 | DEBUG3(printk("%s(): read BIOS %d.%d.\n", __func__, | ||
1900 | ha->bios_revision[1], ha->bios_revision[0])); | ||
1901 | break; | ||
1902 | case ROM_CODE_TYPE_FCODE: | ||
1903 | /* Open Firmware standard for PCI (FCode). */ | ||
1904 | /* Eeeewww... */ | ||
1905 | qla2x00_get_fcode_version(ha, pcids); | ||
1906 | break; | ||
1907 | case ROM_CODE_TYPE_EFI: | ||
1908 | /* Extensible Firmware Interface (EFI). */ | ||
1909 | ha->efi_revision[0] = | ||
1910 | qla2x00_read_flash_byte(ha, pcids + 0x12); | ||
1911 | ha->efi_revision[1] = | ||
1912 | qla2x00_read_flash_byte(ha, pcids + 0x13); | ||
1913 | DEBUG3(printk("%s(): read EFI %d.%d.\n", __func__, | ||
1914 | ha->efi_revision[1], ha->efi_revision[0])); | ||
1915 | break; | ||
1916 | default: | ||
1917 | DEBUG2(printk("%s(): Unrecognized code type %x at " | ||
1918 | "pcids %x.\n", __func__, code_type, pcids)); | ||
1919 | break; | ||
1920 | } | ||
1921 | |||
1922 | last_image = qla2x00_read_flash_byte(ha, pcids + 0x15) & BIT_7; | ||
1923 | |||
1924 | /* Locate next PCI expansion ROM. */ | ||
1925 | pcihdr += ((qla2x00_read_flash_byte(ha, pcids + 0x11) << 8) | | ||
1926 | qla2x00_read_flash_byte(ha, pcids + 0x10)) * 512; | ||
1927 | } while (!last_image); | ||
1928 | |||
1929 | if (IS_QLA2322(ha)) { | ||
1930 | /* Read firmware image information. */ | ||
1931 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | ||
1932 | dbyte = mbuf; | ||
1933 | memset(dbyte, 0, 8); | ||
1934 | dcode = (uint16_t *)dbyte; | ||
1935 | |||
1936 | qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10, | ||
1937 | 8); | ||
1938 | DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n", | ||
1939 | __func__, ha->host_no)); | ||
1940 | DEBUG3(qla2x00_dump_buffer((uint8_t *)dbyte, 8)); | ||
1941 | |||
1942 | if ((dcode[0] == 0xffff && dcode[1] == 0xffff && | ||
1943 | dcode[2] == 0xffff && dcode[3] == 0xffff) || | ||
1944 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | ||
1945 | dcode[3] == 0)) { | ||
1946 | DEBUG2(printk("%s(): Unrecognized fw revision at " | ||
1947 | "%x.\n", __func__, FA_RISC_CODE_ADDR * 4)); | ||
1948 | } else { | ||
1949 | /* values are in big endian */ | ||
1950 | ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1]; | ||
1951 | ha->fw_revision[1] = dbyte[2] << 16 | dbyte[3]; | ||
1952 | ha->fw_revision[2] = dbyte[4] << 16 | dbyte[5]; | ||
1953 | } | ||
1954 | } | ||
1955 | |||
1956 | qla2x00_flash_disable(ha); | ||
1957 | |||
1958 | return ret; | ||
1959 | } | ||
1960 | |||
1961 | int | ||
1962 | qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | ||
1963 | { | ||
1964 | int ret = QLA_SUCCESS; | ||
1965 | uint32_t pcihdr, pcids; | ||
1966 | uint32_t *dcode; | ||
1967 | uint8_t *bcode; | ||
1968 | uint8_t code_type, last_image; | ||
1969 | int i; | ||
1970 | |||
1971 | if (!mbuf) | ||
1972 | return QLA_FUNCTION_FAILED; | ||
1973 | |||
1974 | memset(ha->bios_revision, 0, sizeof(ha->bios_revision)); | ||
1975 | memset(ha->efi_revision, 0, sizeof(ha->efi_revision)); | ||
1976 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | ||
1977 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | ||
1978 | |||
1979 | dcode = mbuf; | ||
1980 | |||
1981 | /* Begin with first PCI expansion ROM header. */ | ||
1982 | pcihdr = 0; | ||
1983 | last_image = 1; | ||
1984 | do { | ||
1985 | /* Verify PCI expansion ROM header. */ | ||
1986 | qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20); | ||
1987 | bcode = mbuf + (pcihdr % 4); | ||
1988 | if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) { | ||
1989 | /* No signature */ | ||
1990 | DEBUG2(printk("scsi(%ld): No matching ROM " | ||
1991 | "signature.\n", ha->host_no)); | ||
1992 | ret = QLA_FUNCTION_FAILED; | ||
1993 | break; | ||
1994 | } | ||
1995 | |||
1996 | /* Locate PCI data structure. */ | ||
1997 | pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); | ||
1998 | |||
1999 | qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20); | ||
2000 | bcode = mbuf + (pcihdr % 4); | ||
2001 | |||
2002 | /* Validate signature of PCI data structure. */ | ||
2003 | if (bcode[0x0] != 'P' || bcode[0x1] != 'C' || | ||
2004 | bcode[0x2] != 'I' || bcode[0x3] != 'R') { | ||
2005 | /* Incorrect header. */ | ||
2006 | DEBUG2(printk("%s(): PCI data struct not found " | ||
2007 | "pcir_adr=%x.\n", __func__, pcids)); | ||
2008 | ret = QLA_FUNCTION_FAILED; | ||
2009 | break; | ||
2010 | } | ||
2011 | |||
2012 | /* Read version */ | ||
2013 | code_type = bcode[0x14]; | ||
2014 | switch (code_type) { | ||
2015 | case ROM_CODE_TYPE_BIOS: | ||
2016 | /* Intel x86, PC-AT compatible. */ | ||
2017 | ha->bios_revision[0] = bcode[0x12]; | ||
2018 | ha->bios_revision[1] = bcode[0x13]; | ||
2019 | DEBUG3(printk("%s(): read BIOS %d.%d.\n", __func__, | ||
2020 | ha->bios_revision[1], ha->bios_revision[0])); | ||
2021 | break; | ||
2022 | case ROM_CODE_TYPE_FCODE: | ||
2023 | /* Open Firmware standard for PCI (FCode). */ | ||
2024 | ha->fcode_revision[0] = bcode[0x12]; | ||
2025 | ha->fcode_revision[1] = bcode[0x13]; | ||
2026 | DEBUG3(printk("%s(): read FCODE %d.%d.\n", __func__, | ||
2027 | ha->fcode_revision[1], ha->fcode_revision[0])); | ||
2028 | break; | ||
2029 | case ROM_CODE_TYPE_EFI: | ||
2030 | /* Extensible Firmware Interface (EFI). */ | ||
2031 | ha->efi_revision[0] = bcode[0x12]; | ||
2032 | ha->efi_revision[1] = bcode[0x13]; | ||
2033 | DEBUG3(printk("%s(): read EFI %d.%d.\n", __func__, | ||
2034 | ha->efi_revision[1], ha->efi_revision[0])); | ||
2035 | break; | ||
2036 | default: | ||
2037 | DEBUG2(printk("%s(): Unrecognized code type %x at " | ||
2038 | "pcids %x.\n", __func__, code_type, pcids)); | ||
2039 | break; | ||
2040 | } | ||
2041 | |||
2042 | last_image = bcode[0x15] & BIT_7; | ||
2043 | |||
2044 | /* Locate next PCI expansion ROM. */ | ||
2045 | pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512; | ||
2046 | } while (!last_image); | ||
2047 | |||
2048 | /* Read firmware image information. */ | ||
2049 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | ||
2050 | dcode = mbuf; | ||
2051 | |||
2052 | qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4); | ||
2053 | for (i = 0; i < 4; i++) | ||
2054 | dcode[i] = be32_to_cpu(dcode[i]); | ||
2055 | |||
2056 | if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff && | ||
2057 | dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) || | ||
2058 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | ||
2059 | dcode[3] == 0)) { | ||
2060 | DEBUG2(printk("%s(): Unrecognized fw version at %x.\n", | ||
2061 | __func__, FA_RISC_CODE_ADDR)); | ||
2062 | } else { | ||
2063 | ha->fw_revision[0] = dcode[0]; | ||
2064 | ha->fw_revision[1] = dcode[1]; | ||
2065 | ha->fw_revision[2] = dcode[2]; | ||
2066 | ha->fw_revision[3] = dcode[3]; | ||
2067 | } | ||
2068 | |||
2069 | return ret; | ||
2070 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 459e0d6bd2b4..61347aee55ce 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.01.07-k4" | 10 | #define QLA2XXX_VERSION "8.01.07-k5" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 24cffd98ee63..f33e2eb9f1b9 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -673,27 +673,6 @@ void __scsi_done(struct scsi_cmnd *cmd) | |||
673 | } | 673 | } |
674 | 674 | ||
675 | /* | 675 | /* |
676 | * Function: scsi_retry_command | ||
677 | * | ||
678 | * Purpose: Send a command back to the low level to be retried. | ||
679 | * | ||
680 | * Notes: This command is always executed in the context of the | ||
681 | * bottom half handler, or the error handler thread. Low | ||
682 | * level drivers should not become re-entrant as a result of | ||
683 | * this. | ||
684 | */ | ||
685 | int scsi_retry_command(struct scsi_cmnd *cmd) | ||
686 | { | ||
687 | /* | ||
688 | * Zero the sense information from the last time we tried | ||
689 | * this command. | ||
690 | */ | ||
691 | memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); | ||
692 | |||
693 | return scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * Function: scsi_finish_command | 676 | * Function: scsi_finish_command |
698 | * | 677 | * |
699 | * Purpose: Pass command off to upper layer for finishing of I/O | 678 | * Purpose: Pass command off to upper layer for finishing of I/O |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 30ee3d72c021..5adbbeedec38 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -51,10 +51,10 @@ | |||
51 | #include "scsi_logging.h" | 51 | #include "scsi_logging.h" |
52 | #include "scsi_debug.h" | 52 | #include "scsi_debug.h" |
53 | 53 | ||
54 | #define SCSI_DEBUG_VERSION "1.80" | 54 | #define SCSI_DEBUG_VERSION "1.81" |
55 | static const char * scsi_debug_version_date = "20061018"; | 55 | static const char * scsi_debug_version_date = "20070104"; |
56 | 56 | ||
57 | /* Additional Sense Code (ASC) used */ | 57 | /* Additional Sense Code (ASC) */ |
58 | #define NO_ADDITIONAL_SENSE 0x0 | 58 | #define NO_ADDITIONAL_SENSE 0x0 |
59 | #define LOGICAL_UNIT_NOT_READY 0x4 | 59 | #define LOGICAL_UNIT_NOT_READY 0x4 |
60 | #define UNRECOVERED_READ_ERR 0x11 | 60 | #define UNRECOVERED_READ_ERR 0x11 |
@@ -65,9 +65,13 @@ static const char * scsi_debug_version_date = "20061018"; | |||
65 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | 65 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 |
66 | #define POWERON_RESET 0x29 | 66 | #define POWERON_RESET 0x29 |
67 | #define SAVING_PARAMS_UNSUP 0x39 | 67 | #define SAVING_PARAMS_UNSUP 0x39 |
68 | #define TRANSPORT_PROBLEM 0x4b | ||
68 | #define THRESHOLD_EXCEEDED 0x5d | 69 | #define THRESHOLD_EXCEEDED 0x5d |
69 | #define LOW_POWER_COND_ON 0x5e | 70 | #define LOW_POWER_COND_ON 0x5e |
70 | 71 | ||
72 | /* Additional Sense Code Qualifier (ASCQ) */ | ||
73 | #define ACK_NAK_TO 0x3 | ||
74 | |||
71 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | 75 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ |
72 | 76 | ||
73 | /* Default values for driver parameters */ | 77 | /* Default values for driver parameters */ |
@@ -95,15 +99,20 @@ static const char * scsi_debug_version_date = "20061018"; | |||
95 | #define SCSI_DEBUG_OPT_MEDIUM_ERR 2 | 99 | #define SCSI_DEBUG_OPT_MEDIUM_ERR 2 |
96 | #define SCSI_DEBUG_OPT_TIMEOUT 4 | 100 | #define SCSI_DEBUG_OPT_TIMEOUT 4 |
97 | #define SCSI_DEBUG_OPT_RECOVERED_ERR 8 | 101 | #define SCSI_DEBUG_OPT_RECOVERED_ERR 8 |
102 | #define SCSI_DEBUG_OPT_TRANSPORT_ERR 16 | ||
98 | /* When "every_nth" > 0 then modulo "every_nth" commands: | 103 | /* When "every_nth" > 0 then modulo "every_nth" commands: |
99 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set | 104 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set |
100 | * - a RECOVERED_ERROR is simulated on successful read and write | 105 | * - a RECOVERED_ERROR is simulated on successful read and write |
101 | * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. | 106 | * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. |
107 | * - a TRANSPORT_ERROR is simulated on successful read and write | ||
108 | * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set. | ||
102 | * | 109 | * |
103 | * When "every_nth" < 0 then after "- every_nth" commands: | 110 | * When "every_nth" < 0 then after "- every_nth" commands: |
104 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set | 111 | * - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set |
105 | * - a RECOVERED_ERROR is simulated on successful read and write | 112 | * - a RECOVERED_ERROR is simulated on successful read and write |
106 | * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. | 113 | * commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set. |
114 | * - a TRANSPORT_ERROR is simulated on successful read and write | ||
115 | * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set. | ||
107 | * This will continue until some other action occurs (e.g. the user | 116 | * This will continue until some other action occurs (e.g. the user |
108 | * writing a new value (other than -1 or 1) to every_nth via sysfs). | 117 | * writing a new value (other than -1 or 1) to every_nth via sysfs). |
109 | */ | 118 | */ |
@@ -315,6 +324,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
315 | int target = SCpnt->device->id; | 324 | int target = SCpnt->device->id; |
316 | struct sdebug_dev_info * devip = NULL; | 325 | struct sdebug_dev_info * devip = NULL; |
317 | int inj_recovered = 0; | 326 | int inj_recovered = 0; |
327 | int inj_transport = 0; | ||
318 | int delay_override = 0; | 328 | int delay_override = 0; |
319 | 329 | ||
320 | if (done == NULL) | 330 | if (done == NULL) |
@@ -352,6 +362,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
352 | return 0; /* ignore command causing timeout */ | 362 | return 0; /* ignore command causing timeout */ |
353 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) | 363 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) |
354 | inj_recovered = 1; /* to reads and writes below */ | 364 | inj_recovered = 1; /* to reads and writes below */ |
365 | else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) | ||
366 | inj_transport = 1; /* to reads and writes below */ | ||
355 | } | 367 | } |
356 | 368 | ||
357 | if (devip->wlun) { | 369 | if (devip->wlun) { |
@@ -468,7 +480,11 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
468 | mk_sense_buffer(devip, RECOVERED_ERROR, | 480 | mk_sense_buffer(devip, RECOVERED_ERROR, |
469 | THRESHOLD_EXCEEDED, 0); | 481 | THRESHOLD_EXCEEDED, 0); |
470 | errsts = check_condition_result; | 482 | errsts = check_condition_result; |
471 | } | 483 | } else if (inj_transport && (0 == errsts)) { |
484 | mk_sense_buffer(devip, ABORTED_COMMAND, | ||
485 | TRANSPORT_PROBLEM, ACK_NAK_TO); | ||
486 | errsts = check_condition_result; | ||
487 | } | ||
472 | break; | 488 | break; |
473 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | 489 | case REPORT_LUNS: /* mandatory, ignore unit attention */ |
474 | delay_override = 1; | 490 | delay_override = 1; |
@@ -531,6 +547,9 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
531 | delay_override = 1; | 547 | delay_override = 1; |
532 | errsts = check_readiness(SCpnt, 0, devip); | 548 | errsts = check_readiness(SCpnt, 0, devip); |
533 | break; | 549 | break; |
550 | case WRITE_BUFFER: | ||
551 | errsts = check_readiness(SCpnt, 1, devip); | ||
552 | break; | ||
534 | default: | 553 | default: |
535 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 554 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
536 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 555 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
@@ -954,7 +973,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
954 | int alloc_len, n, ret; | 973 | int alloc_len, n, ret; |
955 | 974 | ||
956 | alloc_len = (cmd[3] << 8) + cmd[4]; | 975 | alloc_len = (cmd[3] << 8) + cmd[4]; |
957 | arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL); | 976 | arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC); |
977 | if (! arr) | ||
978 | return DID_REQUEUE << 16; | ||
958 | if (devip->wlun) | 979 | if (devip->wlun) |
959 | pq_pdt = 0x1e; /* present, wlun */ | 980 | pq_pdt = 0x1e; /* present, wlun */ |
960 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | 981 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) |
@@ -1217,7 +1238,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd * scp, | |||
1217 | alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) | 1238 | alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) |
1218 | + cmd[9]); | 1239 | + cmd[9]); |
1219 | 1240 | ||
1220 | arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL); | 1241 | arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC); |
1242 | if (! arr) | ||
1243 | return DID_REQUEUE << 16; | ||
1221 | /* | 1244 | /* |
1222 | * EVPD page 0x88 states we have two ports, one | 1245 | * EVPD page 0x88 states we have two ports, one |
1223 | * real and a fake port with no device connected. | 1246 | * real and a fake port with no device connected. |
@@ -1996,6 +2019,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1996 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 2019 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
1997 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 2020 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
1998 | devip = devInfoReg(sdp); | 2021 | devip = devInfoReg(sdp); |
2022 | if (NULL == devip) | ||
2023 | return 1; /* no resources, will be marked offline */ | ||
1999 | sdp->hostdata = devip; | 2024 | sdp->hostdata = devip; |
2000 | if (sdp->host->cmd_per_lun) | 2025 | if (sdp->host->cmd_per_lun) |
2001 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 2026 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
@@ -2044,7 +2069,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
2044 | } | 2069 | } |
2045 | } | 2070 | } |
2046 | if (NULL == open_devip) { /* try and make a new one */ | 2071 | if (NULL == open_devip) { /* try and make a new one */ |
2047 | open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL); | 2072 | open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC); |
2048 | if (NULL == open_devip) { | 2073 | if (NULL == open_devip) { |
2049 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2074 | printk(KERN_ERR "%s: out of memory at line %d\n", |
2050 | __FUNCTION__, __LINE__); | 2075 | __FUNCTION__, __LINE__); |
@@ -2388,7 +2413,7 @@ MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); | |||
2388 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | 2413 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); |
2389 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2414 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
2390 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); | 2415 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
2391 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); | 2416 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); |
2392 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); | 2417 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); |
2393 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); | 2418 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); |
2394 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); | 2419 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); |
@@ -2943,7 +2968,6 @@ static int sdebug_add_adapter(void) | |||
2943 | struct list_head *lh, *lh_sf; | 2968 | struct list_head *lh, *lh_sf; |
2944 | 2969 | ||
2945 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); | 2970 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
2946 | |||
2947 | if (NULL == sdbg_host) { | 2971 | if (NULL == sdbg_host) { |
2948 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2972 | printk(KERN_ERR "%s: out of memory at line %d\n", |
2949 | __FUNCTION__, __LINE__); | 2973 | __FUNCTION__, __LINE__); |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 2ecb6ff42444..b8edcf5b5451 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -359,6 +359,11 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
359 | return SUCCESS; | 359 | return SUCCESS; |
360 | 360 | ||
361 | case MEDIUM_ERROR: | 361 | case MEDIUM_ERROR: |
362 | if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */ | ||
363 | sshdr.asc == 0x13 || /* AMNF DATA FIELD */ | ||
364 | sshdr.asc == 0x14) { /* RECORD NOT FOUND */ | ||
365 | return SUCCESS; | ||
366 | } | ||
362 | return NEEDS_RETRY; | 367 | return NEEDS_RETRY; |
363 | 368 | ||
364 | case HARDWARE_ERROR: | 369 | case HARDWARE_ERROR: |
@@ -453,6 +458,128 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) | |||
453 | } | 458 | } |
454 | 459 | ||
455 | /** | 460 | /** |
461 | * scsi_try_host_reset - ask host adapter to reset itself | ||
462 | * @scmd: SCSI cmd to send hsot reset. | ||
463 | **/ | ||
464 | static int scsi_try_host_reset(struct scsi_cmnd *scmd) | ||
465 | { | ||
466 | unsigned long flags; | ||
467 | int rtn; | ||
468 | |||
469 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", | ||
470 | __FUNCTION__)); | ||
471 | |||
472 | if (!scmd->device->host->hostt->eh_host_reset_handler) | ||
473 | return FAILED; | ||
474 | |||
475 | rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd); | ||
476 | |||
477 | if (rtn == SUCCESS) { | ||
478 | if (!scmd->device->host->hostt->skip_settle_delay) | ||
479 | ssleep(HOST_RESET_SETTLE_TIME); | ||
480 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
481 | scsi_report_bus_reset(scmd->device->host, | ||
482 | scmd_channel(scmd)); | ||
483 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
484 | } | ||
485 | |||
486 | return rtn; | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * scsi_try_bus_reset - ask host to perform a bus reset | ||
491 | * @scmd: SCSI cmd to send bus reset. | ||
492 | **/ | ||
493 | static int scsi_try_bus_reset(struct scsi_cmnd *scmd) | ||
494 | { | ||
495 | unsigned long flags; | ||
496 | int rtn; | ||
497 | |||
498 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n", | ||
499 | __FUNCTION__)); | ||
500 | |||
501 | if (!scmd->device->host->hostt->eh_bus_reset_handler) | ||
502 | return FAILED; | ||
503 | |||
504 | rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd); | ||
505 | |||
506 | if (rtn == SUCCESS) { | ||
507 | if (!scmd->device->host->hostt->skip_settle_delay) | ||
508 | ssleep(BUS_RESET_SETTLE_TIME); | ||
509 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
510 | scsi_report_bus_reset(scmd->device->host, | ||
511 | scmd_channel(scmd)); | ||
512 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
513 | } | ||
514 | |||
515 | return rtn; | ||
516 | } | ||
517 | |||
518 | /** | ||
519 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev | ||
520 | * @scmd: SCSI cmd used to send BDR | ||
521 | * | ||
522 | * Notes: | ||
523 | * There is no timeout for this operation. if this operation is | ||
524 | * unreliable for a given host, then the host itself needs to put a | ||
525 | * timer on it, and set the host back to a consistent state prior to | ||
526 | * returning. | ||
527 | **/ | ||
528 | static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | ||
529 | { | ||
530 | int rtn; | ||
531 | |||
532 | if (!scmd->device->host->hostt->eh_device_reset_handler) | ||
533 | return FAILED; | ||
534 | |||
535 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); | ||
536 | if (rtn == SUCCESS) { | ||
537 | scmd->device->was_reset = 1; | ||
538 | scmd->device->expecting_cc_ua = 1; | ||
539 | } | ||
540 | |||
541 | return rtn; | ||
542 | } | ||
543 | |||
544 | static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
545 | { | ||
546 | if (!scmd->device->host->hostt->eh_abort_handler) | ||
547 | return FAILED; | ||
548 | |||
549 | return scmd->device->host->hostt->eh_abort_handler(scmd); | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * scsi_try_to_abort_cmd - Ask host to abort a running command. | ||
554 | * @scmd: SCSI cmd to abort from Lower Level. | ||
555 | * | ||
556 | * Notes: | ||
557 | * This function will not return until the user's completion function | ||
558 | * has been called. there is no timeout on this operation. if the | ||
559 | * author of the low-level driver wishes this operation to be timed, | ||
560 | * they can provide this facility themselves. helper functions in | ||
561 | * scsi_error.c can be supplied to make this easier to do. | ||
562 | **/ | ||
563 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
564 | { | ||
565 | /* | ||
566 | * scsi_done was called just after the command timed out and before | ||
567 | * we had a chance to process it. (db) | ||
568 | */ | ||
569 | if (scmd->serial_number == 0) | ||
570 | return SUCCESS; | ||
571 | return __scsi_try_to_abort_cmd(scmd); | ||
572 | } | ||
573 | |||
574 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | ||
575 | { | ||
576 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | ||
577 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | ||
578 | if (scsi_try_bus_reset(scmd) != SUCCESS) | ||
579 | scsi_try_host_reset(scmd); | ||
580 | } | ||
581 | |||
582 | /** | ||
456 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory | 583 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory |
457 | * @scmd: SCSI command structure to hijack | 584 | * @scmd: SCSI command structure to hijack |
458 | * @cmnd: CDB to send | 585 | * @cmnd: CDB to send |
@@ -579,13 +706,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
579 | break; | 706 | break; |
580 | } | 707 | } |
581 | } else { | 708 | } else { |
582 | /* | 709 | scsi_abort_eh_cmnd(scmd); |
583 | * FIXME(eric) - we are not tracking whether we could | ||
584 | * abort a timed out command or not. not sure how | ||
585 | * we should treat them differently anyways. | ||
586 | */ | ||
587 | if (shost->hostt->eh_abort_handler) | ||
588 | shost->hostt->eh_abort_handler(scmd); | ||
589 | rtn = FAILED; | 710 | rtn = FAILED; |
590 | } | 711 | } |
591 | 712 | ||
@@ -672,8 +793,8 @@ EXPORT_SYMBOL(scsi_eh_finish_cmd); | |||
672 | * XXX: Long term this code should go away, but that needs an audit of | 793 | * XXX: Long term this code should go away, but that needs an audit of |
673 | * all LLDDs first. | 794 | * all LLDDs first. |
674 | **/ | 795 | **/ |
675 | static int scsi_eh_get_sense(struct list_head *work_q, | 796 | int scsi_eh_get_sense(struct list_head *work_q, |
676 | struct list_head *done_q) | 797 | struct list_head *done_q) |
677 | { | 798 | { |
678 | struct scsi_cmnd *scmd, *next; | 799 | struct scsi_cmnd *scmd, *next; |
679 | int rtn; | 800 | int rtn; |
@@ -715,31 +836,7 @@ static int scsi_eh_get_sense(struct list_head *work_q, | |||
715 | 836 | ||
716 | return list_empty(work_q); | 837 | return list_empty(work_q); |
717 | } | 838 | } |
718 | 839 | EXPORT_SYMBOL_GPL(scsi_eh_get_sense); | |
719 | /** | ||
720 | * scsi_try_to_abort_cmd - Ask host to abort a running command. | ||
721 | * @scmd: SCSI cmd to abort from Lower Level. | ||
722 | * | ||
723 | * Notes: | ||
724 | * This function will not return until the user's completion function | ||
725 | * has been called. there is no timeout on this operation. if the | ||
726 | * author of the low-level driver wishes this operation to be timed, | ||
727 | * they can provide this facility themselves. helper functions in | ||
728 | * scsi_error.c can be supplied to make this easier to do. | ||
729 | **/ | ||
730 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
731 | { | ||
732 | if (!scmd->device->host->hostt->eh_abort_handler) | ||
733 | return FAILED; | ||
734 | |||
735 | /* | ||
736 | * scsi_done was called just after the command timed out and before | ||
737 | * we had a chance to process it. (db) | ||
738 | */ | ||
739 | if (scmd->serial_number == 0) | ||
740 | return SUCCESS; | ||
741 | return scmd->device->host->hostt->eh_abort_handler(scmd); | ||
742 | } | ||
743 | 840 | ||
744 | /** | 841 | /** |
745 | * scsi_eh_tur - Send TUR to device. | 842 | * scsi_eh_tur - Send TUR to device. |
@@ -815,32 +912,6 @@ static int scsi_eh_abort_cmds(struct list_head *work_q, | |||
815 | } | 912 | } |
816 | 913 | ||
817 | /** | 914 | /** |
818 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev | ||
819 | * @scmd: SCSI cmd used to send BDR | ||
820 | * | ||
821 | * Notes: | ||
822 | * There is no timeout for this operation. if this operation is | ||
823 | * unreliable for a given host, then the host itself needs to put a | ||
824 | * timer on it, and set the host back to a consistent state prior to | ||
825 | * returning. | ||
826 | **/ | ||
827 | static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | ||
828 | { | ||
829 | int rtn; | ||
830 | |||
831 | if (!scmd->device->host->hostt->eh_device_reset_handler) | ||
832 | return FAILED; | ||
833 | |||
834 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); | ||
835 | if (rtn == SUCCESS) { | ||
836 | scmd->device->was_reset = 1; | ||
837 | scmd->device->expecting_cc_ua = 1; | ||
838 | } | ||
839 | |||
840 | return rtn; | ||
841 | } | ||
842 | |||
843 | /** | ||
844 | * scsi_eh_try_stu - Send START_UNIT to device. | 915 | * scsi_eh_try_stu - Send START_UNIT to device. |
845 | * @scmd: Scsi cmd to send START_UNIT | 916 | * @scmd: Scsi cmd to send START_UNIT |
846 | * | 917 | * |
@@ -971,64 +1042,6 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost, | |||
971 | } | 1042 | } |
972 | 1043 | ||
973 | /** | 1044 | /** |
974 | * scsi_try_bus_reset - ask host to perform a bus reset | ||
975 | * @scmd: SCSI cmd to send bus reset. | ||
976 | **/ | ||
977 | static int scsi_try_bus_reset(struct scsi_cmnd *scmd) | ||
978 | { | ||
979 | unsigned long flags; | ||
980 | int rtn; | ||
981 | |||
982 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n", | ||
983 | __FUNCTION__)); | ||
984 | |||
985 | if (!scmd->device->host->hostt->eh_bus_reset_handler) | ||
986 | return FAILED; | ||
987 | |||
988 | rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd); | ||
989 | |||
990 | if (rtn == SUCCESS) { | ||
991 | if (!scmd->device->host->hostt->skip_settle_delay) | ||
992 | ssleep(BUS_RESET_SETTLE_TIME); | ||
993 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
994 | scsi_report_bus_reset(scmd->device->host, | ||
995 | scmd_channel(scmd)); | ||
996 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
997 | } | ||
998 | |||
999 | return rtn; | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
1003 | * scsi_try_host_reset - ask host adapter to reset itself | ||
1004 | * @scmd: SCSI cmd to send hsot reset. | ||
1005 | **/ | ||
1006 | static int scsi_try_host_reset(struct scsi_cmnd *scmd) | ||
1007 | { | ||
1008 | unsigned long flags; | ||
1009 | int rtn; | ||
1010 | |||
1011 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n", | ||
1012 | __FUNCTION__)); | ||
1013 | |||
1014 | if (!scmd->device->host->hostt->eh_host_reset_handler) | ||
1015 | return FAILED; | ||
1016 | |||
1017 | rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd); | ||
1018 | |||
1019 | if (rtn == SUCCESS) { | ||
1020 | if (!scmd->device->host->hostt->skip_settle_delay) | ||
1021 | ssleep(HOST_RESET_SETTLE_TIME); | ||
1022 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
1023 | scsi_report_bus_reset(scmd->device->host, | ||
1024 | scmd_channel(scmd)); | ||
1025 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
1026 | } | ||
1027 | |||
1028 | return rtn; | ||
1029 | } | ||
1030 | |||
1031 | /** | ||
1032 | * scsi_eh_bus_reset - send a bus reset | 1045 | * scsi_eh_bus_reset - send a bus reset |
1033 | * @shost: scsi host being recovered. | 1046 | * @shost: scsi host being recovered. |
1034 | * @eh_done_q: list_head for processed commands. | 1047 | * @eh_done_q: list_head for processed commands. |
@@ -1411,9 +1424,9 @@ static void scsi_restart_operations(struct Scsi_Host *shost) | |||
1411 | * @eh_done_q: list_head for processed commands. | 1424 | * @eh_done_q: list_head for processed commands. |
1412 | * | 1425 | * |
1413 | **/ | 1426 | **/ |
1414 | static void scsi_eh_ready_devs(struct Scsi_Host *shost, | 1427 | void scsi_eh_ready_devs(struct Scsi_Host *shost, |
1415 | struct list_head *work_q, | 1428 | struct list_head *work_q, |
1416 | struct list_head *done_q) | 1429 | struct list_head *done_q) |
1417 | { | 1430 | { |
1418 | if (!scsi_eh_stu(shost, work_q, done_q)) | 1431 | if (!scsi_eh_stu(shost, work_q, done_q)) |
1419 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) | 1432 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) |
@@ -1421,6 +1434,7 @@ static void scsi_eh_ready_devs(struct Scsi_Host *shost, | |||
1421 | if (!scsi_eh_host_reset(work_q, done_q)) | 1434 | if (!scsi_eh_host_reset(work_q, done_q)) |
1422 | scsi_eh_offline_sdevs(work_q, done_q); | 1435 | scsi_eh_offline_sdevs(work_q, done_q); |
1423 | } | 1436 | } |
1437 | EXPORT_SYMBOL_GPL(scsi_eh_ready_devs); | ||
1424 | 1438 | ||
1425 | /** | 1439 | /** |
1426 | * scsi_eh_flush_done_q - finish processed commands or retry them. | 1440 | * scsi_eh_flush_done_q - finish processed commands or retry them. |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a1cd6e6a292a..9f7482d0b594 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1399,7 +1399,7 @@ static void scsi_softirq_done(struct request *rq) | |||
1399 | scsi_finish_command(cmd); | 1399 | scsi_finish_command(cmd); |
1400 | break; | 1400 | break; |
1401 | case NEEDS_RETRY: | 1401 | case NEEDS_RETRY: |
1402 | scsi_retry_command(cmd); | 1402 | scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); |
1403 | break; | 1403 | break; |
1404 | case ADD_TO_MLQUEUE: | 1404 | case ADD_TO_MLQUEUE: |
1405 | scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); | 1405 | scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); |
@@ -2249,6 +2249,8 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, | |||
2249 | size_t sg_len = 0, len_complete = 0; | 2249 | size_t sg_len = 0, len_complete = 0; |
2250 | struct page *page; | 2250 | struct page *page; |
2251 | 2251 | ||
2252 | WARN_ON(!irqs_disabled()); | ||
2253 | |||
2252 | for (i = 0; i < sg_count; i++) { | 2254 | for (i = 0; i < sg_count; i++) { |
2253 | len_complete = sg_len; /* Complete sg-entries */ | 2255 | len_complete = sg_len; /* Complete sg-entries */ |
2254 | sg_len += sg[i].length; | 2256 | sg_len += sg[i].length; |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index f458c2f686d2..ee8efe849bf4 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -28,7 +28,6 @@ extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); | |||
28 | extern int scsi_setup_command_freelist(struct Scsi_Host *shost); | 28 | extern int scsi_setup_command_freelist(struct Scsi_Host *shost); |
29 | extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); | 29 | extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); |
30 | extern void __scsi_done(struct scsi_cmnd *cmd); | 30 | extern void __scsi_done(struct scsi_cmnd *cmd); |
31 | extern int scsi_retry_command(struct scsi_cmnd *cmd); | ||
32 | #ifdef CONFIG_SCSI_LOGGING | 31 | #ifdef CONFIG_SCSI_LOGGING |
33 | void scsi_log_send(struct scsi_cmnd *cmd); | 32 | void scsi_log_send(struct scsi_cmnd *cmd); |
34 | void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); | 33 | void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); |
@@ -58,6 +57,11 @@ extern int scsi_error_handler(void *host); | |||
58 | extern int scsi_decide_disposition(struct scsi_cmnd *cmd); | 57 | extern int scsi_decide_disposition(struct scsi_cmnd *cmd); |
59 | extern void scsi_eh_wakeup(struct Scsi_Host *shost); | 58 | extern void scsi_eh_wakeup(struct Scsi_Host *shost); |
60 | extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); | 59 | extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); |
60 | void scsi_eh_ready_devs(struct Scsi_Host *shost, | ||
61 | struct list_head *work_q, | ||
62 | struct list_head *done_q); | ||
63 | int scsi_eh_get_sense(struct list_head *work_q, | ||
64 | struct list_head *done_q); | ||
61 | 65 | ||
62 | /* scsi_lib.c */ | 66 | /* scsi_lib.c */ |
63 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); | 67 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 96b7cbd746a8..a43b9ec3aefd 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -1029,7 +1029,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
1029 | 1029 | ||
1030 | sdev_printk(KERN_INFO, sdev, | 1030 | sdev_printk(KERN_INFO, sdev, |
1031 | "scsi scan: consider passing scsi_mod." | 1031 | "scsi scan: consider passing scsi_mod." |
1032 | "dev_flags=%s:%s:0x240 or 0x800240\n", | 1032 | "dev_flags=%s:%s:0x240 or 0x1000240\n", |
1033 | scsi_inq_str(vend, result, 8, 16), | 1033 | scsi_inq_str(vend, result, 8, 16), |
1034 | scsi_inq_str(mod, result, 16, 32)); | 1034 | scsi_inq_str(mod, result, 16, 32)); |
1035 | }); | 1035 | }); |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 5c0b75bbfa10..6d39150e205b 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -336,6 +336,51 @@ show_sas_device_type(struct class_device *cdev, char *buf) | |||
336 | } | 336 | } |
337 | static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); | 337 | static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); |
338 | 338 | ||
339 | static ssize_t do_sas_phy_enable(struct class_device *cdev, | ||
340 | size_t count, int enable) | ||
341 | { | ||
342 | struct sas_phy *phy = transport_class_to_phy(cdev); | ||
343 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
344 | struct sas_internal *i = to_sas_internal(shost->transportt); | ||
345 | int error; | ||
346 | |||
347 | error = i->f->phy_enable(phy, enable); | ||
348 | if (error) | ||
349 | return error; | ||
350 | phy->enabled = enable; | ||
351 | return count; | ||
352 | }; | ||
353 | |||
354 | static ssize_t store_sas_phy_enable(struct class_device *cdev, | ||
355 | const char *buf, size_t count) | ||
356 | { | ||
357 | if (count < 1) | ||
358 | return -EINVAL; | ||
359 | |||
360 | switch (buf[0]) { | ||
361 | case '0': | ||
362 | do_sas_phy_enable(cdev, count, 0); | ||
363 | break; | ||
364 | case '1': | ||
365 | do_sas_phy_enable(cdev, count, 1); | ||
366 | break; | ||
367 | default: | ||
368 | return -EINVAL; | ||
369 | } | ||
370 | |||
371 | return count; | ||
372 | } | ||
373 | |||
374 | static ssize_t show_sas_phy_enable(struct class_device *cdev, char *buf) | ||
375 | { | ||
376 | struct sas_phy *phy = transport_class_to_phy(cdev); | ||
377 | |||
378 | return snprintf(buf, 20, "%d", phy->enabled); | ||
379 | } | ||
380 | |||
381 | static CLASS_DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable, | ||
382 | store_sas_phy_enable); | ||
383 | |||
339 | static ssize_t do_sas_phy_reset(struct class_device *cdev, | 384 | static ssize_t do_sas_phy_reset(struct class_device *cdev, |
340 | size_t count, int hard_reset) | 385 | size_t count, int hard_reset) |
341 | { | 386 | { |
@@ -435,6 +480,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) | |||
435 | return NULL; | 480 | return NULL; |
436 | 481 | ||
437 | phy->number = number; | 482 | phy->number = number; |
483 | phy->enabled = 1; | ||
438 | 484 | ||
439 | device_initialize(&phy->dev); | 485 | device_initialize(&phy->dev); |
440 | phy->dev.parent = get_device(parent); | 486 | phy->dev.parent = get_device(parent); |
@@ -579,8 +625,19 @@ static void sas_port_release(struct device *dev) | |||
579 | static void sas_port_create_link(struct sas_port *port, | 625 | static void sas_port_create_link(struct sas_port *port, |
580 | struct sas_phy *phy) | 626 | struct sas_phy *phy) |
581 | { | 627 | { |
582 | sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id); | 628 | int res; |
583 | sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port"); | 629 | |
630 | res = sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, | ||
631 | phy->dev.bus_id); | ||
632 | if (res) | ||
633 | goto err; | ||
634 | res = sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port"); | ||
635 | if (res) | ||
636 | goto err; | ||
637 | return; | ||
638 | err: | ||
639 | printk(KERN_ERR "%s: Cannot create port links, err=%d\n", | ||
640 | __FUNCTION__, res); | ||
584 | } | 641 | } |
585 | 642 | ||
586 | static void sas_port_delete_link(struct sas_port *port, | 643 | static void sas_port_delete_link(struct sas_port *port, |
@@ -818,13 +875,20 @@ EXPORT_SYMBOL(sas_port_delete_phy); | |||
818 | 875 | ||
819 | void sas_port_mark_backlink(struct sas_port *port) | 876 | void sas_port_mark_backlink(struct sas_port *port) |
820 | { | 877 | { |
878 | int res; | ||
821 | struct device *parent = port->dev.parent->parent->parent; | 879 | struct device *parent = port->dev.parent->parent->parent; |
822 | 880 | ||
823 | if (port->is_backlink) | 881 | if (port->is_backlink) |
824 | return; | 882 | return; |
825 | port->is_backlink = 1; | 883 | port->is_backlink = 1; |
826 | sysfs_create_link(&port->dev.kobj, &parent->kobj, | 884 | res = sysfs_create_link(&port->dev.kobj, &parent->kobj, |
827 | parent->bus_id); | 885 | parent->bus_id); |
886 | if (res) | ||
887 | goto err; | ||
888 | return; | ||
889 | err: | ||
890 | printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n", | ||
891 | __FUNCTION__, res); | ||
828 | 892 | ||
829 | } | 893 | } |
830 | EXPORT_SYMBOL(sas_port_mark_backlink); | 894 | EXPORT_SYMBOL(sas_port_mark_backlink); |
@@ -1237,7 +1301,7 @@ int sas_rphy_add(struct sas_rphy *rphy) | |||
1237 | if (identify->device_type == SAS_END_DEVICE && | 1301 | if (identify->device_type == SAS_END_DEVICE && |
1238 | rphy->scsi_target_id != -1) { | 1302 | rphy->scsi_target_id != -1) { |
1239 | scsi_scan_target(&rphy->dev, 0, | 1303 | scsi_scan_target(&rphy->dev, 0, |
1240 | rphy->scsi_target_id, ~0, 0); | 1304 | rphy->scsi_target_id, SCAN_WILD_CARD, 0); |
1241 | } | 1305 | } |
1242 | 1306 | ||
1243 | return 0; | 1307 | return 0; |
@@ -1253,7 +1317,7 @@ EXPORT_SYMBOL(sas_rphy_add); | |||
1253 | * Note: | 1317 | * Note: |
1254 | * This function must only be called on a remote | 1318 | * This function must only be called on a remote |
1255 | * PHY that has not sucessfully been added using | 1319 | * PHY that has not sucessfully been added using |
1256 | * sas_rphy_add(). | 1320 | * sas_rphy_add() (or has been sas_rphy_remove()'d) |
1257 | */ | 1321 | */ |
1258 | void sas_rphy_free(struct sas_rphy *rphy) | 1322 | void sas_rphy_free(struct sas_rphy *rphy) |
1259 | { | 1323 | { |
@@ -1272,18 +1336,30 @@ void sas_rphy_free(struct sas_rphy *rphy) | |||
1272 | EXPORT_SYMBOL(sas_rphy_free); | 1336 | EXPORT_SYMBOL(sas_rphy_free); |
1273 | 1337 | ||
1274 | /** | 1338 | /** |
1275 | * sas_rphy_delete -- remove SAS remote PHY | 1339 | * sas_rphy_delete -- remove and free SAS remote PHY |
1276 | * @rphy: SAS remote PHY to remove | 1340 | * @rphy: SAS remote PHY to remove and free |
1277 | * | 1341 | * |
1278 | * Removes the specified SAS remote PHY. | 1342 | * Removes the specified SAS remote PHY and frees it. |
1279 | */ | 1343 | */ |
1280 | void | 1344 | void |
1281 | sas_rphy_delete(struct sas_rphy *rphy) | 1345 | sas_rphy_delete(struct sas_rphy *rphy) |
1282 | { | 1346 | { |
1347 | sas_rphy_remove(rphy); | ||
1348 | sas_rphy_free(rphy); | ||
1349 | } | ||
1350 | EXPORT_SYMBOL(sas_rphy_delete); | ||
1351 | |||
1352 | /** | ||
1353 | * sas_rphy_remove -- remove SAS remote PHY | ||
1354 | * @rphy: SAS remote phy to remove | ||
1355 | * | ||
1356 | * Removes the specified SAS remote PHY. | ||
1357 | */ | ||
1358 | void | ||
1359 | sas_rphy_remove(struct sas_rphy *rphy) | ||
1360 | { | ||
1283 | struct device *dev = &rphy->dev; | 1361 | struct device *dev = &rphy->dev; |
1284 | struct sas_port *parent = dev_to_sas_port(dev->parent); | 1362 | struct sas_port *parent = dev_to_sas_port(dev->parent); |
1285 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | ||
1286 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | ||
1287 | 1363 | ||
1288 | switch (rphy->identify.device_type) { | 1364 | switch (rphy->identify.device_type) { |
1289 | case SAS_END_DEVICE: | 1365 | case SAS_END_DEVICE: |
@@ -1299,17 +1375,10 @@ sas_rphy_delete(struct sas_rphy *rphy) | |||
1299 | 1375 | ||
1300 | transport_remove_device(dev); | 1376 | transport_remove_device(dev); |
1301 | device_del(dev); | 1377 | device_del(dev); |
1302 | transport_destroy_device(dev); | ||
1303 | |||
1304 | mutex_lock(&sas_host->lock); | ||
1305 | list_del(&rphy->list); | ||
1306 | mutex_unlock(&sas_host->lock); | ||
1307 | 1378 | ||
1308 | parent->rphy = NULL; | 1379 | parent->rphy = NULL; |
1309 | |||
1310 | put_device(dev); | ||
1311 | } | 1380 | } |
1312 | EXPORT_SYMBOL(sas_rphy_delete); | 1381 | EXPORT_SYMBOL(sas_rphy_remove); |
1313 | 1382 | ||
1314 | /** | 1383 | /** |
1315 | * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY | 1384 | * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY |
@@ -1389,6 +1458,10 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1389 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ | 1458 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ |
1390 | !i->f->set_phy_speed, S_IRUGO) | 1459 | !i->f->set_phy_speed, S_IRUGO) |
1391 | 1460 | ||
1461 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func) \ | ||
1462 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ | ||
1463 | !i->f->func, S_IRUGO) | ||
1464 | |||
1392 | #define SETUP_PORT_ATTRIBUTE(field) \ | 1465 | #define SETUP_PORT_ATTRIBUTE(field) \ |
1393 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) | 1466 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) |
1394 | 1467 | ||
@@ -1396,10 +1469,10 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1396 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) | 1469 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) |
1397 | 1470 | ||
1398 | #define SETUP_PHY_ATTRIBUTE_WRONLY(field) \ | 1471 | #define SETUP_PHY_ATTRIBUTE_WRONLY(field) \ |
1399 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) | 1472 | SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, 1) |
1400 | 1473 | ||
1401 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \ | 1474 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \ |
1402 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) | 1475 | SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, i->f->func) |
1403 | 1476 | ||
1404 | #define SETUP_END_DEV_ATTRIBUTE(field) \ | 1477 | #define SETUP_END_DEV_ATTRIBUTE(field) \ |
1405 | SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1) | 1478 | SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1) |
@@ -1479,6 +1552,7 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1479 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); | 1552 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); |
1480 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); | 1553 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
1481 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); | 1554 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
1555 | SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable); | ||
1482 | i->phy_attrs[count] = NULL; | 1556 | i->phy_attrs[count] = NULL; |
1483 | 1557 | ||
1484 | count = 0; | 1558 | count = 0; |
@@ -1587,7 +1661,7 @@ static void __exit sas_transport_exit(void) | |||
1587 | } | 1661 | } |
1588 | 1662 | ||
1589 | MODULE_AUTHOR("Christoph Hellwig"); | 1663 | MODULE_AUTHOR("Christoph Hellwig"); |
1590 | MODULE_DESCRIPTION("SAS Transphy Attributes"); | 1664 | MODULE_DESCRIPTION("SAS Transport Attributes"); |
1591 | MODULE_LICENSE("GPL"); | 1665 | MODULE_LICENSE("GPL"); |
1592 | 1666 | ||
1593 | module_init(sas_transport_init); | 1667 | module_init(sas_transport_init); |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 014d7fea1ff3..6f56f8750635 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -46,7 +46,6 @@ | |||
46 | * two cc/ua clears */ | 46 | * two cc/ua clears */ |
47 | 47 | ||
48 | /* Private data accessors (keep these out of the header file) */ | 48 | /* Private data accessors (keep these out of the header file) */ |
49 | #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) | ||
50 | #define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) | 49 | #define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) |
51 | #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) | 50 | #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) |
52 | 51 | ||
diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 551baccec523..018c65f73ac4 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c | |||
@@ -123,6 +123,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, | |||
123 | hostdata->differential = differential; | 123 | hostdata->differential = differential; |
124 | hostdata->clock = clock; | 124 | hostdata->clock = clock; |
125 | hostdata->chip710 = 1; | 125 | hostdata->chip710 = 1; |
126 | hostdata->burst_length = 8; | ||
126 | 127 | ||
127 | /* and register the chip */ | 128 | /* and register the chip */ |
128 | if((host = NCR_700_detect(&sim710_driver_template, hostdata, dev)) | 129 | if((host = NCR_700_detect(&sim710_driver_template, hostdata, dev)) |
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c new file mode 100644 index 000000000000..6bc505115841 --- /dev/null +++ b/drivers/scsi/sni_53c710.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* -*- mode: c; c-basic-offset: 8 -*- */ | ||
2 | |||
3 | /* SNI RM driver | ||
4 | * | ||
5 | * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com | ||
6 | **----------------------------------------------------------------------------- | ||
7 | ** | ||
8 | ** This program is free software; you can redistribute it and/or modify | ||
9 | ** it under the terms of the GNU General Public License as published by | ||
10 | ** the Free Software Foundation; either version 2 of the License, or | ||
11 | ** (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 | ** You should have received a copy of the GNU General Public License | ||
19 | ** along with this program; if not, write to the Free Software | ||
20 | ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | ** | ||
22 | **----------------------------------------------------------------------------- | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * Based on lasi700.c | ||
27 | */ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/stat.h> | ||
34 | #include <linux/mm.h> | ||
35 | #include <linux/blkdev.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/dma-mapping.h> | ||
39 | #include <linux/platform_device.h> | ||
40 | |||
41 | #include <asm/page.h> | ||
42 | #include <asm/pgtable.h> | ||
43 | #include <asm/irq.h> | ||
44 | #include <asm/delay.h> | ||
45 | |||
46 | #include <scsi/scsi_host.h> | ||
47 | #include <scsi/scsi_device.h> | ||
48 | #include <scsi/scsi_transport.h> | ||
49 | #include <scsi/scsi_transport_spi.h> | ||
50 | |||
51 | #include "53c700.h" | ||
52 | |||
53 | MODULE_AUTHOR("Thomas Bogendörfer"); | ||
54 | MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver"); | ||
55 | MODULE_LICENSE("GPL"); | ||
56 | |||
57 | #define SNIRM710_CLOCK 32 | ||
58 | |||
59 | static struct scsi_host_template snirm710_template = { | ||
60 | .name = "SNI RM SCSI 53c710", | ||
61 | .proc_name = "snirm_53c710", | ||
62 | .this_id = 7, | ||
63 | .module = THIS_MODULE, | ||
64 | }; | ||
65 | |||
66 | static int __init snirm710_probe(struct platform_device *dev) | ||
67 | { | ||
68 | unsigned long base; | ||
69 | struct NCR_700_Host_Parameters *hostdata; | ||
70 | struct Scsi_Host *host; | ||
71 | struct resource *res; | ||
72 | |||
73 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
74 | if (!res) | ||
75 | return -ENODEV; | ||
76 | |||
77 | base = res->start; | ||
78 | hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); | ||
79 | if (!hostdata) { | ||
80 | printk(KERN_ERR "%s: Failed to allocate host data\n", | ||
81 | dev->dev.bus_id); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | hostdata->dev = &dev->dev; | ||
86 | dma_set_mask(&dev->dev, DMA_32BIT_MASK); | ||
87 | hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100); | ||
88 | hostdata->differential = 0; | ||
89 | |||
90 | hostdata->clock = SNIRM710_CLOCK; | ||
91 | hostdata->force_le_on_be = 1; | ||
92 | hostdata->chip710 = 1; | ||
93 | hostdata->burst_length = 4; | ||
94 | |||
95 | host = NCR_700_detect(&snirm710_template, hostdata, &dev->dev); | ||
96 | if (!host) | ||
97 | goto out_kfree; | ||
98 | host->this_id = 7; | ||
99 | host->base = base; | ||
100 | host->irq = platform_get_irq(dev, 0); | ||
101 | if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) { | ||
102 | printk(KERN_ERR "snirm710: request_irq failed!\n"); | ||
103 | goto out_put_host; | ||
104 | } | ||
105 | |||
106 | dev_set_drvdata(&dev->dev, host); | ||
107 | scsi_scan_host(host); | ||
108 | |||
109 | return 0; | ||
110 | |||
111 | out_put_host: | ||
112 | scsi_host_put(host); | ||
113 | out_kfree: | ||
114 | iounmap(hostdata->base); | ||
115 | kfree(hostdata); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | static int __exit snirm710_driver_remove(struct platform_device *dev) | ||
120 | { | ||
121 | struct Scsi_Host *host = dev_get_drvdata(&dev->dev); | ||
122 | struct NCR_700_Host_Parameters *hostdata = | ||
123 | (struct NCR_700_Host_Parameters *)host->hostdata[0]; | ||
124 | |||
125 | scsi_remove_host(host); | ||
126 | NCR_700_release(host); | ||
127 | free_irq(host->irq, host); | ||
128 | iounmap(hostdata->base); | ||
129 | kfree(hostdata); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver snirm710_driver = { | ||
135 | .probe = snirm710_probe, | ||
136 | .remove = __devexit_p(snirm710_driver_remove), | ||
137 | .driver = { | ||
138 | .name = "snirm_53c710", | ||
139 | }, | ||
140 | }; | ||
141 | |||
142 | static int __init snirm710_init(void) | ||
143 | { | ||
144 | int err; | ||
145 | |||
146 | if ((err = platform_driver_register(&snirm710_driver))) { | ||
147 | printk(KERN_ERR "Driver registration failed\n"); | ||
148 | return err; | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void __exit snirm710_exit(void) | ||
154 | { | ||
155 | platform_driver_unregister(&snirm710_driver); | ||
156 | } | ||
157 | |||
158 | module_init(snirm710_init); | ||
159 | module_exit(snirm710_exit); | ||
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 488ec7948a57..16e279be4a3e 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -9,7 +9,7 @@ | |||
9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, | 9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, |
10 | Michael Schaefer, J"org Weule, and Eric Youngdale. | 10 | Michael Schaefer, J"org Weule, and Eric Youngdale. |
11 | 11 | ||
12 | Copyright 1992 - 2006 Kai Makisara | 12 | Copyright 1992 - 2007 Kai Makisara |
13 | email Kai.Makisara@kolumbus.fi | 13 | email Kai.Makisara@kolumbus.fi |
14 | 14 | ||
15 | Some small formal changes - aeb, 950809 | 15 | Some small formal changes - aeb, 950809 |
@@ -17,7 +17,7 @@ | |||
17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support | 17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support |
18 | */ | 18 | */ |
19 | 19 | ||
20 | static const char *verstr = "20061107"; | 20 | static const char *verstr = "20070203"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -1168,6 +1168,7 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1168 | STps = &(STp->ps[i]); | 1168 | STps = &(STp->ps[i]); |
1169 | STps->rw = ST_IDLE; | 1169 | STps->rw = ST_IDLE; |
1170 | } | 1170 | } |
1171 | STp->try_dio_now = STp->try_dio; | ||
1171 | STp->recover_count = 0; | 1172 | STp->recover_count = 0; |
1172 | DEB( STp->nbr_waits = STp->nbr_finished = 0; | 1173 | DEB( STp->nbr_waits = STp->nbr_finished = 0; |
1173 | STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; ) | 1174 | STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; ) |
@@ -1400,9 +1401,9 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | |||
1400 | struct st_buffer *STbp = STp->buffer; | 1401 | struct st_buffer *STbp = STp->buffer; |
1401 | 1402 | ||
1402 | if (is_read) | 1403 | if (is_read) |
1403 | i = STp->try_dio && try_rdio; | 1404 | i = STp->try_dio_now && try_rdio; |
1404 | else | 1405 | else |
1405 | i = STp->try_dio && try_wdio; | 1406 | i = STp->try_dio_now && try_wdio; |
1406 | 1407 | ||
1407 | if (i && ((unsigned long)buf & queue_dma_alignment( | 1408 | if (i && ((unsigned long)buf & queue_dma_alignment( |
1408 | STp->device->request_queue)) == 0) { | 1409 | STp->device->request_queue)) == 0) { |
@@ -1599,7 +1600,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1599 | STm->do_async_writes && STps->eof < ST_EOM_OK; | 1600 | STm->do_async_writes && STps->eof < ST_EOM_OK; |
1600 | 1601 | ||
1601 | if (STp->block_size != 0 && STm->do_buffer_writes && | 1602 | if (STp->block_size != 0 && STm->do_buffer_writes && |
1602 | !(STp->try_dio && try_wdio) && STps->eof < ST_EOM_OK && | 1603 | !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK && |
1603 | STbp->buffer_bytes < STbp->buffer_size) { | 1604 | STbp->buffer_bytes < STbp->buffer_size) { |
1604 | STp->dirty = 1; | 1605 | STp->dirty = 1; |
1605 | /* Don't write a buffer that is not full enough. */ | 1606 | /* Don't write a buffer that is not full enough. */ |
@@ -1769,7 +1770,7 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1769 | if (STp->block_size == 0) | 1770 | if (STp->block_size == 0) |
1770 | blks = bytes = count; | 1771 | blks = bytes = count; |
1771 | else { | 1772 | else { |
1772 | if (!(STp->try_dio && try_rdio) && STm->do_read_ahead) { | 1773 | if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) { |
1773 | blks = (STp->buffer)->buffer_blocks; | 1774 | blks = (STp->buffer)->buffer_blocks; |
1774 | bytes = blks * STp->block_size; | 1775 | bytes = blks * STp->block_size; |
1775 | } else { | 1776 | } else { |
@@ -1948,10 +1949,12 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) | |||
1948 | goto out; | 1949 | goto out; |
1949 | 1950 | ||
1950 | STm = &(STp->modes[STp->current_mode]); | 1951 | STm = &(STp->modes[STp->current_mode]); |
1951 | if (!(STm->do_read_ahead) && STp->block_size != 0 && | 1952 | if (STp->block_size != 0 && (count % STp->block_size) != 0) { |
1952 | (count % STp->block_size) != 0) { | 1953 | if (!STm->do_read_ahead) { |
1953 | retval = (-EINVAL); /* Read must be integral number of blocks */ | 1954 | retval = (-EINVAL); /* Read must be integral number of blocks */ |
1954 | goto out; | 1955 | goto out; |
1956 | } | ||
1957 | STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */ | ||
1955 | } | 1958 | } |
1956 | 1959 | ||
1957 | STps = &(STp->ps[STp->partition]); | 1960 | STps = &(STp->ps[STp->partition]); |
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 05a5cae126ec..50f3deb1f9ed 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -117,7 +117,8 @@ struct scsi_tape { | |||
117 | unsigned char cln_sense_value; | 117 | unsigned char cln_sense_value; |
118 | unsigned char cln_sense_mask; | 118 | unsigned char cln_sense_mask; |
119 | unsigned char use_pf; /* Set Page Format bit in all mode selects? */ | 119 | unsigned char use_pf; /* Set Page Format bit in all mode selects? */ |
120 | unsigned char try_dio; /* try direct i/o? */ | 120 | unsigned char try_dio; /* try direct i/o in general? */ |
121 | unsigned char try_dio_now; /* try direct i/o before next close? */ | ||
121 | unsigned char c_algo; /* compression algorithm */ | 122 | unsigned char c_algo; /* compression algorithm */ |
122 | unsigned char pos_unknown; /* after reset position unknown */ | 123 | unsigned char pos_unknown; /* after reset position unknown */ |
123 | int tape_type; | 124 | int tape_type; |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 0689e004a281..ad0182ef7809 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -323,12 +323,20 @@ struct sas_ha_event { | |||
323 | struct sas_ha_struct *ha; | 323 | struct sas_ha_struct *ha; |
324 | }; | 324 | }; |
325 | 325 | ||
326 | enum sas_ha_state { | ||
327 | SAS_HA_REGISTERED, | ||
328 | SAS_HA_UNREGISTERED | ||
329 | }; | ||
330 | |||
326 | struct sas_ha_struct { | 331 | struct sas_ha_struct { |
327 | /* private: */ | 332 | /* private: */ |
328 | spinlock_t event_lock; | 333 | spinlock_t event_lock; |
329 | struct sas_ha_event ha_events[HA_NUM_EVENTS]; | 334 | struct sas_ha_event ha_events[HA_NUM_EVENTS]; |
330 | unsigned long pending; | 335 | unsigned long pending; |
331 | 336 | ||
337 | enum sas_ha_state state; | ||
338 | spinlock_t state_lock; | ||
339 | |||
332 | struct scsi_core core; | 340 | struct scsi_core core; |
333 | 341 | ||
334 | /* public: */ | 342 | /* public: */ |
@@ -553,7 +561,8 @@ struct sas_task { | |||
553 | #define SAS_TASK_STATE_PENDING 1 | 561 | #define SAS_TASK_STATE_PENDING 1 |
554 | #define SAS_TASK_STATE_DONE 2 | 562 | #define SAS_TASK_STATE_DONE 2 |
555 | #define SAS_TASK_STATE_ABORTED 4 | 563 | #define SAS_TASK_STATE_ABORTED 4 |
556 | #define SAS_TASK_INITIATOR_ABORTED 8 | 564 | #define SAS_TASK_NEED_DEV_RESET 8 |
565 | #define SAS_TASK_AT_INITIATOR 16 | ||
557 | 566 | ||
558 | static inline struct sas_task *sas_alloc_task(gfp_t flags) | 567 | static inline struct sas_task *sas_alloc_task(gfp_t flags) |
559 | { | 568 | { |
@@ -612,6 +621,9 @@ struct sas_domain_function_template { | |||
612 | extern int sas_register_ha(struct sas_ha_struct *); | 621 | extern int sas_register_ha(struct sas_ha_struct *); |
613 | extern int sas_unregister_ha(struct sas_ha_struct *); | 622 | extern int sas_unregister_ha(struct sas_ha_struct *); |
614 | 623 | ||
624 | int sas_set_phy_speed(struct sas_phy *phy, | ||
625 | struct sas_phy_linkrates *rates); | ||
626 | int sas_phy_enable(struct sas_phy *phy, int enabled); | ||
615 | int sas_phy_reset(struct sas_phy *phy, int hard_reset); | 627 | int sas_phy_reset(struct sas_phy *phy, int hard_reset); |
616 | extern int sas_queuecommand(struct scsi_cmnd *, | 628 | extern int sas_queuecommand(struct scsi_cmnd *, |
617 | void (*scsi_done)(struct scsi_cmnd *)); | 629 | void (*scsi_done)(struct scsi_cmnd *)); |
@@ -645,6 +657,9 @@ void sas_unregister_dev(struct domain_device *); | |||
645 | 657 | ||
646 | void sas_init_dev(struct domain_device *); | 658 | void sas_init_dev(struct domain_device *); |
647 | 659 | ||
648 | void sas_task_abort(struct work_struct *); | 660 | void sas_task_abort(struct sas_task *); |
661 | int __sas_task_abort(struct sas_task *); | ||
662 | int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); | ||
663 | int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); | ||
649 | 664 | ||
650 | #endif /* _SASLIB_H_ */ | 665 | #endif /* _SASLIB_H_ */ |
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 59633a82de47..9aedc19820b0 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h | |||
@@ -54,6 +54,7 @@ struct sas_identify { | |||
54 | struct sas_phy { | 54 | struct sas_phy { |
55 | struct device dev; | 55 | struct device dev; |
56 | int number; | 56 | int number; |
57 | int enabled; | ||
57 | 58 | ||
58 | /* phy identification */ | 59 | /* phy identification */ |
59 | struct sas_identify identify; | 60 | struct sas_identify identify; |
@@ -163,6 +164,7 @@ struct sas_function_template { | |||
163 | int (*get_enclosure_identifier)(struct sas_rphy *, u64 *); | 164 | int (*get_enclosure_identifier)(struct sas_rphy *, u64 *); |
164 | int (*get_bay_identifier)(struct sas_rphy *); | 165 | int (*get_bay_identifier)(struct sas_rphy *); |
165 | int (*phy_reset)(struct sas_phy *, int); | 166 | int (*phy_reset)(struct sas_phy *, int); |
167 | int (*phy_enable)(struct sas_phy *, int); | ||
166 | int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); | 168 | int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); |
167 | }; | 169 | }; |
168 | 170 | ||
@@ -180,6 +182,7 @@ extern struct sas_rphy *sas_end_device_alloc(struct sas_port *); | |||
180 | extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); | 182 | extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); |
181 | void sas_rphy_free(struct sas_rphy *); | 183 | void sas_rphy_free(struct sas_rphy *); |
182 | extern int sas_rphy_add(struct sas_rphy *); | 184 | extern int sas_rphy_add(struct sas_rphy *); |
185 | extern void sas_rphy_remove(struct sas_rphy *); | ||
183 | extern void sas_rphy_delete(struct sas_rphy *); | 186 | extern void sas_rphy_delete(struct sas_rphy *); |
184 | extern int scsi_is_sas_rphy(const struct device *); | 187 | extern int scsi_is_sas_rphy(const struct device *); |
185 | 188 | ||
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h index da180f738477..286e9628ed8b 100644 --- a/include/scsi/scsi_transport_spi.h +++ b/include/scsi/scsi_transport_spi.h | |||
@@ -85,6 +85,7 @@ struct spi_host_attrs { | |||
85 | #define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) | 85 | #define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) |
86 | #define spi_hold_mcs(x) (((struct spi_transport_attrs *)&(x)->starget_data)->hold_mcs) | 86 | #define spi_hold_mcs(x) (((struct spi_transport_attrs *)&(x)->starget_data)->hold_mcs) |
87 | #define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) | 87 | #define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) |
88 | #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) | ||
88 | 89 | ||
89 | #define spi_support_sync(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_sync) | 90 | #define spi_support_sync(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_sync) |
90 | #define spi_support_wide(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_wide) | 91 | #define spi_support_wide(x) (((struct spi_transport_attrs *)&(x)->starget_data)->support_wide) |