summaryrefslogtreecommitdiff
path: root/drivers/message
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/Makefile2
-rw-r--r--drivers/message/fusion/Kconfig19
-rw-r--r--drivers/message/fusion/Makefile1
-rw-r--r--drivers/message/fusion/lsi/mpi.h5
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h69
-rw-r--r--drivers/message/fusion/lsi/mpi_fc.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt2
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h3
-rw-r--r--drivers/message/fusion/lsi/mpi_lan.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_log_fc.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_raid.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_targ.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_tool.h1
-rw-r--r--drivers/message/fusion/lsi/mpi_type.h1
-rw-r--r--drivers/message/fusion/mptbase.c528
-rw-r--r--drivers/message/fusion/mptbase.h15
-rw-r--r--drivers/message/fusion/mptctl.c418
-rw-r--r--drivers/message/fusion/mptdebug.h8
-rw-r--r--drivers/message/fusion/mptfc.c204
-rw-r--r--drivers/message/fusion/mptlan.c133
-rw-r--r--drivers/message/fusion/mptlan.h11
-rw-r--r--drivers/message/fusion/mptsas.c531
-rw-r--r--drivers/message/fusion/mptsas.h3
-rw-r--r--drivers/message/fusion/mptscsih.c182
-rw-r--r--drivers/message/fusion/mptscsih.h18
-rw-r--r--drivers/message/fusion/mptspi.c72
-rw-r--r--drivers/message/i2o/Kconfig121
-rw-r--r--drivers/message/i2o/Makefile16
-rw-r--r--drivers/message/i2o/README98
-rw-r--r--drivers/message/i2o/README.ioctl394
-rw-r--r--drivers/message/i2o/bus-osm.c176
-rw-r--r--drivers/message/i2o/config-osm.c90
-rw-r--r--drivers/message/i2o/core.h69
-rw-r--r--drivers/message/i2o/debug.c472
-rw-r--r--drivers/message/i2o/device.c584
-rw-r--r--drivers/message/i2o/driver.c378
-rw-r--r--drivers/message/i2o/exec-osm.c612
-rw-r--r--drivers/message/i2o/i2o_block.c1228
-rw-r--r--drivers/message/i2o/i2o_block.h103
-rw-r--r--drivers/message/i2o/i2o_config.c1163
-rw-r--r--drivers/message/i2o/i2o_proc.c2045
-rw-r--r--drivers/message/i2o/i2o_scsi.c815
-rw-r--r--drivers/message/i2o/iop.c1248
-rw-r--r--drivers/message/i2o/memory.c313
-rw-r--r--drivers/message/i2o/pci.c497
48 files changed, 1025 insertions, 11631 deletions
diff --git a/drivers/message/Makefile b/drivers/message/Makefile
index 97ef5a01ad11..5fe5ecfc5d77 100644
--- a/drivers/message/Makefile
+++ b/drivers/message/Makefile
@@ -1,6 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for MPT based block devices
#
-obj-$(CONFIG_I2O) += i2o/
obj-$(CONFIG_FUSION) += fusion/
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index a34a11d2fef2..88a6e506a942 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -1,8 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
menuconfig FUSION
bool "Fusion MPT device support"
- depends on PCI
- ---help---
+ depends on PCI && HAS_IOPORT
+ help
Say Y here to get to see options for Fusion Message
Passing Technology (MPT) drivers.
This option alone does not add any kernel code.
@@ -15,7 +16,7 @@ config FUSION_SPI
tristate "Fusion MPT ScsiHost drivers for SPI"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
- ---help---
+ help
SCSI HOST support for a parallel SCSI host adapters.
List of supported controllers:
@@ -29,8 +30,8 @@ config FUSION_SPI
config FUSION_FC
tristate "Fusion MPT ScsiHost drivers for FC"
depends on PCI && SCSI
- select SCSI_FC_ATTRS
- ---help---
+ depends on SCSI_FC_ATTRS
+ help
SCSI HOST support for a Fiber Channel host adapters.
List of supported controllers:
@@ -49,7 +50,7 @@ config FUSION_SAS
tristate "Fusion MPT ScsiHost drivers for SAS"
depends on PCI && SCSI
select SCSI_SAS_ATTRS
- ---help---
+ help
SCSI HOST support for a SAS host adapters.
List of supported controllers:
@@ -74,7 +75,7 @@ config FUSION_MAX_SGE
config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver"
depends on FUSION_SPI || FUSION_FC || FUSION_SAS
- ---help---
+ help
The Fusion MPT misc device driver provides specialized control
of MPT adapters via system ioctl calls. Use of ioctl calls to
the MPT driver requires that you create and use a misc device
@@ -93,7 +94,7 @@ config FUSION_CTL
config FUSION_LAN
tristate "Fusion MPT LAN driver"
depends on FUSION_FC && NET_FC
- ---help---
+ help
This module supports LAN IP traffic over Fibre Channel port(s)
on Fusion MPT compatible hardware (LSIFC9xx chips).
The physical interface used is defined in RFC 2625.
@@ -109,7 +110,7 @@ config FUSION_LAN
config FUSION_LOGGING
bool "Fusion MPT logging facility"
- ---help---
+ help
This turns on a logging facility that can be used to debug a number
of Fusion MPT related problems.
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index d182a24b3195..e2d98b5c6f98 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Fusion MPT drivers; recognized debug defines...
# enable verbose logging
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 11c0f461320e..eccbe54d43f3 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
@@ -423,8 +424,8 @@ typedef struct _SGE_TRANSACTION32
U8 ContextSize;
U8 DetailsLength;
U8 Flags;
- U32 TransactionContext[1];
- U32 TransactionDetails[1];
+ U32 TransactionContext;
+ U32 TransactionDetails[];
} SGE_TRANSACTION32, MPI_POINTER PTR_SGE_TRANSACTION32,
SGETransaction32_t, MPI_POINTER pSGETransaction32_t;
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index d9bcfba6b049..1167a16d8fb4 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
@@ -312,7 +313,7 @@
* define.
* Added BIOS Page 4 structure.
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
- * Physcial Disk Page 1.
+ * Physical Disk Page 1.
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
* Manufacturing Page 4.
* Added Solid State Drives Supported bit to IOC Page 6
@@ -1017,14 +1018,6 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
#define MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE (0x08)
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI_IOC_PAGE_2_RAID_VOLUME_MAX
-#define MPI_IOC_PAGE_2_RAID_VOLUME_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_IOC_2
{
CONFIG_PAGE_HEADER Header; /* 00h */
@@ -1033,7 +1026,7 @@ typedef struct _CONFIG_PAGE_IOC_2
U8 MaxVolumes; /* 09h */
U8 NumActivePhysDisks; /* 0Ah */
U8 MaxPhysDisks; /* 0Bh */
- CONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[MPI_IOC_PAGE_2_RAID_VOLUME_MAX];/* 0Ch */
+ CONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[] __counted_by(NumActiveVolumes); /* 0Ch */
} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
IOCPage2_t, MPI_POINTER pIOCPage2_t;
@@ -1063,21 +1056,13 @@ typedef struct _IOC_3_PHYS_DISK
} IOC_3_PHYS_DISK, MPI_POINTER PTR_IOC_3_PHYS_DISK,
Ioc3PhysDisk_t, MPI_POINTER pIoc3PhysDisk_t;
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI_IOC_PAGE_3_PHYSDISK_MAX
-#define MPI_IOC_PAGE_3_PHYSDISK_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_IOC_3
{
CONFIG_PAGE_HEADER Header; /* 00h */
U8 NumPhysDisks; /* 04h */
U8 Reserved1; /* 05h */
U16 Reserved2; /* 06h */
- IOC_3_PHYS_DISK PhysDisk[MPI_IOC_PAGE_3_PHYSDISK_MAX]; /* 08h */
+ IOC_3_PHYS_DISK PhysDisk[] __counted_by(NumPhysDisks); /* 08h */
} CONFIG_PAGE_IOC_3, MPI_POINTER PTR_CONFIG_PAGE_IOC_3,
IOCPage3_t, MPI_POINTER pIOCPage3_t;
@@ -1092,21 +1077,13 @@ typedef struct _IOC_4_SEP
} IOC_4_SEP, MPI_POINTER PTR_IOC_4_SEP,
Ioc4Sep_t, MPI_POINTER pIoc4Sep_t;
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI_IOC_PAGE_4_SEP_MAX
-#define MPI_IOC_PAGE_4_SEP_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_IOC_4
{
CONFIG_PAGE_HEADER Header; /* 00h */
U8 ActiveSEP; /* 04h */
U8 MaxSEP; /* 05h */
U16 Reserved1; /* 06h */
- IOC_4_SEP SEP[MPI_IOC_PAGE_4_SEP_MAX]; /* 08h */
+ IOC_4_SEP SEP[] __counted_by(ActiveSEP); /* 08h */
} CONFIG_PAGE_IOC_4, MPI_POINTER PTR_CONFIG_PAGE_IOC_4,
IOCPage4_t, MPI_POINTER pIOCPage4_t;
@@ -1801,13 +1778,13 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
#define MPI_FCPORTPAGE0_SUPPORT_CLASS_2 (0x00000002)
#define MPI_FCPORTPAGE0_SUPPORT_CLASS_3 (0x00000004)
-#define MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0 Unknown - transceiver incapable of reporting */
+#define MPI_FCPORTPAGE0_SUPPORT_SPEED_UNKNOWN (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0 Unknown - transceiver incapable of reporting */
#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1 1 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2 2 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */
#define MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED (0x00000008) /* (SNIA)HBA_PORTSPEED_4GBIT 8 4 GBit/sec */
-#define MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN
+#define MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN MPI_FCPORTPAGE0_SUPPORT_SPEED_UNKNOWN
#define MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED
#define MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED
@@ -2003,7 +1980,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_6
U64 LinkFailureCount; /* 50h */
U64 LossOfSyncCount; /* 58h */
U64 LossOfSignalCount; /* 60h */
- U64 PrimativeSeqErrCount; /* 68h */
+ U64 PrimitiveSeqErrCount; /* 68h */
U64 InvalidTxWordCount; /* 70h */
U64 InvalidCrcCount; /* 78h */
U64 FcpInitiatorIoCount; /* 80h */
@@ -2294,14 +2271,6 @@ typedef struct _RAID_VOL0_SETTINGS
#define MPI_RAID_HOT_SPARE_POOL_6 (0x40)
#define MPI_RAID_HOT_SPARE_POOL_7 (0x80)
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX
-#define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_RAID_VOL_0
{
CONFIG_PAGE_HEADER Header; /* 00h */
@@ -2320,7 +2289,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
U8 DataScrubRate; /* 25h */
U8 ResyncRate; /* 26h */
U8 InactiveStatus; /* 27h */
- RAID_VOL0_PHYS_DISK PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX];/* 28h */
+ RAID_VOL0_PHYS_DISK PhysDisk[] __counted_by(NumPhysDisks); /* 28h */
} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
@@ -2454,14 +2423,6 @@ typedef struct _RAID_PHYS_DISK1_PATH
#define MPI_RAID_PHYSDISK1_FLAG_INVALID (0x0001)
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength or NumPhysDiskPaths at runtime.
- */
-#ifndef MPI_RAID_PHYS_DISK1_PATH_MAX
-#define MPI_RAID_PHYS_DISK1_PATH_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1
{
CONFIG_PAGE_HEADER Header; /* 00h */
@@ -2469,7 +2430,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1
U8 PhysDiskNum; /* 05h */
U16 Reserved2; /* 06h */
U32 Reserved1; /* 08h */
- RAID_PHYS_DISK1_PATH Path[MPI_RAID_PHYS_DISK1_PATH_MAX];/* 0Ch */
+ RAID_PHYS_DISK1_PATH Path[] __counted_by(NumPhysDiskPaths);/* 0Ch */
} CONFIG_PAGE_RAID_PHYS_DISK_1, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_1,
RaidPhysDiskPage1_t, MPI_POINTER pRaidPhysDiskPage1_t;
@@ -2554,14 +2515,6 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA
} MPI_SAS_IO_UNIT0_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT0_PHY_DATA,
SasIOUnit0PhyData, MPI_POINTER pSasIOUnit0PhyData;
-/*
- * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
- * one and check Header.PageLength at runtime.
- */
-#ifndef MPI_SAS_IOUNIT0_PHY_MAX
-#define MPI_SAS_IOUNIT0_PHY_MAX (1)
-#endif
-
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
@@ -2570,7 +2523,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
U8 NumPhys; /* 0Ch */
U8 Reserved2; /* 0Dh */
U16 Reserved3; /* 0Eh */
- MPI_SAS_IO_UNIT0_PHY_DATA PhyData[MPI_SAS_IOUNIT0_PHY_MAX]; /* 10h */
+ MPI_SAS_IO_UNIT0_PHY_DATA PhyData[] __counted_by(NumPhys); /* 10h */
} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
diff --git a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h
index 7d663ce76f8c..bdea95e0cde2 100644
--- a/drivers/message/fusion/lsi/mpi_fc.h
+++ b/drivers/message/fusion/lsi/mpi_fc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index fa9249b4971a..2f76204fa1b0 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -513,7 +513,7 @@ mpi_cnfg.h
* define.
* Added BIOS Page 4 structure.
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
- * Physcial Disk Page 1.
+ * Physical Disk Page 1.
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
* Manufacturing Page 4.
* Added Solid State Drives Supported bit to IOC Page 6
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index 4295d062caa7..bc6326ff2f22 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 19fb21b8f0ce..1534460fd5b1 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
@@ -447,7 +448,7 @@ typedef struct _MSG_EVENT_NOTIFY_REPLY
U32 IOCLogInfo; /* 10h */
U32 Event; /* 14h */
U32 EventContext; /* 18h */
- U32 Data[1]; /* 1Ch */
+ U32 Data[]; /* 1Ch */
} MSG_EVENT_NOTIFY_REPLY, MPI_POINTER PTR_MSG_EVENT_NOTIFY_REPLY,
EventNotificationReply_t, MPI_POINTER pEventNotificationReply_t;
diff --git a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h
index f41fcb69b359..d06f9928684a 100644
--- a/drivers/message/fusion/lsi/mpi_lan.h
+++ b/drivers/message/fusion/lsi/mpi_lan.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h
index 03be8b217709..f1e75dd5dd58 100644
--- a/drivers/message/fusion/lsi/mpi_log_fc.h
+++ b/drivers/message/fusion/lsi/mpi_log_fc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation. All rights reserved.
*
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index f62960b5d527..27fe17a75eaa 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/***************************************************************************
* *
* Copyright (c) 2000-2008 LSI Corporation. All rights reserved. *
diff --git a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h
index add60cc85be1..36688a921ef2 100644
--- a/drivers/message/fusion/lsi/mpi_raid.h
+++ b/drivers/message/fusion/lsi/mpi_raid.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2001-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index ab410036bbfc..56013f288aaa 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2004-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
index c3dea7f6909d..97e6eead6cb4 100644
--- a/drivers/message/fusion/lsi/mpi_targ.h
+++ b/drivers/message/fusion/lsi/mpi_targ.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h
index 53cd715aa7e4..b11456fb8277 100644
--- a/drivers/message/fusion/lsi/mpi_tool.h
+++ b/drivers/message/fusion/lsi/mpi_tool.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2001-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h
index 888b26dbc413..073e637cfdb4 100644
--- a/drivers/message/fusion/lsi/mpi_type.h
+++ b/drivers/message/fusion/lsi/mpi_type.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2000-2008 LSI Corporation.
*
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 767ff4d839f4..e60a8d3947c9 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -57,12 +57,8 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
-#include <linux/interrupt.h> /* needed for in_interrupt() proto */
+#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
#include <linux/kthread.h>
#include <scsi/scsi_host.h>
@@ -103,7 +99,7 @@ module_param(mpt_channel_mapping, int, 0);
MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
static int mpt_debug_level;
-static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
+static int mpt_set_debug_level(const char *val, const struct kernel_param *kp);
module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
&mpt_debug_level, 0600);
MODULE_PARM_DESC(mpt_debug_level,
@@ -201,9 +197,9 @@ static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_valu
static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
#ifdef CONFIG_PROC_FS
-static const struct file_operations mpt_summary_proc_fops;
-static const struct file_operations mpt_version_proc_fops;
-static const struct file_operations mpt_iocinfo_proc_fops;
+static int mpt_summary_proc_show(struct seq_file *m, void *v);
+static int mpt_version_proc_show(struct seq_file *m, void *v);
+static int mpt_iocinfo_proc_show(struct seq_file *m, void *v);
#endif
static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
@@ -246,7 +242,7 @@ pci_enable_io_access(struct pci_dev *pdev)
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
}
-static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
+static int mpt_set_debug_level(const char *val, const struct kernel_param *kp)
{
int ret = param_set_int(val, kp);
MPT_ADAPTER *ioc;
@@ -304,8 +300,8 @@ mpt_is_discovery_complete(MPT_ADAPTER *ioc)
if (!hdr.ExtPageLength)
goto out;
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer)
goto out;
@@ -320,8 +316,8 @@ mpt_is_discovery_complete(MPT_ADAPTER *ioc)
rc = 1;
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return rc;
}
@@ -339,14 +335,14 @@ static int mpt_remove_dead_ioc_func(void *arg)
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
struct pci_dev *pdev;
- if ((ioc == NULL))
+ if (!ioc)
return -1;
pdev = ioc->pcidev;
- if ((pdev == NULL))
+ if (!pdev)
return -1;
- pci_stop_and_remove_bus_device(pdev);
+ pci_stop_and_remove_bus_device_locked(pdev);
return 0;
}
@@ -477,7 +473,6 @@ mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
mpt_free_msg_frame(ioc, mf);
mb();
return;
- break;
}
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
break;
@@ -646,15 +641,14 @@ mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
freereq = 0;
if (event != MPI_EVENT_EVENT_CHANGE)
break;
+ fallthrough;
case MPI_FUNCTION_CONFIG:
case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
- if (reply) {
- ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
- memcpy(ioc->mptbase_cmds.reply, reply,
- min(MPT_DEFAULT_FRAME_SIZE,
- 4 * reply->u.reply.MsgLength));
- }
+ ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
+ memcpy(ioc->mptbase_cmds.reply, reply,
+ min(MPT_DEFAULT_FRAME_SIZE,
+ 4 * reply->u.reply.MsgLength));
if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
complete(&ioc->mptbase_cmds.done);
@@ -718,7 +712,7 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
MptDriverClass[cb_idx] = dclass;
MptEvHandlers[cb_idx] = NULL;
last_drv_idx = cb_idx;
- strlcpy(MptCallbacksName[cb_idx], func_name,
+ strscpy(MptCallbacksName[cb_idx], func_name,
MPT_MAX_CALLBACKNAME_LEN+1);
break;
}
@@ -835,7 +829,6 @@ int
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
{
MPT_ADAPTER *ioc;
- const struct pci_device_id *id;
if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
return -EINVAL;
@@ -844,10 +837,8 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
/* call per pci device probe entry point */
list_for_each_entry(ioc, &ioc_list, list) {
- id = ioc->pcidev->driver ?
- ioc->pcidev->driver->id_table : NULL;
if (dd_cbfunc->probe)
- dd_cbfunc->probe(ioc->pcidev, id);
+ dd_cbfunc->probe(ioc->pcidev);
}
return 0;
@@ -964,7 +955,7 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
u32 mf_dma_addr;
int req_offset;
- u16 req_idx; /* Request index */
+ u16 req_idx; /* Request index */
/* ensure values are reset properly! */
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
@@ -1000,7 +991,7 @@ mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
u32 mf_dma_addr;
int req_offset;
- u16 req_idx; /* Request index */
+ u16 req_idx; /* Request index */
/* ensure values are reset properly! */
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
@@ -1037,7 +1028,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
goto out;
/* signature to know if this mf is freed */
mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
- list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
+ list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
#ifdef MFCNT
ioc->mfcnt--;
#endif
@@ -1134,11 +1125,12 @@ mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
static void
mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
{
- SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
- pChain->Length = cpu_to_le16(length);
- pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
- pChain->NextChainOffset = next;
- pChain->Address = cpu_to_le32(dma_addr);
+ SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
+
+ pChain->Length = cpu_to_le16(length);
+ pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
+ pChain->NextChainOffset = next;
+ pChain->Address = cpu_to_le32(dma_addr);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1153,18 +1145,18 @@ mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
static void
mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
{
- SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
- u32 tmp = dma_addr & 0xFFFFFFFF;
+ SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
+ u32 tmp = dma_addr & 0xFFFFFFFF;
- pChain->Length = cpu_to_le16(length);
- pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
- MPI_SGE_FLAGS_64_BIT_ADDRESSING);
+ pChain->Length = cpu_to_le16(length);
+ pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
+ MPI_SGE_FLAGS_64_BIT_ADDRESSING);
- pChain->NextChainOffset = next;
+ pChain->NextChainOffset = next;
- pChain->Address.Low = cpu_to_le32(tmp);
- tmp = (u32)(upper_32_bits(dma_addr));
- pChain->Address.High = cpu_to_le32(tmp);
+ pChain->Address.Low = cpu_to_le32(tmp);
+ tmp = (u32)(upper_32_bits(dma_addr));
+ pChain->Address.High = cpu_to_le32(tmp);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1282,8 +1274,6 @@ mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
static int
mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
{
- int r = 0;
-
/* return if in use */
if (CHIPREG_READ32(&ioc->chip->Doorbell)
& MPI_DOORBELL_ACTIVE)
@@ -1297,9 +1287,9 @@ mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int slee
(access_control_value<<12)));
/* Wait for IOC to clear Doorbell Status bit */
- if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
+ if (WaitForDoorbellAck(ioc, 5, sleepFlag) < 0)
return -2;
- }else
+ else
return 0;
}
@@ -1328,13 +1318,13 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
return 0; /* fw doesn't need any host buffers */
/* spin till we get enough memory */
- while(host_page_buffer_sz > 0) {
-
- if((ioc->HostPageBuffer = pci_alloc_consistent(
- ioc->pcidev,
- host_page_buffer_sz,
- &ioc->HostPageBuffer_dma)) != NULL) {
-
+ while (host_page_buffer_sz > 0) {
+ ioc->HostPageBuffer =
+ dma_alloc_coherent(&ioc->pcidev->dev,
+ host_page_buffer_sz,
+ &ioc->HostPageBuffer_dma,
+ GFP_KERNEL);
+ if (ioc->HostPageBuffer) {
dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
ioc->name, ioc->HostPageBuffer,
@@ -1366,7 +1356,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
-return 0;
+ return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1402,14 +1392,13 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
* @vendor: pci vendor id
* @device: pci device id
* @revision: pci revision id
- * @prod_name: string returned
*
* Returns product string displayed when driver loads,
* in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
*
**/
-static void
-mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
+static const char*
+mpt_get_product_name(u16 vendor, u16 device, u8 revision)
{
char *product_str = NULL;
@@ -1635,8 +1624,7 @@ mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
}
out:
- if (product_str)
- sprintf(prod_name, "%s", product_str);
+ return product_str;
}
/**
@@ -1673,16 +1661,14 @@ mpt_mapresources(MPT_ADAPTER *ioc)
const uint64_t required_mask = dma_get_required_mask
(&pdev->dev);
if (required_mask > DMA_BIT_MASK(32)
- && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
- && !pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(64))) {
+ && !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))
+ && !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
ioc->dma_mask = DMA_BIT_MASK(64);
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
ioc->name));
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
- && !pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(32))) {
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))
+ && !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
ioc->dma_mask = DMA_BIT_MASK(32);
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
@@ -1693,9 +1679,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
goto out_pci_release_region;
}
} else {
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
- && !pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(32))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))
+ && !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
ioc->dma_mask = DMA_BIT_MASK(32);
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
@@ -1786,7 +1771,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
struct proc_dir_entry *dent;
#endif
- ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
+ ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
if (ioc == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
return -ENOMEM;
@@ -1809,8 +1794,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->pcidev = pdev;
if (mpt_mapresources(ioc)) {
- kfree(ioc);
- return r;
+ goto out_free_ioc;
}
/*
@@ -1872,29 +1856,28 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initialize workqueue */
INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
- snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
- "mpt_poll_%d", ioc->id);
ioc->reset_work_q =
- create_singlethread_workqueue(ioc->reset_work_q_name);
+ alloc_workqueue("mpt_poll_%d", WQ_MEM_RECLAIM | WQ_PERCPU, 0,
+ ioc->id);
if (!ioc->reset_work_q) {
printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
ioc->name);
- pci_release_selected_regions(pdev, ioc->bars);
- kfree(ioc);
- return -ENOMEM;
+ r = -ENOMEM;
+ goto out_unmap_resources;
}
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
ioc->name, &ioc->facts, &ioc->pfacts[0]));
- mpt_get_product_name(pdev->vendor, pdev->device, pdev->revision,
- ioc->prod_name);
+ ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
+ pdev->revision);
switch (pdev->device)
{
case MPI_MANUFACTPAGE_DEVICEID_FC939X:
case MPI_MANUFACTPAGE_DEVICEID_FC949X:
ioc->errata_flag_1064 = 1;
+ fallthrough;
case MPI_MANUFACTPAGE_DEVICEID_FC909:
case MPI_MANUFACTPAGE_DEVICEID_FC929:
case MPI_MANUFACTPAGE_DEVICEID_FC919:
@@ -1939,6 +1922,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
+ fallthrough;
case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
ioc->bus_type = SPI;
@@ -2001,18 +1985,30 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_LIST_HEAD(&ioc->fw_event_list);
spin_lock_init(&ioc->fw_event_lock);
- snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
- ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
+ ioc->fw_event_q = alloc_workqueue("mpt/%d",
+ WQ_MEM_RECLAIM | WQ_PERCPU, 0,
+ ioc->id);
+ if (!ioc->fw_event_q) {
+ printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
+ ioc->name);
+ r = -ENOMEM;
+ goto out_remove_ioc;
+ }
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
CAN_SLEEP)) != 0){
printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
ioc->name, r);
+ destroy_workqueue(ioc->fw_event_q);
+ ioc->fw_event_q = NULL;
+
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
iounmap(ioc->memmap);
+ if (pci_is_enabled(pdev))
+ pci_disable_device(pdev);
if (r != -5)
pci_release_selected_regions(pdev, ioc->bars);
@@ -2020,7 +2016,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->reset_work_q = NULL;
kfree(ioc);
- pci_set_drvdata(pdev, NULL);
return r;
}
@@ -2028,7 +2023,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
if(MptDeviceDriverHandlers[cb_idx] &&
MptDeviceDriverHandlers[cb_idx]->probe) {
- MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
+ MptDeviceDriverHandlers[cb_idx]->probe(pdev);
}
}
@@ -2038,8 +2033,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
*/
dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
if (dent) {
- proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
- proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
+ proc_create_single_data("info", S_IRUGO, dent,
+ mpt_iocinfo_proc_show, ioc);
+ proc_create_single_data("summary", S_IRUGO, dent,
+ mpt_summary_proc_show, ioc);
}
#endif
@@ -2048,6 +2045,24 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
msecs_to_jiffies(MPT_POLLING_INTERVAL));
return 0;
+
+out_remove_ioc:
+ list_del(&ioc->list);
+ if (ioc->alt_ioc)
+ ioc->alt_ioc->alt_ioc = NULL;
+
+ destroy_workqueue(ioc->reset_work_q);
+ ioc->reset_work_q = NULL;
+
+out_unmap_resources:
+ iounmap(ioc->memmap);
+ pci_disable_device(pdev);
+ pci_release_selected_regions(pdev, ioc->bars);
+
+out_free_ioc:
+ kfree(ioc);
+
+ return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2060,7 +2075,7 @@ void
mpt_detach(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
- char pname[32];
+ char pname[64];
u8 cb_idx;
unsigned long flags;
struct workqueue_struct *wq;
@@ -2081,11 +2096,11 @@ mpt_detach(struct pci_dev *pdev)
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
destroy_workqueue(wq);
- sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
+ snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
remove_proc_entry(pname, NULL);
- sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
+ snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
remove_proc_entry(pname, NULL);
- sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
+ snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
remove_proc_entry(pname, NULL);
/* call per device driver remove entry point */
@@ -2133,7 +2148,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
device_state);
/* put ioc into READY_STATE */
- if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
+ if (SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
printk(MYIOC_s_ERR_FMT
"pci-suspend: IOC msg unit reset failed!\n", ioc->name);
}
@@ -2566,10 +2581,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
(void) GetLanConfigPages(ioc);
a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "LanAddr = %02X:%02X:%02X"
- ":%02X:%02X:%02X\n",
- ioc->name, a[5], a[4],
- a[3], a[2], a[1], a[0]));
+ "LanAddr = %pMR\n", ioc->name, a));
}
break;
@@ -2719,8 +2731,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
sz = ioc->alloc_sz;
dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
ioc->name, ioc->alloc, ioc->alloc_sz));
- pci_free_consistent(ioc->pcidev, sz,
- ioc->alloc, ioc->alloc_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
+ ioc->alloc_dma);
ioc->reply_frames = NULL;
ioc->req_frames = NULL;
ioc->alloc = NULL;
@@ -2729,8 +2741,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->sense_buf_pool != NULL) {
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
- pci_free_consistent(ioc->pcidev, sz,
- ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
+ ioc->sense_buf_pool_dma);
ioc->sense_buf_pool = NULL;
ioc->alloc_total -= sz;
}
@@ -2753,9 +2765,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz;
- pci_free_consistent(ioc->pcidev, sz,
- ioc->spi_data.pIocPg4,
- ioc->spi_data.IocPg4_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz,
+ ioc->spi_data.pIocPg4,
+ ioc->spi_data.IocPg4_dma);
ioc->spi_data.pIocPg4 = NULL;
ioc->alloc_total -= sz;
}
@@ -2780,7 +2792,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
"HostPageBuffer free @ %p, sz=%d bytes\n",
ioc->name, ioc->HostPageBuffer,
ioc->HostPageBuffer_sz));
- pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
+ dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz,
ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
ioc->HostPageBuffer = NULL;
ioc->HostPageBuffer_sz = 0;
@@ -2824,13 +2836,6 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
pci_disable_device(ioc->pcidev);
pci_release_selected_regions(ioc->pcidev, ioc->bars);
-#if defined(CONFIG_MTRR) && 0
- if (ioc->mtrr_reg > 0) {
- mtrr_del(ioc->mtrr_reg, 0, 0);
- dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
- }
-#endif
-
/* Zap the adapter lookup ptr! */
list_del(&ioc->list);
@@ -2856,21 +2861,21 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
printk(KERN_INFO "%s: ", ioc->name);
if (ioc->prod_name)
- printk("%s: ", ioc->prod_name);
- printk("Capabilities={");
+ pr_cont("%s: ", ioc->prod_name);
+ pr_cont("Capabilities={");
if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
- printk("Initiator");
+ pr_cont("Initiator");
i++;
}
if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
- printk("%sTarget", i ? "," : "");
+ pr_cont("%sTarget", i ? "," : "");
i++;
}
if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
- printk("%sLAN", i ? "," : "");
+ pr_cont("%sLAN", i ? "," : "");
i++;
}
@@ -2879,12 +2884,12 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
* This would probably evoke more questions than it's worth
*/
if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
- printk("%sLogBusAddr", i ? "," : "");
+ pr_cont("%sLogBusAddr", i ? "," : "");
i++;
}
#endif
- printk("}\n");
+ pr_cont("}\n");
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -3070,7 +3075,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
int req_sz;
int reply_sz;
int sz;
- u32 status, vv;
+ u32 vv;
u8 shiftFactor=1;
/* IOC *must* NOT be in RESET state! */
@@ -3128,7 +3133,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
- status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
/* CHECKME! IOCStatus, IOCLogInfo */
facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
@@ -3175,12 +3179,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
}
- sz = facts->FWImageSize;
- if ( sz & 0x01 )
- sz += 1;
- if ( sz & 0x02 )
- sz += 2;
- facts->FWImageSize = sz;
+ facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
if (!facts->RequestFrameSize) {
/* Something is wrong! */
@@ -3512,7 +3511,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
rc = 0;
goto out;
}
- ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
+ ioc->cached_fw = dma_alloc_coherent(&ioc->pcidev->dev, size,
+ &ioc->cached_fw_dma, GFP_ATOMIC);
if (!ioc->cached_fw) {
printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
ioc->name);
@@ -3545,7 +3545,8 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
sz = ioc->facts.FWImageSize;
dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
- pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, ioc->cached_fw,
+ ioc->cached_fw_dma);
ioc->alloc_total -= sz;
ioc->cached_fw = NULL;
}
@@ -4444,9 +4445,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
*/
if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
ioc->dma_mask > DMA_BIT_MASK(35)) {
- if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
- && !pci_set_consistent_dma_mask(ioc->pcidev,
- DMA_BIT_MASK(32))) {
+ if (!dma_set_mask(&ioc->pcidev->dev, DMA_BIT_MASK(32))
+ && !dma_set_coherent_mask(&ioc->pcidev->dev, DMA_BIT_MASK(32))) {
dma_mask = DMA_BIT_MASK(35);
d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"setting 35 bit addressing for "
@@ -4454,10 +4454,10 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->name));
} else {
/*Reseting DMA mask to 64 bit*/
- pci_set_dma_mask(ioc->pcidev,
- DMA_BIT_MASK(64));
- pci_set_consistent_dma_mask(ioc->pcidev,
- DMA_BIT_MASK(64));
+ dma_set_mask(&ioc->pcidev->dev,
+ DMA_BIT_MASK(64));
+ dma_set_coherent_mask(&ioc->pcidev->dev,
+ DMA_BIT_MASK(64));
printk(MYIOC_s_ERR_FMT
"failed setting 35 bit addressing for "
@@ -4487,7 +4487,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->name, sz, sz, num_chain));
total_size += sz;
- mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
+ mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size,
+ &alloc_dma, GFP_KERNEL);
if (mem == NULL) {
printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
ioc->name);
@@ -4521,19 +4522,6 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
-#if defined(CONFIG_MTRR) && 0
- /*
- * Enable Write Combining MTRR for IOC's memory region.
- * (at least as much as we can; "size and base must be
- * multiples of 4 kiB"
- */
- ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
- sz,
- MTRR_TYPE_WRCOMB, 1);
- dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
- ioc->name, ioc->req_frames_dma, sz));
-#endif
-
for (i = 0; i < ioc->req_depth; i++) {
alloc_dma += ioc->req_sz;
mem += ioc->req_sz;
@@ -4577,8 +4565,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
- ioc->sense_buf_pool =
- pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
+ ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz,
+ &ioc->sense_buf_pool_dma, GFP_KERNEL);
if (ioc->sense_buf_pool == NULL) {
printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
ioc->name);
@@ -4604,8 +4592,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
alloc_dma += ioc->reply_sz;
}
- if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
- ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
+ if (dma_mask == DMA_BIT_MASK(35) && !dma_set_mask(&ioc->pcidev->dev,
+ ioc->dma_mask) && !dma_set_coherent_mask(&ioc->pcidev->dev,
ioc->dma_mask))
d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"restoring 64 bit addressing\n", ioc->name));
@@ -4616,23 +4604,21 @@ out_fail:
if (ioc->alloc != NULL) {
sz = ioc->alloc_sz;
- pci_free_consistent(ioc->pcidev,
- sz,
- ioc->alloc, ioc->alloc_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
+ ioc->alloc_dma);
ioc->reply_frames = NULL;
ioc->req_frames = NULL;
ioc->alloc_total -= sz;
}
if (ioc->sense_buf_pool != NULL) {
sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
- pci_free_consistent(ioc->pcidev,
- sz,
- ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
+ ioc->sense_buf_pool_dma);
ioc->sense_buf_pool = NULL;
}
- if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
- DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
+ if (dma_mask == DMA_BIT_MASK(35) && !dma_set_mask(&ioc->pcidev->dev,
+ DMA_BIT_MASK(64)) && !dma_set_coherent_mask(&ioc->pcidev->dev,
DMA_BIT_MASK(64)))
d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"restoring 64 bit addressing\n", ioc->name));
@@ -4979,7 +4965,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
if (hdr.PageLength > 0) {
data_sz = hdr.PageLength * 4;
- ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
+ ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page0_dma, GFP_KERNEL);
rc = -ENOMEM;
if (ppage0_alloc) {
memset((u8 *)ppage0_alloc, 0, data_sz);
@@ -4993,7 +4980,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
}
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ (u8 *)ppage0_alloc, page0_dma);
/* FIXME!
* Normalize endianness of structure data,
@@ -5025,7 +5013,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
data_sz = hdr.PageLength * 4;
rc = -ENOMEM;
- ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
+ ppage1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page1_dma, GFP_KERNEL);
if (ppage1_alloc) {
memset((u8 *)ppage1_alloc, 0, data_sz);
cfg.physAddr = page1_dma;
@@ -5037,7 +5026,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
}
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ (u8 *)ppage1_alloc, page1_dma);
/* FIXME!
* Normalize endianness of structure data,
@@ -5055,9 +5045,11 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
* @ioc: Pointer to MPT_ADAPTER structure
* @persist_opcode: see below
*
- * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
- * devices not currently present.
- * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
+ * =============================== ======================================
+ * MPI_SAS_OP_CLEAR_NOT_PRESENT Free all persist TargetID mappings for
+ * devices not currently present.
+ * MPI_SAS_OP_CLEAR_ALL_PERSISTENT Clear al persist TargetID mappings
+ * =============================== ======================================
*
* NOTE: Don't use not this function during interrupt time.
*
@@ -5324,7 +5316,8 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
/* Read the config page */
data_sz = hdr.PageLength * 4;
rc = -ENOMEM;
- ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
+ ppage_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page_dma, GFP_KERNEL);
if (ppage_alloc) {
memset((u8 *)ppage_alloc, 0, data_sz);
cfg.physAddr = page_dma;
@@ -5334,7 +5327,8 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
if ((rc = mpt_config(ioc, &cfg)) == 0)
ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ (u8 *)ppage_alloc, page_dma);
}
return rc;
@@ -5409,7 +5403,9 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
return -EFAULT;
if (header.PageLength > 0) {
- pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
+ pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
+ header.PageLength * 4, &buf_dma,
+ GFP_KERNEL);
if (pbuf) {
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.physAddr = buf_dma;
@@ -5465,7 +5461,9 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
}
}
if (pbuf) {
- pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
+ dma_free_coherent(&ioc->pcidev->dev,
+ header.PageLength * 4, pbuf,
+ buf_dma);
}
}
}
@@ -5487,7 +5485,9 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
if (header.PageLength > 0) {
/* Allocate memory and read SCSI Port Page 2
*/
- pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
+ pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
+ header.PageLength * 4, &buf_dma,
+ GFP_KERNEL);
if (pbuf) {
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
cfg.physAddr = buf_dma;
@@ -5552,7 +5552,9 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
}
}
- pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
+ dma_free_coherent(&ioc->pcidev->dev,
+ header.PageLength * 4, pbuf,
+ buf_dma);
}
}
@@ -5668,8 +5670,8 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
if (!hdr.PageLength)
goto out;
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer)
goto out;
@@ -5716,8 +5718,8 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
}
/**
@@ -5761,8 +5763,8 @@ mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
rc = -ENOMEM;
@@ -5785,8 +5787,8 @@ mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
return rc;
}
@@ -5828,8 +5830,8 @@ mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
rc = 0;
@@ -5849,8 +5851,8 @@ mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
return rc;
}
@@ -5900,8 +5902,8 @@ mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
rc = -ENOMEM;
@@ -5938,8 +5940,8 @@ mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
return rc;
}
@@ -5995,7 +5997,8 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
return -EFAULT;
iocpage2sz = header.PageLength * 4;
- pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
+ pIoc2 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage2sz, &ioc2_dma,
+ GFP_KERNEL);
if (!pIoc2)
return -ENOMEM;
@@ -6004,13 +6007,12 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0)
goto out;
- mem = kmalloc(iocpage2sz, GFP_KERNEL);
+ mem = kmemdup(pIoc2, iocpage2sz, GFP_KERNEL);
if (!mem) {
rc = -ENOMEM;
goto out;
}
- memcpy(mem, (u8 *)pIoc2, iocpage2sz);
ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
mpt_read_ioc_pg_3(ioc);
@@ -6021,7 +6023,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
pIoc2->RaidVolume[i].VolumeID);
out:
- pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
+ dma_free_coherent(&ioc->pcidev->dev, iocpage2sz, pIoc2, ioc2_dma);
return rc;
}
@@ -6063,7 +6065,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
/* Read Header good, alloc memory
*/
iocpage3sz = header.PageLength * 4;
- pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
+ pIoc3 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage3sz, &ioc3_dma,
+ GFP_KERNEL);
if (!pIoc3)
return 0;
@@ -6080,7 +6083,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
}
}
- pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
+ dma_free_coherent(&ioc->pcidev->dev, iocpage3sz, pIoc3, ioc3_dma);
return 0;
}
@@ -6114,7 +6117,8 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
- pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
+ pIoc4 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage4sz,
+ &ioc4_dma, GFP_KERNEL);
if (!pIoc4)
return;
ioc->alloc_total += iocpage4sz;
@@ -6132,7 +6136,8 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
ioc->spi_data.IocPg4_dma = ioc4_dma;
ioc->spi_data.IocPg4Sz = iocpage4sz;
} else {
- pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
+ dma_free_coherent(&ioc->pcidev->dev, iocpage4sz, pIoc4,
+ ioc4_dma);
ioc->spi_data.pIocPg4 = NULL;
ioc->alloc_total -= iocpage4sz;
}
@@ -6169,7 +6174,8 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
/* Read Header good, alloc memory
*/
iocpage1sz = header.PageLength * 4;
- pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
+ pIoc1 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage1sz, &ioc1_dma,
+ GFP_KERNEL);
if (!pIoc1)
return;
@@ -6220,7 +6226,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
}
}
- pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
+ dma_free_coherent(&ioc->pcidev->dev, iocpage1sz, pIoc1, ioc1_dma);
return;
}
@@ -6249,7 +6255,8 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
goto out;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
- pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
+ pbuf = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &buf_dma, GFP_KERNEL);
if (!pbuf)
goto out;
@@ -6262,10 +6269,11 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
- out:
+out:
if (pbuf)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4, pbuf,
+ buf_dma);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6339,7 +6347,6 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
* Page header is updated.
*
* Returns 0 for success
- * -EPERM if not allowed due to ISR context
* -EAGAIN if no msg frames currently available
* -EFAULT for non-successful reply or no reply (timeout)
*/
@@ -6357,19 +6364,10 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
u8 page_type = 0, extend_page;
unsigned long timeleft;
unsigned long flags;
- int in_isr;
u8 issue_hard_reset = 0;
u8 retry_count = 0;
- /* Prevent calling wait_event() (below), if caller happens
- * to be in ISR context, because that is fatal!
- */
- in_isr = in_interrupt();
- if (in_isr) {
- dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
- ioc->name));
- return -EPERM;
- }
+ might_sleep();
/* don't send a config page during diag reset */
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
@@ -6614,8 +6612,10 @@ procmpt_create(void)
if (mpt_proc_root_dir == NULL)
return -ENOTDIR;
- proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
- proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
+ proc_create_single("summary", S_IRUGO, mpt_proc_root_dir,
+ mpt_summary_proc_show);
+ proc_create_single("version", S_IRUGO, mpt_proc_root_dir,
+ mpt_version_proc_show);
return 0;
}
@@ -6654,29 +6654,16 @@ static int mpt_summary_proc_show(struct seq_file *m, void *v)
return 0;
}
-static int mpt_summary_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, mpt_summary_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations mpt_summary_proc_fops = {
- .owner = THIS_MODULE,
- .open = mpt_summary_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static int mpt_version_proc_show(struct seq_file *m, void *v)
{
u8 cb_idx;
- int scsi, fc, sas, lan, ctl, targ, dmp;
+ int scsi, fc, sas, lan, ctl, targ;
char *drvname;
seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
seq_printf(m, " Fusion MPT base driver\n");
- scsi = fc = sas = lan = ctl = targ = dmp = 0;
+ scsi = fc = sas = lan = ctl = targ = 0;
for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
drvname = NULL;
if (MptCallbacks[cb_idx]) {
@@ -6709,19 +6696,6 @@ static int mpt_version_proc_show(struct seq_file *m, void *v)
return 0;
}
-static int mpt_version_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, mpt_version_proc_show, NULL);
-}
-
-static const struct file_operations mpt_version_proc_fops = {
- .owner = THIS_MODULE,
- .open = mpt_version_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
{
MPT_ADAPTER *ioc = m->private;
@@ -6789,8 +6763,7 @@ static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
if (ioc->bus_type == FC) {
if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
- seq_printf(m, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
- a[5], a[4], a[3], a[2], a[1], a[0]);
+ seq_printf(m, " LanAddr = %pMR\n", a);
}
seq_printf(m, " WWN = %08X%08X:%08X%08X\n",
ioc->fc_port_page0[p].WWNN.High,
@@ -6802,19 +6775,6 @@ static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
return 0;
}
-
-static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations mpt_iocinfo_proc_fops = {
- .owner = THIS_MODULE,
- .open = mpt_iocinfo_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
#endif /* CONFIG_PROC_FS } */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6867,8 +6827,7 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
- y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
- a[5], a[4], a[3], a[2], a[1], a[0]);
+ y += sprintf(buffer+len+y, ", LanAddr=%pMR", a);
}
y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
@@ -6881,6 +6840,7 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
*size = y;
}
+#ifdef CONFIG_PROC_FS
static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
{
char expVer[32];
@@ -6901,8 +6861,7 @@ static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int
if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
- seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
- a[5], a[4], a[3], a[2], a[1], a[0]);
+ seq_printf(m, ", LanAddr=%pMR", a);
}
seq_printf(m, ", IRQ=%d", ioc->pci_irq);
@@ -6912,6 +6871,7 @@ static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int
seq_putc(m, '\n');
}
+#endif
/**
* mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
@@ -6974,7 +6934,7 @@ EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
* @ioc: Pointer to MPT_ADAPTER structure
*
**/
-void
+void __noreturn
mpt_halt_firmware(MPT_ADAPTER *ioc)
{
u32 ioc_raw_state;
@@ -7007,7 +6967,7 @@ EXPORT_SYMBOL(mpt_halt_firmware);
* IOC doesn't reply to any outstanding request. This will transfer IOC
* to READY state.
**/
-int
+static int
mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
{
int rc;
@@ -7046,8 +7006,6 @@ mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
ioc->ioc_reset_in_progress = 1;
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
- rc = -1;
-
for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
if (MptResetHandlers[cb_idx])
mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
@@ -7406,7 +7364,7 @@ mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: No Persistancy: "
+ "SAS Device Status Change: No Persistency: "
"id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
@@ -7611,11 +7569,11 @@ mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
u8 phy_num = (u8)(evData0);
u8 port_num = (u8)(evData0 >> 8);
u8 port_width = (u8)(evData0 >> 16);
- u8 primative = (u8)(evData0 >> 24);
+ u8 primitive = (u8)(evData0 >> 24);
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Broadcase Primative: phy=%d port=%d "
- "width=%d primative=0x%02x",
- phy_num, port_num, port_width, primative);
+ "SAS Broadcast Primitive: phy=%d port=%d "
+ "width=%d primitive=0x%02x",
+ phy_num, port_num, port_width, primitive);
break;
}
@@ -7644,7 +7602,7 @@ mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
snprintf(evStr, EVENT_DESCR_STR_SZ,
"SAS Initiator Device Table Overflow: max initiators=%02d "
- "current initators=%02d",
+ "current initiators=%02d",
max_init, current_init);
break;
}
@@ -7707,7 +7665,7 @@ mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
break;
}
if (ds)
- strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
+ strscpy(evStr, ds, EVENT_DESCR_STR_SZ);
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
@@ -8102,15 +8060,15 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
static void
mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
{
-union loginfo_type {
- u32 loginfo;
- struct {
- u32 subcode:16;
- u32 code:8;
- u32 originator:4;
- u32 bus_type:4;
- }dw;
-};
+ union loginfo_type {
+ u32 loginfo;
+ struct {
+ u32 subcode:16;
+ u32 code:8;
+ u32 originator:4;
+ u32 bus_type:4;
+ } dw;
+ };
union loginfo_type sas_loginfo;
char *originator_desc = NULL;
char *code_desc = NULL;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 76c05bc24cb7..b406fd676da0 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -257,7 +257,7 @@ typedef enum {
} MPT_DRIVER_CLASS;
struct mpt_pci_driver{
- int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
+ int (*probe) (struct pci_dev *dev);
void (*remove) (struct pci_dev *dev);
};
@@ -274,7 +274,7 @@ typedef union _MPT_FRAME_TRACKER {
} linkage;
/*
* NOTE: When request frames are free, on the linkage structure
- * contets are valid. All other values are invalid.
+ * contents are valid. All other values are invalid.
* In particular, do NOT reply on offset [2]
* (in words) being the * message context.
* The message context must be reset (computed via base address
@@ -405,7 +405,7 @@ typedef struct _VirtTarget {
typedef struct _VirtDevice {
VirtTarget *vtarget;
u8 configured_lun;
- int lun;
+ u64 lun;
} VirtDevice;
/*
@@ -605,7 +605,7 @@ typedef struct _MPT_ADAPTER
int id; /* Unique adapter id N {0,1,2,...} */
int pci_irq; /* This irq */
char name[MPT_NAME_LENGTH]; /* "iocN" */
- char prod_name[MPT_NAME_LENGTH]; /* "LSIFC9x9" */
+ const char *prod_name; /* "LSIFC9x9" */
#ifdef CONFIG_FUSION_LOGGING
/* used in mpt_display_event_info */
char evStr[EVENT_DESCR_STR_SZ];
@@ -671,7 +671,6 @@ typedef struct _MPT_ADAPTER
u8 *HostPageBuffer; /* SAS - host page buffer support */
u32 HostPageBuffer_sz;
dma_addr_t HostPageBuffer_dma;
- int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
int bars; /* bitmask of BAR's that must be configured */
int msi_enable;
@@ -730,7 +729,6 @@ typedef struct _MPT_ADAPTER
struct list_head fw_event_list;
spinlock_t fw_event_lock;
u8 fw_events_off; /* if '1', then ignore events */
- char fw_event_q_name[MPT_KOBJ_NAME_LEN];
struct mutex sas_discovery_mutex;
u8 sas_discovery_runtime;
@@ -758,7 +756,6 @@ typedef struct _MPT_ADAPTER
u8 wait_on_reset_completion;
MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
- struct work_struct sas_persist_task;
struct work_struct fc_setup_reset_work;
struct list_head fc_rports;
@@ -766,7 +763,6 @@ typedef struct _MPT_ADAPTER
u8 fc_link_speed[2];
spinlock_t fc_rescan_work_lock;
struct work_struct fc_rescan_work;
- char fc_rescan_work_q_name[MPT_KOBJ_NAME_LEN];
struct workqueue_struct *fc_rescan_work_q;
/* driver forced bus resets count */
@@ -780,7 +776,6 @@ typedef struct _MPT_ADAPTER
spinlock_t scsi_lookup_lock;
u64 dma_mask;
u32 broadcast_aen_busy;
- char reset_work_q_name[MPT_KOBJ_NAME_LEN];
struct workqueue_struct *reset_work_q;
struct delayed_work fault_reset_work;
@@ -946,7 +941,7 @@ extern int mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc,
u8 phys_disk_num);
extern int mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
extern void mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
-extern void mpt_halt_firmware(MPT_ADAPTER *ioc);
+extern void __noreturn mpt_halt_firmware(MPT_ADAPTER *ioc);
/*
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index dcc8385adeb3..77fa55df70d0 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -58,7 +58,7 @@
#include <linux/compat.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -100,21 +100,21 @@ struct buflist {
* Function prototypes. Called from OS entry point mptctl_ioctl.
* arg contents specific to function.
*/
-static int mptctl_fw_download(unsigned long arg);
-static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
-static int mptctl_gettargetinfo(unsigned long arg);
-static int mptctl_readtest(unsigned long arg);
-static int mptctl_mpt_command(unsigned long arg);
-static int mptctl_eventquery(unsigned long arg);
-static int mptctl_eventenable(unsigned long arg);
-static int mptctl_eventreport(unsigned long arg);
-static int mptctl_replace_fw(unsigned long arg);
-
-static int mptctl_do_reset(unsigned long arg);
-static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
-static int mptctl_hp_targetinfo(unsigned long arg);
-
-static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
+static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
+static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
+
+static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
+static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
+
+static int mptctl_probe(struct pci_dev *);
static void mptctl_remove(struct pci_dev *);
#ifdef CONFIG_COMPAT
@@ -123,8 +123,8 @@ static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
/*
* Private function calls.
*/
-static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
-static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
+static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -321,7 +321,6 @@ mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
int ii;
int retval;
unsigned long timeout;
- unsigned long time_count;
u16 iocstatus;
@@ -383,7 +382,6 @@ mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
ioc->name, tm_type, timeout));
INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
- time_count = jiffies;
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
(ioc->facts.MsgVersion >= MPI_VERSION_01_05))
mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf);
@@ -565,7 +563,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
* TODO - this define is not in MPI spec yet,
* but they plan to set it to 0x21
*/
- if (event == 0x21 ) {
+ if (event == 0x21) {
ioc->aen_event_read_flag=1;
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n",
ioc->name));
@@ -622,7 +620,6 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
mpt_ioctl_header __user *uhdr = (void __user *) arg;
mpt_ioctl_header khdr;
- int iocnum;
unsigned iocnumX;
int nonblock = (file->f_flags & O_NONBLOCK);
int ret;
@@ -636,12 +633,11 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
ret = -ENXIO; /* (-6) No such device or address */
- /* Verify intended MPT adapter - set iocnum and the adapter
+ /* Verify intended MPT adapter - set iocnumX and the adapter
* pointer (iocp)
*/
iocnumX = khdr.iocnum & 0xFF;
- if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
- (iocp == NULL))
+ if ((mpt_verify_adapter(iocnumX, &iocp) < 0) || (iocp == NULL))
return -ENODEV;
if (!iocp->active) {
@@ -656,19 +652,19 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
* by TM and FW reloads.
*/
if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
- return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
+ return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd));
} else if (cmd == MPTTARGETINFO) {
- return mptctl_gettargetinfo(arg);
+ return mptctl_gettargetinfo(iocp, arg);
} else if (cmd == MPTTEST) {
- return mptctl_readtest(arg);
+ return mptctl_readtest(iocp, arg);
} else if (cmd == MPTEVENTQUERY) {
- return mptctl_eventquery(arg);
+ return mptctl_eventquery(iocp, arg);
} else if (cmd == MPTEVENTENABLE) {
- return mptctl_eventenable(arg);
+ return mptctl_eventenable(iocp, arg);
} else if (cmd == MPTEVENTREPORT) {
- return mptctl_eventreport(arg);
+ return mptctl_eventreport(iocp, arg);
} else if (cmd == MPTFWREPLACE) {
- return mptctl_replace_fw(arg);
+ return mptctl_replace_fw(iocp, arg);
}
/* All of these commands require an interrupt or
@@ -678,15 +674,15 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
if (cmd == MPTFWDOWNLOAD)
- ret = mptctl_fw_download(arg);
+ ret = mptctl_fw_download(iocp, arg);
else if (cmd == MPTCOMMAND)
- ret = mptctl_mpt_command(arg);
+ ret = mptctl_mpt_command(iocp, arg);
else if (cmd == MPTHARDRESET)
- ret = mptctl_do_reset(arg);
+ ret = mptctl_do_reset(iocp, arg);
else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
- ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
+ ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd));
else if (cmd == HP_GETTARGETINFO)
- ret = mptctl_hp_targetinfo(arg);
+ ret = mptctl_hp_targetinfo(iocp, arg);
else
ret = -EINVAL;
@@ -705,11 +701,10 @@ mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}
-static int mptctl_do_reset(unsigned long arg)
+static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg)
{
struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
struct mpt_ioctl_diag_reset krinfo;
- MPT_ADAPTER *iocp;
if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
@@ -718,12 +713,6 @@ static int mptctl_do_reset(unsigned long arg)
return -EFAULT;
}
- if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
- printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
- __FILE__, __LINE__, krinfo.hdr.iocnum);
- return -ENODEV; /* (-6) No such device or address */
- }
-
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
iocp->name));
@@ -754,7 +743,7 @@ static int mptctl_do_reset(unsigned long arg)
* -ENOMSG if FW upload returned bad status
*/
static int
-mptctl_fw_download(unsigned long arg)
+mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg)
{
struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
struct mpt_fw_xfer kfwdl;
@@ -766,7 +755,7 @@ mptctl_fw_download(unsigned long arg)
return -EFAULT;
}
- return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
+ return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -784,11 +773,10 @@ mptctl_fw_download(unsigned long arg)
* -ENOMSG if FW upload returned bad status
*/
static int
-mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen)
{
FWDownload_t *dlmsg;
MPT_FRAME_HDR *mf;
- MPT_ADAPTER *iocp;
FWDownloadTCSGE_t *ptsge;
MptSge_t *sgl, *sgIn;
char *sgOut;
@@ -808,17 +796,10 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
pFWDownloadReply_t ReplyMsg = NULL;
unsigned long timeleft;
- if (mpt_verify_adapter(ioc, &iocp) < 0) {
- printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
- ioc);
- return -ENODEV; /* (-6) No such device or address */
- } else {
-
- /* Valid device. Get a message frame and construct the FW download message.
- */
- if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
- return -EAGAIN;
- }
+ /* Valid device. Get a message frame and construct the FW download message.
+ */
+ if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+ return -EAGAIN;
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
"mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
@@ -826,8 +807,6 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
iocp->name, ufwbuf));
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
iocp->name, (int)fwlen));
- dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc = %04xh\n",
- iocp->name, ioc));
dlmsg = (FWDownload_t*) mf;
ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
@@ -1038,6 +1017,10 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
int i, buflist_ent;
int sg_spill = MAX_FRAGS_SPILL1;
int dir;
+
+ if (bytes < 0)
+ return NULL;
+
/* initialization */
*frags = 0;
*blp = NULL;
@@ -1056,14 +1039,15 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
* copying the data in this array into the correct place in the
* request and chain buffers.
*/
- sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
+ sglbuf = dma_alloc_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES,
+ sglbuf_dma, GFP_KERNEL);
if (sglbuf == NULL)
goto free_and_fail;
if (sgdir & 0x04000000)
- dir = PCI_DMA_TODEVICE;
+ dir = DMA_TO_DEVICE;
else
- dir = PCI_DMA_FROMDEVICE;
+ dir = DMA_FROM_DEVICE;
/* At start:
* sgl = sglbuf = point to beginning of sg buffer
@@ -1077,9 +1061,9 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
while (bytes_allocd < bytes) {
this_alloc = min(alloc_sz, bytes-bytes_allocd);
buflist[buflist_ent].len = this_alloc;
- buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
- this_alloc,
- &pa);
+ buflist[buflist_ent].kptr = dma_alloc_coherent(&ioc->pcidev->dev,
+ this_alloc,
+ &pa, GFP_KERNEL);
if (buflist[buflist_ent].kptr == NULL) {
alloc_sz = alloc_sz / 2;
if (alloc_sz == 0) {
@@ -1095,8 +1079,9 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
bytes_allocd += this_alloc;
sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
- dma_addr = pci_map_single(ioc->pcidev,
- buflist[buflist_ent].kptr, this_alloc, dir);
+ dma_addr = dma_map_single(&ioc->pcidev->dev,
+ buflist[buflist_ent].kptr,
+ this_alloc, dir);
sgl->Address = dma_addr;
fragcnt++;
@@ -1155,9 +1140,11 @@ free_and_fail:
kptr = buflist[i].kptr;
len = buflist[i].len;
- pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
+ dma_free_coherent(&ioc->pcidev->dev, len, kptr,
+ dma_addr);
}
- pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
+ dma_free_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES, sglbuf,
+ *sglbuf_dma);
}
kfree(buflist);
return NULL;
@@ -1177,9 +1164,9 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
int n = 0;
if (sg->FlagsLength & 0x04000000)
- dir = PCI_DMA_TODEVICE;
+ dir = DMA_TO_DEVICE;
else
- dir = PCI_DMA_FROMDEVICE;
+ dir = DMA_FROM_DEVICE;
nib = (sg->FlagsLength & 0xF0000000) >> 28;
while (! (nib & 0x4)) { /* eob */
@@ -1194,8 +1181,10 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
dma_addr = sg->Address;
kptr = bl->kptr;
len = bl->len;
- pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
- pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
+ dma_unmap_single(&ioc->pcidev->dev, dma_addr, len,
+ dir);
+ dma_free_coherent(&ioc->pcidev->dev, len, kptr,
+ dma_addr);
n++;
}
sg++;
@@ -1212,12 +1201,12 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
dma_addr = sg->Address;
kptr = bl->kptr;
len = bl->len;
- pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
- pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
+ dma_unmap_single(&ioc->pcidev->dev, dma_addr, len, dir);
+ dma_free_coherent(&ioc->pcidev->dev, len, kptr, dma_addr);
n++;
}
- pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
+ dma_free_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES, sgl, sgl_dma);
kfree(buflist);
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
ioc->name, n));
@@ -1234,13 +1223,11 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
* -ENODEV if no such device/adapter
*/
static int
-mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
+mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
{
struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_iocinfo *karg;
- MPT_ADAPTER *ioc;
struct pci_dev *pdev;
- int iocnum;
unsigned int port;
int cim_rev;
struct scsi_device *sdev;
@@ -1261,27 +1248,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
else
return -EFAULT;
- karg = kmalloc(data_size, GFP_KERNEL);
- if (karg == NULL) {
- printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
- __FILE__, __LINE__);
- return -ENOMEM;
- }
-
- if (copy_from_user(karg, uarg, data_size)) {
- printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
- "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
- __FILE__, __LINE__, uarg);
- kfree(karg);
- return -EFAULT;
- }
-
- if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- kfree(karg);
- return -ENODEV;
+ karg = memdup_user(uarg, data_size);
+ if (IS_ERR(karg)) {
+ printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
+ __FILE__, __LINE__, PTR_ERR(karg));
+ return PTR_ERR(karg);
}
/* Verify the data transfer size is correct. */
@@ -1357,8 +1328,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Set the Version Strings.
*/
- strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
- karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
+ strscpy_pad(karg->driverVersion, MPT_LINUX_PACKAGE_NAME,
+ sizeof(karg->driverVersion));
karg->busChangeEvent = 0;
karg->hostId = ioc->pfacts[port].PortSCSIID;
@@ -1389,20 +1360,17 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
* -ENODEV if no such device/adapter
*/
static int
-mptctl_gettargetinfo (unsigned long arg)
+mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_targetinfo karg;
- MPT_ADAPTER *ioc;
VirtDevice *vdevice;
char *pmem;
int *pdata;
- int iocnum;
int numDevices = 0;
int lun;
int maxWordsLeft;
int numBytes;
- u8 port;
struct scsi_device *sdev;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
@@ -1412,22 +1380,10 @@ mptctl_gettargetinfo (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
ioc->name));
- /* Get the port number and set the maximum number of bytes
- * in the returned structure.
- * Ignore the port setting.
- */
numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
maxWordsLeft = numBytes/sizeof(int);
- port = karg.hdr.port;
if (maxWordsLeft <= 0) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
@@ -1514,12 +1470,10 @@ mptctl_gettargetinfo (unsigned long arg)
* -ENODEV if no such device/adapter
*/
static int
-mptctl_readtest (unsigned long arg)
+mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_test __user *uarg = (void __user *) arg;
struct mpt_ioctl_test karg;
- MPT_ADAPTER *ioc;
- int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
@@ -1528,13 +1482,6 @@ mptctl_readtest (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
ioc->name));
/* Fill in the data and return the structure to the calling
@@ -1546,10 +1493,8 @@ mptctl_readtest (unsigned long arg)
#else
karg.chip_type = ioc->pcidev->device;
#endif
- strncpy (karg.name, ioc->name, MPT_MAX_NAME);
- karg.name[MPT_MAX_NAME-1]='\0';
- strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
- karg.product[MPT_PRODUCT_LENGTH-1]='\0';
+ strscpy_pad(karg.name, ioc->name, sizeof(karg.name));
+ strscpy_pad(karg.product, ioc->prod_name, sizeof(karg.product));
/* Copy the data from kernel memory to user memory
*/
@@ -1575,12 +1520,10 @@ mptctl_readtest (unsigned long arg)
* -ENODEV if no such device/adapter
*/
static int
-mptctl_eventquery (unsigned long arg)
+mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventquery karg;
- MPT_ADAPTER *ioc;
- int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
@@ -1589,13 +1532,6 @@ mptctl_eventquery (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
ioc->name));
karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
@@ -1614,12 +1550,10 @@ mptctl_eventquery (unsigned long arg)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
-mptctl_eventenable (unsigned long arg)
+mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventenable karg;
- MPT_ADAPTER *ioc;
- int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
@@ -1628,13 +1562,6 @@ mptctl_eventenable (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
ioc->name));
if (ioc->events == NULL) {
@@ -1662,12 +1589,10 @@ mptctl_eventenable (unsigned long arg)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
-mptctl_eventreport (unsigned long arg)
+mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventreport karg;
- MPT_ADAPTER *ioc;
- int iocnum;
int numBytes, maxEvents, max;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
@@ -1677,12 +1602,6 @@ mptctl_eventreport (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
ioc->name));
@@ -1690,7 +1609,7 @@ mptctl_eventreport (unsigned long arg)
maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
- max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
+ max = min(maxEvents, MPTCTL_EVENT_LOG_SIZE);
/* If fewer than 1 event is requested, there must have
* been some type of error.
@@ -1716,12 +1635,10 @@ mptctl_eventreport (unsigned long arg)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
-mptctl_replace_fw (unsigned long arg)
+mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
struct mpt_ioctl_replace_fw karg;
- MPT_ADAPTER *ioc;
- int iocnum;
int newFwSize;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
@@ -1731,13 +1648,6 @@ mptctl_replace_fw (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
ioc->name));
/* If caching FW, Free the old FW image
@@ -1749,12 +1659,7 @@ mptctl_replace_fw (unsigned long arg)
/* Allocate memory for the new FW image
*/
- newFwSize = karg.newImageSize;
-
- if (newFwSize & 0x01)
- newFwSize += 1;
- if (newFwSize & 0x02)
- newFwSize += 2;
+ newFwSize = ALIGN(karg.newImageSize, 4);
mpt_alloc_fw_memory(ioc, newFwSize);
if (ioc->cached_fw == NULL)
@@ -1789,12 +1694,10 @@ mptctl_replace_fw (unsigned long arg)
* -ENOMEM if memory allocation error
*/
static int
-mptctl_mpt_command (unsigned long arg)
+mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg)
{
struct mpt_ioctl_command __user *uarg = (void __user *) arg;
struct mpt_ioctl_command karg;
- MPT_ADAPTER *ioc;
- int iocnum;
int rc;
@@ -1805,14 +1708,7 @@ mptctl_mpt_command (unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
- rc = mptctl_do_mpt_command (karg, &uarg->MF);
+ rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF);
return rc;
}
@@ -1830,9 +1726,8 @@ mptctl_mpt_command (unsigned long arg)
* -EPERM if SCSI I/O and target is untagged
*/
static int
-mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
+mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr)
{
- MPT_ADAPTER *ioc;
MPT_FRAME_HDR *mf = NULL;
MPIHeader_t *hdr;
char *psge;
@@ -1841,7 +1736,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
dma_addr_t dma_addr_in;
dma_addr_t dma_addr_out;
int sgSize = 0; /* Num SG elements */
- int iocnum, flagsLength;
+ int flagsLength;
int sz, rc = 0;
int msgContext;
u16 req_idx;
@@ -1856,13 +1751,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
bufIn.kptr = bufOut.kptr = NULL;
bufIn.len = bufOut.len = 0;
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
-
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
@@ -1872,6 +1760,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
+ /* Basic sanity checks to prevent underflows or integer overflows */
+ if (karg.maxReplyBytes < 0 ||
+ karg.dataInSize < 0 ||
+ karg.dataOutSize < 0 ||
+ karg.dataSgeOffset < 0 ||
+ karg.maxSenseBytes < 0 ||
+ karg.dataSgeOffset > ioc->req_sz / 4)
+ return -EINVAL;
+
/* Verify that the final request frame will not be too large.
*/
sz = karg.dataSgeOffset * 4;
@@ -2205,8 +2102,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
flagsLength |= karg.dataOutSize;
bufOut.len = karg.dataOutSize;
- bufOut.kptr = pci_alloc_consistent(
- ioc->pcidev, bufOut.len, &dma_addr_out);
+ bufOut.kptr = dma_alloc_coherent(&ioc->pcidev->dev,
+ bufOut.len,
+ &dma_addr_out, GFP_KERNEL);
if (bufOut.kptr == NULL) {
rc = -ENOMEM;
@@ -2239,8 +2137,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
flagsLength |= karg.dataInSize;
bufIn.len = karg.dataInSize;
- bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
- bufIn.len, &dma_addr_in);
+ bufIn.kptr = dma_alloc_coherent(&ioc->pcidev->dev,
+ bufIn.len,
+ &dma_addr_in, GFP_KERNEL);
if (bufIn.kptr == NULL) {
rc = -ENOMEM;
@@ -2388,13 +2287,13 @@ done_free_mem:
/* Free the allocated memory.
*/
if (bufOut.kptr != NULL) {
- pci_free_consistent(ioc->pcidev,
- bufOut.len, (void *) bufOut.kptr, dma_addr_out);
+ dma_free_coherent(&ioc->pcidev->dev, bufOut.len,
+ (void *)bufOut.kptr, dma_addr_out);
}
if (bufIn.kptr != NULL) {
- pci_free_consistent(ioc->pcidev,
- bufIn.len, (void *) bufIn.kptr, dma_addr_in);
+ dma_free_coherent(&ioc->pcidev->dev, bufIn.len,
+ (void *)bufIn.kptr, dma_addr_in);
}
/* mf is null if command issued successfully
@@ -2418,23 +2317,20 @@ done_free_mem:
* -ENOMEM if memory allocation error
*/
static int
-mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
+mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
{
hp_host_info_t __user *uarg = (void __user *) arg;
- MPT_ADAPTER *ioc;
struct pci_dev *pdev;
char *pbuf=NULL;
dma_addr_t buf_dma;
hp_host_info_t karg;
CONFIGPARMS cfg;
ConfigPageHeader_t hdr;
- int iocnum;
int rc, cim_rev;
ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
MPT_FRAME_HDR *mf = NULL;
- MPIHeader_t *mpi_hdr;
unsigned long timeleft;
- int retval;
+ u32 msgcontext;
/* Reset long to int. Should affect IA64 and SPARC only
*/
@@ -2452,12 +2348,6 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
ioc->name));
@@ -2481,24 +2371,13 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
else
karg.host_no = -1;
- /* Reformat the fw_version into a string
- */
- karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
- ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
- karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
- karg.fw_version[2] = '.';
- karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
- ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
- karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
- karg.fw_version[5] = '.';
- karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
- ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
- karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
- karg.fw_version[8] = '.';
- karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
- ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
- karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
- karg.fw_version[11] = '\0';
+ /* Reformat the fw_version into a string */
+ snprintf(karg.fw_version, sizeof(karg.fw_version),
+ "%.2hhu.%.2hhu.%.2hhu.%.2hhu",
+ ioc->facts.FWVersion.Struct.Major,
+ ioc->facts.FWVersion.Struct.Minor,
+ ioc->facts.FWVersion.Struct.Unit,
+ ioc->facts.FWVersion.Struct.Dev);
/* Issue a config request to get the device serial number
*/
@@ -2513,23 +2392,28 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
cfg.dir = 0; /* read */
cfg.timeout = 10;
- strncpy(karg.serial_number, " ", 24);
+ strscpy_pad(karg.serial_number, " ", sizeof(karg.serial_number));
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.cfghdr.hdr->PageLength > 0) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
- pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
+ pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
+ hdr.PageLength * 4,
+ &buf_dma, GFP_KERNEL);
if (pbuf) {
cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) {
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
if (strlen(pdata->BoardTracerNumber) > 1) {
- strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
- karg.serial_number[24-1]='\0';
+ strscpy_pad(karg.serial_number,
+ pdata->BoardTracerNumber,
+ sizeof(karg.serial_number));
}
}
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
+ dma_free_coherent(&ioc->pcidev->dev,
+ hdr.PageLength * 4, pbuf,
+ buf_dma);
pbuf = NULL;
}
}
@@ -2571,7 +2455,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
}
}
- /*
+ /*
* Gather ISTWI(Industry Standard Two Wire Interface) Data
*/
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
@@ -2581,11 +2465,11 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
}
IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
- mpi_hdr = (MPIHeader_t *) mf;
+ msgcontext = IstwiRWRequest->MsgContext;
memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
+ IstwiRWRequest->MsgContext = msgcontext;
IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
- IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
IstwiRWRequest->NumAddressBytes = 0x01;
IstwiRWRequest->DataLength = cpu_to_le16(0x04);
@@ -2594,13 +2478,12 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
else
IstwiRWRequest->DeviceAddr = 0xB0;
- pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
+ pbuf = dma_alloc_coherent(&ioc->pcidev->dev, 4, &buf_dma, GFP_KERNEL);
if (!pbuf)
goto out;
ioc->add_sge((char *)&IstwiRWRequest->SGL,
(MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
- retval = 0;
SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
IstwiRWRequest->MsgContext);
INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
@@ -2610,7 +2493,6 @@ retry_wait:
timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
- retval = -ETIME;
printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
mpt_free_msg_frame(ioc, mf);
@@ -2643,7 +2525,7 @@ retry_wait:
SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
if (pbuf)
- pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
+ dma_free_coherent(&ioc->pcidev->dev, 4, pbuf, buf_dma);
/* Copy the data from kernel memory to user memory
*/
@@ -2670,15 +2552,13 @@ retry_wait:
* -ENOMEM if memory allocation error
*/
static int
-mptctl_hp_targetinfo(unsigned long arg)
+mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg)
{
hp_target_info_t __user *uarg = (void __user *) arg;
SCSIDevicePage0_t *pg0_alloc;
SCSIDevicePage3_t *pg3_alloc;
- MPT_ADAPTER *ioc;
MPT_SCSI_HOST *hd = NULL;
hp_target_info_t karg;
- int iocnum;
int data_sz;
dma_addr_t page_dma;
CONFIGPARMS cfg;
@@ -2692,12 +2572,8 @@ mptctl_hp_targetinfo(unsigned long arg)
return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
- (ioc == NULL)) {
- printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum);
- return -ENODEV;
- }
+ if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
+ return -EINVAL;
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
ioc->name));
@@ -2715,7 +2591,8 @@ mptctl_hp_targetinfo(unsigned long arg)
/* Get the data transfer speeds
*/
data_sz = ioc->spi_data.sdp0length * 4;
- pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
+ pg0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz, &page_dma,
+ GFP_KERNEL);
if (pg0_alloc) {
hdr.PageVersion = ioc->spi_data.sdp0version;
hdr.PageLength = data_sz;
@@ -2753,7 +2630,8 @@ mptctl_hp_targetinfo(unsigned long arg)
karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
}
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz, (u8 *)pg0_alloc,
+ page_dma);
}
/* Set defaults
@@ -2779,8 +2657,8 @@ mptctl_hp_targetinfo(unsigned long arg)
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
- pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
- ioc->pcidev, data_sz, &page_dma);
+ pg3_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page_dma, GFP_KERNEL);
if (pg3_alloc) {
cfg.physAddr = page_dma;
cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
@@ -2789,7 +2667,8 @@ mptctl_hp_targetinfo(unsigned long arg)
karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
}
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ (u8 *)pg3_alloc, page_dma);
}
}
hd = shost_priv(ioc->sh);
@@ -2812,7 +2691,6 @@ mptctl_hp_targetinfo(unsigned long arg)
static const struct file_operations mptctl_fops = {
.owner = THIS_MODULE,
- .llseek = no_llseek,
.fasync = mptctl_fasync,
.unlocked_ioctl = mptctl_ioctl,
#ifdef CONFIG_COMPAT
@@ -2863,7 +2741,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
kfw.fwlen = kfw32.fwlen;
kfw.bufp = compat_ptr(kfw32.bufp);
- ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
+ ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen);
mutex_unlock(&iocp->ioctl_cmds.mutex);
@@ -2917,7 +2795,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
/* Pass new structure to do_mpt_command
*/
- ret = mptctl_do_mpt_command (karg, &uarg->MF);
+ ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
mutex_unlock(&iocp->ioctl_cmds.mutex);
@@ -2969,7 +2847,7 @@ static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long a
*/
static int
-mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+mptctl_probe(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
@@ -2999,7 +2877,6 @@ static struct mpt_pci_driver mptctl_driver = {
static int __init mptctl_init(void)
{
int err;
- int where = 1;
show_mptmod_ver(my_NAME, my_VERSION);
@@ -3018,7 +2895,6 @@ static int __init mptctl_init(void)
/*
* Install our handler
*/
- ++where;
mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
"mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
diff --git a/drivers/message/fusion/mptdebug.h b/drivers/message/fusion/mptdebug.h
index 28e478879284..c281b1359419 100644
--- a/drivers/message/fusion/mptdebug.h
+++ b/drivers/message/fusion/mptdebug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/drivers/message/fusion/mptdebug.h
* For use with LSI PCI chip/adapter(s)
@@ -66,12 +67,13 @@
#ifdef CONFIG_FUSION_LOGGING
#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \
-{ \
+do { \
if (IOC->debug_level & BITS) \
CMD; \
-}
+} while (0)
#else
-#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
+#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \
+do { } while (0)
#endif
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index fd75108c355e..8f587c0efd9d 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -50,7 +50,7 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/delay.h> /* for mdelay */
-#include <linux/interrupt.h> /* needed for in_interrupt() proto */
+#include <linux/interrupt.h>
#include <linux/reboot.h> /* notifier code */
#include <linux/workqueue.h>
#include <linux/sort.h>
@@ -96,7 +96,7 @@ static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptfc_target_alloc(struct scsi_target *starget);
-static int mptfc_slave_alloc(struct scsi_device *sdev);
+static int mptfc_sdev_init(struct scsi_device *sdev);
static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
static void mptfc_target_destroy(struct scsi_target *starget);
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
@@ -104,9 +104,8 @@ static void mptfc_remove(struct pci_dev *pdev);
static int mptfc_abort(struct scsi_cmnd *SCpnt);
static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
-static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
-static struct scsi_host_template mptfc_driver_template = {
+static const struct scsi_host_template mptfc_driver_template = {
.module = THIS_MODULE,
.proc_name = "mptfc",
.show_info = mptscsih_show_info,
@@ -114,30 +113,31 @@ static struct scsi_host_template mptfc_driver_template = {
.info = mptscsih_info,
.queuecommand = mptfc_qcmd,
.target_alloc = mptfc_target_alloc,
- .slave_alloc = mptfc_slave_alloc,
- .slave_configure = mptscsih_slave_configure,
+ .sdev_init = mptfc_sdev_init,
+ .sdev_configure = mptscsih_sdev_configure,
.target_destroy = mptfc_target_destroy,
- .slave_destroy = mptscsih_slave_destroy,
+ .sdev_destroy = mptscsih_sdev_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
+ .eh_timed_out = fc_eh_timed_out,
.eh_abort_handler = mptfc_abort,
.eh_device_reset_handler = mptfc_dev_reset,
.eh_bus_reset_handler = mptfc_bus_reset,
- .eh_host_reset_handler = mptfc_host_reset,
+ .eh_host_reset_handler = mptscsih_host_reset,
.bios_param = mptscsih_bios_param,
.can_queue = MPT_FC_CAN_QUEUE,
.this_id = -1,
.sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192,
.cmd_per_lun = 7,
- .use_clustering = ENABLE_CLUSTERING,
- .shost_attrs = mptscsih_host_attrs,
+ .dma_alignment = 511,
+ .shost_groups = mptscsih_host_attr_groups,
};
/****************************************************************************
* Supported hardware
*/
-static struct pci_device_id mptfc_pci_table[] = {
+static const struct pci_device_id mptfc_pci_table[] = {
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
@@ -184,80 +184,109 @@ static struct fc_function_template mptfc_transport_functions = {
};
static int
-mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
- int (*func)(struct scsi_cmnd *SCpnt),
- const char *caller)
+mptfc_block_error_handler(struct fc_rport *rport)
{
MPT_SCSI_HOST *hd;
- struct scsi_device *sdev = SCpnt->device;
- struct Scsi_Host *shost = sdev->host;
- struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+ struct Scsi_Host *shost = rport_to_shost(rport);
unsigned long flags;
int ready;
- MPT_ADAPTER *ioc;
+ MPT_ADAPTER *ioc;
int loops = 40; /* seconds */
- hd = shost_priv(SCpnt->device->host);
+ hd = shost_priv(shost);
ioc = hd->ioc;
spin_lock_irqsave(shost->host_lock, flags);
while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
|| (loops > 0 && ioc->active == 0)) {
spin_unlock_irqrestore(shost->host_lock, flags);
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "mptfc_block_error_handler.%d: %d:%d, port status is "
- "%x, active flag %d, deferring %s recovery.\n",
+ "mptfc_block_error_handler.%d: %s, port status is "
+ "%x, active flag %d, deferring recovery.\n",
ioc->name, ioc->sh->host_no,
- SCpnt->device->id, SCpnt->device->lun,
- ready, ioc->active, caller));
+ dev_name(&rport->dev), ready, ioc->active));
msleep(1000);
spin_lock_irqsave(shost->host_lock, flags);
loops --;
}
spin_unlock_irqrestore(shost->host_lock, flags);
- if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
- || ioc->active == 0) {
+ if (ready == DID_NO_CONNECT || ioc->active == 0) {
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "%s.%d: %d:%d, failing recovery, "
- "port state %x, active %d, vdevice %p.\n", caller,
+ "mpt_block_error_handler.%d: %s, failing recovery, "
+ "port state %x, active %d.\n",
ioc->name, ioc->sh->host_no,
- SCpnt->device->id, SCpnt->device->lun, ready,
- ioc->active, SCpnt->device->hostdata));
+ dev_name(&rport->dev), ready, ioc->active));
return FAILED;
}
- dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "%s.%d: %d:%d, executing recovery.\n", caller,
- ioc->name, ioc->sh->host_no,
- SCpnt->device->id, SCpnt->device->lun));
- return (*func)(SCpnt);
+ return SUCCESS;
}
static int
mptfc_abort(struct scsi_cmnd *SCpnt)
{
- return
- mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
+ struct Scsi_Host *shost = SCpnt->device->host;
+ struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+ MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
+ int rtn;
+
+ rtn = mptfc_block_error_handler(rport);
+ if (rtn == SUCCESS) {
+ dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+ "%s.%d: %d:%llu, executing recovery.\n", __func__,
+ hd->ioc->name, shost->host_no,
+ SCpnt->device->id, SCpnt->device->lun));
+ rtn = mptscsih_abort(SCpnt);
+ }
+ return rtn;
}
static int
mptfc_dev_reset(struct scsi_cmnd *SCpnt)
{
- return
- mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
+ struct Scsi_Host *shost = SCpnt->device->host;
+ struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+ MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
+ int rtn;
+
+ rtn = mptfc_block_error_handler(rport);
+ if (rtn == SUCCESS) {
+ dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+ "%s.%d: %d:%llu, executing recovery.\n", __func__,
+ hd->ioc->name, shost->host_no,
+ SCpnt->device->id, SCpnt->device->lun));
+ rtn = mptscsih_dev_reset(SCpnt);
+ }
+ return rtn;
}
static int
mptfc_bus_reset(struct scsi_cmnd *SCpnt)
{
- return
- mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
-}
+ struct Scsi_Host *shost = SCpnt->device->host;
+ MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
+ int channel = SCpnt->device->channel;
+ struct mptfc_rport_info *ri;
+ int rtn = FAILED;
-static int
-mptfc_host_reset(struct scsi_cmnd *SCpnt)
-{
- return
- mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __func__);
+ list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
+ if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
+ VirtTarget *vtarget = ri->starget->hostdata;
+
+ if (!vtarget || vtarget->channel != channel)
+ continue;
+ rtn = fc_block_rport(ri->rport);
+ if (rtn != 0)
+ break;
+ }
+ }
+ if (rtn == 0) {
+ dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+ "%s.%d: %d:%llu, executing recovery.\n", __func__,
+ hd->ioc->name, shost->host_no,
+ SCpnt->device->id, SCpnt->device->lun));
+ rtn = mptscsih_bus_reset(SCpnt);
+ }
+ return rtn;
}
static void
@@ -339,8 +368,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
break;
data_sz = hdr.PageLength * 4;
- ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
- &page0_dma);
+ ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page0_dma, GFP_KERNEL);
rc = -ENOMEM;
if (!ppage0_alloc)
break;
@@ -375,8 +404,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
*p_p0 = *ppage0_alloc; /* save data */
*p_pp0++ = p_p0++; /* save addr */
}
- pci_free_consistent(ioc->pcidev, data_sz,
- (u8 *) ppage0_alloc, page0_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ ppage0_alloc, page0_dma);
if (rc != 0)
break;
@@ -474,7 +503,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
/*
* if already mapped, remap here. If not mapped,
* target_alloc will allocate vtarget and map,
- * slave_alloc will fill in vdevice from vtarget.
+ * sdev_init will fill in vdevice from vtarget.
*/
if (ri->starget) {
vtarget = ri->starget->hostdata;
@@ -525,8 +554,7 @@ mptfc_target_destroy(struct scsi_target *starget)
if (ri) /* better be! */
ri->starget = NULL;
}
- if (starget->hostdata)
- kfree(starget->hostdata);
+ kfree(starget->hostdata);
starget->hostdata = NULL;
}
@@ -603,7 +631,7 @@ mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device
* Init memory once per LUN.
*/
static int
-mptfc_slave_alloc(struct scsi_device *sdev)
+mptfc_sdev_init(struct scsi_device *sdev)
{
MPT_SCSI_HOST *hd;
VirtTarget *vtarget;
@@ -623,7 +651,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdevice) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ printk(MYIOC_s_ERR_FMT "sdev_init kmalloc(%zd) FAILED!\n",
ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
@@ -649,7 +677,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
}
static int
-mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
{
struct mptfc_rport_info *ri;
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
@@ -658,14 +686,14 @@ mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
if (!vdevice || !vdevice->vtarget) {
SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
err = fc_remote_port_chkready(rport);
if (unlikely(err)) {
SCpnt->result = err;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
@@ -673,15 +701,13 @@ mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
ri = *((struct mptfc_rport_info **)rport->dd_data);
if (unlikely(!ri)) {
SCpnt->result = DID_IMM_RETRY << 16;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
- return mptscsih_qcmd(SCpnt,done);
+ return mptscsih_qcmd(SCpnt);
}
-static DEF_SCSI_QCMD(mptfc_qcmd)
-
/*
* mptfc_display_port_link_speed - displaying link speed
* @ioc: Pointer to MPT_ADAPTER structure
@@ -703,7 +729,7 @@ mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0d
state = pp0dest->PortState;
if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
- new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
+ new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN) {
old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
@@ -774,7 +800,8 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
data_sz = hdr.PageLength * 4;
rc = -ENOMEM;
- ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
+ ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page0_dma, GFP_KERNEL);
if (ppage0_alloc) {
try_again:
@@ -828,7 +855,8 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
mptfc_display_port_link_speed(ioc, portnum, pp0dest);
}
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz, ppage0_alloc,
+ page0_dma);
}
return rc;
@@ -915,9 +943,8 @@ start_over:
if (data_sz < sizeof(FCPortPage1_t))
data_sz = sizeof(FCPortPage1_t);
- page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
- data_sz,
- &page1_dma);
+ page1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
+ &page1_dma, GFP_KERNEL);
if (!page1_alloc)
return -ENOMEM;
}
@@ -927,14 +954,12 @@ start_over:
data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
if (hdr.PageLength * 4 > data_sz) {
ioc->fc_data.fc_port_page1[portnum].data = NULL;
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
- page1_alloc, page1_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz,
+ page1_alloc, page1_dma);
goto start_over;
}
}
- memset(page1_alloc,0,data_sz);
-
cfg.physAddr = page1_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
@@ -945,8 +970,8 @@ start_over:
}
else {
ioc->fc_data.fc_port_page1[portnum].data = NULL;
- pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
- page1_alloc, page1_dma);
+ dma_free_coherent(&ioc->pcidev->dev, data_sz, page1_alloc,
+ page1_dma);
}
return rc;
@@ -1302,7 +1327,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!)
*/
- ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
+ ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
if (!ioc->ScsiLookup) {
error = -ENOMEM;
goto out_mptfc_probe;
@@ -1324,12 +1349,12 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* initialize workqueue */
- snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
- "mptfc_wq_%d", sh->host_no);
- ioc->fc_rescan_work_q =
- create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
- if (!ioc->fc_rescan_work_q)
- goto out_mptfc_probe;
+ ioc->fc_rescan_work_q = alloc_ordered_workqueue(
+ "mptfc_wq_%d", WQ_MEM_RECLAIM, sh->host_no);
+ if (!ioc->fc_rescan_work_q) {
+ error = -ENOMEM;
+ goto out_mptfc_host;
+ }
/*
* Pre-fetch FC port WWN and stuff...
@@ -1350,6 +1375,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
+out_mptfc_host:
+ scsi_remove_host(sh);
+
out_mptfc_probe:
mptscsih_remove(pdev);
@@ -1371,7 +1399,6 @@ static struct pci_driver mptfc_driver = {
static int
mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{
- MPT_SCSI_HOST *hd;
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
unsigned long flags;
int rc=1;
@@ -1382,8 +1409,7 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
- if (ioc->sh == NULL ||
- ((hd = shost_priv(ioc->sh)) == NULL))
+ if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
return 1;
switch (event) {
@@ -1521,14 +1547,16 @@ static void mptfc_remove(struct pci_dev *pdev)
for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
if (ioc->fc_data.fc_port_page1[ii].data) {
- pci_free_consistent(ioc->pcidev,
- ioc->fc_data.fc_port_page1[ii].pg_sz,
- (u8 *) ioc->fc_data.fc_port_page1[ii].data,
- ioc->fc_data.fc_port_page1[ii].dma);
+ dma_free_coherent(&ioc->pcidev->dev,
+ ioc->fc_data.fc_port_page1[ii].pg_sz,
+ ioc->fc_data.fc_port_page1[ii].data,
+ ioc->fc_data.fc_port_page1[ii].dma);
ioc->fc_data.fc_port_page1[ii].data = NULL;
}
}
+ scsi_remove_host(ioc->sh);
+
mptscsih_remove(pdev);
}
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index cbe96072a6cc..de2e7bcf4784 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -72,9 +72,6 @@ MODULE_VERSION(my_VERSION);
#define MPT_LAN_RECEIVE_POST_REQUEST_SIZE \
(sizeof(LANReceivePostRequest_t) - sizeof(SGE_MPI_UNION))
-#define MPT_LAN_TRANSACTION32_SIZE \
- (sizeof(SGETransaction32_t) - sizeof(u32))
-
/*
* Fusion MPT LAN private structures
*/
@@ -394,7 +391,8 @@ mpt_lan_open(struct net_device *dev)
"a moment.\n");
}
- priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
+ priv->mpt_txfidx = kmalloc_array(priv->tx_max_out, sizeof(int),
+ GFP_KERNEL);
if (priv->mpt_txfidx == NULL)
goto out;
priv->mpt_txfidx_tail = -1;
@@ -408,8 +406,8 @@ mpt_lan_open(struct net_device *dev)
dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
- priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int),
- GFP_KERNEL);
+ priv->mpt_rxfidx = kmalloc_array(priv->max_buckets_out, sizeof(int),
+ GFP_KERNEL);
if (priv->mpt_rxfidx == NULL)
goto out_SendCtl;
priv->mpt_rxfidx_tail = -1;
@@ -518,9 +516,9 @@ mpt_lan_close(struct net_device *dev)
if (priv->RcvCtl[i].skb != NULL) {
/**/ dlprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
/**/ "is still out\n", i));
- pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma,
- priv->RcvCtl[i].len,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[i].dma,
+ priv->RcvCtl[i].len, DMA_FROM_DEVICE);
dev_kfree_skb(priv->RcvCtl[i].skb);
}
}
@@ -530,9 +528,9 @@ mpt_lan_close(struct net_device *dev)
for (i = 0; i < priv->tx_max_out; i++) {
if (priv->SendCtl[i].skb != NULL) {
- pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[i].dma,
- priv->SendCtl[i].len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev,
+ priv->SendCtl[i].dma,
+ priv->SendCtl[i].len, DMA_TO_DEVICE);
dev_kfree_skb(priv->SendCtl[i].skb);
}
}
@@ -549,19 +547,9 @@ mpt_lan_close(struct net_device *dev)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
-mpt_lan_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < MPT_LAN_MIN_MTU) || (new_mtu > MPT_LAN_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* Tx timeout handler. */
static void
-mpt_lan_tx_timeout(struct net_device *dev)
+mpt_lan_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
struct mpt_lan_priv *priv = netdev_priv(dev);
MPT_ADAPTER *mpt_dev = priv->mpt_dev;
@@ -594,8 +582,8 @@ mpt_lan_send_turbo(struct net_device *dev, u32 tmsg)
__func__, sent));
priv->SendCtl[ctx].skb = NULL;
- pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
- priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev, priv->SendCtl[ctx].dma,
+ priv->SendCtl[ctx].len, DMA_TO_DEVICE);
dev_kfree_skb_irq(sent);
spin_lock_irqsave(&priv->txfidx_lock, flags);
@@ -660,8 +648,9 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep)
__func__, sent));
priv->SendCtl[ctx].skb = NULL;
- pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
- priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev,
+ priv->SendCtl[ctx].dma,
+ priv->SendCtl[ctx].len, DMA_TO_DEVICE);
dev_kfree_skb_irq(sent);
priv->mpt_txfidx[++priv->mpt_txfidx_tail] = ctx;
@@ -680,7 +669,7 @@ out:
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
+static netdev_tx_t
mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
{
struct mpt_lan_priv *priv = netdev_priv(dev);
@@ -732,8 +721,8 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
skb_reset_mac_header(skb);
skb_pull(skb, 12);
- dma = pci_map_single(mpt_dev->pcidev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
+ dma = dma_map_single(&mpt_dev->pcidev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
priv->SendCtl[ctx].skb = skb;
priv->SendCtl[ctx].dma = dma;
@@ -754,7 +743,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
pTrans->ContextSize = sizeof(u32);
pTrans->DetailsLength = 2 * sizeof(u32);
pTrans->Flags = 0;
- pTrans->TransactionContext[0] = cpu_to_le32(ctx);
+ pTrans->TransactionContext = cpu_to_le32(ctx);
// dioprintk((KERN_INFO MYNAM ": %s/%s: BC = %08x, skb = %p, buff = %p\n",
// IOC_AND_NETDEV_NAMES_s_s(dev),
@@ -791,7 +780,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
pSimple->Address.High = 0;
mpt_put_msg_frame (LanCtx, mpt_dev, mf);
- dev->trans_start = jiffies;
+ netif_trans_update(dev);
dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
IOC_AND_NETDEV_NAMES_s_s(dev),
@@ -880,13 +869,17 @@ mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg)
return -ENOMEM;
}
- pci_dma_sync_single_for_cpu(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
skb_copy_from_linear_data(old_skb, skb_put(skb, len), len);
- pci_dma_sync_single_for_device(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
goto out;
}
@@ -894,8 +887,8 @@ mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg)
priv->RcvCtl[ctx].skb = NULL;
- pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev, priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len, DMA_FROM_DEVICE);
out:
spin_lock_irqsave(&priv->rxfidx_lock, flags);
@@ -939,8 +932,8 @@ mpt_lan_receive_post_free(struct net_device *dev,
// dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
priv->RcvCtl[ctx].skb = NULL;
- pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev, priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
@@ -1040,16 +1033,16 @@ mpt_lan_receive_post_reply(struct net_device *dev,
// IOC_AND_NETDEV_NAMES_s_s(dev),
// i, l));
- pci_dma_sync_single_for_cpu(mpt_dev->pcidev,
- priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
skb_copy_from_linear_data(old_skb, skb_put(skb, l), l);
- pci_dma_sync_single_for_device(mpt_dev->pcidev,
- priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
szrem -= l;
@@ -1068,17 +1061,17 @@ mpt_lan_receive_post_reply(struct net_device *dev,
return -ENOMEM;
}
- pci_dma_sync_single_for_cpu(mpt_dev->pcidev,
- priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
skb_copy_from_linear_data(old_skb, skb_put(skb, len), len);
- pci_dma_sync_single_for_device(mpt_dev->pcidev,
- priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(&mpt_dev->pcidev->dev,
+ priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len,
+ DMA_FROM_DEVICE);
spin_lock_irqsave(&priv->rxfidx_lock, flags);
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
@@ -1089,8 +1082,8 @@ mpt_lan_receive_post_reply(struct net_device *dev,
priv->RcvCtl[ctx].skb = NULL;
- pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
- priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
+ dma_unmap_single(&mpt_dev->pcidev->dev, priv->RcvCtl[ctx].dma,
+ priv->RcvCtl[ctx].len, DMA_FROM_DEVICE);
priv->RcvCtl[ctx].dma = 0;
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
@@ -1168,7 +1161,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
__func__, buckets, curr));
max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) /
- (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t));
+ (sizeof(SGETransaction32_t) + sizeof(SGESimple64_t));
while (buckets) {
mf = mpt_get_msg_frame(LanCtx, mpt_dev);
@@ -1211,10 +1204,10 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
skb = priv->RcvCtl[ctx].skb;
if (skb && (priv->RcvCtl[ctx].len != len)) {
- pci_unmap_single(mpt_dev->pcidev,
+ dma_unmap_single(&mpt_dev->pcidev->dev,
priv->RcvCtl[ctx].dma,
priv->RcvCtl[ctx].len,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
dev_kfree_skb(priv->RcvCtl[ctx].skb);
skb = priv->RcvCtl[ctx].skb = NULL;
}
@@ -1230,8 +1223,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
break;
}
- dma = pci_map_single(mpt_dev->pcidev, skb->data,
- len, PCI_DMA_FROMDEVICE);
+ dma = dma_map_single(&mpt_dev->pcidev->dev,
+ skb->data, len,
+ DMA_FROM_DEVICE);
priv->RcvCtl[ctx].skb = skb;
priv->RcvCtl[ctx].dma = dma;
@@ -1243,7 +1237,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
pTrans->ContextSize = sizeof(u32);
pTrans->DetailsLength = 0;
pTrans->Flags = 0;
- pTrans->TransactionContext[0] = cpu_to_le32(ctx);
+ pTrans->TransactionContext = cpu_to_le32(ctx);
pSimple = (SGESimple64_t *) pTrans->TransactionDetails;
@@ -1304,7 +1298,6 @@ static const struct net_device_ops mpt_netdev_ops = {
.ndo_open = mpt_lan_open,
.ndo_stop = mpt_lan_close,
.ndo_start_xmit = mpt_lan_sdu_send,
- .ndo_change_mtu = mpt_lan_change_mtu,
.ndo_tx_timeout = mpt_lan_tx_timeout,
};
@@ -1363,7 +1356,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
HWaddr[5] = a[0];
dev->addr_len = FC_ALEN;
- memcpy(dev->dev_addr, HWaddr, FC_ALEN);
+ dev_addr_set(dev, HWaddr);
memset(dev->broadcast, 0xff, FC_ALEN);
/* The Tx queue is 127 deep on the 909.
@@ -1375,6 +1368,10 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
dev->netdev_ops = &mpt_netdev_ops;
dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;
+ /* MTU range: 96 - 65280 */
+ dev->min_mtu = MPT_LAN_MIN_MTU;
+ dev->max_mtu = MPT_LAN_MAX_MTU;
+
dlprintk((KERN_INFO MYNAM ": Finished registering dev "
"and setting initial values\n"));
@@ -1386,7 +1383,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
}
static int
-mptlan_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+mptlan_probe(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct net_device *dev;
@@ -1436,7 +1433,9 @@ mptlan_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct net_device *dev = ioc->netdev;
+ struct mpt_lan_priv *priv = netdev_priv(dev);
+ cancel_delayed_work_sync(&priv->post_buckets_task);
if(dev != NULL) {
unregister_netdev(dev);
free_netdev(dev);
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 69e9d5463564..40b34f670065 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -51,10 +51,7 @@
#define LINUX_MPTLAN_H_INCLUDED
/*****************************************************************************/
-#if !defined(__GENKSYMS__)
#include <linux/module.h>
-#endif
-
#include <linux/netdevice.h>
#include <linux/errno.h>
// #include <linux/etherdevice.h>
@@ -64,13 +61,13 @@
#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/printk.h>
#include <linux/slab.h>
-#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
/* Override mptbase.h by pre-defining these! */
@@ -112,13 +109,13 @@ MODULE_DESCRIPTION(LANAME);
#ifdef MPT_LAN_IO_DEBUG
#define dioprintk(x) printk x
#else
-#define dioprintk(x)
+#define dioprintk(x) no_printk x
#endif
#ifdef MPT_LAN_DEBUG
#define dlprintk(x) printk x
#else
-#define dlprintk(x)
+#define dlprintk(x) no_printk x
#endif
#define NETDEV_TO_LANPRIV_PTR(d) ((struct mpt_lan_priv *)netdev_priv(d))
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index dd239bdbfcb4..185c08eab4ca 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -86,7 +86,7 @@ MODULE_PARM_DESC(mpt_pt_clear,
" Clear persistency table: enable=1 "
"(default=MPTSCSIH_PT_CLEAR=0)");
-/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
+/* scsi-mid layer global parameter is max_report_luns, which is 511 */
#define MPTSAS_MAX_LUN (16895)
static int max_lun = MPTSAS_MAX_LUN;
module_param(max_lun, int, 0);
@@ -129,7 +129,7 @@ static void mptsas_expander_delete(MPT_ADAPTER *ioc,
static void mptsas_send_expander_event(struct fw_event_work *fw_event);
static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
-static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
+static void mptsas_broadcast_primitive_work(struct fw_event_work *fw_event);
static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
void mptsas_schedule_target_reset(void *ioc);
@@ -289,6 +289,7 @@ mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
spin_lock_irqsave(&ioc->fw_event_lock, flags);
list_add_tail(&fw_event->list, &ioc->fw_event_list);
+ fw_event->users = 1;
INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)"
"on cpuid %d\n", ioc->name, __func__,
@@ -314,6 +315,15 @@ mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
}
+static void __mptsas_free_fw_event(MPT_ADAPTER *ioc,
+ struct fw_event_work *fw_event)
+{
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
+ ioc->name, __func__, fw_event));
+ list_del(&fw_event->list);
+ kfree(fw_event);
+}
+
/* free memory associated to a sas firmware event */
static void
mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
@@ -321,10 +331,9 @@ mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
unsigned long flags;
spin_lock_irqsave(&ioc->fw_event_lock, flags);
- devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
- ioc->name, __func__, fw_event));
- list_del(&fw_event->list);
- kfree(fw_event);
+ fw_event->users--;
+ if (!fw_event->users)
+ __mptsas_free_fw_event(ioc, fw_event);
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
}
@@ -333,9 +342,10 @@ mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
static void
mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
{
- struct fw_event_work *fw_event, *next;
+ struct fw_event_work *fw_event;
struct mptsas_target_reset_event *target_reset_list, *n;
MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
+ unsigned long flags;
/* flush the target_reset_list */
if (!list_empty(&hd->target_reset_list)) {
@@ -350,14 +360,29 @@ mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
}
}
- if (list_empty(&ioc->fw_event_list) ||
- !ioc->fw_event_q || in_interrupt())
+ if (list_empty(&ioc->fw_event_list) || !ioc->fw_event_q)
return;
- list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
- if (cancel_delayed_work(&fw_event->work))
- mptsas_free_fw_event(ioc, fw_event);
+ spin_lock_irqsave(&ioc->fw_event_lock, flags);
+
+ while (!list_empty(&ioc->fw_event_list)) {
+ bool canceled = false;
+
+ fw_event = list_first_entry(&ioc->fw_event_list,
+ struct fw_event_work, list);
+ fw_event->users++;
+ spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
+ if (cancel_delayed_work_sync(&fw_event->work))
+ canceled = true;
+
+ spin_lock_irqsave(&ioc->fw_event_lock, flags);
+ if (canceled)
+ fw_event->users--;
+ fw_event->users--;
+ WARN_ON_ONCE(fw_event->users);
+ __mptsas_free_fw_event(ioc, fw_event);
}
+ spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
}
@@ -395,12 +420,14 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
}
/**
- * mptsas_find_portinfo_by_sas_address -
+ * mptsas_find_portinfo_by_sas_address - find and return portinfo for
+ * this sas_address
* @ioc: Pointer to MPT_ADAPTER structure
- * @handle:
+ * @sas_address: expander sas address
*
- * This function should be called with the sas_topology_mutex already held
+ * This function should be called with the sas_topology_mutex already held.
*
+ * Return: %NULL if not found.
**/
static struct mptsas_portinfo *
mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
@@ -542,12 +569,14 @@ starget)
}
/**
- * mptsas_add_device_component -
+ * mptsas_add_device_component - adds a new device component to our lists
* @ioc: Pointer to MPT_ADAPTER structure
- * @channel: fw mapped id's
- * @id:
- * @sas_address:
- * @device_info:
+ * @channel: channel number
+ * @id: Logical Target ID for reset (if appropriate)
+ * @sas_address: expander sas address
+ * @device_info: specific bits (flags) for devices
+ * @slot: enclosure slot ID
+ * @enclosure_logical_id: enclosure WWN
*
**/
static void
@@ -609,10 +638,10 @@ mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
}
/**
- * mptsas_add_device_component_by_fw -
+ * mptsas_add_device_component_by_fw - adds a new device component by FW ID
* @ioc: Pointer to MPT_ADAPTER structure
- * @channel: fw mapped id's
- * @id:
+ * @channel: channel number
+ * @id: Logical Target ID
*
**/
static void
@@ -643,8 +672,7 @@ mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
/**
* mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
* @ioc: Pointer to MPT_ADAPTER structure
- * @channel: fw mapped id's
- * @id:
+ * @starget: SCSI target for this SCSI device
*
**/
static void
@@ -674,8 +702,8 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
if (!hdr.PageLength)
goto out;
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer)
goto out;
@@ -741,27 +769,25 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
}
/**
- * mptsas_add_device_component_starget -
+ * mptsas_add_device_component_starget - adds a SCSI target device component
* @ioc: Pointer to MPT_ADAPTER structure
- * @starget:
+ * @starget: SCSI target for this SCSI device
*
**/
static void
mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
struct scsi_target *starget)
{
- VirtTarget *vtarget;
struct sas_rphy *rphy;
struct mptsas_phyinfo *phy_info = NULL;
struct mptsas_enclosure enclosure_info;
rphy = dev_to_rphy(starget->dev.parent);
- vtarget = starget->hostdata;
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
rphy->identify.sas_address);
if (!phy_info)
@@ -783,7 +809,7 @@ mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
* mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
* @ioc: Pointer to MPT_ADAPTER structure
* @channel: os mapped id's
- * @id:
+ * @id: Logical Target ID
*
**/
static void
@@ -955,11 +981,12 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
}
/**
- * csmisas_find_vtarget
+ * mptsas_find_vtarget - find a virtual target device (FC LUN device or
+ * SCSI target device)
*
- * @ioc
- * @volume_id
- * @volume_bus
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @channel: channel number
+ * @id: Logical Target ID
*
**/
static VirtTarget *
@@ -990,11 +1017,10 @@ mptsas_queue_device_delete(MPT_ADAPTER *ioc,
MpiEventDataSasDeviceStatusChange_t *sas_event_data)
{
struct fw_event_work *fw_event;
- int sz;
- sz = offsetof(struct fw_event_work, event_data) +
- sizeof(MpiEventDataSasDeviceStatusChange_t);
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event) +
+ sizeof(MpiEventDataSasDeviceStatusChange_t),
+ GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
ioc->name, __func__, __LINE__);
@@ -1011,10 +1037,8 @@ static void
mptsas_queue_rescan(MPT_ADAPTER *ioc)
{
struct fw_event_work *fw_event;
- int sz;
- sz = offsetof(struct fw_event_work, event_data);
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
ioc->name, __func__, __LINE__);
@@ -1027,15 +1051,14 @@ mptsas_queue_rescan(MPT_ADAPTER *ioc)
/**
- * mptsas_target_reset
- *
- * Issues TARGET_RESET to end device using handshaking method
+ * mptsas_target_reset - Issues TARGET_RESET to end device using
+ * handshaking method
*
- * @ioc
- * @channel
- * @id
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @channel: channel number
+ * @id: Logical Target ID for reset
*
- * Returns (1) success
+ * Return: (1) success
* (0) failure
*
**/
@@ -1099,15 +1122,15 @@ mptsas_block_io_starget(struct scsi_target *starget)
}
/**
- * mptsas_target_reset_queue
+ * mptsas_target_reset_queue - queue a target reset
+ *
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @sas_event_data: SAS Device Status Change Event data
*
- * Receive request for TARGET_RESET after receiving an firmware
+ * Receive request for TARGET_RESET after receiving a firmware
* event NOT_RESPONDING_EVENT, then put command in link list
* and queue if task_queue already in use.
*
- * @ioc
- * @sas_event_data
- *
**/
static void
mptsas_target_reset_queue(MPT_ADAPTER *ioc,
@@ -1168,7 +1191,6 @@ mptsas_schedule_target_reset(void *iocp)
* issue target reset to next device in the queue
*/
- head = &hd->target_reset_list;
if (list_empty(head))
return;
@@ -1188,9 +1210,11 @@ mptsas_schedule_target_reset(void *iocp)
/**
* mptsas_taskmgmt_complete - complete SAS task management function
* @ioc: Pointer to MPT_ADAPTER structure
+ * @mf: MPT message frame
+ * @mr: SCSI Task Management Reply structure ptr (may be %NULL)
*
* Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
- * queue to finish off removing device from upper layers. then send next
+ * queue to finish off removing device from upper layers, then send next
* TARGET_RESET in the queue.
**/
static int
@@ -1206,27 +1230,28 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
"(mf = %p, mr = %p)\n", ioc->name, mf, mr));
pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
- if (pScsiTmReply) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
- "\ttask_type = 0x%02X, iocstatus = 0x%04X "
- "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
- "term_cmnds = %d\n", ioc->name,
- pScsiTmReply->Bus, pScsiTmReply->TargetID,
- pScsiTmReply->TaskType,
- le16_to_cpu(pScsiTmReply->IOCStatus),
- le32_to_cpu(pScsiTmReply->IOCLogInfo),
- pScsiTmReply->ResponseCode,
- le32_to_cpu(pScsiTmReply->TerminationCount)));
-
- if (pScsiTmReply->ResponseCode)
- mptscsih_taskmgmt_response_code(ioc,
- pScsiTmReply->ResponseCode);
- }
-
- if (pScsiTmReply && (pScsiTmReply->TaskType ==
+ if (!pScsiTmReply)
+ return 0;
+
+ dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
+ "\ttask_type = 0x%02X, iocstatus = 0x%04X "
+ "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
+ "term_cmnds = %d\n", ioc->name,
+ pScsiTmReply->Bus, pScsiTmReply->TargetID,
+ pScsiTmReply->TaskType,
+ le16_to_cpu(pScsiTmReply->IOCStatus),
+ le32_to_cpu(pScsiTmReply->IOCLogInfo),
+ pScsiTmReply->ResponseCode,
+ le32_to_cpu(pScsiTmReply->TerminationCount)));
+
+ if (pScsiTmReply->ResponseCode)
+ mptscsih_taskmgmt_response_code(ioc,
+ pScsiTmReply->ResponseCode);
+
+ if (pScsiTmReply->TaskType ==
MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
- MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
+ MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
memcpy(ioc->taskmgmt_cmds.reply, mr,
@@ -1280,10 +1305,10 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
}
/**
- * mptscsih_ioc_reset
+ * mptsas_ioc_reset - issue an IOC reset for this reset phase
*
- * @ioc
- * @reset_phase
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @reset_phase: id of phase of reset
*
**/
static int
@@ -1330,7 +1355,7 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/**
- * enum device_state -
+ * enum device_state - TUR device state
* @DEVICE_RETRY: need to retry the TUR
* @DEVICE_ERROR: TUR return error, don't add device
* @DEVICE_READY: device can be added
@@ -1374,8 +1399,8 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -1401,8 +1426,8 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
enclosure->sep_channel = buffer->SEPBus;
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -1575,7 +1600,7 @@ mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
mptsas_port_delete(ioc, phy_info->port_details);
}
-struct mptsas_phyinfo *
+static struct mptsas_phyinfo *
mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
struct mptsas_devinfo *sas_device)
{
@@ -1668,7 +1693,7 @@ mptsas_firmware_event_work(struct work_struct *work)
mptsas_free_fw_event(ioc, fw_event);
break;
case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
- mptsas_broadcast_primative_work(fw_event);
+ mptsas_broadcast_primitive_work(fw_event);
break;
case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
mptsas_send_expander_event(fw_event);
@@ -1685,7 +1710,7 @@ mptsas_firmware_event_work(struct work_struct *work)
static int
-mptsas_slave_configure(struct scsi_device *sdev)
+mptsas_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim)
{
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = shost_priv(host);
@@ -1711,7 +1736,7 @@ mptsas_slave_configure(struct scsi_device *sdev)
mptsas_add_device_component_starget(ioc, scsi_target(sdev));
out:
- return mptscsih_slave_configure(sdev);
+ return mptscsih_sdev_configure(sdev, lim);
}
static int
@@ -1842,7 +1867,7 @@ mptsas_target_destroy(struct scsi_target *starget)
static int
-mptsas_slave_alloc(struct scsi_device *sdev)
+mptsas_sdev_init(struct scsi_device *sdev)
{
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = shost_priv(host);
@@ -1855,7 +1880,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdevice) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
+ printk(MYIOC_s_ERR_FMT "sdev_init kzalloc(%zd) FAILED!\n",
ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
@@ -1896,7 +1921,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
}
static int
-mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
{
MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc;
@@ -1904,11 +1929,11 @@ mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
- hd = shost_priv(SCpnt->device->host);
+ hd = shost_priv(shost);
ioc = hd->ioc;
if (ioc->sas_discovery_quiesce_io)
@@ -1917,24 +1942,22 @@ mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
if (ioc->debug_level & MPT_DEBUG_SCSI)
scsi_print_command(SCpnt);
- return mptscsih_qcmd(SCpnt,done);
+ return mptscsih_qcmd(SCpnt);
}
-static DEF_SCSI_QCMD(mptsas_qcmd)
-
/**
- * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
+ * mptsas_eh_timed_out - resets the scsi_cmnd timeout
* if the device under question is currently in the
* device removal delay.
* @sc: scsi command that the midlayer is about to time out
*
**/
-static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
+static enum scsi_timeout_action mptsas_eh_timed_out(struct scsi_cmnd *sc)
{
MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc;
VirtDevice *vdevice;
- enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
+ enum scsi_timeout_action rc = SCSI_EH_NOT_HANDLED;
hd = shost_priv(sc->device->host);
if (hd == NULL) {
@@ -1957,7 +1980,7 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
"SML need to reset the timer (sc=%p)\n",
ioc->name, __func__, sc));
- rc = BLK_EH_RESET_TIMER;
+ rc = SCSI_EH_RESET_TIMER;
}
vdevice = sc->device->hostdata;
if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
@@ -1965,7 +1988,7 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
"or in device removal delay (sc=%p)\n",
ioc->name, __func__, sc));
- rc = BLK_EH_RESET_TIMER;
+ rc = SCSI_EH_RESET_TIMER;
goto done;
}
@@ -1974,7 +1997,7 @@ done:
}
-static struct scsi_host_template mptsas_driver_template = {
+static const struct scsi_host_template mptsas_driver_template = {
.module = THIS_MODULE,
.proc_name = "mptsas",
.show_info = mptscsih_show_info,
@@ -1982,11 +2005,12 @@ static struct scsi_host_template mptsas_driver_template = {
.info = mptscsih_info,
.queuecommand = mptsas_qcmd,
.target_alloc = mptsas_target_alloc,
- .slave_alloc = mptsas_slave_alloc,
- .slave_configure = mptsas_slave_configure,
+ .sdev_init = mptsas_sdev_init,
+ .sdev_configure = mptsas_sdev_configure,
.target_destroy = mptsas_target_destroy,
- .slave_destroy = mptscsih_slave_destroy,
+ .sdev_destroy = mptscsih_sdev_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
+ .eh_timed_out = mptsas_eh_timed_out,
.eh_abort_handler = mptscsih_abort,
.eh_device_reset_handler = mptscsih_dev_reset,
.eh_host_reset_handler = mptscsih_host_reset,
@@ -1996,8 +2020,9 @@ static struct scsi_host_template mptsas_driver_template = {
.sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192,
.cmd_per_lun = 7,
- .use_clustering = ENABLE_CLUSTERING,
- .shost_attrs = mptscsih_host_attrs,
+ .dma_alignment = 511,
+ .shost_groups = mptscsih_host_attr_groups,
+ .no_write_same = 1,
};
static int mptsas_get_linkerrors(struct sas_phy *phy)
@@ -2034,8 +2059,8 @@ static int mptsas_get_linkerrors(struct sas_phy *phy)
if (!hdr.ExtPageLength)
return -ENXIO;
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
@@ -2057,8 +2082,8 @@ static int mptsas_get_linkerrors(struct sas_phy *phy)
le32_to_cpu(buffer->PhyResetProblemCount);
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
return error;
}
@@ -2213,33 +2238,26 @@ mptsas_get_bay_identifier(struct sas_rphy *rphy)
return rc;
}
-static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
- struct request *req)
+static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
+ struct sas_rphy *rphy)
{
MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
MPT_FRAME_HDR *mf;
SmpPassthroughRequest_t *smpreq;
- struct request *rsp = req->next_rq;
- int ret;
int flagsLength;
unsigned long timeleft;
char *psge;
- dma_addr_t dma_addr_in = 0;
- dma_addr_t dma_addr_out = 0;
u64 sas_address = 0;
-
- if (!rsp) {
- printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
- ioc->name, __func__);
- return -EINVAL;
- }
+ unsigned int reslen = 0;
+ int ret = -EINVAL;
/* do we need to support multiple segments? */
- if (bio_segments(req->bio) > 1 || bio_segments(rsp->bio) > 1) {
- printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
- ioc->name, __func__, bio_segments(req->bio), blk_rq_bytes(req),
- bio_segments(rsp->bio), blk_rq_bytes(rsp));
- return -EINVAL;
+ if (job->request_payload.sg_cnt > 1 ||
+ job->reply_payload.sg_cnt > 1) {
+ printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
+ ioc->name, __func__, job->request_payload.payload_len,
+ job->reply_payload.payload_len);
+ goto out;
}
ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
@@ -2255,7 +2273,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
smpreq = (SmpPassthroughRequest_t *)mf;
memset(smpreq, 0, sizeof(*smpreq));
- smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
+ smpreq->RequestDataLength =
+ cpu_to_le16(job->request_payload.payload_len - 4);
smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
if (rphy)
@@ -2281,13 +2300,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_DIRECTION)
<< MPI_SGE_FLAGS_SHIFT;
- flagsLength |= (blk_rq_bytes(req) - 4);
- dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
- blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
- if (!dma_addr_out)
+ if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list,
+ 1, DMA_BIDIRECTIONAL))
goto put_mf;
- ioc->add_sge(psge, flagsLength, dma_addr_out);
+
+ flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4);
+ ioc->add_sge(psge, flagsLength,
+ sg_dma_address(job->request_payload.sg_list));
psge += ioc->SGE_size;
/* response */
@@ -2297,12 +2317,13 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
MPI_SGE_FLAGS_END_OF_BUFFER;
flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
- flagsLength |= blk_rq_bytes(rsp) + 4;
- dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
- blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
- if (!dma_addr_in)
- goto unmap;
- ioc->add_sge(psge, flagsLength, dma_addr_in);
+
+ if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list,
+ 1, DMA_BIDIRECTIONAL))
+ goto unmap_out;
+ flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4;
+ ioc->add_sge(psge, flagsLength,
+ sg_dma_address(job->reply_payload.sg_list));
INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
@@ -2313,10 +2334,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
mpt_free_msg_frame(ioc, mf);
mf = NULL;
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
- goto unmap;
+ goto unmap_in;
if (!timeleft)
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
- goto unmap;
+ goto unmap_in;
}
mf = NULL;
@@ -2324,23 +2345,22 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
SmpPassthroughReply_t *smprep;
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
- memcpy(req->sense, smprep, sizeof(*smprep));
- req->sense_len = sizeof(*smprep);
- req->resid_len = 0;
- rsp->resid_len -= smprep->ResponseDataLength;
+ memcpy(job->reply, smprep, sizeof(*smprep));
+ job->reply_len = sizeof(*smprep);
+ reslen = smprep->ResponseDataLength;
} else {
printk(MYIOC_s_ERR_FMT
"%s: smp passthru reply failed to be returned\n",
ioc->name, __func__);
ret = -ENXIO;
}
-unmap:
- if (dma_addr_out)
- pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
- PCI_DMA_BIDIRECTIONAL);
- if (dma_addr_in)
- pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
- PCI_DMA_BIDIRECTIONAL);
+
+unmap_in:
+ dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1,
+ DMA_BIDIRECTIONAL);
+unmap_out:
+ dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1,
+ DMA_BIDIRECTIONAL);
put_mf:
if (mf)
mpt_free_msg_frame(ioc, mf);
@@ -2348,7 +2368,7 @@ out_unlock:
CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
mutex_unlock(&ioc->sas_mgmt.mutex);
out:
- return ret;
+ bsg_job_done(job, ret, reslen);
}
static struct sas_function_template mptsas_transport_functions = {
@@ -2393,8 +2413,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2433,8 +2453,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
}
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2468,8 +2488,8 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2490,8 +2510,8 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2532,8 +2552,8 @@ mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2554,8 +2574,8 @@ mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2595,8 +2615,8 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2635,8 +2655,8 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
device_info->flags = le16_to_cpu(buffer->Flags);
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2678,8 +2698,8 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2718,8 +2738,8 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
}
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2758,8 +2778,8 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
goto out;
}
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer) {
error = -ENOMEM;
goto out;
@@ -2791,8 +2811,8 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
+ dma_handle);
out:
return error;
}
@@ -2814,10 +2834,10 @@ struct rep_manu_reply{
u8 sas_format:1;
u8 reserved1:7;
u8 reserved2[3];
- u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
- u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
- u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
- u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
+ u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN] __nonstring;
+ u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN] __nonstring;
+ u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN] __nonstring;
+ u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN] __nonstring;
u16 component_id;
u8 component_revision_id;
u8 reserved3;
@@ -2825,14 +2845,15 @@ struct rep_manu_reply{
};
/**
- * mptsas_exp_repmanufacture_info -
+ * mptsas_exp_repmanufacture_info - sets expander manufacturer info
* @ioc: per adapter object
* @sas_address: expander sas address
* @edev: the sas_expander_device object
*
- * Fills in the sas_expander_device object when SMP port is created.
+ * For an edge expander or a fanout expander:
+ * fills in the sas_expander_device object when SMP port is created.
*
- * Returns 0 for success, non-zero for failure.
+ * Return: 0 for success, non-zero for failure.
*/
static int
mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
@@ -2876,7 +2897,8 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
- data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
+ data_out = dma_alloc_coherent(&ioc->pcidev->dev, sz, &data_out_dma,
+ GFP_KERNEL);
if (!data_out) {
printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
@@ -2937,27 +2959,23 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
u8 *tmp;
- smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
- if (le16_to_cpu(smprep->ResponseDataLength) !=
- sizeof(struct rep_manu_reply))
+ smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
+ if (le16_to_cpu(smprep->ResponseDataLength) !=
+ sizeof(struct rep_manu_reply))
goto out_free;
- manufacture_reply = data_out + sizeof(struct rep_manu_request);
- strncpy(edev->vendor_id, manufacture_reply->vendor_id,
- SAS_EXPANDER_VENDOR_ID_LEN);
- strncpy(edev->product_id, manufacture_reply->product_id,
- SAS_EXPANDER_PRODUCT_ID_LEN);
- strncpy(edev->product_rev, manufacture_reply->product_rev,
- SAS_EXPANDER_PRODUCT_REV_LEN);
- edev->level = manufacture_reply->sas_format;
- if (manufacture_reply->sas_format) {
- strncpy(edev->component_vendor_id,
- manufacture_reply->component_vendor_id,
- SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
- tmp = (u8 *)&manufacture_reply->component_id;
- edev->component_id = tmp[0] << 8 | tmp[1];
- edev->component_revision_id =
- manufacture_reply->component_revision_id;
+ manufacture_reply = data_out + sizeof(struct rep_manu_request);
+ memtostr(edev->vendor_id, manufacture_reply->vendor_id);
+ memtostr(edev->product_id, manufacture_reply->product_id);
+ memtostr(edev->product_rev, manufacture_reply->product_rev);
+ edev->level = manufacture_reply->sas_format;
+ if (manufacture_reply->sas_format) {
+ memtostr(edev->component_vendor_id,
+ manufacture_reply->component_vendor_id);
+ tmp = (u8 *)&manufacture_reply->component_id;
+ edev->component_id = tmp[0] << 8 | tmp[1];
+ edev->component_revision_id =
+ manufacture_reply->component_revision_id;
}
} else {
printk(MYIOC_s_ERR_FMT
@@ -2967,7 +2985,8 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
}
out_free:
if (data_out_dma)
- pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
+ dma_free_coherent(&ioc->pcidev->dev, sz, data_out,
+ data_out_dma);
put_mf:
if (mf)
mpt_free_msg_frame(ioc, mf);
@@ -2976,7 +2995,7 @@ out_unlock:
mutex_unlock(&ioc->sas_mgmt.mutex);
out:
return ret;
- }
+}
static void
mptsas_parse_device_info(struct sas_identify *identify,
@@ -3270,7 +3289,7 @@ static int mptsas_probe_one_phy(struct device *dev,
rphy_to_expander_device(rphy));
}
- /* If the device exists,verify it wasn't previously flagged
+ /* If the device exists, verify it wasn't previously flagged
as a missing device. If so, clear it */
vtarget = mptsas_find_vtarget(ioc,
phy_info->attached.channel,
@@ -3426,14 +3445,12 @@ mptsas_expander_event_add(MPT_ADAPTER *ioc,
__le64 sas_address;
port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
- if (!port_info)
- BUG();
+ BUG_ON(!port_info);
port_info->num_phys = (expander_data->NumPhys) ?
expander_data->NumPhys : 1;
port_info->phy_info = kcalloc(port_info->num_phys,
sizeof(struct mptsas_phyinfo), GFP_KERNEL);
- if (!port_info->phy_info)
- BUG();
+ BUG_ON(!port_info->phy_info);
memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
for (i = 0; i < port_info->num_phys; i++) {
port_info->phy_info[i].portinfo = port_info;
@@ -3599,8 +3616,7 @@ static void mptsas_expander_delete(MPT_ADAPTER *ioc,
/**
* mptsas_send_expander_event - expanders events
- * @ioc: Pointer to MPT_ADAPTER structure
- * @expander_data: event data
+ * @fw_event: event data
*
*
* This function handles adding, removing, and refreshing
@@ -3645,12 +3661,12 @@ mptsas_send_expander_event(struct fw_event_work *fw_event)
/**
- * mptsas_expander_add -
+ * mptsas_expander_add - adds a newly discovered expander
* @ioc: Pointer to MPT_ADAPTER structure
- * @handle:
+ * @handle: device handle
*
*/
-struct mptsas_portinfo *
+static struct mptsas_portinfo *
mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
{
struct mptsas_portinfo buffer, *port_info;
@@ -3661,7 +3677,7 @@ mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
return NULL;
- port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
+ port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
if (!port_info) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name,
@@ -3765,7 +3781,7 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event)
printk(MYIOC_s_DEBUG_FMT
"SDEV OUTSTANDING CMDS"
"%d\n", ioc->name,
- sdev->device_busy));
+ scsi_device_busy(sdev)));
}
}
@@ -3858,10 +3874,8 @@ retry_page:
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
sas_info->sas_address);
- if (phy_info) {
- mptsas_del_end_device(ioc, phy_info);
- goto redo_device_scan;
- }
+ mptsas_del_end_device(ioc, phy_info);
+ goto redo_device_scan;
} else
mptsas_volume_delete(ioc, sas_info->fw.id);
}
@@ -3872,9 +3886,8 @@ retry_page:
redo_expander_scan:
list_for_each_entry(port_info, &ioc->sas_topology, list) {
- if (port_info->phy_info &&
- (!(port_info->phy_info[0].identify.device_info &
- MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+ if (!(port_info->phy_info[0].identify.device_info &
+ MPI_SAS_DEVICE_INFO_SMP_TARGET))
continue;
found_expander = 0;
handle = 0xFFFF;
@@ -3991,9 +4004,9 @@ mptsas_probe_devices(MPT_ADAPTER *ioc)
}
/**
- * mptsas_scan_sas_topology -
+ * mptsas_scan_sas_topology - scans new SAS topology
+ * (part of probe or rescan)
* @ioc: Pointer to MPT_ADAPTER structure
- * @sas_address:
*
**/
static void
@@ -4096,7 +4109,7 @@ mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
continue;
}
depth = scsi_track_queue_full(sdev,
- current_depth - 1);
+ sdev->queue_depth - 1);
if (depth > 0)
sdev_printk(KERN_INFO, sdev,
"Queue depth reduced to (%d)\n",
@@ -4106,7 +4119,7 @@ mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
"Tagged Command Queueing is being "
"disabled\n");
else if (depth == 0)
- sdev_printk(KERN_INFO, sdev,
+ sdev_printk(KERN_DEBUG, sdev,
"Queue depth not changed yet\n");
}
}
@@ -4141,11 +4154,12 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
}
/**
- * mptsas_find_phyinfo_by_phys_disk_num -
+ * mptsas_find_phyinfo_by_phys_disk_num - find phyinfo for the
+ * specified @phys_disk_num
* @ioc: Pointer to MPT_ADAPTER structure
- * @phys_disk_num:
- * @channel:
- * @id:
+ * @phys_disk_num: (hot plug) physical disk number (for RAID support)
+ * @channel: channel number
+ * @id: Logical Target ID
*
**/
static struct mptsas_phyinfo *
@@ -4217,10 +4231,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
static void
mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
{
- int rc;
-
sdev->no_uld_attach = data ? 1 : 0;
- rc = scsi_device_reprobe(sdev);
+ WARN_ON(scsi_device_reprobe(sdev));
}
static void
@@ -4256,8 +4268,8 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
if (!hdr.PageLength)
goto out;
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
- &dma_handle);
+ buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ &dma_handle, GFP_KERNEL);
if (!buffer)
goto out;
@@ -4303,8 +4315,8 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
out:
if (buffer)
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
- dma_handle);
+ dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
+ buffer, dma_handle);
}
/*
* Work queue thread to handle SAS hotplug events
@@ -4331,13 +4343,14 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
hot_plug_info->id) {
printk(MYIOC_s_WARN_FMT "firmware bug: unable "
- "to add hidden disk - target_id matchs "
+ "to add hidden disk - target_id matches "
"volume_id\n", ioc->name);
mptsas_free_fw_event(ioc, fw_event);
return;
}
}
mpt_findImVolumes(ioc);
+ fallthrough;
case MPTSAS_ADD_DEVICE:
memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
@@ -4358,11 +4371,10 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
return;
phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
- /* Only For SATA Device ADD */
- if (!phy_info && (sas_device.device_info &
- MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
+ /* Device hot plug */
+ if (!phy_info) {
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "%s %d SATA HOT PLUG: "
+ "%s %d HOT PLUG: "
"parent handle of device %x\n", ioc->name,
__func__, __LINE__, sas_device.handle_parent));
port_info = mptsas_find_portinfo_by_handle(ioc,
@@ -4764,8 +4776,9 @@ mptsas_send_raid_event(struct fw_event_work *fw_event)
* @lun: Logical unit for reset (if appropriate)
* @task_context: Context for the task to be aborted
* @timeout: timeout for task management control
+ * @issue_reset: set to 1 on return if reset is needed, else 0
*
- * return 0 on success and -1 on failure:
+ * Return: 0 on success or -1 on failure.
*
*/
static int
@@ -4837,13 +4850,13 @@ mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
}
/**
- * mptsas_broadcast_primative_work - Handle broadcast primitives
- * @work: work queue payload containing info describing the event
+ * mptsas_broadcast_primitive_work - Handle broadcast primitives
+ * @fw_event: work queue payload containing info describing the event
*
- * this will be handled in workqueue context.
+ * This will be handled in workqueue context.
*/
static void
-mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
+mptsas_broadcast_primitive_work(struct fw_event_work *fw_event)
{
MPT_ADAPTER *ioc = fw_event->ioc;
MPT_FRAME_HDR *mf;
@@ -4985,7 +4998,7 @@ static int
mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
{
u32 event = le32_to_cpu(reply->Event);
- int sz, event_data_sz;
+ int event_data_sz;
struct fw_event_work *fw_event;
unsigned long delay;
@@ -5095,8 +5108,7 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
event_data_sz = ((reply->MsgLength * 4) -
offsetof(EventNotificationReply_t, Data));
- sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
__func__, __LINE__);
@@ -5323,7 +5335,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return error;
}
-void
+static void
mptsas_shutdown(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
@@ -5365,7 +5377,7 @@ static void mptsas_remove(struct pci_dev *pdev)
mptscsih_remove(pdev);
}
-static struct pci_device_id mptsas_pci_table[] = {
+static const struct pci_device_id mptsas_pci_table[] = {
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
@@ -5406,7 +5418,6 @@ mptsas_init(void)
sas_attach_transport(&mptsas_transport_functions);
if (!mptsas_transport_template)
return -ENODEV;
- mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
"mptscsih_io_done");
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h
index 57e86ab77661..71abf3477495 100644
--- a/drivers/message/fusion/mptsas.h
+++ b/drivers/message/fusion/mptsas.h
@@ -107,10 +107,11 @@ struct mptsas_hotplug_event {
struct fw_event_work {
struct list_head list;
struct delayed_work work;
+ int users;
MPT_ADAPTER *ioc;
u32 event;
u8 retries;
- u8 __attribute__((aligned(4))) event_data[1];
+ char event_data[] __aligned(4);
};
struct mptsas_discovery_event {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 727819cc7034..3304f8824cf7 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -52,7 +52,7 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/delay.h> /* for mdelay */
-#include <linux/interrupt.h> /* needed for in_interrupt() proto */
+#include <linux/interrupt.h>
#include <linux/reboot.h> /* notifier code */
#include <linux/workqueue.h>
@@ -95,7 +95,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
- int lun, int ctx2abort, ulong timeout);
+ u64 lun, int ctx2abort, ulong timeout);
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
@@ -118,8 +118,6 @@ int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
int mptscsih_resume(struct pci_dev *pdev);
#endif
-#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -536,7 +534,7 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc
}
scsi_print_command(sc);
- printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %d\n",
+ printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
"resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
@@ -692,7 +690,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
*/
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
pScsiReply->ResponseInfo) {
- printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
+ printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
"FCP_ResponseInfo=%08xh\n", ioc->name,
sc->device->host->host_no, sc->device->channel,
sc->device->id, sc->device->lun,
@@ -786,6 +784,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/*
* Allow non-SAS & non-NEXUS_LOSS to drop into below code
*/
+ fallthrough;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
/* Linux handles an unsolicited DID_RESET better
@@ -882,6 +881,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
scsi_set_resid(sc, 0);
+ fallthrough;
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
sc->result = (DID_OK << 16) | scsi_status;
@@ -1009,7 +1009,7 @@ out:
/* Unmap the DMA buffers, if any. */
scsi_dma_unmap(sc);
- sc->scsi_done(sc); /* Issue the command callback */
+ scsi_done(sc); /* Issue the command callback */
/* Free Chain buffers */
mptscsih_freeChainBuffers(ioc, req_idx);
@@ -1054,7 +1054,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
"completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
"idx=%x\n", ioc->name, channel, id, sc, mf, ii));
- sc->scsi_done(sc);
+ scsi_done(sc);
}
}
EXPORT_SYMBOL(mptscsih_flush_running_cmds);
@@ -1071,7 +1071,7 @@ EXPORT_SYMBOL(mptscsih_flush_running_cmds);
*
* Returns: None.
*
- * Called from slave_destroy.
+ * Called from sdev_destroy.
*/
static void
mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
@@ -1118,7 +1118,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
"fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
vdevice->vtarget->channel, vdevice->vtarget->id,
sc, mf, ii));
- sc->scsi_done(sc);
+ scsi_done(sc);
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
}
}
@@ -1155,7 +1155,7 @@ mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSI
return;
ioc = hd->ioc;
if (time - hd->last_queue_full > 10 * HZ) {
- dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
+ dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
ioc->name, 0, sc->device->id, sc->device->lun));
hd->last_queue_full = time;
}
@@ -1176,10 +1176,10 @@ mptscsih_remove(struct pci_dev *pdev)
MPT_SCSI_HOST *hd;
int sz1;
- scsi_remove_host(host);
-
- if((hd = shost_priv(host)) == NULL)
- return;
+ if (host == NULL)
+ hd = NULL;
+ else
+ hd = shost_priv(host);
mptscsih_shutdown(pdev);
@@ -1195,14 +1195,15 @@ mptscsih_remove(struct pci_dev *pdev)
"Free'd ScsiLookup (%d) memory\n",
ioc->name, sz1));
- kfree(hd->info_kbuf);
+ if (hd)
+ kfree(hd->info_kbuf);
/* NULL the Scsi_Host pointer
*/
ioc->sh = NULL;
- scsi_host_put(host);
-
+ if (host)
+ scsi_host_put(host);
mpt_detach(pdev);
}
@@ -1230,7 +1231,6 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
scsi_block_requests(ioc->sh);
- flush_scheduled_work();
mptscsih_shutdown(pdev);
return mpt_suspend(pdev,state);
}
@@ -1271,15 +1271,13 @@ mptscsih_info(struct Scsi_Host *SChost)
h = shost_priv(SChost);
- if (h) {
- if (h->info_kbuf == NULL)
- if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
- return h->info_kbuf;
- h->info_kbuf[0] = '\0';
+ if (h->info_kbuf == NULL)
+ if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
+ return h->info_kbuf;
+ h->info_kbuf[0] = '\0';
- mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
- h->info_kbuf[size-1] = '\0';
- }
+ mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
+ h->info_kbuf[size-1] = '\0';
return h->info_kbuf;
}
@@ -1304,7 +1302,6 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
/**
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
* @SCpnt: Pointer to scsi_cmnd structure
- * @done: Pointer SCSI mid-layer IO completion function
*
* (linux scsi_host_template.queuecommand routine)
* This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
@@ -1313,7 +1310,7 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
* Returns 0. (rtn value discarded by linux scsi mid-layer)
*/
int
-mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptscsih_qcmd(struct scsi_cmnd *SCpnt)
{
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
@@ -1329,10 +1326,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
hd = shost_priv(SCpnt->device->host);
ioc = hd->ioc;
- SCpnt->scsi_done = done;
- dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
- ioc->name, SCpnt, done));
+ dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
+ ioc->name, SCpnt));
if (ioc->taskmgmt_quiesce_io)
return SCSI_MLQUEUE_HOST_BUSY;
@@ -1370,16 +1366,10 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if (vdevice
- && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
- && (SCpnt->device->tagged_supported)) {
+ if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
+ SCpnt->device->tagged_supported)
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
- if (SCpnt->request && SCpnt->request->ioprio) {
- if (((SCpnt->request->ioprio & 0x7) == 1) ||
- !(SCpnt->request->ioprio & 0x7))
- scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
- }
- } else
+ else
scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
@@ -1520,7 +1510,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
*
**/
int
-mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
int ctx2abort, ulong timeout)
{
MPT_FRAME_HDR *mf;
@@ -1528,7 +1518,6 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
int ii;
int retval;
MPT_ADAPTER *ioc = hd->ioc;
- unsigned long timeleft;
u8 issue_hard_reset;
u32 ioc_raw_state;
unsigned long time_count;
@@ -1626,7 +1615,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
}
}
- timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
+ wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
timeout*HZ);
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
retval = FAILED;
@@ -1703,7 +1692,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
*/
if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done(SCpnt);
+ scsi_done(SCpnt);
printk(KERN_ERR MYNAM ": task abort: "
"can't locate host! (sc=%p)\n", SCpnt);
return FAILED;
@@ -1720,7 +1709,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
"task abort: device has been deleted (sc=%p)\n",
ioc->name, SCpnt));
SCpnt->result = DID_NO_CONNECT << 16;
- SCpnt->scsi_done(SCpnt);
+ scsi_done(SCpnt);
retval = SUCCESS;
goto out;
}
@@ -1804,7 +1793,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
+ * mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
* @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
*
* (linux scsi_host_template.eh_dev_reset_handler routine)
@@ -1822,13 +1811,13 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = shost_priv(SCpnt->device->host)) == NULL){
- printk(KERN_ERR MYNAM ": target reset: "
+ printk(KERN_ERR MYNAM ": lun reset: "
"Can't locate host! (sc=%p)\n", SCpnt);
return FAILED;
}
ioc = hd->ioc;
- printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
+ printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
ioc->name, SCpnt);
scsi_print_command(SCpnt);
@@ -1838,21 +1827,14 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
goto out;
}
- /* Target reset to hidden raid component is not supported
- */
- if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
- retval = FAILED;
- goto out;
- }
-
retval = mptscsih_IssueTaskMgmt(hd,
- MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+ MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET,
vdevice->vtarget->channel,
- vdevice->vtarget->id, 0, 0,
+ vdevice->vtarget->id, vdevice->lun, 0,
mptscsih_get_tm_timeout(ioc));
out:
- printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
+ printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
if (retval == 0)
@@ -1946,7 +1928,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
/* If our attempts to reset the host failed, then return a failed
* status. The host will be taken off line by the SCSI mid-layer.
*/
- retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
+ retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
if (retval < 0)
status = FAILED;
else
@@ -2092,7 +2074,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
* This is anyones guess quite frankly.
*/
int
-mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
+mptscsih_bios_param(struct scsi_device * sdev, struct gendisk *unused,
sector_t capacity, int geom[])
{
int heads;
@@ -2290,7 +2272,7 @@ EXPORT_SYMBOL(mptscsih_raid_id_to_num);
* Called if no device present or device being unloaded
*/
void
-mptscsih_slave_destroy(struct scsi_device *sdev)
+mptscsih_sdev_destroy(struct scsi_device *sdev)
{
struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = shost_priv(host);
@@ -2316,26 +2298,21 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
* mptscsih_change_queue_depth - This function will set a devices queue depth
* @sdev: per scsi_device pointer
* @qdepth: requested queue depth
- * @reason: calling context
*
* Adding support for new 'change_queue_depth' api.
*/
int
-mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
MPT_SCSI_HOST *hd = shost_priv(sdev->host);
VirtTarget *vtarget;
struct scsi_target *starget;
int max_depth;
- int tagged;
MPT_ADAPTER *ioc = hd->ioc;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
- if (reason != SCSI_QDEPTH_DEFAULT)
- return -EOPNOTSUPP;
-
if (ioc->bus_type == SPI) {
if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
max_depth = 1;
@@ -2352,13 +2329,8 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
if (qdepth > max_depth)
qdepth = max_depth;
- if (qdepth == 1)
- tagged = 0;
- else
- tagged = MSG_SIMPLE_TAG;
- scsi_adjust_queue_depth(sdev, tagged, qdepth);
- return sdev->queue_depth;
+ return scsi_change_queue_depth(sdev, qdepth);
}
/*
@@ -2368,7 +2340,7 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
* Return non-zero if fails.
*/
int
-mptscsih_slave_configure(struct scsi_device *sdev)
+mptscsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim)
{
struct Scsi_Host *sh = sdev->host;
VirtTarget *vtarget;
@@ -2382,7 +2354,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
vdevice = sdev->hostdata;
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "device @ %p, channel=%d, id=%d, lun=%d\n",
+ "device @ %p, channel=%d, id=%d, lun=%llu\n",
ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
if (ioc->bus_type == SPI)
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
@@ -2402,14 +2374,10 @@ mptscsih_slave_configure(struct scsi_device *sdev)
ioc->name, vtarget->negoFlags, vtarget->maxOffset,
vtarget->minSyncFactor));
- mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
- SCSI_QDEPTH_DEFAULT);
+ mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "tagged %d, simple %d, ordered %d\n",
- ioc->name,sdev->tagged_supported, sdev->simple_tags,
- sdev->ordered_tags));
-
- blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
+ "tagged %d, simple %d\n",
+ ioc->name,sdev->tagged_supported, sdev->simple_tags));
return 0;
}
@@ -2444,7 +2412,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
/* Copy the sense received into the scsi command block. */
req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
- memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
+ memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
/* Log SMART data (asc = 0x5D, non-IM case only) if required.
*/
@@ -2888,14 +2856,14 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
timeout = 10;
break;
- case RESERVE:
+ case RESERVE_6:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
timeout = 10;
break;
- case RELEASE:
+ case RELEASE_6:
cmdLen = 6;
dir = MPI_SCSIIO_CONTROL_READ;
CDB[0] = cmd;
@@ -2973,7 +2941,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
+ (my_idx * MPT_SENSE_BUFFER_ALLOC));
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
+ "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
ioc->name, __func__, cmd, io->channel, io->id, io->lun));
if (dir == MPI_SCSIIO_CONTROL_READ)
@@ -3240,23 +3208,31 @@ mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
mptscsih_debug_level_show, mptscsih_debug_level_store);
-struct device_attribute *mptscsih_host_attrs[] = {
- &dev_attr_version_fw,
- &dev_attr_version_bios,
- &dev_attr_version_mpi,
- &dev_attr_version_product,
- &dev_attr_version_nvdata_persistent,
- &dev_attr_version_nvdata_default,
- &dev_attr_board_name,
- &dev_attr_board_assembly,
- &dev_attr_board_tracer,
- &dev_attr_io_delay,
- &dev_attr_device_delay,
- &dev_attr_debug_level,
+static struct attribute *mptscsih_host_attrs[] = {
+ &dev_attr_version_fw.attr,
+ &dev_attr_version_bios.attr,
+ &dev_attr_version_mpi.attr,
+ &dev_attr_version_product.attr,
+ &dev_attr_version_nvdata_persistent.attr,
+ &dev_attr_version_nvdata_default.attr,
+ &dev_attr_board_name.attr,
+ &dev_attr_board_assembly.attr,
+ &dev_attr_board_tracer.attr,
+ &dev_attr_io_delay.attr,
+ &dev_attr_device_delay.attr,
+ &dev_attr_debug_level.attr,
NULL,
};
-EXPORT_SYMBOL(mptscsih_host_attrs);
+static const struct attribute_group mptscsih_host_attr_group = {
+ .attrs = mptscsih_host_attrs
+};
+
+const struct attribute_group *mptscsih_host_attr_groups[] = {
+ &mptscsih_host_attr_group,
+ NULL
+};
+EXPORT_SYMBOL(mptscsih_host_attr_groups);
EXPORT_SYMBOL(mptscsih_remove);
EXPORT_SYMBOL(mptscsih_shutdown);
@@ -3267,8 +3243,8 @@ EXPORT_SYMBOL(mptscsih_resume);
EXPORT_SYMBOL(mptscsih_show_info);
EXPORT_SYMBOL(mptscsih_info);
EXPORT_SYMBOL(mptscsih_qcmd);
-EXPORT_SYMBOL(mptscsih_slave_destroy);
-EXPORT_SYMBOL(mptscsih_slave_configure);
+EXPORT_SYMBOL(mptscsih_sdev_destroy);
+EXPORT_SYMBOL(mptscsih_sdev_configure);
EXPORT_SYMBOL(mptscsih_abort);
EXPORT_SYMBOL(mptscsih_dev_reset);
EXPORT_SYMBOL(mptscsih_bus_reset);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 83f503162f7a..f9678d48100c 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -98,7 +98,7 @@ typedef struct _internal_cmd {
u8 cmd; /* SCSI Op Code */
u8 channel; /* bus number */
u8 id; /* SCSI ID (virtual) */
- int lun;
+ u64 lun;
u8 flags; /* Bit Field - See above */
u8 physDiskNum; /* Phys disk number, -1 else */
u8 rsvd2;
@@ -113,26 +113,26 @@ extern int mptscsih_resume(struct pci_dev *pdev);
#endif
extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
extern const char * mptscsih_info(struct Scsi_Host *SChost);
-extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
+extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt);
extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
- u8 id, int lun, int ctx2abort, ulong timeout);
-extern void mptscsih_slave_destroy(struct scsi_device *device);
-extern int mptscsih_slave_configure(struct scsi_device *device);
+ u8 id, u64 lun, int ctx2abort, ulong timeout);
+extern void mptscsih_sdev_destroy(struct scsi_device *device);
+extern int mptscsih_sdev_configure(struct scsi_device *device,
+ struct queue_limits *lim);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
-extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
+extern int mptscsih_bios_param(struct scsi_device * sdev, struct gendisk *unused, sector_t capacity, int geom[]);
extern int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth,
- int reason);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
-extern struct device_attribute *mptscsih_host_attrs[];
+extern const struct attribute_group *mptscsih_host_attr_groups[];
extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
extern void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 5653e505f91f..a3901fbfac4f 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -52,7 +52,7 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/delay.h> /* for mdelay */
-#include <linux/interrupt.h> /* needed for in_interrupt() proto */
+#include <linux/interrupt.h>
#include <linux/reboot.h> /* notifier code */
#include <linux/workqueue.h>
#include <linux/raid_class.h>
@@ -101,7 +101,7 @@ static u8 mptspiInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for interna
* @target: per target private data
* @sdev: SCSI device
*
- * Update the target negotiation parameters based on the the Inquiry
+ * Update the target negotiation parameters based on the Inquiry
* data, adapter capabilities, and NVRAM settings.
**/
static void
@@ -258,8 +258,6 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
IOCPage4_t *IOCPage4Ptr;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
- u16 req_idx;
- u32 frameOffset;
u32 flagsLength;
int ii;
@@ -276,9 +274,6 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
*/
pReq = (Config_t *)mf;
- req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
- frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
-
/* Complete the request frame (same for all requests).
*/
pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
@@ -461,8 +456,7 @@ static int mptspi_target_alloc(struct scsi_target *starget)
static void
mptspi_target_destroy(struct scsi_target *starget)
{
- if (starget->hostdata)
- kfree(starget->hostdata);
+ kfree(starget->hostdata);
starget->hostdata = NULL;
}
@@ -620,7 +614,7 @@ static void mptspi_read_parameters(struct scsi_target *starget)
spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
}
-int
+static int
mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
{
MPT_ADAPTER *ioc = hd->ioc;
@@ -719,7 +713,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
mptspi_read_parameters(sdev->sdev_target);
}
-static int mptspi_slave_alloc(struct scsi_device *sdev)
+static int mptspi_sdev_init(struct scsi_device *sdev)
{
MPT_SCSI_HOST *hd = shost_priv(sdev->host);
VirtTarget *vtarget;
@@ -733,7 +727,7 @@ static int mptspi_slave_alloc(struct scsi_device *sdev)
vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdevice) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ printk(MYIOC_s_ERR_FMT "sdev_init kmalloc(%zd) FAILED!\n",
ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
@@ -752,7 +746,8 @@ static int mptspi_slave_alloc(struct scsi_device *sdev)
return 0;
}
-static int mptspi_slave_configure(struct scsi_device *sdev)
+static int mptspi_sdev_configure(struct scsi_device *sdev,
+ struct queue_limits *lim)
{
struct _MPT_SCSI_HOST *hd = shost_priv(sdev->host);
VirtTarget *vtarget = scsi_target(sdev)->hostdata;
@@ -760,7 +755,7 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
mptspi_initTarget(hd, vtarget, sdev);
- ret = mptscsih_slave_configure(sdev);
+ ret = mptscsih_sdev_configure(sdev, lim);
if (ret)
return ret;
@@ -780,34 +775,32 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
}
static int
-mptspi_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptspi_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
{
- struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
+ struct _MPT_SCSI_HOST *hd = shost_priv(shost);
VirtDevice *vdevice = SCpnt->device->hostdata;
MPT_ADAPTER *ioc = hd->ioc;
if (!vdevice || !vdevice->vtarget) {
SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
if (SCpnt->device->channel == 1 &&
mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) {
SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
+ scsi_done(SCpnt);
return 0;
}
if (spi_dv_pending(scsi_target(SCpnt->device)))
ddvprintk(ioc, scsi_print_command(SCpnt));
- return mptscsih_qcmd(SCpnt,done);
+ return mptscsih_qcmd(SCpnt);
}
-static DEF_SCSI_QCMD(mptspi_qcmd)
-
-static void mptspi_slave_destroy(struct scsi_device *sdev)
+static void mptspi_sdev_destroy(struct scsi_device *sdev)
{
struct scsi_target *starget = scsi_target(sdev);
VirtTarget *vtarget = starget->hostdata;
@@ -825,10 +818,10 @@ static void mptspi_slave_destroy(struct scsi_device *sdev)
mptspi_write_spi_device_pg1(starget, &pg1);
}
- mptscsih_slave_destroy(sdev);
+ mptscsih_sdev_destroy(sdev);
}
-static struct scsi_host_template mptspi_driver_template = {
+static const struct scsi_host_template mptspi_driver_template = {
.module = THIS_MODULE,
.proc_name = "mptspi",
.show_info = mptscsih_show_info,
@@ -836,10 +829,10 @@ static struct scsi_host_template mptspi_driver_template = {
.info = mptscsih_info,
.queuecommand = mptspi_qcmd,
.target_alloc = mptspi_target_alloc,
- .slave_alloc = mptspi_slave_alloc,
- .slave_configure = mptspi_slave_configure,
+ .sdev_init = mptspi_sdev_init,
+ .sdev_configure = mptspi_sdev_configure,
.target_destroy = mptspi_target_destroy,
- .slave_destroy = mptspi_slave_destroy,
+ .sdev_destroy = mptspi_sdev_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
.eh_device_reset_handler = mptscsih_dev_reset,
@@ -851,8 +844,8 @@ static struct scsi_host_template mptspi_driver_template = {
.sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192,
.cmd_per_lun = 7,
- .use_clustering = ENABLE_CLUSTERING,
- .shost_attrs = mptscsih_host_attrs,
+ .dma_alignment = 511,
+ .shost_groups = mptscsih_host_attr_groups,
};
static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
@@ -1153,7 +1146,7 @@ static void mpt_work_wrapper(struct work_struct *work)
}
shost_printk(KERN_INFO, shost, MYIOC_s_FMT
"Integrated RAID detects new device %d\n", ioc->name, disk);
- scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1);
+ scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, SCSI_SCAN_RESCAN);
}
@@ -1246,7 +1239,7 @@ static struct spi_function_template mptspi_transport_functions = {
* Supported hardware
*/
-static struct pci_device_id mptspi_pci_table[] = {
+static const struct pci_device_id mptspi_pci_table[] = {
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_ATTO, MPI_MANUFACTPAGE_DEVID_53C1030,
@@ -1422,6 +1415,11 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_mptspi_probe;
}
+ /* VMWare emulation doesn't properly implement WRITE_SAME
+ */
+ if (pdev->subsystem_vendor == 0x15AD)
+ sh->no_write_same = 1;
+
spin_lock_irqsave(&ioc->FreeQlock, flags);
/* Attach the SCSI Host to the IOC structure
@@ -1497,7 +1495,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!)
*/
- ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
+ ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
if (!ioc->ScsiLookup) {
error = -ENOMEM;
goto out_mptspi_probe;
@@ -1546,11 +1544,19 @@ out_mptspi_probe:
return error;
}
+static void mptspi_remove(struct pci_dev *pdev)
+{
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+
+ scsi_remove_host(ioc->sh);
+ mptscsih_remove(pdev);
+}
+
static struct pci_driver mptspi_driver = {
.name = "mptspi",
.id_table = mptspi_pci_table,
.probe = mptspi_probe,
- .remove = mptscsih_remove,
+ .remove = mptspi_remove,
.shutdown = mptscsih_shutdown,
#ifdef CONFIG_PM
.suspend = mptscsih_suspend,
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
deleted file mode 100644
index 5afa0e393ecf..000000000000
--- a/drivers/message/i2o/Kconfig
+++ /dev/null
@@ -1,121 +0,0 @@
-
-menuconfig I2O
- tristate "I2O device support"
- depends on PCI
- ---help---
- The Intelligent Input/Output (I2O) architecture allows hardware
- drivers to be split into two parts: an operating system specific
- module called the OSM and an hardware specific module called the
- HDM. The OSM can talk to a whole range of HDM's, and ideally the
- HDM's are not OS dependent. This allows for the same HDM driver to
- be used under different operating systems if the relevant OSM is in
- place. In order for this to work, you need to have an I2O interface
- adapter card in your computer. This card contains a special I/O
- processor (IOP), thus allowing high speeds since the CPU does not
- have to deal with I/O.
-
- If you say Y here, you will get a choice of interface adapter
- drivers and OSM's with the following questions.
-
- To compile this support as a module, choose M here: the
- modules will be called i2o_core.
-
- If unsure, say N.
-
-if I2O
-
-config I2O_LCT_NOTIFY_ON_CHANGES
- bool "Enable LCT notification"
- default y
- ---help---
- Only say N here if you have a I2O controller from SUN. The SUN
- firmware doesn't support LCT notification on changes. If this option
- is enabled on such a controller the driver will hang up in a endless
- loop. On all other controllers say Y.
-
- If unsure, say Y.
-
-config I2O_EXT_ADAPTEC
- bool "Enable Adaptec extensions"
- default y
- ---help---
- Say Y for support of raidutils for Adaptec I2O controllers. You also
- have to say Y to "I2O Configuration support", "I2O SCSI OSM" below
- and to "SCSI generic support" under "SCSI device configuration".
-
-config I2O_EXT_ADAPTEC_DMA64
- bool "Enable 64-bit DMA"
- depends on I2O_EXT_ADAPTEC && ( 64BIT || HIGHMEM64G )
- default y
- ---help---
- Say Y for support of 64-bit DMA transfer mode on Adaptec I2O
- controllers.
- Note: You need at least firmware version 3709.
-
-config I2O_CONFIG
- tristate "I2O Configuration support"
- depends on VIRT_TO_BUS
- ---help---
- Say Y for support of the configuration interface for the I2O adapters.
- If you have a RAID controller from Adaptec and you want to use the
- raidutils to manage your RAID array, you have to say Y here.
-
- To compile this support as a module, choose M here: the
- module will be called i2o_config.
-
- Note: If you want to use the new API you have to download the
- i2o_config patch from http://i2o.shadowconnect.com/
-
-config I2O_CONFIG_OLD_IOCTL
- bool "Enable ioctls (OBSOLETE)"
- depends on I2O_CONFIG
- default y
- ---help---
- Enables old ioctls.
-
-config I2O_BUS
- tristate "I2O Bus Adapter OSM"
- ---help---
- Include support for the I2O Bus Adapter OSM. The Bus Adapter OSM
- provides access to the busses on the I2O controller. The main purpose
- is to rescan the bus to find new devices.
-
- To compile this support as a module, choose M here: the
- module will be called i2o_bus.
-
-config I2O_BLOCK
- tristate "I2O Block OSM"
- depends on BLOCK
- ---help---
- Include support for the I2O Block OSM. The Block OSM presents disk
- and other structured block devices to the operating system. If you
- are using an RAID controller, you could access the array only by
- the Block OSM driver. But it is possible to access the single disks
- by the SCSI OSM driver, for example to monitor the disks.
-
- To compile this support as a module, choose M here: the
- module will be called i2o_block.
-
-config I2O_SCSI
- tristate "I2O SCSI OSM"
- depends on SCSI
- ---help---
- Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel
- I2O controller. You can use both the SCSI and Block OSM together if
- you wish. To access a RAID array, you must use the Block OSM driver.
- But you could use the SCSI OSM driver to monitor the single disks.
-
- To compile this support as a module, choose M here: the
- module will be called i2o_scsi.
-
-config I2O_PROC
- tristate "I2O /proc support"
- ---help---
- If you say Y here and to "/proc file system support", you will be
- able to read I2O related information from the virtual directory
- /proc/i2o.
-
- To compile this support as a module, choose M here: the
- module will be called i2o_proc.
-
-endif # I2O
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
deleted file mode 100644
index b0982dacfd0a..000000000000
--- a/drivers/message/i2o/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for the kernel I2O OSM.
-#
-# Note : at this point, these files are compiled on all systems.
-# In the future, some of these should be built conditionally.
-#
-
-i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o
-i2o_bus-y += bus-osm.o
-i2o_config-y += config-osm.o
-obj-$(CONFIG_I2O) += i2o_core.o
-obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o
-obj-$(CONFIG_I2O_BUS) += i2o_bus.o
-obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
-obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o
-obj-$(CONFIG_I2O_PROC) += i2o_proc.o
diff --git a/drivers/message/i2o/README b/drivers/message/i2o/README
deleted file mode 100644
index f072a8eb3041..000000000000
--- a/drivers/message/i2o/README
+++ /dev/null
@@ -1,98 +0,0 @@
-
- Linux I2O Support (c) Copyright 1999 Red Hat Software
- and others.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version
- 2 of the License, or (at your option) any later version.
-
-AUTHORS (so far)
-
-Alan Cox, Building Number Three Ltd.
- Core code, SCSI and Block OSMs
-
-Steve Ralston, LSI Logic Corp.
- Debugging SCSI and Block OSM
-
-Deepak Saxena, Intel Corp.
- Various core/block extensions
- /proc interface, bug fixes
- Ioctl interfaces for control
- Debugging LAN OSM
-
-Philip Rumpf
- Fixed assorted dumb SMP locking bugs
-
-Juha Sievanen, University of Helsinki Finland
- LAN OSM code
- /proc interface to LAN class
- Bug fixes
- Core code extensions
-
-Auvo Häkkinen, University of Helsinki Finland
- LAN OSM code
- /Proc interface to LAN class
- Bug fixes
- Core code extensions
-
-Taneli Vähäkangas, University of Helsinki Finland
- Fixes to i2o_config
-
-CREDITS
-
- This work was made possible by
-
-Red Hat Software
- Funding for the Building #3 part of the project
-
-Symbios Logic (Now LSI)
- Host adapters, hints, known to work platforms when I hit
- compatibility problems
-
-BoxHill Corporation
- Loan of initial FibreChannel disk array used for development work.
-
-European Commission
- Funding the work done by the University of Helsinki
-
-SysKonnect
- Loan of FDDI and Gigabit Ethernet cards
-
-ASUSTeK
- Loan of I2O motherboard
-
-STATUS:
-
-o The core setup works within limits.
-o The scsi layer seems to almost work.
- I'm still chasing down the hang bug.
-o The block OSM is mostly functional
-o LAN OSM works with FDDI and Ethernet cards.
-
-TO DO:
-
-General:
-o Provide hidden address space if asked
-o Long term message flow control
-o PCI IOP's without interrupts are not supported yet
-o Push FAIL handling into the core
-o DDM control interfaces for module load etc
-o Add I2O 2.0 support (Deffered to 2.5 kernel)
-
-Block:
-o Multiple major numbers
-o Read ahead and cache handling stuff. Talk to Ingo and people
-o Power management
-o Finish Media changers
-
-SCSI:
-o Find the right way to associate drives/luns/busses
-
-Lan:
-o Performance tuning
-o Test Fibre Channel code
-
-Tape:
-o Anyone seen anything implementing this ?
- (D.S: Will attempt to do so if spare cycles permit)
diff --git a/drivers/message/i2o/README.ioctl b/drivers/message/i2o/README.ioctl
deleted file mode 100644
index 4a7d2ebdfc97..000000000000
--- a/drivers/message/i2o/README.ioctl
+++ /dev/null
@@ -1,394 +0,0 @@
-
-Linux I2O User Space Interface
-rev 0.3 - 04/20/99
-
-=============================================================================
-Originally written by Deepak Saxena(deepak@plexity.net)
-Currently maintained by Deepak Saxena(deepak@plexity.net)
-=============================================================================
-
-I. Introduction
-
-The Linux I2O subsystem provides a set of ioctl() commands that can be
-utilized by user space applications to communicate with IOPs and devices
-on individual IOPs. This document defines the specific ioctl() commands
-that are available to the user and provides examples of their uses.
-
-This document assumes the reader is familiar with or has access to the
-I2O specification as no I2O message parameters are outlined. For information
-on the specification, see http://www.i2osig.org
-
-This document and the I2O user space interface are currently maintained
-by Deepak Saxena. Please send all comments, errata, and bug fixes to
-deepak@csociety.purdue.edu
-
-II. IOP Access
-
-Access to the I2O subsystem is provided through the device file named
-/dev/i2o/ctl. This file is a character file with major number 10 and minor
-number 166. It can be created through the following command:
-
- mknod /dev/i2o/ctl c 10 166
-
-III. Determining the IOP Count
-
- SYNOPSIS
-
- ioctl(fd, I2OGETIOPS, int *count);
-
- u8 count[MAX_I2O_CONTROLLERS];
-
- DESCRIPTION
-
- This function returns the system's active IOP table. count should
- point to a buffer containing MAX_I2O_CONTROLLERS entries. Upon
- returning, each entry will contain a non-zero value if the given
- IOP unit is active, and NULL if it is inactive or non-existent.
-
- RETURN VALUE.
-
- Returns 0 if no errors occur, and -1 otherwise. If an error occurs,
- errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
-
-IV. Getting Hardware Resource Table
-
- SYNOPSIS
-
- ioctl(fd, I2OHRTGET, struct i2o_cmd_hrt *hrt);
-
- struct i2o_cmd_hrtlct
- {
- u32 iop; /* IOP unit number */
- void *resbuf; /* Buffer for result */
- u32 *reslen; /* Buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function returns the Hardware Resource Table of the IOP specified
- by hrt->iop in the buffer pointed to by hrt->resbuf. The actual size of
- the data is written into *(hrt->reslen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(hrt->reslen)
-
-V. Getting Logical Configuration Table
-
- SYNOPSIS
-
- ioctl(fd, I2OLCTGET, struct i2o_cmd_lct *lct);
-
- struct i2o_cmd_hrtlct
- {
- u32 iop; /* IOP unit number */
- void *resbuf; /* Buffer for result */
- u32 *reslen; /* Buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function returns the Logical Configuration Table of the IOP specified
- by lct->iop in the buffer pointed to by lct->resbuf. The actual size of
- the data is written into *(lct->reslen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(lct->reslen)
-
-VI. Setting Parameters
-
- SYNOPSIS
-
- ioctl(fd, I2OPARMSET, struct i2o_parm_setget *ops);
-
- struct i2o_cmd_psetget
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device TID */
- void *opbuf; /* Operation List buffer */
- u32 oplen; /* Operation List buffer length in bytes */
- void *resbuf; /* Result List buffer */
- u32 *reslen; /* Result List buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function posts a UtilParamsSet message to the device identified
- by ops->iop and ops->tid. The operation list for the message is
- sent through the ops->opbuf buffer, and the result list is written
- into the buffer pointed to by ops->resbuf. The number of bytes
- written is placed into *(ops->reslen).
-
- RETURNS
-
- The return value is the size in bytes of the data written into
- ops->resbuf if no errors occur. If an error occurs, -1 is returned
- and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
- A return value of 0 does not mean that the value was actually
- changed properly on the IOP. The user should check the result
- list to determine the specific status of the transaction.
-
-VII. Getting Parameters
-
- SYNOPSIS
-
- ioctl(fd, I2OPARMGET, struct i2o_parm_setget *ops);
-
- struct i2o_parm_setget
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device TID */
- void *opbuf; /* Operation List buffer */
- u32 oplen; /* Operation List buffer length in bytes */
- void *resbuf; /* Result List buffer */
- u32 *reslen; /* Result List buffer length in bytes */
- };
-
- DESCRIPTION
-
- This function posts a UtilParamsGet message to the device identified
- by ops->iop and ops->tid. The operation list for the message is
- sent through the ops->opbuf buffer, and the result list is written
- into the buffer pointed to by ops->resbuf. The actual size of data
- written is placed into *(ops->reslen).
-
- RETURNS
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
- A return value of 0 does not mean that the value was actually
- properly retrieved. The user should check the result list
- to determine the specific status of the transaction.
-
-VIII. Downloading Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWDL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* DownloadFlags field */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Pointer to software buffer */
- u32 *swlen; /* Length of software buffer */
- u32 *maxfrag; /* Number of fragments */
- u32 *curfrag; /* Current fragment number */
- };
-
- DESCRIPTION
-
- This function downloads a software fragment pointed by sw->buf
- to the iop identified by sw->iop. The DownloadFlags, SwID, SwType
- and SwSize fields of the ExecSwDownload message are filled in with
- the values of sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen).
-
- The fragments _must_ be sent in order and be 8K in size. The last
- fragment _may_ be shorter, however. The kernel will compute its
- size based on information in the sw->swlen field.
-
- Please note that SW transfers can take a long time.
-
- RETURNS
-
- This function returns 0 no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-IX. Uploading Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* UploadFlags */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Pointer to software buffer */
- u32 *swlen; /* Length of software buffer */
- u32 *maxfrag; /* Number of fragments */
- u32 *curfrag; /* Current fragment number */
- };
-
- DESCRIPTION
-
- This function uploads a software fragment from the IOP identified
- by sw->iop, sw->sw_type, sw->sw_id and optionally sw->swlen fields.
- The UploadFlags, SwID, SwType and SwSize fields of the ExecSwUpload
- message are filled in with the values of sw->flags, sw->sw_id,
- sw->sw_type and *(sw->swlen).
-
- The fragments _must_ be requested in order and be 8K in size. The
- user is responsible for allocating memory pointed by sw->buf. The
- last fragment _may_ be shorter.
-
- Please note that SW transfers can take a long time.
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-X. Removing Software
-
- SYNOPSIS
-
- ioctl(fd, I2OSWDEL, struct i2o_sw_xfer *sw);
-
- struct i2o_sw_xfer
- {
- u32 iop; /* IOP unit number */
- u8 flags; /* RemoveFlags */
- u8 sw_type; /* Software type */
- u32 sw_id; /* Software ID */
- void *buf; /* Unused */
- u32 *swlen; /* Length of the software data */
- u32 *maxfrag; /* Unused */
- u32 *curfrag; /* Unused */
- };
-
- DESCRIPTION
-
- This function removes software from the IOP identified by sw->iop.
- The RemoveFlags, SwID, SwType and SwSize fields of the ExecSwRemove message
- are filled in with the values of sw->flags, sw->sw_id, sw->sw_type and
- *(sw->swlen). Give zero in *(sw->len) if the value is unknown. IOP uses
- *(sw->swlen) value to verify correct identication of the module to remove.
- The actual size of the module is written into *(sw->swlen).
-
- RETURNS
-
- This function returns 0 if no errors occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-X. Validating Configuration
-
- SYNOPSIS
-
- ioctl(fd, I2OVALIDATE, int *iop);
- u32 iop;
-
- DESCRIPTION
-
- This function posts an ExecConfigValidate message to the controller
- identified by iop. This message indicates that the current
- configuration is accepted. The iop changes the status of suspect drivers
- to valid and may delete old drivers from its store.
-
- RETURNS
-
- This function returns 0 if no erro occur. If an error occurs, -1 is
- returned and errno is set appropriately:
-
- ETIMEDOUT Timeout waiting for reply message
- ENXIO Invalid IOP number
-
-XI. Configuration Dialog
-
- SYNOPSIS
-
- ioctl(fd, I2OHTML, struct i2o_html *htquery);
- struct i2o_html
- {
- u32 iop; /* IOP unit number */
- u32 tid; /* Target device ID */
- u32 page; /* HTML page */
- void *resbuf; /* Buffer for reply HTML page */
- u32 *reslen; /* Length in bytes of reply buffer */
- void *qbuf; /* Pointer to HTTP query string */
- u32 qlen; /* Length in bytes of query string buffer */
- };
-
- DESCRIPTION
-
- This function posts an UtilConfigDialog message to the device identified
- by htquery->iop and htquery->tid. The requested HTML page number is
- provided by the htquery->page field, and the resultant data is stored
- in the buffer pointed to by htquery->resbuf. If there is an HTTP query
- string that is to be sent to the device, it should be sent in the buffer
- pointed to by htquery->qbuf. If there is no query string, this field
- should be set to NULL. The actual size of the reply received is written
- into *(htquery->reslen).
-
- RETURNS
-
- This function returns 0 if no error occur. If an error occurs, -1
- is returned and errno is set appropriately:
-
- EFAULT Invalid user space pointer was passed
- ENXIO Invalid IOP number
- ENOBUFS Buffer not large enough. If this occurs, the required
- buffer length is written into *(ops->reslen)
- ETIMEDOUT Timeout waiting for reply message
- ENOMEM Kernel memory allocation error
-
-XII. Events
-
- In the process of determining this. Current idea is to have use
- the select() interface to allow user apps to periodically poll
- the /dev/i2o/ctl device for events. When select() notifies the user
- that an event is available, the user would call read() to retrieve
- a list of all the events that are pending for the specific device.
-
-=============================================================================
-Revision History
-=============================================================================
-
-Rev 0.1 - 04/01/99
-- Initial revision
-
-Rev 0.2 - 04/06/99
-- Changed return values to match UNIX ioctl() standard. Only return values
- are 0 and -1. All errors are reported through errno.
-- Added summary of proposed possible event interfaces
-
-Rev 0.3 - 04/20/99
-- Changed all ioctls() to use pointers to user data instead of actual data
-- Updated error values to match the code
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
deleted file mode 100644
index c463dc2efc09..000000000000
--- a/drivers/message/i2o/bus-osm.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Bus Adapter OSM
- *
- * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Fixes/additions:
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * initial version.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-
-#define OSM_NAME "bus-osm"
-#define OSM_VERSION "1.317"
-#define OSM_DESCRIPTION "I2O Bus Adapter OSM"
-
-static struct i2o_driver i2o_bus_driver;
-
-/* Bus OSM class handling definition */
-static struct i2o_class_id i2o_bus_class_id[] = {
- {I2O_CLASS_BUS_ADAPTER},
- {I2O_CLASS_END}
-};
-
-/**
- * i2o_bus_scan - Scan the bus for new devices
- * @dev: I2O device of the bus, which should be scanned
- *
- * Scans the bus dev for new / removed devices. After the scan a new LCT
- * will be fetched automatically.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_bus_scan(struct i2o_device *dev)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return -ETIMEDOUT;
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.
- tid);
-
- return i2o_msg_post_wait(dev->iop, msg, 60);
-};
-
-/**
- * i2o_bus_store_scan - Scan the I2O Bus Adapter
- * @d: device which should be scanned
- * @attr: device_attribute
- * @buf: output buffer
- * @count: buffer size
- *
- * Returns count.
- */
-static ssize_t i2o_bus_store_scan(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2o_device *i2o_dev = to_i2o_device(d);
- int rc;
-
- if ((rc = i2o_bus_scan(i2o_dev)))
- osm_warn("bus scan failed %d\n", rc);
-
- return count;
-}
-
-/* Bus Adapter OSM device attributes */
-static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);
-
-/**
- * i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it
- * @dev: device to verify if it is a I2O Bus Adapter device
- *
- * Because we want all Bus Adapters always return 0.
- * Except when we fail. Then we are sad.
- *
- * Returns 0, except when we fail to excel.
- */
-static int i2o_bus_probe(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
- int rc;
-
- rc = device_create_file(dev, &dev_attr_scan);
- if (rc)
- goto err_out;
-
- osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);
-
- return 0;
-
-err_out:
- put_device(dev);
- return rc;
-};
-
-/**
- * i2o_bus_remove - remove the I2O Bus Adapter device from the system again
- * @dev: I2O Bus Adapter device which should be removed
- *
- * Always returns 0.
- */
-static int i2o_bus_remove(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
-
- device_remove_file(dev, &dev_attr_scan);
-
- put_device(dev);
-
- osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
-
- return 0;
-};
-
-/* Bus Adapter OSM driver struct */
-static struct i2o_driver i2o_bus_driver = {
- .name = OSM_NAME,
- .classes = i2o_bus_class_id,
- .driver = {
- .probe = i2o_bus_probe,
- .remove = i2o_bus_remove,
- },
-};
-
-/**
- * i2o_bus_init - Bus Adapter OSM initialization function
- *
- * Only register the Bus Adapter OSM in the I2O core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_bus_init(void)
-{
- int rc;
-
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- /* Register Bus Adapter OSM into I2O core */
- rc = i2o_driver_register(&i2o_bus_driver);
- if (rc) {
- osm_err("Could not register Bus Adapter OSM\n");
- return rc;
- }
-
- return 0;
-};
-
-/**
- * i2o_bus_exit - Bus Adapter OSM exit function
- *
- * Unregisters Bus Adapter OSM from I2O core.
- */
-static void __exit i2o_bus_exit(void)
-{
- i2o_driver_unregister(&i2o_bus_driver);
-};
-
-MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_bus_init);
-module_exit(i2o_bus_exit);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
deleted file mode 100644
index 3bba7aa82e58..000000000000
--- a/drivers/message/i2o/config-osm.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Configuration OSM
- *
- * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Fixes/additions:
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * initial version.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-#include <linux/dcache.h>
-#include <linux/namei.h>
-#include <linux/fs.h>
-
-#include <asm/uaccess.h>
-
-#define OSM_NAME "config-osm"
-#define OSM_VERSION "1.323"
-#define OSM_DESCRIPTION "I2O Configuration OSM"
-
-/* access mode user rw */
-#define S_IWRSR (S_IRUSR | S_IWUSR)
-
-static struct i2o_driver i2o_config_driver;
-
-/* Config OSM driver struct */
-static struct i2o_driver i2o_config_driver = {
- .name = OSM_NAME,
-};
-
-#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
-#include "i2o_config.c"
-#endif
-
-/**
- * i2o_config_init - Configuration OSM initialization function
- *
- * Registers Configuration OSM in the I2O core and if old ioctl's are
- * compiled in initialize them.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_config_init(void)
-{
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- if (i2o_driver_register(&i2o_config_driver)) {
- osm_err("handler register failed.\n");
- return -EBUSY;
- }
-#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
- if (i2o_config_old_init()) {
- osm_err("old config handler initialization failed\n");
- i2o_driver_unregister(&i2o_config_driver);
- return -EBUSY;
- }
-#endif
-
- return 0;
-}
-
-/**
- * i2o_config_exit - Configuration OSM exit function
- *
- * If old ioctl's are compiled in exit remove them and unregisters
- * Configuration OSM from I2O core.
- */
-static void i2o_config_exit(void)
-{
-#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
- i2o_config_old_exit();
-#endif
-
- i2o_driver_unregister(&i2o_config_driver);
-}
-
-MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_config_init);
-module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
deleted file mode 100644
index cbe384fb848c..000000000000
--- a/drivers/message/i2o/core.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * I2O core internal declarations
- *
- * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Fixes/additions:
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * initial version.
- */
-
-/* Exec-OSM */
-extern struct i2o_driver i2o_exec_driver;
-extern int i2o_exec_lct_get(struct i2o_controller *);
-
-extern int __init i2o_exec_init(void);
-extern void i2o_exec_exit(void);
-
-/* driver */
-extern struct bus_type i2o_bus_type;
-
-extern int i2o_driver_dispatch(struct i2o_controller *, u32);
-
-extern int __init i2o_driver_init(void);
-extern void i2o_driver_exit(void);
-
-/* PCI */
-extern int __init i2o_pci_init(void);
-extern void __exit i2o_pci_exit(void);
-
-/* device */
-extern struct device_attribute i2o_device_attrs[];
-
-extern void i2o_device_remove(struct i2o_device *);
-extern int i2o_device_parse_lct(struct i2o_controller *);
-
-int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
- int oplen, void *reslist, int reslen);
-
-/* IOP */
-extern struct i2o_controller *i2o_iop_alloc(void);
-
-/**
- * i2o_iop_free - Free the i2o_controller struct
- * @c: I2O controller to free
- */
-static inline void i2o_iop_free(struct i2o_controller *c)
-{
- i2o_pool_free(&c->in_msg);
- kfree(c);
-}
-
-extern int i2o_iop_add(struct i2o_controller *);
-extern void i2o_iop_remove(struct i2o_controller *);
-
-/* control registers relative to c->base */
-#define I2O_IRQ_STATUS 0x30
-#define I2O_IRQ_MASK 0x34
-#define I2O_IN_PORT 0x40
-#define I2O_OUT_PORT 0x44
-
-/* Motorola/Freescale specific register offset */
-#define I2O_MOTOROLA_PORT_OFFSET 0x10400
-
-#define I2O_IRQ_OUTBOUND_POST 0x00000008
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
deleted file mode 100644
index ce62d8bfe1c8..000000000000
--- a/drivers/message/i2o/debug.c
+++ /dev/null
@@ -1,472 +0,0 @@
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-
-static void i2o_report_util_cmd(u8 cmd);
-static void i2o_report_exec_cmd(u8 cmd);
-static void i2o_report_fail_status(u8 req_status, u32 * msg);
-static void i2o_report_common_status(u8 req_status);
-static void i2o_report_common_dsc(u16 detailed_status);
-
-/*
- * Used for error reporting/debugging purposes.
- * Report Cmd name, Request status, Detailed Status.
- */
-void i2o_report_status(const char *severity, const char *str,
- struct i2o_message *m)
-{
- u32 *msg = (u32 *) m;
- u8 cmd = (msg[1] >> 24) & 0xFF;
- u8 req_status = (msg[4] >> 24) & 0xFF;
- u16 detailed_status = msg[4] & 0xFFFF;
-
- if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
- return; // No status in this reply
-
- printk("%s%s: ", severity, str);
-
- if (cmd < 0x1F) // Utility cmd
- i2o_report_util_cmd(cmd);
-
- else if (cmd >= 0xA0 && cmd <= 0xEF) // Executive cmd
- i2o_report_exec_cmd(cmd);
- else
- printk("Cmd = %0#2x, ", cmd); // Other cmds
-
- if (msg[0] & MSG_FAIL) {
- i2o_report_fail_status(req_status, msg);
- return;
- }
-
- i2o_report_common_status(req_status);
-
- if (cmd < 0x1F || (cmd >= 0xA0 && cmd <= 0xEF))
- i2o_report_common_dsc(detailed_status);
- else
- printk(" / DetailedStatus = %0#4x.\n",
- detailed_status);
-}
-
-/* Used to dump a message to syslog during debugging */
-void i2o_dump_message(struct i2o_message *m)
-{
-#ifdef DEBUG
- u32 *msg = (u32 *) m;
- int i;
- printk(KERN_INFO "Dumping I2O message size %d @ %p\n",
- msg[0] >> 16 & 0xffff, msg);
- for (i = 0; i < ((msg[0] >> 16) & 0xffff); i++)
- printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]);
-#endif
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Following fail status are common to all classes.
- * The preserved message must be handled in the reply handler.
- */
-static void i2o_report_fail_status(u8 req_status, u32 * msg)
-{
- static char *FAIL_STATUS[] = {
- "0x80", /* not used */
- "SERVICE_SUSPENDED", /* 0x81 */
- "SERVICE_TERMINATED", /* 0x82 */
- "CONGESTION",
- "FAILURE",
- "STATE_ERROR",
- "TIME_OUT",
- "ROUTING_FAILURE",
- "INVALID_VERSION",
- "INVALID_OFFSET",
- "INVALID_MSG_FLAGS",
- "FRAME_TOO_SMALL",
- "FRAME_TOO_LARGE",
- "INVALID_TARGET_ID",
- "INVALID_INITIATOR_ID",
- "INVALID_INITIATOR_CONTEX", /* 0x8F */
- "UNKNOWN_FAILURE" /* 0xFF */
- };
-
- if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
- printk("TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
- req_status);
- else
- printk("TRANSPORT_%s.\n",
- FAIL_STATUS[req_status & 0x0F]);
-
- /* Dump some details */
-
- printk(KERN_ERR " InitiatorId = %d, TargetId = %d\n",
- (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF);
- printk(KERN_ERR " LowestVersion = 0x%02X, HighestVersion = 0x%02X\n",
- (msg[4] >> 8) & 0xFF, msg[4] & 0xFF);
- printk(KERN_ERR " FailingHostUnit = 0x%04X, FailingIOP = 0x%03X\n",
- msg[5] >> 16, msg[5] & 0xFFF);
-
- printk(KERN_ERR " Severity: 0x%02X\n", (msg[4] >> 16) & 0xFF);
- if (msg[4] & (1 << 16))
- printk(KERN_DEBUG "(FormatError), "
- "this msg can never be delivered/processed.\n");
- if (msg[4] & (1 << 17))
- printk(KERN_DEBUG "(PathError), "
- "this msg can no longer be delivered/processed.\n");
- if (msg[4] & (1 << 18))
- printk(KERN_DEBUG "(PathState), "
- "the system state does not allow delivery.\n");
- if (msg[4] & (1 << 19))
- printk(KERN_DEBUG
- "(Congestion), resources temporarily not available;"
- "do not retry immediately.\n");
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Following reply status are common to all classes.
- */
-static void i2o_report_common_status(u8 req_status)
-{
- static char *REPLY_STATUS[] = {
- "SUCCESS",
- "ABORT_DIRTY",
- "ABORT_NO_DATA_TRANSFER",
- "ABORT_PARTIAL_TRANSFER",
- "ERROR_DIRTY",
- "ERROR_NO_DATA_TRANSFER",
- "ERROR_PARTIAL_TRANSFER",
- "PROCESS_ABORT_DIRTY",
- "PROCESS_ABORT_NO_DATA_TRANSFER",
- "PROCESS_ABORT_PARTIAL_TRANSFER",
- "TRANSACTION_ERROR",
- "PROGRESS_REPORT"
- };
-
- if (req_status >= ARRAY_SIZE(REPLY_STATUS))
- printk("RequestStatus = %0#2x", req_status);
- else
- printk("%s", REPLY_STATUS[req_status]);
-}
-
-/*
- * Used for error reporting/debugging purposes.
- * Following detailed status are valid for executive class,
- * utility class, DDM class and for transaction error replies.
- */
-static void i2o_report_common_dsc(u16 detailed_status)
-{
- static char *COMMON_DSC[] = {
- "SUCCESS",
- "0x01", // not used
- "BAD_KEY",
- "TCL_ERROR",
- "REPLY_BUFFER_FULL",
- "NO_SUCH_PAGE",
- "INSUFFICIENT_RESOURCE_SOFT",
- "INSUFFICIENT_RESOURCE_HARD",
- "0x08", // not used
- "CHAIN_BUFFER_TOO_LARGE",
- "UNSUPPORTED_FUNCTION",
- "DEVICE_LOCKED",
- "DEVICE_RESET",
- "INAPPROPRIATE_FUNCTION",
- "INVALID_INITIATOR_ADDRESS",
- "INVALID_MESSAGE_FLAGS",
- "INVALID_OFFSET",
- "INVALID_PARAMETER",
- "INVALID_REQUEST",
- "INVALID_TARGET_ADDRESS",
- "MESSAGE_TOO_LARGE",
- "MESSAGE_TOO_SMALL",
- "MISSING_PARAMETER",
- "TIMEOUT",
- "UNKNOWN_ERROR",
- "UNKNOWN_FUNCTION",
- "UNSUPPORTED_VERSION",
- "DEVICE_BUSY",
- "DEVICE_NOT_AVAILABLE"
- };
-
- if (detailed_status > I2O_DSC_DEVICE_NOT_AVAILABLE)
- printk(" / DetailedStatus = %0#4x.\n",
- detailed_status);
- else
- printk(" / %s.\n", COMMON_DSC[detailed_status]);
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_util_cmd(u8 cmd)
-{
- switch (cmd) {
- case I2O_CMD_UTIL_NOP:
- printk("UTIL_NOP, ");
- break;
- case I2O_CMD_UTIL_ABORT:
- printk("UTIL_ABORT, ");
- break;
- case I2O_CMD_UTIL_CLAIM:
- printk("UTIL_CLAIM, ");
- break;
- case I2O_CMD_UTIL_RELEASE:
- printk("UTIL_CLAIM_RELEASE, ");
- break;
- case I2O_CMD_UTIL_CONFIG_DIALOG:
- printk("UTIL_CONFIG_DIALOG, ");
- break;
- case I2O_CMD_UTIL_DEVICE_RESERVE:
- printk("UTIL_DEVICE_RESERVE, ");
- break;
- case I2O_CMD_UTIL_DEVICE_RELEASE:
- printk("UTIL_DEVICE_RELEASE, ");
- break;
- case I2O_CMD_UTIL_EVT_ACK:
- printk("UTIL_EVENT_ACKNOWLEDGE, ");
- break;
- case I2O_CMD_UTIL_EVT_REGISTER:
- printk("UTIL_EVENT_REGISTER, ");
- break;
- case I2O_CMD_UTIL_LOCK:
- printk("UTIL_LOCK, ");
- break;
- case I2O_CMD_UTIL_LOCK_RELEASE:
- printk("UTIL_LOCK_RELEASE, ");
- break;
- case I2O_CMD_UTIL_PARAMS_GET:
- printk("UTIL_PARAMS_GET, ");
- break;
- case I2O_CMD_UTIL_PARAMS_SET:
- printk("UTIL_PARAMS_SET, ");
- break;
- case I2O_CMD_UTIL_REPLY_FAULT_NOTIFY:
- printk("UTIL_REPLY_FAULT_NOTIFY, ");
- break;
- default:
- printk("Cmd = %0#2x, ", cmd);
- }
-}
-
-/*
- * Used for error reporting/debugging purposes
- */
-static void i2o_report_exec_cmd(u8 cmd)
-{
- switch (cmd) {
- case I2O_CMD_ADAPTER_ASSIGN:
- printk("EXEC_ADAPTER_ASSIGN, ");
- break;
- case I2O_CMD_ADAPTER_READ:
- printk("EXEC_ADAPTER_READ, ");
- break;
- case I2O_CMD_ADAPTER_RELEASE:
- printk("EXEC_ADAPTER_RELEASE, ");
- break;
- case I2O_CMD_BIOS_INFO_SET:
- printk("EXEC_BIOS_INFO_SET, ");
- break;
- case I2O_CMD_BOOT_DEVICE_SET:
- printk("EXEC_BOOT_DEVICE_SET, ");
- break;
- case I2O_CMD_CONFIG_VALIDATE:
- printk("EXEC_CONFIG_VALIDATE, ");
- break;
- case I2O_CMD_CONN_SETUP:
- printk("EXEC_CONN_SETUP, ");
- break;
- case I2O_CMD_DDM_DESTROY:
- printk("EXEC_DDM_DESTROY, ");
- break;
- case I2O_CMD_DDM_ENABLE:
- printk("EXEC_DDM_ENABLE, ");
- break;
- case I2O_CMD_DDM_QUIESCE:
- printk("EXEC_DDM_QUIESCE, ");
- break;
- case I2O_CMD_DDM_RESET:
- printk("EXEC_DDM_RESET, ");
- break;
- case I2O_CMD_DDM_SUSPEND:
- printk("EXEC_DDM_SUSPEND, ");
- break;
- case I2O_CMD_DEVICE_ASSIGN:
- printk("EXEC_DEVICE_ASSIGN, ");
- break;
- case I2O_CMD_DEVICE_RELEASE:
- printk("EXEC_DEVICE_RELEASE, ");
- break;
- case I2O_CMD_HRT_GET:
- printk("EXEC_HRT_GET, ");
- break;
- case I2O_CMD_ADAPTER_CLEAR:
- printk("EXEC_IOP_CLEAR, ");
- break;
- case I2O_CMD_ADAPTER_CONNECT:
- printk("EXEC_IOP_CONNECT, ");
- break;
- case I2O_CMD_ADAPTER_RESET:
- printk("EXEC_IOP_RESET, ");
- break;
- case I2O_CMD_LCT_NOTIFY:
- printk("EXEC_LCT_NOTIFY, ");
- break;
- case I2O_CMD_OUTBOUND_INIT:
- printk("EXEC_OUTBOUND_INIT, ");
- break;
- case I2O_CMD_PATH_ENABLE:
- printk("EXEC_PATH_ENABLE, ");
- break;
- case I2O_CMD_PATH_QUIESCE:
- printk("EXEC_PATH_QUIESCE, ");
- break;
- case I2O_CMD_PATH_RESET:
- printk("EXEC_PATH_RESET, ");
- break;
- case I2O_CMD_STATIC_MF_CREATE:
- printk("EXEC_STATIC_MF_CREATE, ");
- break;
- case I2O_CMD_STATIC_MF_RELEASE:
- printk("EXEC_STATIC_MF_RELEASE, ");
- break;
- case I2O_CMD_STATUS_GET:
- printk("EXEC_STATUS_GET, ");
- break;
- case I2O_CMD_SW_DOWNLOAD:
- printk("EXEC_SW_DOWNLOAD, ");
- break;
- case I2O_CMD_SW_UPLOAD:
- printk("EXEC_SW_UPLOAD, ");
- break;
- case I2O_CMD_SW_REMOVE:
- printk("EXEC_SW_REMOVE, ");
- break;
- case I2O_CMD_SYS_ENABLE:
- printk("EXEC_SYS_ENABLE, ");
- break;
- case I2O_CMD_SYS_MODIFY:
- printk("EXEC_SYS_MODIFY, ");
- break;
- case I2O_CMD_SYS_QUIESCE:
- printk("EXEC_SYS_QUIESCE, ");
- break;
- case I2O_CMD_SYS_TAB_SET:
- printk("EXEC_SYS_TAB_SET, ");
- break;
- default:
- printk("Cmd = %#02x, ", cmd);
- }
-}
-
-void i2o_debug_state(struct i2o_controller *c)
-{
- printk(KERN_INFO "%s: State = ", c->name);
- switch (((i2o_status_block *) c->status_block.virt)->iop_state) {
- case 0x01:
- printk("INIT\n");
- break;
- case 0x02:
- printk("RESET\n");
- break;
- case 0x04:
- printk("HOLD\n");
- break;
- case 0x05:
- printk("READY\n");
- break;
- case 0x08:
- printk("OPERATIONAL\n");
- break;
- case 0x10:
- printk("FAILED\n");
- break;
- case 0x11:
- printk("FAULTED\n");
- break;
- default:
- printk("%x (unknown !!)\n",
- ((i2o_status_block *) c->status_block.virt)->iop_state);
- }
-};
-
-void i2o_dump_hrt(struct i2o_controller *c)
-{
- u32 *rows = (u32 *) c->hrt.virt;
- u8 *p = (u8 *) c->hrt.virt;
- u8 *d;
- int count;
- int length;
- int i;
- int state;
-
- if (p[3] != 0) {
- printk(KERN_ERR
- "%s: HRT table for controller is too new a version.\n",
- c->name);
- return;
- }
-
- count = p[0] | (p[1] << 8);
- length = p[2];
-
- printk(KERN_INFO "%s: HRT has %d entries of %d bytes each.\n",
- c->name, count, length << 2);
-
- rows += 2;
-
- for (i = 0; i < count; i++) {
- printk(KERN_INFO "Adapter %08X: ", rows[0]);
- p = (u8 *) (rows + 1);
- d = (u8 *) (rows + 2);
- state = p[1] << 8 | p[0];
-
- printk("TID %04X:[", state & 0xFFF);
- state >>= 12;
- if (state & (1 << 0))
- printk("H"); /* Hidden */
- if (state & (1 << 2)) {
- printk("P"); /* Present */
- if (state & (1 << 1))
- printk("C"); /* Controlled */
- }
- if (state > 9)
- printk("*"); /* Hard */
-
- printk("]:");
-
- switch (p[3] & 0xFFFF) {
- case 0:
- /* Adapter private bus - easy */
- printk("Local bus %d: I/O at 0x%04X Mem 0x%08X", p[2],
- d[1] << 8 | d[0], *(u32 *) (d + 4));
- break;
- case 1:
- /* ISA bus */
- printk("ISA %d: CSN %d I/O at 0x%04X Mem 0x%08X", p[2],
- d[2], d[1] << 8 | d[0], *(u32 *) (d + 4));
- break;
-
- case 2: /* EISA bus */
- printk("EISA %d: Slot %d I/O at 0x%04X Mem 0x%08X",
- p[2], d[3], d[1] << 8 | d[0], *(u32 *) (d + 4));
- break;
-
- case 3: /* MCA bus */
- printk("MCA %d: Slot %d I/O at 0x%04X Mem 0x%08X", p[2],
- d[3], d[1] << 8 | d[0], *(u32 *) (d + 4));
- break;
-
- case 4: /* PCI bus */
- printk("PCI %d: Bus %d Device %d Function %d", p[2],
- d[2], d[1], d[0]);
- break;
-
- case 0x80: /* Other */
- default:
- printk("Unsupported bus type.");
- break;
- }
- printk("\n");
- rows += length;
- }
-}
-
-EXPORT_SYMBOL(i2o_dump_message);
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
deleted file mode 100644
index 4547db99f7da..000000000000
--- a/drivers/message/i2o/device.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Functions to handle I2O devices
- *
- * Copyright (C) 2004 Markus Lidel <Markus.Lidel@shadowconnect.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Fixes/additions:
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * initial version.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "core.h"
-
-/**
- * i2o_device_issue_claim - claim or release a device
- * @dev: I2O device to claim or release
- * @cmd: claim or release command
- * @type: type of claim
- *
- * Issue I2O UTIL_CLAIM or UTIL_RELEASE messages. The message to be sent
- * is set by cmd. dev is the I2O device which should be claim or
- * released and the type is the claim type (see the I2O spec).
- *
- * Returs 0 on success or negative error code on failure.
- */
-static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
- u32 type)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid);
- msg->body[0] = cpu_to_le32(type);
-
- return i2o_msg_post_wait(dev->iop, msg, 60);
-}
-
-/**
- * i2o_device_claim - claim a device for use by an OSM
- * @dev: I2O device to claim
- *
- * Do the leg work to assign a device to a given OSM. If the claim succeeds,
- * the owner is the primary. If the attempt fails a negative errno code
- * is returned. On success zero is returned.
- */
-int i2o_device_claim(struct i2o_device *dev)
-{
- int rc = 0;
-
- mutex_lock(&dev->lock);
-
- rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY);
- if (!rc)
- pr_debug("i2o: claim of device %d succeeded\n",
- dev->lct_data.tid);
- else
- pr_debug("i2o: claim of device %d failed %d\n",
- dev->lct_data.tid, rc);
-
- mutex_unlock(&dev->lock);
-
- return rc;
-}
-
-/**
- * i2o_device_claim_release - release a device that the OSM is using
- * @dev: device to release
- *
- * Drop a claim by an OSM on a given I2O device.
- *
- * AC - some devices seem to want to refuse an unclaim until they have
- * finished internal processing. It makes sense since you don't want a
- * new device to go reconfiguring the entire system until you are done.
- * Thus we are prepared to wait briefly.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_device_claim_release(struct i2o_device *dev)
-{
- int tries;
- int rc = 0;
-
- mutex_lock(&dev->lock);
-
- /*
- * If the controller takes a nonblocking approach to
- * releases we have to sleep/poll for a few times.
- */
- for (tries = 0; tries < 10; tries++) {
- rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_RELEASE,
- I2O_CLAIM_PRIMARY);
- if (!rc)
- break;
-
- ssleep(1);
- }
-
- if (!rc)
- pr_debug("i2o: claim release of device %d succeeded\n",
- dev->lct_data.tid);
- else
- pr_debug("i2o: claim release of device %d failed %d\n",
- dev->lct_data.tid, rc);
-
- mutex_unlock(&dev->lock);
-
- return rc;
-}
-
-/**
- * i2o_device_release - release the memory for a I2O device
- * @dev: I2O device which should be released
- *
- * Release the allocated memory. This function is called if refcount of
- * device reaches 0 automatically.
- */
-static void i2o_device_release(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
-
- pr_debug("i2o: device %s released\n", dev_name(dev));
-
- kfree(i2o_dev);
-}
-
-/**
- * i2o_device_show_class_id - Displays class id of I2O device
- * @dev: device of which the class id should be displayed
- * @attr: pointer to device attribute
- * @buf: buffer into which the class id should be printed
- *
- * Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_show_class_id(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
-
- sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
- return strlen(buf) + 1;
-}
-
-/**
- * i2o_device_show_tid - Displays TID of I2O device
- * @dev: device of which the TID should be displayed
- * @attr: pointer to device attribute
- * @buf: buffer into which the TID should be printed
- *
- * Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_show_tid(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
-
- sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
- return strlen(buf) + 1;
-}
-
-/* I2O device attributes */
-struct device_attribute i2o_device_attrs[] = {
- __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
- __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
- __ATTR_NULL
-};
-
-/**
- * i2o_device_alloc - Allocate a I2O device and initialize it
- *
- * Allocate the memory for a I2O device and initialize locks and lists
- *
- * Returns the allocated I2O device or a negative error code if the device
- * could not be allocated.
- */
-static struct i2o_device *i2o_device_alloc(void)
-{
- struct i2o_device *dev;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- INIT_LIST_HEAD(&dev->list);
- mutex_init(&dev->lock);
-
- dev->device.bus = &i2o_bus_type;
- dev->device.release = &i2o_device_release;
-
- return dev;
-}
-
-/**
- * i2o_device_add - allocate a new I2O device and add it to the IOP
- * @c: I2O controller that the device is on
- * @entry: LCT entry of the I2O device
- *
- * Allocate a new I2O device and initialize it with the LCT entry. The
- * device is appended to the device list of the controller.
- *
- * Returns zero on success, or a -ve errno.
- */
-static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
-{
- struct i2o_device *i2o_dev, *tmp;
- int rc;
-
- i2o_dev = i2o_device_alloc();
- if (IS_ERR(i2o_dev)) {
- printk(KERN_ERR "i2o: unable to allocate i2o device\n");
- return PTR_ERR(i2o_dev);
- }
-
- i2o_dev->lct_data = *entry;
-
- dev_set_name(&i2o_dev->device, "%d:%03x", c->unit,
- i2o_dev->lct_data.tid);
-
- i2o_dev->iop = c;
- i2o_dev->device.parent = &c->device;
-
- rc = device_register(&i2o_dev->device);
- if (rc)
- goto err;
-
- list_add_tail(&i2o_dev->list, &c->devices);
-
- /* create user entries for this device */
- tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
- if (tmp && (tmp != i2o_dev)) {
- rc = sysfs_create_link(&i2o_dev->device.kobj,
- &tmp->device.kobj, "user");
- if (rc)
- goto unreg_dev;
- }
-
- /* create user entries referring to this device */
- list_for_each_entry(tmp, &c->devices, list)
- if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev)) {
- rc = sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "user");
- if (rc)
- goto rmlink1;
- }
-
- /* create parent entries for this device */
- tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
- if (tmp && (tmp != i2o_dev)) {
- rc = sysfs_create_link(&i2o_dev->device.kobj,
- &tmp->device.kobj, "parent");
- if (rc)
- goto rmlink1;
- }
-
- /* create parent entries referring to this device */
- list_for_each_entry(tmp, &c->devices, list)
- if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev)) {
- rc = sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "parent");
- if (rc)
- goto rmlink2;
- }
-
- i2o_driver_notify_device_add_all(i2o_dev);
-
- pr_debug("i2o: device %s added\n", dev_name(&i2o_dev->device));
-
- return 0;
-
-rmlink2:
- /* If link creating failed halfway, we loop whole list to cleanup.
- * And we don't care wrong removing of link, because sysfs_remove_link
- * will take care of it.
- */
- list_for_each_entry(tmp, &c->devices, list) {
- if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "parent");
- }
- sysfs_remove_link(&i2o_dev->device.kobj, "parent");
-rmlink1:
- list_for_each_entry(tmp, &c->devices, list)
- if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "user");
- sysfs_remove_link(&i2o_dev->device.kobj, "user");
-unreg_dev:
- list_del(&i2o_dev->list);
- device_unregister(&i2o_dev->device);
-err:
- kfree(i2o_dev);
- return rc;
-}
-
-/**
- * i2o_device_remove - remove an I2O device from the I2O core
- * @i2o_dev: I2O device which should be released
- *
- * Is used on I2O controller removal or LCT modification, when the device
- * is removed from the system. Note that the device could still hang
- * around until the refcount reaches 0.
- */
-void i2o_device_remove(struct i2o_device *i2o_dev)
-{
- struct i2o_device *tmp;
- struct i2o_controller *c = i2o_dev->iop;
-
- i2o_driver_notify_device_remove_all(i2o_dev);
-
- sysfs_remove_link(&i2o_dev->device.kobj, "parent");
- sysfs_remove_link(&i2o_dev->device.kobj, "user");
-
- list_for_each_entry(tmp, &c->devices, list) {
- if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "parent");
- if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- sysfs_remove_link(&tmp->device.kobj, "user");
- }
- list_del(&i2o_dev->list);
-
- device_unregister(&i2o_dev->device);
-}
-
-/**
- * i2o_device_parse_lct - Parse a previously fetched LCT and create devices
- * @c: I2O controller from which the LCT should be parsed.
- *
- * The Logical Configuration Table tells us what we can talk to on the
- * board. For every entry we create an I2O device, which is registered in
- * the I2O core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_device_parse_lct(struct i2o_controller *c)
-{
- struct i2o_device *dev, *tmp;
- i2o_lct *lct;
- u32 *dlct = c->dlct.virt;
- int max = 0, i = 0;
- u16 table_size;
- u32 buf;
-
- mutex_lock(&c->lct_lock);
-
- kfree(c->lct);
-
- buf = le32_to_cpu(*dlct++);
- table_size = buf & 0xffff;
-
- lct = c->lct = kmalloc(table_size * 4, GFP_KERNEL);
- if (!lct) {
- mutex_unlock(&c->lct_lock);
- return -ENOMEM;
- }
-
- lct->lct_ver = buf >> 28;
- lct->boot_tid = buf >> 16 & 0xfff;
- lct->table_size = table_size;
- lct->change_ind = le32_to_cpu(*dlct++);
- lct->iop_flags = le32_to_cpu(*dlct++);
-
- table_size -= 3;
-
- pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max,
- lct->table_size);
-
- while (table_size > 0) {
- i2o_lct_entry *entry = &lct->lct_entry[max];
- int found = 0;
-
- buf = le32_to_cpu(*dlct++);
- entry->entry_size = buf & 0xffff;
- entry->tid = buf >> 16 & 0xfff;
-
- entry->change_ind = le32_to_cpu(*dlct++);
- entry->device_flags = le32_to_cpu(*dlct++);
-
- buf = le32_to_cpu(*dlct++);
- entry->class_id = buf & 0xfff;
- entry->version = buf >> 12 & 0xf;
- entry->vendor_id = buf >> 16;
-
- entry->sub_class = le32_to_cpu(*dlct++);
-
- buf = le32_to_cpu(*dlct++);
- entry->user_tid = buf & 0xfff;
- entry->parent_tid = buf >> 12 & 0xfff;
- entry->bios_info = buf >> 24;
-
- memcpy(&entry->identity_tag, dlct, 8);
- dlct += 2;
-
- entry->event_capabilities = le32_to_cpu(*dlct++);
-
- /* add new devices, which are new in the LCT */
- list_for_each_entry_safe(dev, tmp, &c->devices, list) {
- if (entry->tid == dev->lct_data.tid) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- i2o_device_add(c, entry);
-
- table_size -= 9;
- max++;
- }
-
- /* remove devices, which are not in the LCT anymore */
- list_for_each_entry_safe(dev, tmp, &c->devices, list) {
- int found = 0;
-
- for (i = 0; i < max; i++) {
- if (lct->lct_entry[i].tid == dev->lct_data.tid) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- i2o_device_remove(dev);
- }
-
- mutex_unlock(&c->lct_lock);
-
- return 0;
-}
-
-/*
- * Run time support routines
- */
-
-/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
- *
- * This function can be used for all UtilParamsGet/Set operations.
- * The OperationList is given in oplist-buffer,
- * and results are returned in reslist-buffer.
- * Note that the minimum sized reslist is 8 bytes and contains
- * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
- */
-int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
- int oplen, void *reslist, int reslen)
-{
- struct i2o_message *msg;
- int i = 0;
- int rc;
- struct i2o_dma res;
- struct i2o_controller *c = i2o_dev->iop;
- struct device *dev = &c->pdev->dev;
-
- res.virt = NULL;
-
- if (i2o_dma_alloc(dev, &res, reslen))
- return -ENOMEM;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg)) {
- i2o_dma_free(dev, &res);
- return PTR_ERR(msg);
- }
-
- i = 0;
- msg->u.head[1] =
- cpu_to_le32(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid);
- msg->body[i++] = cpu_to_le32(0x00000000);
- msg->body[i++] = cpu_to_le32(0x4C000000 | oplen); /* OperationList */
- memcpy(&msg->body[i], oplist, oplen);
- i += (oplen / 4 + (oplen % 4 ? 1 : 0));
- msg->body[i++] = cpu_to_le32(0xD0000000 | res.len); /* ResultList */
- msg->body[i++] = cpu_to_le32(res.phys);
-
- msg->u.head[0] =
- cpu_to_le32(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) |
- SGL_OFFSET_5);
-
- rc = i2o_msg_post_wait_mem(c, msg, 10, &res);
-
- /* This only looks like a memory leak - don't "fix" it. */
- if (rc == -ETIMEDOUT)
- return rc;
-
- memcpy(reslist, res.virt, res.len);
- i2o_dma_free(dev, &res);
-
- return rc;
-}
-
-/*
- * Query one field group value or a whole scalar group.
- */
-int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
- void *buf, int buflen)
-{
- u32 opblk[] = { cpu_to_le32(0x00000001),
- cpu_to_le32((u16) group << 16 | I2O_PARAMS_FIELD_GET),
- cpu_to_le32((s16) field << 16 | 0x00000001)
- };
- u8 *resblk; /* 8 bytes for header */
- int rc;
-
- resblk = kmalloc(buflen + 8, GFP_KERNEL);
- if (!resblk)
- return -ENOMEM;
-
- rc = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
- sizeof(opblk), resblk, buflen + 8);
-
- memcpy(buf, resblk + 8, buflen); /* cut off header */
-
- kfree(resblk);
-
- return rc;
-}
-
-/*
- * if oper == I2O_PARAMS_TABLE_GET, get from all rows
- * if fieldcount == -1 return all fields
- * ibuf and ibuflen are unused (use NULL, 0)
- * else return specific fields
- * ibuf contains fieldindexes
- *
- * if oper == I2O_PARAMS_LIST_GET, get from specific rows
- * if fieldcount == -1 return all fields
- * ibuf contains rowcount, keyvalues
- * else return specific fields
- * fieldcount is # of fieldindexes
- * ibuf contains fieldindexes, rowcount, keyvalues
- *
- * You could also use directly function i2o_issue_params().
- */
-int i2o_parm_table_get(struct i2o_device *dev, int oper, int group,
- int fieldcount, void *ibuf, int ibuflen, void *resblk,
- int reslen)
-{
- u16 *opblk;
- int size;
-
- size = 10 + ibuflen;
- if (size % 4)
- size += 4 - size % 4;
-
- opblk = kmalloc(size, GFP_KERNEL);
- if (opblk == NULL) {
- printk(KERN_ERR "i2o: no memory for query buffer.\n");
- return -ENOMEM;
- }
-
- opblk[0] = 1; /* operation count */
- opblk[1] = 0; /* pad */
- opblk[2] = oper;
- opblk[3] = group;
- opblk[4] = fieldcount;
- memcpy(opblk + 5, ibuf, ibuflen); /* other params */
-
- size = i2o_parm_issue(dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
- size, resblk, reslen);
-
- kfree(opblk);
- if (size > reslen)
- return reslen;
-
- return size;
-}
-
-EXPORT_SYMBOL(i2o_device_claim);
-EXPORT_SYMBOL(i2o_device_claim_release);
-EXPORT_SYMBOL(i2o_parm_field_get);
-EXPORT_SYMBOL(i2o_parm_table_get);
-EXPORT_SYMBOL(i2o_parm_issue);
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
deleted file mode 100644
index 813eaa33fa14..000000000000
--- a/drivers/message/i2o/driver.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Functions to handle I2O drivers (OSMs) and I2O bus type for sysfs
- *
- * Copyright (C) 2004 Markus Lidel <Markus.Lidel@shadowconnect.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Fixes/additions:
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * initial version.
- */
-
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/rwsem.h>
-#include <linux/i2o.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "core.h"
-
-#define OSM_NAME "i2o"
-
-/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
-static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
-module_param_named(max_drivers, i2o_max_drivers, uint, 0);
-MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support");
-
-/* I2O drivers lock and array */
-static spinlock_t i2o_drivers_lock;
-static struct i2o_driver **i2o_drivers;
-
-/**
- * i2o_bus_match - Tell if I2O device class id matches the class ids of the I2O driver (OSM)
- * @dev: device which should be verified
- * @drv: the driver to match against
- *
- * Used by the bus to check if the driver wants to handle the device.
- *
- * Returns 1 if the class ids of the driver match the class id of the
- * device, otherwise 0.
- */
-static int i2o_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_driver *i2o_drv = to_i2o_driver(drv);
- struct i2o_class_id *ids = i2o_drv->classes;
-
- if (ids)
- while (ids->class_id != I2O_CLASS_END) {
- if (ids->class_id == i2o_dev->lct_data.class_id)
- return 1;
- ids++;
- }
- return 0;
-};
-
-/* I2O bus type */
-struct bus_type i2o_bus_type = {
- .name = "i2o",
- .match = i2o_bus_match,
- .dev_attrs = i2o_device_attrs
-};
-
-/**
- * i2o_driver_register - Register a I2O driver (OSM) in the I2O core
- * @drv: I2O driver which should be registered
- *
- * Registers the OSM drv in the I2O core and creates an event queues if
- * necessary.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_driver_register(struct i2o_driver *drv)
-{
- struct i2o_controller *c;
- int i;
- int rc = 0;
- unsigned long flags;
-
- osm_debug("Register driver %s\n", drv->name);
-
- if (drv->event) {
- drv->event_queue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1,
- drv->name);
- if (!drv->event_queue) {
- osm_err("Could not initialize event queue for driver "
- "%s\n", drv->name);
- return -EFAULT;
- }
- osm_debug("Event queue initialized for driver %s\n", drv->name);
- } else
- drv->event_queue = NULL;
-
- drv->driver.name = drv->name;
- drv->driver.bus = &i2o_bus_type;
-
- spin_lock_irqsave(&i2o_drivers_lock, flags);
-
- for (i = 0; i2o_drivers[i]; i++)
- if (i >= i2o_max_drivers) {
- osm_err("too many drivers registered, increase "
- "max_drivers\n");
- spin_unlock_irqrestore(&i2o_drivers_lock, flags);
- return -EFAULT;
- }
-
- drv->context = i;
- i2o_drivers[i] = drv;
-
- spin_unlock_irqrestore(&i2o_drivers_lock, flags);
-
- osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
-
- list_for_each_entry(c, &i2o_controllers, list) {
- struct i2o_device *i2o_dev;
-
- i2o_driver_notify_controller_add(drv, c);
- list_for_each_entry(i2o_dev, &c->devices, list)
- i2o_driver_notify_device_add(drv, i2o_dev);
- }
-
- rc = driver_register(&drv->driver);
- if (rc) {
- if (drv->event) {
- destroy_workqueue(drv->event_queue);
- drv->event_queue = NULL;
- }
- }
-
- return rc;
-};
-
-/**
- * i2o_driver_unregister - Unregister a I2O driver (OSM) from the I2O core
- * @drv: I2O driver which should be unregistered
- *
- * Unregisters the OSM drv from the I2O core and cleanup event queues if
- * necessary.
- */
-void i2o_driver_unregister(struct i2o_driver *drv)
-{
- struct i2o_controller *c;
- unsigned long flags;
-
- osm_debug("unregister driver %s\n", drv->name);
-
- driver_unregister(&drv->driver);
-
- list_for_each_entry(c, &i2o_controllers, list) {
- struct i2o_device *i2o_dev;
-
- list_for_each_entry(i2o_dev, &c->devices, list)
- i2o_driver_notify_device_remove(drv, i2o_dev);
-
- i2o_driver_notify_controller_remove(drv, c);
- }
-
- spin_lock_irqsave(&i2o_drivers_lock, flags);
- i2o_drivers[drv->context] = NULL;
- spin_unlock_irqrestore(&i2o_drivers_lock, flags);
-
- if (drv->event_queue) {
- destroy_workqueue(drv->event_queue);
- drv->event_queue = NULL;
- osm_debug("event queue removed for %s\n", drv->name);
- }
-};
-
-/**
- * i2o_driver_dispatch - dispatch an I2O reply message
- * @c: I2O controller of the message
- * @m: I2O message number
- *
- * The reply is delivered to the driver from which the original message
- * was. This function is only called from interrupt context.
- *
- * Returns 0 on success and the message should not be flushed. Returns > 0
- * on success and if the message should be flushed afterwords. Returns
- * negative error code on failure (the message will be flushed too).
- */
-int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
-{
- struct i2o_driver *drv;
- struct i2o_message *msg = i2o_msg_out_to_virt(c, m);
- u32 context = le32_to_cpu(msg->u.s.icntxt);
- unsigned long flags;
-
- if (unlikely(context >= i2o_max_drivers)) {
- osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
- context);
- return -EIO;
- }
-
- spin_lock_irqsave(&i2o_drivers_lock, flags);
- drv = i2o_drivers[context];
- spin_unlock_irqrestore(&i2o_drivers_lock, flags);
-
- if (unlikely(!drv)) {
- osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
- context);
- return -EIO;
- }
-
- if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
- struct i2o_device *dev, *tmp;
- struct i2o_event *evt;
- u16 size;
- u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff;
-
- osm_debug("event received from device %d\n", tid);
-
- if (!drv->event)
- return -EIO;
-
- /* cut of header from message size (in 32-bit words) */
- size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
-
- evt = kzalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
- if (!evt)
- return -ENOMEM;
-
- evt->size = size;
- evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
- evt->event_indicator = le32_to_cpu(msg->body[0]);
- memcpy(&evt->data, &msg->body[1], size * 4);
-
- list_for_each_entry_safe(dev, tmp, &c->devices, list)
- if (dev->lct_data.tid == tid) {
- evt->i2o_dev = dev;
- break;
- }
-
- INIT_WORK(&evt->work, drv->event);
- queue_work(drv->event_queue, &evt->work);
- return 1;
- }
-
- if (unlikely(!drv->reply)) {
- osm_debug("%s: Reply to driver %s, but no reply function"
- " defined!\n", c->name, drv->name);
- return -EIO;
- }
-
- return drv->reply(c, m, msg);
-}
-
-/**
- * i2o_driver_notify_controller_add_all - Send notify of added controller
- * @c: newly added controller
- *
- * Send notifications to all registered drivers that a new controller was
- * added.
- */
-void i2o_driver_notify_controller_add_all(struct i2o_controller *c)
-{
- int i;
- struct i2o_driver *drv;
-
- for (i = 0; i < i2o_max_drivers; i++) {
- drv = i2o_drivers[i];
-
- if (drv)
- i2o_driver_notify_controller_add(drv, c);
- }
-}
-
-/**
- * i2o_driver_notify_controller_remove_all - Send notify of removed controller
- * @c: controller that is being removed
- *
- * Send notifications to all registered drivers that a controller was
- * removed.
- */
-void i2o_driver_notify_controller_remove_all(struct i2o_controller *c)
-{
- int i;
- struct i2o_driver *drv;
-
- for (i = 0; i < i2o_max_drivers; i++) {
- drv = i2o_drivers[i];
-
- if (drv)
- i2o_driver_notify_controller_remove(drv, c);
- }
-}
-
-/**
- * i2o_driver_notify_device_add_all - Send notify of added device
- * @i2o_dev: newly added I2O device
- *
- * Send notifications to all registered drivers that a device was added.
- */
-void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev)
-{
- int i;
- struct i2o_driver *drv;
-
- for (i = 0; i < i2o_max_drivers; i++) {
- drv = i2o_drivers[i];
-
- if (drv)
- i2o_driver_notify_device_add(drv, i2o_dev);
- }
-}
-
-/**
- * i2o_driver_notify_device_remove_all - Send notify of removed device
- * @i2o_dev: device that is being removed
- *
- * Send notifications to all registered drivers that a device was removed.
- */
-void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev)
-{
- int i;
- struct i2o_driver *drv;
-
- for (i = 0; i < i2o_max_drivers; i++) {
- drv = i2o_drivers[i];
-
- if (drv)
- i2o_driver_notify_device_remove(drv, i2o_dev);
- }
-}
-
-/**
- * i2o_driver_init - initialize I2O drivers (OSMs)
- *
- * Registers the I2O bus and allocate memory for the array of OSMs.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int __init i2o_driver_init(void)
-{
- int rc = 0;
-
- spin_lock_init(&i2o_drivers_lock);
-
- if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) {
- osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n",
- i2o_max_drivers);
- i2o_max_drivers = I2O_MAX_DRIVERS;
- }
- osm_info("max drivers = %d\n", i2o_max_drivers);
-
- i2o_drivers =
- kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL);
- if (!i2o_drivers)
- return -ENOMEM;
-
- rc = bus_register(&i2o_bus_type);
-
- if (rc < 0)
- kfree(i2o_drivers);
-
- return rc;
-};
-
-/**
- * i2o_driver_exit - clean up I2O drivers (OSMs)
- *
- * Unregisters the I2O bus and frees driver array.
- */
-void i2o_driver_exit(void)
-{
- bus_unregister(&i2o_bus_type);
- kfree(i2o_drivers);
-};
-
-EXPORT_SYMBOL(i2o_driver_register);
-EXPORT_SYMBOL(i2o_driver_unregister);
-EXPORT_SYMBOL(i2o_driver_notify_controller_add_all);
-EXPORT_SYMBOL(i2o_driver_notify_controller_remove_all);
-EXPORT_SYMBOL(i2o_driver_notify_device_add_all);
-EXPORT_SYMBOL(i2o_driver_notify_device_remove_all);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
deleted file mode 100644
index a3970e56ae53..000000000000
--- a/drivers/message/i2o/exec-osm.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Executive OSM
- *
- * Copyright (C) 1999-2002 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * A lot of the I2O message side code from this is taken from the Red
- * Creek RCPCI45 adapter driver by Red Creek Communications
- *
- * Fixes/additions:
- * Philipp Rumpf
- * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Deepak Saxena <deepak@plexity.net>
- * Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
- * Alan Cox <alan@lxorguk.ukuu.org.uk>:
- * Ported to Linux 2.5.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor fixes for 2.6.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Support for sysfs included.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */
-#include <asm/param.h> /* HZ */
-#include "core.h"
-
-#define OSM_NAME "exec-osm"
-
-struct i2o_driver i2o_exec_driver;
-
-/* global wait list for POST WAIT */
-static LIST_HEAD(i2o_exec_wait_list);
-
-/* Wait struct needed for POST WAIT */
-struct i2o_exec_wait {
- wait_queue_head_t *wq; /* Pointer to Wait queue */
- struct i2o_dma dma; /* DMA buffers to free on failure */
- u32 tcntxt; /* transaction context from reply */
- int complete; /* 1 if reply received otherwise 0 */
- u32 m; /* message id */
- struct i2o_message *msg; /* pointer to the reply message */
- struct list_head list; /* node in global wait list */
- spinlock_t lock; /* lock before modifying */
-};
-
-/* Work struct needed to handle LCT NOTIFY replies */
-struct i2o_exec_lct_notify_work {
- struct work_struct work; /* work struct */
- struct i2o_controller *c; /* controller on which the LCT NOTIFY
- was received */
-};
-
-/* Exec OSM class handling definition */
-static struct i2o_class_id i2o_exec_class_id[] = {
- {I2O_CLASS_EXECUTIVE},
- {I2O_CLASS_END}
-};
-
-/**
- * i2o_exec_wait_alloc - Allocate a i2o_exec_wait struct an initialize it
- *
- * Allocate the i2o_exec_wait struct and initialize the wait.
- *
- * Returns i2o_exec_wait pointer on success or negative error code on
- * failure.
- */
-static struct i2o_exec_wait *i2o_exec_wait_alloc(void)
-{
- struct i2o_exec_wait *wait;
-
- wait = kzalloc(sizeof(*wait), GFP_KERNEL);
- if (!wait)
- return NULL;
-
- INIT_LIST_HEAD(&wait->list);
- spin_lock_init(&wait->lock);
-
- return wait;
-};
-
-/**
- * i2o_exec_wait_free - Free an i2o_exec_wait struct
- * @wait: I2O wait data which should be cleaned up
- */
-static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
-{
- kfree(wait);
-};
-
-/**
- * i2o_msg_post_wait_mem - Post and wait a message with DMA buffers
- * @c: controller
- * @msg: message to post
- * @timeout: time in seconds to wait
- * @dma: i2o_dma struct of the DMA buffer to free on failure
- *
- * This API allows an OSM to post a message and then be told whether or
- * not the system received a successful reply. If the message times out
- * then the value '-ETIMEDOUT' is returned. This is a special case. In
- * this situation the message may (should) complete at an indefinite time
- * in the future. When it completes it will use the memory buffer
- * attached to the request. If -ETIMEDOUT is returned then the memory
- * buffer must not be freed. Instead the event completion will free them
- * for you. In all other cases the buffer are your problem.
- *
- * Returns 0 on success, negative error code on timeout or positive error
- * code from reply.
- */
-int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
- unsigned long timeout, struct i2o_dma *dma)
-{
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
- struct i2o_exec_wait *wait;
- static u32 tcntxt = 0x80000000;
- unsigned long flags;
- int rc = 0;
-
- wait = i2o_exec_wait_alloc();
- if (!wait) {
- i2o_msg_nop(c, msg);
- return -ENOMEM;
- }
-
- if (tcntxt == 0xffffffff)
- tcntxt = 0x80000000;
-
- if (dma)
- wait->dma = *dma;
-
- /*
- * Fill in the message initiator context and transaction context.
- * We will only use transaction contexts >= 0x80000000 for POST WAIT,
- * so we could find a POST WAIT reply easier in the reply handler.
- */
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- wait->tcntxt = tcntxt++;
- msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt);
-
- wait->wq = &wq;
- /*
- * we add elements to the head, because if a entry in the list will
- * never be removed, we have to iterate over it every time
- */
- list_add(&wait->list, &i2o_exec_wait_list);
-
- /*
- * Post the message to the controller. At some point later it will
- * return. If we time out before it returns then complete will be zero.
- */
- i2o_msg_post(c, msg);
-
- wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ);
-
- spin_lock_irqsave(&wait->lock, flags);
-
- wait->wq = NULL;
-
- if (wait->complete)
- rc = le32_to_cpu(wait->msg->body[0]) >> 24;
- else {
- /*
- * We cannot remove it now. This is important. When it does
- * terminate (which it must do if the controller has not
- * died...) then it will otherwise scribble on stuff.
- *
- * FIXME: try abort message
- */
- if (dma)
- dma->virt = NULL;
-
- rc = -ETIMEDOUT;
- }
-
- spin_unlock_irqrestore(&wait->lock, flags);
-
- if (rc != -ETIMEDOUT) {
- i2o_flush_reply(c, wait->m);
- i2o_exec_wait_free(wait);
- }
-
- return rc;
-};
-
-/**
- * i2o_msg_post_wait_complete - Reply to a i2o_msg_post request from IOP
- * @c: I2O controller which answers
- * @m: message id
- * @msg: pointer to the I2O reply message
- * @context: transaction context of request
- *
- * This function is called in interrupt context only. If the reply reached
- * before the timeout, the i2o_exec_wait struct is filled with the message
- * and the task will be waked up. The task is now responsible for returning
- * the message m back to the controller! If the message reaches us after
- * the timeout clean up the i2o_exec_wait struct (including allocated
- * DMA buffer).
- *
- * Return 0 on success and if the message m should not be given back to the
- * I2O controller, or >0 on success and if the message should be given back
- * afterwords. Returns negative error code on failure. In this case the
- * message must also be given back to the controller.
- */
-static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
- struct i2o_message *msg, u32 context)
-{
- struct i2o_exec_wait *wait, *tmp;
- unsigned long flags;
- int rc = 1;
-
- /*
- * We need to search through the i2o_exec_wait_list to see if the given
- * message is still outstanding. If not, it means that the IOP took
- * longer to respond to the message than we had allowed and timer has
- * already expired. Not much we can do about that except log it for
- * debug purposes, increase timeout, and recompile.
- */
- list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
- if (wait->tcntxt == context) {
- spin_lock_irqsave(&wait->lock, flags);
-
- list_del(&wait->list);
-
- wait->m = m;
- wait->msg = msg;
- wait->complete = 1;
-
- if (wait->wq)
- rc = 0;
- else
- rc = -1;
-
- spin_unlock_irqrestore(&wait->lock, flags);
-
- if (rc) {
- struct device *dev;
-
- dev = &c->pdev->dev;
-
- pr_debug("%s: timedout reply received!\n",
- c->name);
- i2o_dma_free(dev, &wait->dma);
- i2o_exec_wait_free(wait);
- } else
- wake_up_interruptible(wait->wq);
-
- return rc;
- }
- }
-
- osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
- context);
-
- return -1;
-};
-
-/**
- * i2o_exec_show_vendor_id - Displays Vendor ID of controller
- * @d: device of which the Vendor ID should be displayed
- * @attr: device_attribute to display
- * @buf: buffer into which the Vendor ID should be printed
- *
- * Returns number of bytes printed into buffer.
- */
-static ssize_t i2o_exec_show_vendor_id(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct i2o_device *dev = to_i2o_device(d);
- u16 id;
-
- if (!i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
- sprintf(buf, "0x%04x", le16_to_cpu(id));
- return strlen(buf) + 1;
- }
-
- return 0;
-};
-
-/**
- * i2o_exec_show_product_id - Displays Product ID of controller
- * @d: device of which the Product ID should be displayed
- * @attr: device_attribute to display
- * @buf: buffer into which the Product ID should be printed
- *
- * Returns number of bytes printed into buffer.
- */
-static ssize_t i2o_exec_show_product_id(struct device *d,
- struct device_attribute *attr,
- char *buf)
-{
- struct i2o_device *dev = to_i2o_device(d);
- u16 id;
-
- if (!i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
- sprintf(buf, "0x%04x", le16_to_cpu(id));
- return strlen(buf) + 1;
- }
-
- return 0;
-};
-
-/* Exec-OSM device attributes */
-static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
-static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
-
-/**
- * i2o_exec_probe - Called if a new I2O device (executive class) appears
- * @dev: I2O device which should be probed
- *
- * Registers event notification for every event from Executive device. The
- * return is always 0, because we want all devices of class Executive.
- *
- * Returns 0 on success.
- */
-static int i2o_exec_probe(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- int rc;
-
- rc = i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
- if (rc) goto err_out;
-
- rc = device_create_file(dev, &dev_attr_vendor_id);
- if (rc) goto err_evtreg;
- rc = device_create_file(dev, &dev_attr_product_id);
- if (rc) goto err_vid;
-
- i2o_dev->iop->exec = i2o_dev;
-
- return 0;
-
-err_vid:
- device_remove_file(dev, &dev_attr_vendor_id);
-err_evtreg:
- i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
-err_out:
- return rc;
-};
-
-/**
- * i2o_exec_remove - Called on I2O device removal
- * @dev: I2O device which was removed
- *
- * Unregisters event notification from Executive I2O device.
- *
- * Returns 0 on success.
- */
-static int i2o_exec_remove(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_product_id);
- device_remove_file(dev, &dev_attr_vendor_id);
-
- i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
-
- return 0;
-};
-
-#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES
-/**
- * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request
- * @c: I2O controller to which the request should be send
- * @change_ind: change indicator
- *
- * This function sends a LCT NOTIFY request to the I2O controller with
- * the change indicator change_ind. If the change_ind == 0 the controller
- * replies immediately after the request. If change_ind > 0 the reply is
- * send after change indicator of the LCT is > change_ind.
- */
-static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
-{
- i2o_status_block *sb = c->status_block.virt;
- struct device *dev;
- struct i2o_message *msg;
-
- mutex_lock(&c->lct_lock);
-
- dev = &c->pdev->dev;
-
- if (i2o_dma_realloc(dev, &c->dlct,
- le32_to_cpu(sb->expected_lct_size))) {
- mutex_unlock(&c->lct_lock);
- return -ENOMEM;
- }
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg)) {
- mutex_unlock(&c->lct_lock);
- return PTR_ERR(msg);
- }
-
- msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
- msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(0x00000000);
- msg->body[0] = cpu_to_le32(0xffffffff);
- msg->body[1] = cpu_to_le32(change_ind);
- msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
- msg->body[3] = cpu_to_le32(c->dlct.phys);
-
- i2o_msg_post(c, msg);
-
- mutex_unlock(&c->lct_lock);
-
- return 0;
-}
-#endif
-
-/**
- * i2o_exec_lct_modified - Called on LCT NOTIFY reply
- * @_work: work struct for a specific controller
- *
- * This function handles asynchronus LCT NOTIFY replies. It parses the
- * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
- * again, otherwise send LCT NOTIFY to get informed on next LCT change.
- */
-static void i2o_exec_lct_modified(struct work_struct *_work)
-{
- struct i2o_exec_lct_notify_work *work =
- container_of(_work, struct i2o_exec_lct_notify_work, work);
- u32 change_ind = 0;
- struct i2o_controller *c = work->c;
-
- kfree(work);
-
- if (i2o_device_parse_lct(c) != -EAGAIN)
- change_ind = c->lct->change_ind + 1;
-
-#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES
- i2o_exec_lct_notify(c, change_ind);
-#endif
-};
-
-/**
- * i2o_exec_reply - I2O Executive reply handler
- * @c: I2O controller from which the reply comes
- * @m: message id
- * @msg: pointer to the I2O reply message
- *
- * This function is always called from interrupt context. If a POST WAIT
- * reply was received, pass it to the complete function. If a LCT NOTIFY
- * reply was received, a new event is created to handle the update.
- *
- * Returns 0 on success and if the reply should not be flushed or > 0
- * on success and if the reply should be flushed. Returns negative error
- * code on failure and if the reply should be flushed.
- */
-static int i2o_exec_reply(struct i2o_controller *c, u32 m,
- struct i2o_message *msg)
-{
- u32 context;
-
- if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
- struct i2o_message __iomem *pmsg;
- u32 pm;
-
- /*
- * If Fail bit is set we must take the transaction context of
- * the preserved message to find the right request again.
- */
-
- pm = le32_to_cpu(msg->body[3]);
- pmsg = i2o_msg_in_to_virt(c, pm);
- context = readl(&pmsg->u.s.tcntxt);
-
- i2o_report_status(KERN_INFO, "i2o_core", msg);
-
- /* Release the preserved msg */
- i2o_msg_nop_mfa(c, pm);
- } else
- context = le32_to_cpu(msg->u.s.tcntxt);
-
- if (context & 0x80000000)
- return i2o_msg_post_wait_complete(c, m, msg, context);
-
- if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
- struct i2o_exec_lct_notify_work *work;
-
- pr_debug("%s: LCT notify received\n", c->name);
-
- work = kmalloc(sizeof(*work), GFP_ATOMIC);
- if (!work)
- return -ENOMEM;
-
- work->c = c;
-
- INIT_WORK(&work->work, i2o_exec_lct_modified);
- queue_work(i2o_exec_driver.event_queue, &work->work);
- return 1;
- }
-
- /*
- * If this happens, we want to dump the message to the syslog so
- * it can be sent back to the card manufacturer by the end user
- * to aid in debugging.
- *
- */
- printk(KERN_WARNING "%s: Unsolicited message reply sent to core!"
- "Message dumped to syslog\n", c->name);
- i2o_dump_message(msg);
-
- return -EFAULT;
-}
-
-/**
- * i2o_exec_event - Event handling function
- * @work: Work item in occurring event
- *
- * Handles events send by the Executive device. At the moment does not do
- * anything useful.
- */
-static void i2o_exec_event(struct work_struct *work)
-{
- struct i2o_event *evt = container_of(work, struct i2o_event, work);
-
- if (likely(evt->i2o_dev))
- osm_debug("Event received from device: %d\n",
- evt->i2o_dev->lct_data.tid);
- kfree(evt);
-};
-
-/**
- * i2o_exec_lct_get - Get the IOP's Logical Configuration Table
- * @c: I2O controller from which the LCT should be fetched
- *
- * Send a LCT NOTIFY request to the controller, and wait
- * I2O_TIMEOUT_LCT_GET seconds until arrival of response. If the LCT is
- * to large, retry it.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_exec_lct_get(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- int i = 0;
- int rc = -EAGAIN;
-
- for (i = 1; i <= I2O_LCT_GET_TRIES; i++) {
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] =
- cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->body[0] = cpu_to_le32(0xffffffff);
- msg->body[1] = cpu_to_le32(0x00000000);
- msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
- msg->body[3] = cpu_to_le32(c->dlct.phys);
-
- rc = i2o_msg_post_wait(c, msg, I2O_TIMEOUT_LCT_GET);
- if (rc < 0)
- break;
-
- rc = i2o_device_parse_lct(c);
- if (rc != -EAGAIN)
- break;
- }
-
- return rc;
-}
-
-/* Exec OSM driver struct */
-struct i2o_driver i2o_exec_driver = {
- .name = OSM_NAME,
- .reply = i2o_exec_reply,
- .event = i2o_exec_event,
- .classes = i2o_exec_class_id,
- .driver = {
- .probe = i2o_exec_probe,
- .remove = i2o_exec_remove,
- },
-};
-
-/**
- * i2o_exec_init - Registers the Exec OSM
- *
- * Registers the Exec OSM in the I2O core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int __init i2o_exec_init(void)
-{
- return i2o_driver_register(&i2o_exec_driver);
-};
-
-/**
- * i2o_exec_exit - Removes the Exec OSM
- *
- * Unregisters the Exec OSM from the I2O core.
- */
-void i2o_exec_exit(void)
-{
- i2o_driver_unregister(&i2o_exec_driver);
-};
-
-EXPORT_SYMBOL(i2o_msg_post_wait_mem);
-EXPORT_SYMBOL(i2o_exec_lct_get);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
deleted file mode 100644
index 6fc3866965df..000000000000
--- a/drivers/message/i2o/i2o_block.c
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * Block OSM
- *
- * Copyright (C) 1999-2002 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * For the purpose of avoiding doubt the preferred form of the work
- * for making modifications shall be a standards compliant form such
- * gzipped tar and not one requiring a proprietary or patent encumbered
- * tool to unpack.
- *
- * Fixes/additions:
- * Steve Ralston:
- * Multiple device handling error fixes,
- * Added a queue depth.
- * Alan Cox:
- * FC920 has an rmw bug. Dont or in the end marker.
- * Removed queue walk, fixed for 64bitness.
- * Rewrote much of the code over time
- * Added indirect block lists
- * Handle 64K limits on many controllers
- * Don't use indirects on the Promise (breaks)
- * Heavily chop down the queue depths
- * Deepak Saxena:
- * Independent queues per IOP
- * Support for dynamic device creation/deletion
- * Code cleanup
- * Support for larger I/Os through merge* functions
- * (taken from DAC960 driver)
- * Boji T Kannanthanam:
- * Set the I2O Block devices to be detected in increasing
- * order of TIDs during boot.
- * Search and set the I2O block device that we boot off
- * from as the first device to be claimed (as /dev/i2o/hda)
- * Properly attach/detach I2O gendisk structure from the
- * system gendisk list. The I2O block devices now appear in
- * /proc/partitions.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor bugfixes for 2.6.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2o.h>
-#include <linux/mutex.h>
-
-#include <linux/mempool.h>
-
-#include <linux/genhd.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-
-#include <scsi/scsi.h>
-
-#include "i2o_block.h"
-
-#define OSM_NAME "block-osm"
-#define OSM_VERSION "1.325"
-#define OSM_DESCRIPTION "I2O Block Device OSM"
-
-static DEFINE_MUTEX(i2o_block_mutex);
-static struct i2o_driver i2o_block_driver;
-
-/* global Block OSM request mempool */
-static struct i2o_block_mempool i2o_blk_req_pool;
-
-/* Block OSM class handling definition */
-static struct i2o_class_id i2o_block_class_id[] = {
- {I2O_CLASS_RANDOM_BLOCK_STORAGE},
- {I2O_CLASS_END}
-};
-
-/**
- * i2o_block_device_free - free the memory of the I2O Block device
- * @dev: I2O Block device, which should be cleaned up
- *
- * Frees the request queue, gendisk and the i2o_block_device structure.
- */
-static void i2o_block_device_free(struct i2o_block_device *dev)
-{
- blk_cleanup_queue(dev->gd->queue);
-
- put_disk(dev->gd);
-
- kfree(dev);
-};
-
-/**
- * i2o_block_remove - remove the I2O Block device from the system again
- * @dev: I2O Block device which should be removed
- *
- * Remove gendisk from system and free all allocated memory.
- *
- * Always returns 0.
- */
-static int i2o_block_remove(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
-
- osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid,
- i2o_blk_dev->gd->disk_name);
-
- i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
-
- del_gendisk(i2o_blk_dev->gd);
-
- dev_set_drvdata(dev, NULL);
-
- i2o_device_claim_release(i2o_dev);
-
- i2o_block_device_free(i2o_blk_dev);
-
- return 0;
-};
-
-/**
- * i2o_block_device flush - Flush all dirty data of I2O device dev
- * @dev: I2O device which should be flushed
- *
- * Flushes all dirty data on device dev.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_device_flush(struct i2o_device *dev)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->
- lct_data.tid);
- msg->body[0] = cpu_to_le32(60 << 16);
- osm_debug("Flushing...\n");
-
- return i2o_msg_post_wait(dev->iop, msg, 60);
-};
-
-/**
- * i2o_block_device_mount - Mount (load) the media of device dev
- * @dev: I2O device which should receive the mount request
- * @media_id: Media Identifier
- *
- * Load a media into drive. Identifier should be set to -1, because the
- * spec does not support any other value.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev->
- lct_data.tid);
- msg->body[0] = cpu_to_le32(-1);
- msg->body[1] = cpu_to_le32(0x00000000);
- osm_debug("Mounting...\n");
-
- return i2o_msg_post_wait(dev->iop, msg, 2);
-};
-
-/**
- * i2o_block_device_lock - Locks the media of device dev
- * @dev: I2O device which should receive the lock request
- * @media_id: Media Identifier
- *
- * Lock media of device dev to prevent removal. The media identifier
- * should be set to -1, because the spec does not support any other value.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->
- lct_data.tid);
- msg->body[0] = cpu_to_le32(-1);
- osm_debug("Locking...\n");
-
- return i2o_msg_post_wait(dev->iop, msg, 2);
-};
-
-/**
- * i2o_block_device_unlock - Unlocks the media of device dev
- * @dev: I2O device which should receive the unlocked request
- * @media_id: Media Identifier
- *
- * Unlocks the media in device dev. The media identifier should be set to
- * -1, because the spec does not support any other value.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id)
-{
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->
- lct_data.tid);
- msg->body[0] = cpu_to_le32(media_id);
- osm_debug("Unlocking...\n");
-
- return i2o_msg_post_wait(dev->iop, msg, 2);
-};
-
-/**
- * i2o_block_device_power - Power management for device dev
- * @dev: I2O device which should receive the power management request
- * @op: Operation to send
- *
- * Send a power management request to the device dev.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_device_power(struct i2o_block_device *dev, u8 op)
-{
- struct i2o_device *i2o_dev = dev->i2o_dev;
- struct i2o_controller *c = i2o_dev->iop;
- struct i2o_message *msg;
- int rc;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->
- lct_data.tid);
- msg->body[0] = cpu_to_le32(op << 24);
- osm_debug("Power...\n");
-
- rc = i2o_msg_post_wait(c, msg, 60);
- if (!rc)
- dev->power = op;
-
- return rc;
-};
-
-/**
- * i2o_block_request_alloc - Allocate an I2O block request struct
- *
- * Allocates an I2O block request struct and initialize the list.
- *
- * Returns a i2o_block_request pointer on success or negative error code
- * on failure.
- */
-static inline struct i2o_block_request *i2o_block_request_alloc(void)
-{
- struct i2o_block_request *ireq;
-
- ireq = mempool_alloc(i2o_blk_req_pool.pool, GFP_ATOMIC);
- if (!ireq)
- return ERR_PTR(-ENOMEM);
-
- INIT_LIST_HEAD(&ireq->queue);
- sg_init_table(ireq->sg_table, I2O_MAX_PHYS_SEGMENTS);
-
- return ireq;
-};
-
-/**
- * i2o_block_request_free - Frees a I2O block request
- * @ireq: I2O block request which should be freed
- *
- * Frees the allocated memory (give it back to the request mempool).
- */
-static inline void i2o_block_request_free(struct i2o_block_request *ireq)
-{
- mempool_free(ireq, i2o_blk_req_pool.pool);
-};
-
-/**
- * i2o_block_sglist_alloc - Allocate the SG list and map it
- * @c: I2O controller to which the request belongs
- * @ireq: I2O block request
- * @mptr: message body pointer
- *
- * Builds the SG list and map it to be accessible by the controller.
- *
- * Returns 0 on failure or 1 on success.
- */
-static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
- struct i2o_block_request *ireq,
- u32 ** mptr)
-{
- int nents;
- enum dma_data_direction direction;
-
- ireq->dev = &c->pdev->dev;
- nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table);
-
- if (rq_data_dir(ireq->req) == READ)
- direction = PCI_DMA_FROMDEVICE;
- else
- direction = PCI_DMA_TODEVICE;
-
- ireq->sg_nents = nents;
-
- return i2o_dma_map_sg(c, ireq->sg_table, nents, direction, mptr);
-};
-
-/**
- * i2o_block_sglist_free - Frees the SG list
- * @ireq: I2O block request from which the SG should be freed
- *
- * Frees the SG list from the I2O block request.
- */
-static inline void i2o_block_sglist_free(struct i2o_block_request *ireq)
-{
- enum dma_data_direction direction;
-
- if (rq_data_dir(ireq->req) == READ)
- direction = PCI_DMA_FROMDEVICE;
- else
- direction = PCI_DMA_TODEVICE;
-
- dma_unmap_sg(ireq->dev, ireq->sg_table, ireq->sg_nents, direction);
-};
-
-/**
- * i2o_block_prep_req_fn - Allocates I2O block device specific struct
- * @q: request queue for the request
- * @req: the request to prepare
- *
- * Allocate the necessary i2o_block_request struct and connect it to
- * the request. This is needed that we not lose the SG list later on.
- *
- * Returns BLKPREP_OK on success or BLKPREP_DEFER on failure.
- */
-static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
-{
- struct i2o_block_device *i2o_blk_dev = q->queuedata;
- struct i2o_block_request *ireq;
-
- if (unlikely(!i2o_blk_dev)) {
- osm_err("block device already removed\n");
- return BLKPREP_KILL;
- }
-
- /* connect the i2o_block_request to the request */
- if (!req->special) {
- ireq = i2o_block_request_alloc();
- if (IS_ERR(ireq)) {
- osm_debug("unable to allocate i2o_block_request!\n");
- return BLKPREP_DEFER;
- }
-
- ireq->i2o_blk_dev = i2o_blk_dev;
- req->special = ireq;
- ireq->req = req;
- }
- /* do not come back here */
- req->cmd_flags |= REQ_DONTPREP;
-
- return BLKPREP_OK;
-};
-
-/**
- * i2o_block_delayed_request_fn - delayed request queue function
- * @work: the delayed request with the queue to start
- *
- * If the request queue is stopped for a disk, and there is no open
- * request, a new event is created, which calls this function to start
- * the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never
- * be started again.
- */
-static void i2o_block_delayed_request_fn(struct work_struct *work)
-{
- struct i2o_block_delayed_request *dreq =
- container_of(work, struct i2o_block_delayed_request,
- work.work);
- struct request_queue *q = dreq->queue;
- unsigned long flags;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
- kfree(dreq);
-};
-
-/**
- * i2o_block_end_request - Post-processing of completed commands
- * @req: request which should be completed
- * @error: 0 for success, < 0 for error
- * @nr_bytes: number of bytes to complete
- *
- * Mark the request as complete. The lock must not be held when entering.
- *
- */
-static void i2o_block_end_request(struct request *req, int error,
- int nr_bytes)
-{
- struct i2o_block_request *ireq = req->special;
- struct i2o_block_device *dev = ireq->i2o_blk_dev;
- struct request_queue *q = req->q;
- unsigned long flags;
-
- if (blk_end_request(req, error, nr_bytes))
- if (error)
- blk_end_request_all(req, -EIO);
-
- spin_lock_irqsave(q->queue_lock, flags);
-
- if (likely(dev)) {
- dev->open_queue_depth--;
- list_del(&ireq->queue);
- }
-
- blk_start_queue(q);
-
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- i2o_block_sglist_free(ireq);
- i2o_block_request_free(ireq);
-};
-
-/**
- * i2o_block_reply - Block OSM reply handler.
- * @c: I2O controller from which the message arrives
- * @m: message id of reply
- * @msg: the actual I2O message reply
- *
- * This function gets all the message replies.
- *
- */
-static int i2o_block_reply(struct i2o_controller *c, u32 m,
- struct i2o_message *msg)
-{
- struct request *req;
- int error = 0;
-
- req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
- if (unlikely(!req)) {
- osm_err("NULL reply received!\n");
- return -1;
- }
-
- /*
- * Lets see what is cooking. We stuffed the
- * request in the context.
- */
-
- if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
- u32 status = le32_to_cpu(msg->body[0]);
- /*
- * Device not ready means two things. One is that the
- * the thing went offline (but not a removal media)
- *
- * The second is that you have a SuperTrak 100 and the
- * firmware got constipated. Unlike standard i2o card
- * setups the supertrak returns an error rather than
- * blocking for the timeout in these cases.
- *
- * Don't stick a supertrak100 into cache aggressive modes
- */
-
- osm_err("TID %03x error status: 0x%02x, detailed status: "
- "0x%04x\n", (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
- status >> 24, status & 0xffff);
-
- req->errors++;
-
- error = -EIO;
- }
-
- i2o_block_end_request(req, error, le32_to_cpu(msg->body[1]));
-
- return 1;
-};
-
-static void i2o_block_event(struct work_struct *work)
-{
- struct i2o_event *evt = container_of(work, struct i2o_event, work);
- osm_debug("event received\n");
- kfree(evt);
-};
-
-/*
- * SCSI-CAM for ioctl geometry mapping
- * Duplicated with SCSI - this should be moved into somewhere common
- * perhaps genhd ?
- *
- * LBA -> CHS mapping table taken from:
- *
- * "Incorporating the I2O Architecture into BIOS for Intel Architecture
- * Platforms"
- *
- * This is an I2O document that is only available to I2O members,
- * not developers.
- *
- * From my understanding, this is how all the I2O cards do this
- *
- * Disk Size | Sectors | Heads | Cylinders
- * ---------------+---------+-------+-------------------
- * 1 < X <= 528M | 63 | 16 | X/(63 * 16 * 512)
- * 528M < X <= 1G | 63 | 32 | X/(63 * 32 * 512)
- * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
- * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512)
- *
- */
-#define BLOCK_SIZE_528M 1081344
-#define BLOCK_SIZE_1G 2097152
-#define BLOCK_SIZE_21G 4403200
-#define BLOCK_SIZE_42G 8806400
-#define BLOCK_SIZE_84G 17612800
-
-static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls,
- unsigned char *hds, unsigned char *secs)
-{
- unsigned long heads, sectors, cylinders;
-
- sectors = 63L; /* Maximize sectors per track */
- if (capacity <= BLOCK_SIZE_528M)
- heads = 16;
- else if (capacity <= BLOCK_SIZE_1G)
- heads = 32;
- else if (capacity <= BLOCK_SIZE_21G)
- heads = 64;
- else if (capacity <= BLOCK_SIZE_42G)
- heads = 128;
- else
- heads = 255;
-
- cylinders = (unsigned long)capacity / (heads * sectors);
-
- *cyls = (unsigned short)cylinders; /* Stuff return values */
- *secs = (unsigned char)sectors;
- *hds = (unsigned char)heads;
-}
-
-/**
- * i2o_block_open - Open the block device
- * @bdev: block device being opened
- * @mode: file open mode
- *
- * Power up the device, mount and lock the media. This function is called,
- * if the block device is opened for access.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_open(struct block_device *bdev, fmode_t mode)
-{
- struct i2o_block_device *dev = bdev->bd_disk->private_data;
-
- if (!dev->i2o_dev)
- return -ENODEV;
-
- mutex_lock(&i2o_block_mutex);
- if (dev->power > 0x1f)
- i2o_block_device_power(dev, 0x02);
-
- i2o_block_device_mount(dev->i2o_dev, -1);
-
- i2o_block_device_lock(dev->i2o_dev, -1);
-
- osm_debug("Ready.\n");
- mutex_unlock(&i2o_block_mutex);
-
- return 0;
-};
-
-/**
- * i2o_block_release - Release the I2O block device
- * @disk: gendisk device being released
- * @mode: file open mode
- *
- * Unlock and unmount the media, and power down the device. Gets called if
- * the block device is closed.
- */
-static void i2o_block_release(struct gendisk *disk, fmode_t mode)
-{
- struct i2o_block_device *dev = disk->private_data;
- u8 operation;
-
- /*
- * This is to deal with the case of an application
- * opening a device and then the device disappears while
- * it's in use, and then the application tries to release
- * it. ex: Unmounting a deleted RAID volume at reboot.
- * If we send messages, it will just cause FAILs since
- * the TID no longer exists.
- */
- if (!dev->i2o_dev)
- return;
-
- mutex_lock(&i2o_block_mutex);
- i2o_block_device_flush(dev->i2o_dev);
-
- i2o_block_device_unlock(dev->i2o_dev, -1);
-
- if (dev->flags & (1 << 3 | 1 << 4)) /* Removable */
- operation = 0x21;
- else
- operation = 0x24;
-
- i2o_block_device_power(dev, operation);
- mutex_unlock(&i2o_block_mutex);
-}
-
-static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- i2o_block_biosparam(get_capacity(bdev->bd_disk),
- &geo->cylinders, &geo->heads, &geo->sectors);
- return 0;
-}
-
-/**
- * i2o_block_ioctl - Issue device specific ioctl calls.
- * @bdev: block device being opened
- * @mode: file open mode
- * @cmd: ioctl command
- * @arg: arg
- *
- * Handles ioctl request for the block device.
- *
- * Return 0 on success or negative error on failure.
- */
-static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- struct gendisk *disk = bdev->bd_disk;
- struct i2o_block_device *dev = disk->private_data;
- int ret = -ENOTTY;
-
- /* Anyone capable of this syscall can do *real bad* things */
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- mutex_lock(&i2o_block_mutex);
- switch (cmd) {
- case BLKI2OGRSTRAT:
- ret = put_user(dev->rcache, (int __user *)arg);
- break;
- case BLKI2OGWSTRAT:
- ret = put_user(dev->wcache, (int __user *)arg);
- break;
- case BLKI2OSRSTRAT:
- ret = -EINVAL;
- if (arg < 0 || arg > CACHE_SMARTFETCH)
- break;
- dev->rcache = arg;
- ret = 0;
- break;
- case BLKI2OSWSTRAT:
- ret = -EINVAL;
- if (arg != 0
- && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK))
- break;
- dev->wcache = arg;
- ret = 0;
- break;
- }
- mutex_unlock(&i2o_block_mutex);
-
- return ret;
-};
-
-/**
- * i2o_block_check_events - Have we seen a media change?
- * @disk: gendisk which should be verified
- * @clearing: events being cleared
- *
- * Verifies if the media has changed.
- *
- * Returns 1 if the media was changed or 0 otherwise.
- */
-static unsigned int i2o_block_check_events(struct gendisk *disk,
- unsigned int clearing)
-{
- struct i2o_block_device *p = disk->private_data;
-
- if (p->media_change_flag) {
- p->media_change_flag = 0;
- return DISK_EVENT_MEDIA_CHANGE;
- }
- return 0;
-}
-
-/**
- * i2o_block_transfer - Transfer a request to/from the I2O controller
- * @req: the request which should be transferred
- *
- * This function converts the request into a I2O message. The necessary
- * DMA buffers are allocated and after everything is setup post the message
- * to the I2O controller. No cleanup is done by this function. It is done
- * on the interrupt side when the reply arrives.
- *
- * Return 0 on success or negative error code on failure.
- */
-static int i2o_block_transfer(struct request *req)
-{
- struct i2o_block_device *dev = req->rq_disk->private_data;
- struct i2o_controller *c;
- u32 tid;
- struct i2o_message *msg;
- u32 *mptr;
- struct i2o_block_request *ireq = req->special;
- u32 tcntxt;
- u32 sgl_offset = SGL_OFFSET_8;
- u32 ctl_flags = 0x00000000;
- int rc;
- u32 cmd;
-
- if (unlikely(!dev->i2o_dev)) {
- osm_err("transfer to removed drive\n");
- rc = -ENODEV;
- goto exit;
- }
-
- tid = dev->i2o_dev->lct_data.tid;
- c = dev->i2o_dev->iop;
-
- msg = i2o_msg_get(c);
- if (IS_ERR(msg)) {
- rc = PTR_ERR(msg);
- goto exit;
- }
-
- tcntxt = i2o_cntxt_list_add(c, req);
- if (!tcntxt) {
- rc = -ENOMEM;
- goto nop_msg;
- }
-
- msg->u.s.icntxt = cpu_to_le32(i2o_block_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(tcntxt);
-
- mptr = &msg->body[0];
-
- if (rq_data_dir(req) == READ) {
- cmd = I2O_CMD_BLOCK_READ << 24;
-
- switch (dev->rcache) {
- case CACHE_PREFETCH:
- ctl_flags = 0x201F0008;
- break;
-
- case CACHE_SMARTFETCH:
- if (blk_rq_sectors(req) > 16)
- ctl_flags = 0x201F0008;
- else
- ctl_flags = 0x001F0000;
- break;
-
- default:
- break;
- }
- } else {
- cmd = I2O_CMD_BLOCK_WRITE << 24;
-
- switch (dev->wcache) {
- case CACHE_WRITETHROUGH:
- ctl_flags = 0x001F0008;
- break;
- case CACHE_WRITEBACK:
- ctl_flags = 0x001F0010;
- break;
- case CACHE_SMARTBACK:
- if (blk_rq_sectors(req) > 16)
- ctl_flags = 0x001F0004;
- else
- ctl_flags = 0x001F0010;
- break;
- case CACHE_SMARTTHROUGH:
- if (blk_rq_sectors(req) > 16)
- ctl_flags = 0x001F0004;
- else
- ctl_flags = 0x001F0010;
- default:
- break;
- }
- }
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- if (c->adaptec) {
- u8 cmd[10];
- u32 scsi_flags;
- u16 hwsec;
-
- hwsec = queue_logical_block_size(req->q) >> KERNEL_SECTOR_SHIFT;
- memset(cmd, 0, 10);
-
- sgl_offset = SGL_OFFSET_12;
-
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid);
-
- *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
- *mptr++ = cpu_to_le32(tid);
-
- /*
- * ENABLE_DISCONNECT
- * SIMPLE_TAG
- * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
- */
- if (rq_data_dir(req) == READ) {
- cmd[0] = READ_10;
- scsi_flags = 0x60a0000a;
- } else {
- cmd[0] = WRITE_10;
- scsi_flags = 0xa0a0000a;
- }
-
- *mptr++ = cpu_to_le32(scsi_flags);
-
- *((u32 *) & cmd[2]) = cpu_to_be32(blk_rq_pos(req) * hwsec);
- *((u16 *) & cmd[7]) = cpu_to_be16(blk_rq_sectors(req) * hwsec);
-
- memcpy(mptr, cmd, 10);
- mptr += 4;
- *mptr++ = cpu_to_le32(blk_rq_bytes(req));
- } else
-#endif
- {
- msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
- *mptr++ = cpu_to_le32(ctl_flags);
- *mptr++ = cpu_to_le32(blk_rq_bytes(req));
- *mptr++ =
- cpu_to_le32((u32) (blk_rq_pos(req) << KERNEL_SECTOR_SHIFT));
- *mptr++ =
- cpu_to_le32(blk_rq_pos(req) >> (32 - KERNEL_SECTOR_SHIFT));
- }
-
- if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
- rc = -ENOMEM;
- goto context_remove;
- }
-
- msg->u.head[0] =
- cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset);
-
- list_add_tail(&ireq->queue, &dev->open_queue);
- dev->open_queue_depth++;
-
- i2o_msg_post(c, msg);
-
- return 0;
-
- context_remove:
- i2o_cntxt_list_remove(c, req);
-
- nop_msg:
- i2o_msg_nop(c, msg);
-
- exit:
- return rc;
-};
-
-/**
- * i2o_block_request_fn - request queue handling function
- * @q: request queue from which the request could be fetched
- *
- * Takes the next request from the queue, transfers it and if no error
- * occurs dequeue it from the queue. On arrival of the reply the message
- * will be processed further. If an error occurs requeue the request.
- */
-static void i2o_block_request_fn(struct request_queue *q)
-{
- struct request *req;
-
- while ((req = blk_peek_request(q)) != NULL) {
- if (req->cmd_type == REQ_TYPE_FS) {
- struct i2o_block_delayed_request *dreq;
- struct i2o_block_request *ireq = req->special;
- unsigned int queue_depth;
-
- queue_depth = ireq->i2o_blk_dev->open_queue_depth;
-
- if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) {
- if (!i2o_block_transfer(req)) {
- blk_start_request(req);
- continue;
- } else
- osm_info("transfer error\n");
- }
-
- if (queue_depth)
- break;
-
- /* stop the queue and retry later */
- dreq = kmalloc(sizeof(*dreq), GFP_ATOMIC);
- if (!dreq)
- continue;
-
- dreq->queue = q;
- INIT_DELAYED_WORK(&dreq->work,
- i2o_block_delayed_request_fn);
-
- if (!queue_delayed_work(i2o_block_driver.event_queue,
- &dreq->work,
- I2O_BLOCK_RETRY_TIME))
- kfree(dreq);
- else {
- blk_stop_queue(q);
- break;
- }
- } else {
- blk_start_request(req);
- __blk_end_request_all(req, -EIO);
- }
- }
-};
-
-/* I2O Block device operations definition */
-static const struct block_device_operations i2o_block_fops = {
- .owner = THIS_MODULE,
- .open = i2o_block_open,
- .release = i2o_block_release,
- .ioctl = i2o_block_ioctl,
- .compat_ioctl = i2o_block_ioctl,
- .getgeo = i2o_block_getgeo,
- .check_events = i2o_block_check_events,
-};
-
-/**
- * i2o_block_device_alloc - Allocate memory for a I2O Block device
- *
- * Allocate memory for the i2o_block_device struct, gendisk and request
- * queue and initialize them as far as no additional information is needed.
- *
- * Returns a pointer to the allocated I2O Block device on success or a
- * negative error code on failure.
- */
-static struct i2o_block_device *i2o_block_device_alloc(void)
-{
- struct i2o_block_device *dev;
- struct gendisk *gd;
- struct request_queue *queue;
- int rc;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- osm_err("Insufficient memory to allocate I2O Block disk.\n");
- rc = -ENOMEM;
- goto exit;
- }
-
- INIT_LIST_HEAD(&dev->open_queue);
- spin_lock_init(&dev->lock);
- dev->rcache = CACHE_PREFETCH;
- dev->wcache = CACHE_WRITEBACK;
-
- /* allocate a gendisk with 16 partitions */
- gd = alloc_disk(16);
- if (!gd) {
- osm_err("Insufficient memory to allocate gendisk.\n");
- rc = -ENOMEM;
- goto cleanup_dev;
- }
-
- /* initialize the request queue */
- queue = blk_init_queue(i2o_block_request_fn, &dev->lock);
- if (!queue) {
- osm_err("Insufficient memory to allocate request queue.\n");
- rc = -ENOMEM;
- goto cleanup_queue;
- }
-
- blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
-
- gd->major = I2O_MAJOR;
- gd->queue = queue;
- gd->fops = &i2o_block_fops;
- gd->private_data = dev;
-
- dev->gd = gd;
-
- return dev;
-
- cleanup_queue:
- put_disk(gd);
-
- cleanup_dev:
- kfree(dev);
-
- exit:
- return ERR_PTR(rc);
-};
-
-/**
- * i2o_block_probe - verify if dev is a I2O Block device and install it
- * @dev: device to verify if it is a I2O Block device
- *
- * We only verify if the user_tid of the device is 0xfff and then install
- * the device. Otherwise it is used by some other device (e. g. RAID).
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_block_probe(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_controller *c = i2o_dev->iop;
- struct i2o_block_device *i2o_blk_dev;
- struct gendisk *gd;
- struct request_queue *queue;
- static int unit = 0;
- int rc;
- u64 size;
- u32 blocksize;
- u16 body_size = 4;
- u16 power;
- unsigned short max_sectors;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- if (c->adaptec)
- body_size = 8;
-#endif
-
- if (c->limit_sectors)
- max_sectors = I2O_MAX_SECTORS_LIMITED;
- else
- max_sectors = I2O_MAX_SECTORS;
-
- /* skip devices which are used by IOP */
- if (i2o_dev->lct_data.user_tid != 0xfff) {
- osm_debug("skipping used device %03x\n", i2o_dev->lct_data.tid);
- return -ENODEV;
- }
-
- if (i2o_device_claim(i2o_dev)) {
- osm_warn("Unable to claim device. Installation aborted\n");
- rc = -EFAULT;
- goto exit;
- }
-
- i2o_blk_dev = i2o_block_device_alloc();
- if (IS_ERR(i2o_blk_dev)) {
- osm_err("could not alloc a new I2O block device");
- rc = PTR_ERR(i2o_blk_dev);
- goto claim_release;
- }
-
- i2o_blk_dev->i2o_dev = i2o_dev;
- dev_set_drvdata(dev, i2o_blk_dev);
-
- /* setup gendisk */
- gd = i2o_blk_dev->gd;
- gd->first_minor = unit << 4;
- sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit);
- gd->driverfs_dev = &i2o_dev->device;
-
- /* setup request queue */
- queue = gd->queue;
- queue->queuedata = i2o_blk_dev;
-
- blk_queue_max_hw_sectors(queue, max_sectors);
- blk_queue_max_segments(queue, i2o_sg_tablesize(c, body_size));
-
- osm_debug("max sectors = %d\n", queue->max_sectors);
- osm_debug("phys segments = %d\n", queue->max_phys_segments);
- osm_debug("max hw segments = %d\n", queue->max_hw_segments);
-
- /*
- * Ask for the current media data. If that isn't supported
- * then we ask for the device capacity data
- */
- if (!i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
- !i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
- blk_queue_logical_block_size(queue, le32_to_cpu(blocksize));
- } else
- osm_warn("unable to get blocksize of %s\n", gd->disk_name);
-
- if (!i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
- !i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
- set_capacity(gd, le64_to_cpu(size) >> KERNEL_SECTOR_SHIFT);
- } else
- osm_warn("could not get size of %s\n", gd->disk_name);
-
- if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
- i2o_blk_dev->power = power;
-
- i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff);
-
- add_disk(gd);
-
- unit++;
-
- osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
- i2o_blk_dev->gd->disk_name);
-
- return 0;
-
- claim_release:
- i2o_device_claim_release(i2o_dev);
-
- exit:
- return rc;
-};
-
-/* Block OSM driver struct */
-static struct i2o_driver i2o_block_driver = {
- .name = OSM_NAME,
- .event = i2o_block_event,
- .reply = i2o_block_reply,
- .classes = i2o_block_class_id,
- .driver = {
- .probe = i2o_block_probe,
- .remove = i2o_block_remove,
- },
-};
-
-/**
- * i2o_block_init - Block OSM initialization function
- *
- * Allocate the slab and mempool for request structs, registers i2o_block
- * block device and finally register the Block OSM in the I2O core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_block_init(void)
-{
- int rc;
- int size;
-
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- /* Allocate request mempool and slab */
- size = sizeof(struct i2o_block_request);
- i2o_blk_req_pool.slab = kmem_cache_create("i2o_block_req", size, 0,
- SLAB_HWCACHE_ALIGN, NULL);
- if (!i2o_blk_req_pool.slab) {
- osm_err("can't init request slab\n");
- rc = -ENOMEM;
- goto exit;
- }
-
- i2o_blk_req_pool.pool =
- mempool_create_slab_pool(I2O_BLOCK_REQ_MEMPOOL_SIZE,
- i2o_blk_req_pool.slab);
- if (!i2o_blk_req_pool.pool) {
- osm_err("can't init request mempool\n");
- rc = -ENOMEM;
- goto free_slab;
- }
-
- /* Register the block device interfaces */
- rc = register_blkdev(I2O_MAJOR, "i2o_block");
- if (rc) {
- osm_err("unable to register block device\n");
- goto free_mempool;
- }
-#ifdef MODULE
- osm_info("registered device at major %d\n", I2O_MAJOR);
-#endif
-
- /* Register Block OSM into I2O core */
- rc = i2o_driver_register(&i2o_block_driver);
- if (rc) {
- osm_err("Could not register Block driver\n");
- goto unregister_blkdev;
- }
-
- return 0;
-
- unregister_blkdev:
- unregister_blkdev(I2O_MAJOR, "i2o_block");
-
- free_mempool:
- mempool_destroy(i2o_blk_req_pool.pool);
-
- free_slab:
- kmem_cache_destroy(i2o_blk_req_pool.slab);
-
- exit:
- return rc;
-};
-
-/**
- * i2o_block_exit - Block OSM exit function
- *
- * Unregisters Block OSM from I2O core, unregisters i2o_block block device
- * and frees the mempool and slab.
- */
-static void __exit i2o_block_exit(void)
-{
- /* Unregister I2O Block OSM from I2O core */
- i2o_driver_unregister(&i2o_block_driver);
-
- /* Unregister block device */
- unregister_blkdev(I2O_MAJOR, "i2o_block");
-
- /* Free request mempool and slab */
- mempool_destroy(i2o_blk_req_pool.pool);
- kmem_cache_destroy(i2o_blk_req_pool.slab);
-};
-
-MODULE_AUTHOR("Red Hat");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_block_init);
-module_exit(i2o_block_exit);
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
deleted file mode 100644
index cf8873cbca3f..000000000000
--- a/drivers/message/i2o/i2o_block.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Block OSM structures/API
- *
- * Copyright (C) 1999-2002 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * For the purpose of avoiding doubt the preferred form of the work
- * for making modifications shall be a standards compliant form such
- * gzipped tar and not one requiring a proprietary or patent encumbered
- * tool to unpack.
- *
- * Fixes/additions:
- * Steve Ralston:
- * Multiple device handling error fixes,
- * Added a queue depth.
- * Alan Cox:
- * FC920 has an rmw bug. Dont or in the end marker.
- * Removed queue walk, fixed for 64bitness.
- * Rewrote much of the code over time
- * Added indirect block lists
- * Handle 64K limits on many controllers
- * Don't use indirects on the Promise (breaks)
- * Heavily chop down the queue depths
- * Deepak Saxena:
- * Independent queues per IOP
- * Support for dynamic device creation/deletion
- * Code cleanup
- * Support for larger I/Os through merge* functions
- * (taken from DAC960 driver)
- * Boji T Kannanthanam:
- * Set the I2O Block devices to be detected in increasing
- * order of TIDs during boot.
- * Search and set the I2O block device that we boot off
- * from as the first device to be claimed (as /dev/i2o/hda)
- * Properly attach/detach I2O gendisk structure from the
- * system gendisk list. The I2O block devices now appear in
- * /proc/partitions.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor bugfixes for 2.6.
- */
-
-#ifndef I2O_BLOCK_OSM_H
-#define I2O_BLOCK_OSM_H
-
-#define I2O_BLOCK_RETRY_TIME HZ/4
-#define I2O_BLOCK_MAX_OPEN_REQUESTS 50
-
-/* request queue sizes */
-#define I2O_BLOCK_REQ_MEMPOOL_SIZE 32
-
-#define KERNEL_SECTOR_SHIFT 9
-#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT)
-
-/* I2O Block OSM mempool struct */
-struct i2o_block_mempool {
- struct kmem_cache *slab;
- mempool_t *pool;
-};
-
-/* I2O Block device descriptor */
-struct i2o_block_device {
- struct i2o_device *i2o_dev; /* pointer to I2O device */
- struct gendisk *gd;
- spinlock_t lock; /* queue lock */
- struct list_head open_queue; /* list of transferred, but unfinished
- requests */
- unsigned int open_queue_depth; /* number of requests in the queue */
-
- int rcache; /* read cache flags */
- int wcache; /* write cache flags */
- int flags;
- u16 power; /* power state */
- int media_change_flag; /* media changed flag */
-};
-
-/* I2O Block device request */
-struct i2o_block_request {
- struct list_head queue;
- struct request *req; /* corresponding request */
- struct i2o_block_device *i2o_blk_dev; /* I2O block device */
- struct device *dev; /* device used for DMA */
- int sg_nents; /* number of SG elements */
- struct scatterlist sg_table[I2O_MAX_PHYS_SEGMENTS]; /* SG table */
-};
-
-/* I2O Block device delayed request */
-struct i2o_block_delayed_request {
- struct delayed_work work;
- struct request_queue *queue;
-};
-
-#endif
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
deleted file mode 100644
index a60c188c2bd9..000000000000
--- a/drivers/message/i2o/i2o_config.c
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * I2O Configuration Interface Driver
- *
- * (C) Copyright 1999-2002 Red Hat
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * Fixes/additions:
- * Deepak Saxena (04/20/1999):
- * Added basic ioctl() support
- * Deepak Saxena (06/07/1999):
- * Added software download ioctl (still testing)
- * Auvo Häkkinen (09/10/1999):
- * Changes to i2o_cfg_reply(), ioctl_parms()
- * Added ioct_validate()
- * Taneli Vähäkangas (09/30/1999):
- * Fixed ioctl_swdl()
- * Taneli Vähäkangas (10/04/1999):
- * Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
- * Deepak Saxena (11/18/1999):
- * Added event managmenet support
- * Alan Cox <alan@lxorguk.ukuu.org.uk>:
- * 2.4 rewrite ported to 2.5
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Added pass-thru support for Adaptec's raidutils
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/miscdevice.h>
-#include <linux/mutex.h>
-#include <linux/compat.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-
-#include "core.h"
-
-#define SG_TABLESIZE 30
-
-static DEFINE_MUTEX(i2o_cfg_mutex);
-static long i2o_cfg_ioctl(struct file *, unsigned int, unsigned long);
-
-static spinlock_t i2o_config_lock;
-
-#define MODINC(x,y) ((x) = ((x) + 1) % (y))
-
-struct sg_simple_element {
- u32 flag_count;
- u32 addr_bus;
-};
-
-struct i2o_cfg_info {
- struct file *fp;
- struct fasync_struct *fasync;
- struct i2o_evt_info event_q[I2O_EVT_Q_LEN];
- u16 q_in; // Queue head index
- u16 q_out; // Queue tail index
- u16 q_len; // Queue length
- u16 q_lost; // Number of lost events
- ulong q_id; // Event queue ID...used as tx_context
- struct i2o_cfg_info *next;
-};
-static struct i2o_cfg_info *open_files = NULL;
-static ulong i2o_cfg_info_id = 0;
-
-static int i2o_cfg_getiops(unsigned long arg)
-{
- struct i2o_controller *c;
- u8 __user *user_iop_table = (void __user *)arg;
- u8 tmp[MAX_I2O_CONTROLLERS];
- int ret = 0;
-
- memset(tmp, 0, MAX_I2O_CONTROLLERS);
-
- list_for_each_entry(c, &i2o_controllers, list)
- tmp[c->unit] = 1;
-
- if (copy_to_user(user_iop_table, tmp, MAX_I2O_CONTROLLERS))
- ret = -EFAULT;
-
- return ret;
-};
-
-static int i2o_cfg_gethrt(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg;
- struct i2o_cmd_hrtlct kcmd;
- i2o_hrt *hrt;
- int len;
- u32 reslen;
- int ret = 0;
-
- if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
- return -EFAULT;
-
- if (get_user(reslen, kcmd.reslen) < 0)
- return -EFAULT;
-
- if (kcmd.resbuf == NULL)
- return -EFAULT;
-
- c = i2o_find_iop(kcmd.iop);
- if (!c)
- return -ENXIO;
-
- hrt = (i2o_hrt *) c->hrt.virt;
-
- len = 8 + ((hrt->entry_len * hrt->num_entries) << 2);
-
- if (put_user(len, kcmd.reslen))
- ret = -EFAULT;
- else if (len > reslen)
- ret = -ENOBUFS;
- else if (copy_to_user(kcmd.resbuf, (void *)hrt, len))
- ret = -EFAULT;
-
- return ret;
-};
-
-static int i2o_cfg_getlct(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg;
- struct i2o_cmd_hrtlct kcmd;
- i2o_lct *lct;
- int len;
- int ret = 0;
- u32 reslen;
-
- if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
- return -EFAULT;
-
- if (get_user(reslen, kcmd.reslen) < 0)
- return -EFAULT;
-
- if (kcmd.resbuf == NULL)
- return -EFAULT;
-
- c = i2o_find_iop(kcmd.iop);
- if (!c)
- return -ENXIO;
-
- lct = (i2o_lct *) c->lct;
-
- len = (unsigned int)lct->table_size << 2;
- if (put_user(len, kcmd.reslen))
- ret = -EFAULT;
- else if (len > reslen)
- ret = -ENOBUFS;
- else if (copy_to_user(kcmd.resbuf, lct, len))
- ret = -EFAULT;
-
- return ret;
-};
-
-static int i2o_cfg_parms(unsigned long arg, unsigned int type)
-{
- int ret = 0;
- struct i2o_controller *c;
- struct i2o_device *dev;
- struct i2o_cmd_psetget __user *cmd =
- (struct i2o_cmd_psetget __user *)arg;
- struct i2o_cmd_psetget kcmd;
- u32 reslen;
- u8 *ops;
- u8 *res;
- int len = 0;
-
- u32 i2o_cmd = (type == I2OPARMGET ?
- I2O_CMD_UTIL_PARAMS_GET : I2O_CMD_UTIL_PARAMS_SET);
-
- if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_psetget)))
- return -EFAULT;
-
- if (get_user(reslen, kcmd.reslen))
- return -EFAULT;
-
- c = i2o_find_iop(kcmd.iop);
- if (!c)
- return -ENXIO;
-
- dev = i2o_iop_find_device(c, kcmd.tid);
- if (!dev)
- return -ENXIO;
-
- /*
- * Stop users being able to try and allocate arbitrary amounts
- * of DMA space. 64K is way more than sufficient for this.
- */
- if (kcmd.oplen > 65536)
- return -EMSGSIZE;
-
- ops = memdup_user(kcmd.opbuf, kcmd.oplen);
- if (IS_ERR(ops))
- return PTR_ERR(ops);
-
- /*
- * It's possible to have a _very_ large table
- * and that the user asks for all of it at once...
- */
- res = kmalloc(65536, GFP_KERNEL);
- if (!res) {
- kfree(ops);
- return -ENOMEM;
- }
-
- len = i2o_parm_issue(dev, i2o_cmd, ops, kcmd.oplen, res, 65536);
- kfree(ops);
-
- if (len < 0) {
- kfree(res);
- return -EAGAIN;
- }
-
- if (put_user(len, kcmd.reslen))
- ret = -EFAULT;
- else if (len > reslen)
- ret = -ENOBUFS;
- else if (copy_to_user(kcmd.resbuf, res, len))
- ret = -EFAULT;
-
- kfree(res);
-
- return ret;
-};
-
-static int i2o_cfg_swdl(unsigned long arg)
-{
- struct i2o_sw_xfer kxfer;
- struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
- unsigned char maxfrag = 0, curfrag = 1;
- struct i2o_dma buffer;
- struct i2o_message *msg;
- unsigned int status = 0, swlen = 0, fragsize = 8192;
- struct i2o_controller *c;
-
- if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if (get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- if (get_user(maxfrag, kxfer.maxfrag) < 0)
- return -EFAULT;
-
- if (get_user(curfrag, kxfer.curfrag) < 0)
- return -EFAULT;
-
- if (curfrag == maxfrag)
- fragsize = swlen - (maxfrag - 1) * 8192;
-
- if (!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize))
- return -EFAULT;
-
- c = i2o_find_iop(kxfer.iop);
- if (!c)
- return -ENXIO;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
- i2o_msg_nop(c, msg);
- return -ENOMEM;
- }
-
- if (__copy_from_user(buffer.virt, kxfer.buf, fragsize)) {
- i2o_msg_nop(c, msg);
- i2o_dma_free(&c->pdev->dev, &buffer);
- return -EFAULT;
- }
-
- msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
- msg->u.head[3] = cpu_to_le32(0);
- msg->body[0] =
- cpu_to_le32((((u32) kxfer.flags) << 24) | (((u32) kxfer.
- sw_type) << 16) |
- (((u32) maxfrag) << 8) | (((u32) curfrag)));
- msg->body[1] = cpu_to_le32(swlen);
- msg->body[2] = cpu_to_le32(kxfer.sw_id);
- msg->body[3] = cpu_to_le32(0xD0000000 | fragsize);
- msg->body[4] = cpu_to_le32(buffer.phys);
-
- osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_msg_post_wait_mem(c, msg, 60, &buffer);
-
- if (status != -ETIMEDOUT)
- i2o_dma_free(&c->pdev->dev, &buffer);
-
- if (status != I2O_POST_WAIT_OK) {
- // it fails if you try and send frags out of order
- // and for some yet unknown reasons too
- osm_info("swdl failed, DetailedStatus = %d\n", status);
- return status;
- }
-
- return 0;
-};
-
-static int i2o_cfg_swul(unsigned long arg)
-{
- struct i2o_sw_xfer kxfer;
- struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
- unsigned char maxfrag = 0, curfrag = 1;
- struct i2o_dma buffer;
- struct i2o_message *msg;
- unsigned int status = 0, swlen = 0, fragsize = 8192;
- struct i2o_controller *c;
- int ret = 0;
-
- if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if (get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- if (get_user(maxfrag, kxfer.maxfrag) < 0)
- return -EFAULT;
-
- if (get_user(curfrag, kxfer.curfrag) < 0)
- return -EFAULT;
-
- if (curfrag == maxfrag)
- fragsize = swlen - (maxfrag - 1) * 8192;
-
- if (!kxfer.buf)
- return -EFAULT;
-
- c = i2o_find_iop(kxfer.iop);
- if (!c)
- return -ENXIO;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
- i2o_msg_nop(c, msg);
- return -ENOMEM;
- }
-
- msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID);
- msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
- msg->u.head[3] = cpu_to_le32(0);
- msg->body[0] =
- cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.
- sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag);
- msg->body[1] = cpu_to_le32(swlen);
- msg->body[2] = cpu_to_le32(kxfer.sw_id);
- msg->body[3] = cpu_to_le32(0xD0000000 | fragsize);
- msg->body[4] = cpu_to_le32(buffer.phys);
-
- osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
- status = i2o_msg_post_wait_mem(c, msg, 60, &buffer);
-
- if (status != I2O_POST_WAIT_OK) {
- if (status != -ETIMEDOUT)
- i2o_dma_free(&c->pdev->dev, &buffer);
-
- osm_info("swul failed, DetailedStatus = %d\n", status);
- return status;
- }
-
- if (copy_to_user(kxfer.buf, buffer.virt, fragsize))
- ret = -EFAULT;
-
- i2o_dma_free(&c->pdev->dev, &buffer);
-
- return ret;
-}
-
-static int i2o_cfg_swdel(unsigned long arg)
-{
- struct i2o_controller *c;
- struct i2o_sw_xfer kxfer;
- struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
- struct i2o_message *msg;
- unsigned int swlen;
- int token;
-
- if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
- return -EFAULT;
-
- if (get_user(swlen, kxfer.swlen) < 0)
- return -EFAULT;
-
- c = i2o_find_iop(kxfer.iop);
- if (!c)
- return -ENXIO;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID);
- msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
- msg->u.head[3] = cpu_to_le32(0);
- msg->body[0] =
- cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16);
- msg->body[1] = cpu_to_le32(swlen);
- msg->body[2] = cpu_to_le32(kxfer.sw_id);
-
- token = i2o_msg_post_wait(c, msg, 10);
-
- if (token != I2O_POST_WAIT_OK) {
- osm_info("swdel failed, DetailedStatus = %d\n", token);
- return -ETIMEDOUT;
- }
-
- return 0;
-};
-
-static int i2o_cfg_validate(unsigned long arg)
-{
- int token;
- int iop = (int)arg;
- struct i2o_message *msg;
- struct i2o_controller *c;
-
- c = i2o_find_iop(iop);
- if (!c)
- return -ENXIO;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop);
- msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
- msg->u.head[3] = cpu_to_le32(0);
-
- token = i2o_msg_post_wait(c, msg, 10);
-
- if (token != I2O_POST_WAIT_OK) {
- osm_info("Can't validate configuration, ErrorStatus = %d\n",
- token);
- return -ETIMEDOUT;
- }
-
- return 0;
-};
-
-static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp)
-{
- struct i2o_message *msg;
- struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg;
- struct i2o_evt_id kdesc;
- struct i2o_controller *c;
- struct i2o_device *d;
-
- if (copy_from_user(&kdesc, pdesc, sizeof(struct i2o_evt_id)))
- return -EFAULT;
-
- /* IOP exists? */
- c = i2o_find_iop(kdesc.iop);
- if (!c)
- return -ENXIO;
-
- /* Device exists? */
- d = i2o_iop_find_device(c, kdesc.tid);
- if (!d)
- return -ENODEV;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 |
- kdesc.tid);
- msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
- msg->u.head[3] = cpu_to_le32(i2o_cntxt_list_add(c, fp->private_data));
- msg->body[0] = cpu_to_le32(kdesc.evt_mask);
-
- i2o_msg_post(c, msg);
-
- return 0;
-}
-
-static int i2o_cfg_evt_get(unsigned long arg, struct file *fp)
-{
- struct i2o_cfg_info *p = NULL;
- struct i2o_evt_get __user *uget = (struct i2o_evt_get __user *)arg;
- struct i2o_evt_get kget;
- unsigned long flags;
-
- for (p = open_files; p; p = p->next)
- if (p->q_id == (ulong) fp->private_data)
- break;
-
- if (!p->q_len)
- return -ENOENT;
-
- memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info));
- MODINC(p->q_out, I2O_EVT_Q_LEN);
- spin_lock_irqsave(&i2o_config_lock, flags);
- p->q_len--;
- kget.pending = p->q_len;
- kget.lost = p->q_lost;
- spin_unlock_irqrestore(&i2o_config_lock, flags);
-
- if (copy_to_user(uget, &kget, sizeof(struct i2o_evt_get)))
- return -EFAULT;
- return 0;
-}
-
-#ifdef CONFIG_COMPAT
-static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
- unsigned long arg)
-{
- struct i2o_cmd_passthru32 __user *cmd;
- struct i2o_controller *c;
- u32 __user *user_msg;
- u32 *reply = NULL;
- u32 __user *user_reply = NULL;
- u32 size = 0;
- u32 reply_size = 0;
- u32 rcode = 0;
- struct i2o_dma sg_list[SG_TABLESIZE];
- u32 sg_offset = 0;
- u32 sg_count = 0;
- u32 i = 0;
- u32 sg_index = 0;
- i2o_status_block *sb;
- struct i2o_message *msg;
- unsigned int iop;
-
- cmd = (struct i2o_cmd_passthru32 __user *)arg;
-
- if (get_user(iop, &cmd->iop) || get_user(i, &cmd->msg))
- return -EFAULT;
-
- user_msg = compat_ptr(i);
-
- c = i2o_find_iop(iop);
- if (!c) {
- osm_debug("controller %d not found\n", iop);
- return -ENXIO;
- }
-
- sb = c->status_block.virt;
-
- if (get_user(size, &user_msg[0])) {
- osm_warn("unable to get size!\n");
- return -EFAULT;
- }
- size = size >> 16;
-
- if (size > sb->inbound_frame_size) {
- osm_warn("size of message > inbound_frame_size");
- return -EFAULT;
- }
-
- user_reply = &user_msg[size];
-
- size <<= 2; // Convert to bytes
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- rcode = -EFAULT;
- /* Copy in the user's I2O command */
- if (copy_from_user(msg, user_msg, size)) {
- osm_warn("unable to copy user message\n");
- goto out;
- }
- i2o_dump_message(msg);
-
- if (get_user(reply_size, &user_reply[0]) < 0)
- goto out;
-
- reply_size >>= 16;
- reply_size <<= 2;
-
- rcode = -ENOMEM;
- reply = kzalloc(reply_size, GFP_KERNEL);
- if (!reply) {
- printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
- c->name);
- goto out;
- }
-
- sg_offset = (msg->u.head[0] >> 4) & 0x0f;
-
- memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
- if (sg_offset) {
- struct sg_simple_element *sg;
-
- if (sg_offset * 4 >= size) {
- rcode = -EFAULT;
- goto cleanup;
- }
- // TODO 64bit fix
- sg = (struct sg_simple_element *)((&msg->u.head[0]) +
- sg_offset);
- sg_count =
- (size - sg_offset * 4) / sizeof(struct sg_simple_element);
- if (sg_count > SG_TABLESIZE) {
- printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
- c->name, sg_count);
- rcode = -EINVAL;
- goto cleanup;
- }
-
- for (i = 0; i < sg_count; i++) {
- int sg_size;
- struct i2o_dma *p;
-
- if (!(sg[i].flag_count & 0x10000000
- /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) {
- printk(KERN_DEBUG
- "%s:Bad SG element %d - not simple (%x)\n",
- c->name, i, sg[i].flag_count);
- rcode = -EINVAL;
- goto cleanup;
- }
- sg_size = sg[i].flag_count & 0xffffff;
- p = &(sg_list[sg_index]);
- /* Allocate memory for the transfer */
- if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
- printk(KERN_DEBUG
- "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
- c->name, sg_size, i, sg_count);
- rcode = -ENOMEM;
- goto sg_list_cleanup;
- }
- sg_index++;
- /* Copy in the user's SG buffer if necessary */
- if (sg[i].
- flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
- // TODO 64bit fix
- if (copy_from_user
- (p->virt,
- (void __user *)(unsigned long)sg[i].
- addr_bus, sg_size)) {
- printk(KERN_DEBUG
- "%s: Could not copy SG buf %d FROM user\n",
- c->name, i);
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- }
- //TODO 64bit fix
- sg[i].addr_bus = (u32) p->phys;
- }
- }
-
- rcode = i2o_msg_post_wait(c, msg, 60);
- msg = NULL;
- if (rcode) {
- reply[4] = ((u32) rcode) << 24;
- goto sg_list_cleanup;
- }
-
- if (sg_offset) {
- u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE];
- /* Copy back the Scatter Gather buffers back to user space */
- u32 j;
- // TODO 64bit fix
- struct sg_simple_element *sg;
- int sg_size;
-
- // re-acquire the original message to handle correctly the sg copy operation
- memset(&rmsg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
- // get user msg size in u32s
- if (get_user(size, &user_msg[0])) {
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- size = size >> 16;
- size *= 4;
- if (size > sizeof(rmsg)) {
- rcode = -EINVAL;
- goto sg_list_cleanup;
- }
-
- /* Copy in the user's I2O command */
- if (copy_from_user(rmsg, user_msg, size)) {
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- sg_count =
- (size - sg_offset * 4) / sizeof(struct sg_simple_element);
-
- // TODO 64bit fix
- sg = (struct sg_simple_element *)(rmsg + sg_offset);
- for (j = 0; j < sg_count; j++) {
- /* Copy out the SG list to user's buffer if necessary */
- if (!
- (sg[j].
- flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) {
- sg_size = sg[j].flag_count & 0xffffff;
- // TODO 64bit fix
- if (copy_to_user
- ((void __user *)(u64) sg[j].addr_bus,
- sg_list[j].virt, sg_size)) {
- printk(KERN_WARNING
- "%s: Could not copy %p TO user %x\n",
- c->name, sg_list[j].virt,
- sg[j].addr_bus);
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- }
- }
- }
-
-sg_list_cleanup:
- /* Copy back the reply to user space */
- if (reply_size) {
- // we wrote our own values for context - now restore the user supplied ones
- if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
- printk(KERN_WARNING
- "%s: Could not copy message context FROM user\n",
- c->name);
- rcode = -EFAULT;
- }
- if (copy_to_user(user_reply, reply, reply_size)) {
- printk(KERN_WARNING
- "%s: Could not copy reply TO user\n", c->name);
- rcode = -EFAULT;
- }
- }
- for (i = 0; i < sg_index; i++)
- i2o_dma_free(&c->pdev->dev, &sg_list[i]);
-
-cleanup:
- kfree(reply);
-out:
- if (msg)
- i2o_msg_nop(c, msg);
- return rcode;
-}
-
-static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
- unsigned long arg)
-{
- int ret;
- mutex_lock(&i2o_cfg_mutex);
- switch (cmd) {
- case I2OGETIOPS:
- ret = i2o_cfg_ioctl(file, cmd, arg);
- break;
- case I2OPASSTHRU32:
- ret = i2o_cfg_passthru32(file, cmd, arg);
- break;
- default:
- ret = -ENOIOCTLCMD;
- break;
- }
- mutex_unlock(&i2o_cfg_mutex);
- return ret;
-}
-
-#endif
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC
-static int i2o_cfg_passthru(unsigned long arg)
-{
- struct i2o_cmd_passthru __user *cmd =
- (struct i2o_cmd_passthru __user *)arg;
- struct i2o_controller *c;
- u32 __user *user_msg;
- u32 *reply = NULL;
- u32 __user *user_reply = NULL;
- u32 size = 0;
- u32 reply_size = 0;
- u32 rcode = 0;
- struct i2o_dma sg_list[SG_TABLESIZE];
- u32 sg_offset = 0;
- u32 sg_count = 0;
- int sg_index = 0;
- u32 i = 0;
- i2o_status_block *sb;
- struct i2o_message *msg;
- unsigned int iop;
-
- if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg))
- return -EFAULT;
-
- c = i2o_find_iop(iop);
- if (!c) {
- osm_warn("controller %d not found\n", iop);
- return -ENXIO;
- }
-
- sb = c->status_block.virt;
-
- if (get_user(size, &user_msg[0]))
- return -EFAULT;
- size = size >> 16;
-
- if (size > sb->inbound_frame_size) {
- osm_warn("size of message > inbound_frame_size");
- return -EFAULT;
- }
-
- user_reply = &user_msg[size];
-
- size <<= 2; // Convert to bytes
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- rcode = -EFAULT;
- /* Copy in the user's I2O command */
- if (copy_from_user(msg, user_msg, size))
- goto out;
-
- if (get_user(reply_size, &user_reply[0]) < 0)
- goto out;
-
- reply_size >>= 16;
- reply_size <<= 2;
-
- reply = kzalloc(reply_size, GFP_KERNEL);
- if (!reply) {
- printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
- c->name);
- rcode = -ENOMEM;
- goto out;
- }
-
- sg_offset = (msg->u.head[0] >> 4) & 0x0f;
-
- memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
- if (sg_offset) {
- struct sg_simple_element *sg;
- struct i2o_dma *p;
-
- if (sg_offset * 4 >= size) {
- rcode = -EFAULT;
- goto cleanup;
- }
- // TODO 64bit fix
- sg = (struct sg_simple_element *)((&msg->u.head[0]) +
- sg_offset);
- sg_count =
- (size - sg_offset * 4) / sizeof(struct sg_simple_element);
- if (sg_count > SG_TABLESIZE) {
- printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
- c->name, sg_count);
- rcode = -EINVAL;
- goto cleanup;
- }
-
- for (i = 0; i < sg_count; i++) {
- int sg_size;
-
- if (!(sg[i].flag_count & 0x10000000
- /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) {
- printk(KERN_DEBUG
- "%s:Bad SG element %d - not simple (%x)\n",
- c->name, i, sg[i].flag_count);
- rcode = -EINVAL;
- goto sg_list_cleanup;
- }
- sg_size = sg[i].flag_count & 0xffffff;
- p = &(sg_list[sg_index]);
- if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
- /* Allocate memory for the transfer */
- printk(KERN_DEBUG
- "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
- c->name, sg_size, i, sg_count);
- rcode = -ENOMEM;
- goto sg_list_cleanup;
- }
- sg_index++;
- /* Copy in the user's SG buffer if necessary */
- if (sg[i].
- flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
- // TODO 64bit fix
- if (copy_from_user
- (p->virt, (void __user *)sg[i].addr_bus,
- sg_size)) {
- printk(KERN_DEBUG
- "%s: Could not copy SG buf %d FROM user\n",
- c->name, i);
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- }
- sg[i].addr_bus = p->phys;
- }
- }
-
- rcode = i2o_msg_post_wait(c, msg, 60);
- msg = NULL;
- if (rcode) {
- reply[4] = ((u32) rcode) << 24;
- goto sg_list_cleanup;
- }
-
- if (sg_offset) {
- u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE];
- /* Copy back the Scatter Gather buffers back to user space */
- u32 j;
- // TODO 64bit fix
- struct sg_simple_element *sg;
- int sg_size;
-
- // re-acquire the original message to handle correctly the sg copy operation
- memset(&rmsg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
- // get user msg size in u32s
- if (get_user(size, &user_msg[0])) {
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- size = size >> 16;
- size *= 4;
- if (size > sizeof(rmsg)) {
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
-
- /* Copy in the user's I2O command */
- if (copy_from_user(rmsg, user_msg, size)) {
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- sg_count =
- (size - sg_offset * 4) / sizeof(struct sg_simple_element);
-
- // TODO 64bit fix
- sg = (struct sg_simple_element *)(rmsg + sg_offset);
- for (j = 0; j < sg_count; j++) {
- /* Copy out the SG list to user's buffer if necessary */
- if (!
- (sg[j].
- flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) {
- sg_size = sg[j].flag_count & 0xffffff;
- // TODO 64bit fix
- if (copy_to_user
- ((void __user *)sg[j].addr_bus, sg_list[j].virt,
- sg_size)) {
- printk(KERN_WARNING
- "%s: Could not copy %p TO user %x\n",
- c->name, sg_list[j].virt,
- sg[j].addr_bus);
- rcode = -EFAULT;
- goto sg_list_cleanup;
- }
- }
- }
- }
-
-sg_list_cleanup:
- /* Copy back the reply to user space */
- if (reply_size) {
- // we wrote our own values for context - now restore the user supplied ones
- if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
- printk(KERN_WARNING
- "%s: Could not copy message context FROM user\n",
- c->name);
- rcode = -EFAULT;
- }
- if (copy_to_user(user_reply, reply, reply_size)) {
- printk(KERN_WARNING
- "%s: Could not copy reply TO user\n", c->name);
- rcode = -EFAULT;
- }
- }
-
- for (i = 0; i < sg_index; i++)
- i2o_dma_free(&c->pdev->dev, &sg_list[i]);
-
-cleanup:
- kfree(reply);
-out:
- if (msg)
- i2o_msg_nop(c, msg);
- return rcode;
-}
-#endif
-
-/*
- * IOCTL Handler
- */
-static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- mutex_lock(&i2o_cfg_mutex);
- switch (cmd) {
- case I2OGETIOPS:
- ret = i2o_cfg_getiops(arg);
- break;
-
- case I2OHRTGET:
- ret = i2o_cfg_gethrt(arg);
- break;
-
- case I2OLCTGET:
- ret = i2o_cfg_getlct(arg);
- break;
-
- case I2OPARMSET:
- ret = i2o_cfg_parms(arg, I2OPARMSET);
- break;
-
- case I2OPARMGET:
- ret = i2o_cfg_parms(arg, I2OPARMGET);
- break;
-
- case I2OSWDL:
- ret = i2o_cfg_swdl(arg);
- break;
-
- case I2OSWUL:
- ret = i2o_cfg_swul(arg);
- break;
-
- case I2OSWDEL:
- ret = i2o_cfg_swdel(arg);
- break;
-
- case I2OVALIDATE:
- ret = i2o_cfg_validate(arg);
- break;
-
- case I2OEVTREG:
- ret = i2o_cfg_evt_reg(arg, fp);
- break;
-
- case I2OEVTGET:
- ret = i2o_cfg_evt_get(arg, fp);
- break;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- case I2OPASSTHRU:
- ret = i2o_cfg_passthru(arg);
- break;
-#endif
-
- default:
- osm_debug("unknown ioctl called!\n");
- ret = -EINVAL;
- }
- mutex_unlock(&i2o_cfg_mutex);
- return ret;
-}
-
-static int cfg_open(struct inode *inode, struct file *file)
-{
- struct i2o_cfg_info *tmp = kmalloc(sizeof(struct i2o_cfg_info),
- GFP_KERNEL);
- unsigned long flags;
-
- if (!tmp)
- return -ENOMEM;
-
- mutex_lock(&i2o_cfg_mutex);
- file->private_data = (void *)(i2o_cfg_info_id++);
- tmp->fp = file;
- tmp->fasync = NULL;
- tmp->q_id = (ulong) file->private_data;
- tmp->q_len = 0;
- tmp->q_in = 0;
- tmp->q_out = 0;
- tmp->q_lost = 0;
- tmp->next = open_files;
-
- spin_lock_irqsave(&i2o_config_lock, flags);
- open_files = tmp;
- spin_unlock_irqrestore(&i2o_config_lock, flags);
- mutex_unlock(&i2o_cfg_mutex);
-
- return 0;
-}
-
-static int cfg_fasync(int fd, struct file *fp, int on)
-{
- ulong id = (ulong) fp->private_data;
- struct i2o_cfg_info *p;
- int ret = -EBADF;
-
- mutex_lock(&i2o_cfg_mutex);
- for (p = open_files; p; p = p->next)
- if (p->q_id == id)
- break;
-
- if (p)
- ret = fasync_helper(fd, fp, on, &p->fasync);
- mutex_unlock(&i2o_cfg_mutex);
- return ret;
-}
-
-static int cfg_release(struct inode *inode, struct file *file)
-{
- ulong id = (ulong) file->private_data;
- struct i2o_cfg_info *p, **q;
- unsigned long flags;
-
- mutex_lock(&i2o_cfg_mutex);
- spin_lock_irqsave(&i2o_config_lock, flags);
- for (q = &open_files; (p = *q) != NULL; q = &p->next) {
- if (p->q_id == id) {
- *q = p->next;
- kfree(p);
- break;
- }
- }
- spin_unlock_irqrestore(&i2o_config_lock, flags);
- mutex_unlock(&i2o_cfg_mutex);
-
- return 0;
-}
-
-static const struct file_operations config_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = i2o_cfg_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = i2o_cfg_compat_ioctl,
-#endif
- .open = cfg_open,
- .release = cfg_release,
- .fasync = cfg_fasync,
-};
-
-static struct miscdevice i2o_miscdev = {
- I2O_MINOR,
- "i2octl",
- &config_fops
-};
-
-static int __init i2o_config_old_init(void)
-{
- spin_lock_init(&i2o_config_lock);
-
- if (misc_register(&i2o_miscdev) < 0) {
- osm_err("can't register device.\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static void i2o_config_old_exit(void)
-{
- misc_deregister(&i2o_miscdev);
-}
-
-MODULE_AUTHOR("Red Hat Software");
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
deleted file mode 100644
index b7d87cd227a9..000000000000
--- a/drivers/message/i2o/i2o_proc.c
+++ /dev/null
@@ -1,2045 +0,0 @@
-/*
- * procfs handler for Linux I2O subsystem
- *
- * (c) Copyright 1999 Deepak Saxena
- *
- * Originally written by Deepak Saxena(deepak@plexity.net)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This is an initial test release. The code is based on the design of the
- * ide procfs system (drivers/block/ide-proc.c). Some code taken from
- * i2o-core module by Alan Cox.
- *
- * DISCLAIMER: This code is still under development/test and may cause
- * your system to behave unpredictably. Use at your own discretion.
- *
- *
- * Fixes/additions:
- * Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
- * Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
- * University of Helsinki, Department of Computer Science
- * LAN entries
- * Markus Lidel <Markus.Lidel@shadowconnect.com>
- * Changes for new I2O API
- */
-
-#define OSM_NAME "proc-osm"
-#define OSM_VERSION "1.316"
-#define OSM_DESCRIPTION "I2O ProcFS OSM"
-
-#define I2O_MAX_MODULES 4
-// FIXME!
-#define FMT_U64_HEX "0x%08x%08x"
-#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64))
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-/* Structure used to define /proc entries */
-typedef struct _i2o_proc_entry_t {
- char *name; /* entry name */
- umode_t mode; /* mode */
- const struct file_operations *fops; /* open function */
-} i2o_proc_entry;
-
-/* global I2O /proc/i2o entry */
-static struct proc_dir_entry *i2o_proc_dir_root;
-
-/* proc OSM driver struct */
-static struct i2o_driver i2o_proc_driver = {
- .name = OSM_NAME,
-};
-
-static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len)
-{
- int i;
-
- /* 19990419 -sralston
- * The I2O v1.5 (and v2.0 so far) "official specification"
- * got serial numbers WRONG!
- * Apparently, and despite what Section 3.4.4 says and
- * Figure 3-35 shows (pg 3-39 in the pdf doc),
- * the convention / consensus seems to be:
- * + First byte is SNFormat
- * + Second byte is SNLen (but only if SNFormat==7 (?))
- * + (v2.0) SCSI+BS may use IEEE Registered (64 or 128 bit) format
- */
- switch (serialno[0]) {
- case I2O_SNFORMAT_BINARY: /* Binary */
- seq_printf(seq, "0x");
- for (i = 0; i < serialno[1]; i++) {
- seq_printf(seq, "%02X", serialno[2 + i]);
- }
- break;
-
- case I2O_SNFORMAT_ASCII: /* ASCII */
- if (serialno[1] < ' ') { /* printable or SNLen? */
- /* sanity */
- max_len =
- (max_len < serialno[1]) ? max_len : serialno[1];
- serialno[1 + max_len] = '\0';
-
- /* just print it */
- seq_printf(seq, "%s", &serialno[2]);
- } else {
- /* print chars for specified length */
- for (i = 0; i < serialno[1]; i++) {
- seq_printf(seq, "%c", serialno[2 + i]);
- }
- }
- break;
-
- case I2O_SNFORMAT_UNICODE: /* UNICODE */
- seq_printf(seq, "UNICODE Format. Can't Display\n");
- break;
-
- case I2O_SNFORMAT_LAN48_MAC: /* LAN-48 MAC Address */
- seq_printf(seq, "LAN-48 MAC address @ %pM", &serialno[2]);
- break;
-
- case I2O_SNFORMAT_WAN: /* WAN MAC Address */
- /* FIXME: Figure out what a WAN access address looks like?? */
- seq_printf(seq, "WAN Access Address");
- break;
-
-/* plus new in v2.0 */
- case I2O_SNFORMAT_LAN64_MAC: /* LAN-64 MAC Address */
- /* FIXME: Figure out what a LAN-64 address really looks like?? */
- seq_printf(seq,
- "LAN-64 MAC address @ [?:%02X:%02X:?] %pM",
- serialno[8], serialno[9], &serialno[2]);
- break;
-
- case I2O_SNFORMAT_DDM: /* I2O DDM */
- seq_printf(seq,
- "DDM: Tid=%03Xh, Rsvd=%04Xh, OrgId=%04Xh",
- *(u16 *) & serialno[2],
- *(u16 *) & serialno[4], *(u16 *) & serialno[6]);
- break;
-
- case I2O_SNFORMAT_IEEE_REG64: /* IEEE Registered (64-bit) */
- case I2O_SNFORMAT_IEEE_REG128: /* IEEE Registered (128-bit) */
- /* FIXME: Figure if this is even close?? */
- seq_printf(seq,
- "IEEE NodeName(hi,lo)=(%08Xh:%08Xh), PortName(hi,lo)=(%08Xh:%08Xh)\n",
- *(u32 *) & serialno[2],
- *(u32 *) & serialno[6],
- *(u32 *) & serialno[10], *(u32 *) & serialno[14]);
- break;
-
- case I2O_SNFORMAT_UNKNOWN: /* Unknown 0 */
- case I2O_SNFORMAT_UNKNOWN2: /* Unknown 0xff */
- default:
- seq_printf(seq, "Unknown data format (0x%02x)", serialno[0]);
- break;
- }
-
- return 0;
-}
-
-/**
- * i2o_get_class_name - do i2o class name lookup
- * @class: class number
- *
- * Return a descriptive string for an i2o class.
- */
-static const char *i2o_get_class_name(int class)
-{
- int idx = 16;
- static char *i2o_class_name[] = {
- "Executive",
- "Device Driver Module",
- "Block Device",
- "Tape Device",
- "LAN Interface",
- "WAN Interface",
- "Fibre Channel Port",
- "Fibre Channel Device",
- "SCSI Device",
- "ATE Port",
- "ATE Device",
- "Floppy Controller",
- "Floppy Device",
- "Secondary Bus Port",
- "Peer Transport Agent",
- "Peer Transport",
- "Unknown"
- };
-
- switch (class & 0xfff) {
- case I2O_CLASS_EXECUTIVE:
- idx = 0;
- break;
- case I2O_CLASS_DDM:
- idx = 1;
- break;
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- idx = 2;
- break;
- case I2O_CLASS_SEQUENTIAL_STORAGE:
- idx = 3;
- break;
- case I2O_CLASS_LAN:
- idx = 4;
- break;
- case I2O_CLASS_WAN:
- idx = 5;
- break;
- case I2O_CLASS_FIBRE_CHANNEL_PORT:
- idx = 6;
- break;
- case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
- idx = 7;
- break;
- case I2O_CLASS_SCSI_PERIPHERAL:
- idx = 8;
- break;
- case I2O_CLASS_ATE_PORT:
- idx = 9;
- break;
- case I2O_CLASS_ATE_PERIPHERAL:
- idx = 10;
- break;
- case I2O_CLASS_FLOPPY_CONTROLLER:
- idx = 11;
- break;
- case I2O_CLASS_FLOPPY_DEVICE:
- idx = 12;
- break;
- case I2O_CLASS_BUS_ADAPTER:
- idx = 13;
- break;
- case I2O_CLASS_PEER_TRANSPORT_AGENT:
- idx = 14;
- break;
- case I2O_CLASS_PEER_TRANSPORT:
- idx = 15;
- break;
- }
-
- return i2o_class_name[idx];
-}
-
-#define SCSI_TABLE_SIZE 13
-static char *scsi_devices[] = {
- "Direct-Access Read/Write",
- "Sequential-Access Storage",
- "Printer",
- "Processor",
- "WORM Device",
- "CD-ROM Device",
- "Scanner Device",
- "Optical Memory Device",
- "Medium Changer Device",
- "Communications Device",
- "Graphics Art Pre-Press Device",
- "Graphics Art Pre-Press Device",
- "Array Controller Device"
-};
-
-static char *chtostr(char *tmp, u8 *chars, int n)
-{
- tmp[0] = 0;
- return strncat(tmp, (char *)chars, n);
-}
-
-static int i2o_report_query_status(struct seq_file *seq, int block_status,
- char *group)
-{
- switch (block_status) {
- case -ETIMEDOUT:
- return seq_printf(seq, "Timeout reading group %s.\n", group);
- case -ENOMEM:
- return seq_printf(seq, "No free memory to read the table.\n");
- case -I2O_PARAMS_STATUS_INVALID_GROUP_ID:
- return seq_printf(seq, "Group %s not supported.\n", group);
- default:
- return seq_printf(seq,
- "Error reading group %s. BlockStatus 0x%02X\n",
- group, -block_status);
- }
-}
-
-static char *bus_strings[] = {
- "Local Bus",
- "ISA",
- "EISA",
- "PCI",
- "PCMCIA",
- "NUBUS",
- "CARDBUS"
-};
-
-static int i2o_seq_show_hrt(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- i2o_hrt *hrt = (i2o_hrt *) c->hrt.virt;
- u32 bus;
- int i;
-
- if (hrt->hrt_version) {
- seq_printf(seq,
- "HRT table for controller is too new a version.\n");
- return 0;
- }
-
- seq_printf(seq, "HRT has %d entries of %d bytes each.\n",
- hrt->num_entries, hrt->entry_len << 2);
-
- for (i = 0; i < hrt->num_entries; i++) {
- seq_printf(seq, "Entry %d:\n", i);
- seq_printf(seq, " Adapter ID: %0#10x\n",
- hrt->hrt_entry[i].adapter_id);
- seq_printf(seq, " Controlling tid: %0#6x\n",
- hrt->hrt_entry[i].parent_tid);
-
- if (hrt->hrt_entry[i].bus_type != 0x80) {
- bus = hrt->hrt_entry[i].bus_type;
- seq_printf(seq, " %s Information\n",
- bus_strings[bus]);
-
- switch (bus) {
- case I2O_BUS_LOCAL:
- seq_printf(seq, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.local_bus.
- LbBaseIOPort);
- seq_printf(seq, " MemoryBase: %0#10x\n",
- hrt->hrt_entry[i].bus.local_bus.
- LbBaseMemoryAddress);
- break;
-
- case I2O_BUS_ISA:
- seq_printf(seq, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.isa_bus.
- IsaBaseIOPort);
- seq_printf(seq, " MemoryBase: %0#10x,",
- hrt->hrt_entry[i].bus.isa_bus.
- IsaBaseMemoryAddress);
- seq_printf(seq, " CSN: %0#4x,",
- hrt->hrt_entry[i].bus.isa_bus.CSN);
- break;
-
- case I2O_BUS_EISA:
- seq_printf(seq, " IOBase: %0#6x,",
- hrt->hrt_entry[i].bus.eisa_bus.
- EisaBaseIOPort);
- seq_printf(seq, " MemoryBase: %0#10x,",
- hrt->hrt_entry[i].bus.eisa_bus.
- EisaBaseMemoryAddress);
- seq_printf(seq, " Slot: %0#4x,",
- hrt->hrt_entry[i].bus.eisa_bus.
- EisaSlotNumber);
- break;
-
- case I2O_BUS_PCI:
- seq_printf(seq, " Bus: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.
- PciBusNumber);
- seq_printf(seq, " Dev: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.
- PciDeviceNumber);
- seq_printf(seq, " Func: %0#4x",
- hrt->hrt_entry[i].bus.pci_bus.
- PciFunctionNumber);
- seq_printf(seq, " Vendor: %0#6x",
- hrt->hrt_entry[i].bus.pci_bus.
- PciVendorID);
- seq_printf(seq, " Device: %0#6x\n",
- hrt->hrt_entry[i].bus.pci_bus.
- PciDeviceID);
- break;
-
- default:
- seq_printf(seq, " Unsupported Bus Type\n");
- }
- } else
- seq_printf(seq, " Unknown Bus Type\n");
- }
-
- return 0;
-}
-
-static int i2o_seq_show_lct(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- i2o_lct *lct = (i2o_lct *) c->lct;
- int entries;
- int i;
-
-#define BUS_TABLE_SIZE 3
- static char *bus_ports[] = {
- "Generic Bus",
- "SCSI Bus",
- "Fibre Channel Bus"
- };
-
- entries = (lct->table_size - 3) / 9;
-
- seq_printf(seq, "LCT contains %d %s\n", entries,
- entries == 1 ? "entry" : "entries");
- if (lct->boot_tid)
- seq_printf(seq, "Boot Device @ ID %d\n", lct->boot_tid);
-
- seq_printf(seq, "Current Change Indicator: %#10x\n", lct->change_ind);
-
- for (i = 0; i < entries; i++) {
- seq_printf(seq, "Entry %d\n", i);
- seq_printf(seq, " Class, SubClass : %s",
- i2o_get_class_name(lct->lct_entry[i].class_id));
-
- /*
- * Classes which we'll print subclass info for
- */
- switch (lct->lct_entry[i].class_id & 0xFFF) {
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- switch (lct->lct_entry[i].sub_class) {
- case 0x00:
- seq_printf(seq, ", Direct-Access Read/Write");
- break;
-
- case 0x04:
- seq_printf(seq, ", WORM Drive");
- break;
-
- case 0x05:
- seq_printf(seq, ", CD-ROM Drive");
- break;
-
- case 0x07:
- seq_printf(seq, ", Optical Memory Device");
- break;
-
- default:
- seq_printf(seq, ", Unknown (0x%02x)",
- lct->lct_entry[i].sub_class);
- break;
- }
- break;
-
- case I2O_CLASS_LAN:
- switch (lct->lct_entry[i].sub_class & 0xFF) {
- case 0x30:
- seq_printf(seq, ", Ethernet");
- break;
-
- case 0x40:
- seq_printf(seq, ", 100base VG");
- break;
-
- case 0x50:
- seq_printf(seq, ", IEEE 802.5/Token-Ring");
- break;
-
- case 0x60:
- seq_printf(seq, ", ANSI X3T9.5 FDDI");
- break;
-
- case 0x70:
- seq_printf(seq, ", Fibre Channel");
- break;
-
- default:
- seq_printf(seq, ", Unknown Sub-Class (0x%02x)",
- lct->lct_entry[i].sub_class & 0xFF);
- break;
- }
- break;
-
- case I2O_CLASS_SCSI_PERIPHERAL:
- if (lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE)
- seq_printf(seq, ", %s",
- scsi_devices[lct->lct_entry[i].
- sub_class]);
- else
- seq_printf(seq, ", Unknown Device Type");
- break;
-
- case I2O_CLASS_BUS_ADAPTER:
- if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
- seq_printf(seq, ", %s",
- bus_ports[lct->lct_entry[i].
- sub_class]);
- else
- seq_printf(seq, ", Unknown Bus Type");
- break;
- }
- seq_printf(seq, "\n");
-
- seq_printf(seq, " Local TID : 0x%03x\n",
- lct->lct_entry[i].tid);
- seq_printf(seq, " User TID : 0x%03x\n",
- lct->lct_entry[i].user_tid);
- seq_printf(seq, " Parent TID : 0x%03x\n",
- lct->lct_entry[i].parent_tid);
- seq_printf(seq, " Identity Tag : 0x%x%x%x%x%x%x%x%x\n",
- lct->lct_entry[i].identity_tag[0],
- lct->lct_entry[i].identity_tag[1],
- lct->lct_entry[i].identity_tag[2],
- lct->lct_entry[i].identity_tag[3],
- lct->lct_entry[i].identity_tag[4],
- lct->lct_entry[i].identity_tag[5],
- lct->lct_entry[i].identity_tag[6],
- lct->lct_entry[i].identity_tag[7]);
- seq_printf(seq, " Change Indicator : %0#10x\n",
- lct->lct_entry[i].change_ind);
- seq_printf(seq, " Event Capab Mask : %0#10x\n",
- lct->lct_entry[i].device_flags);
- }
-
- return 0;
-}
-
-static int i2o_seq_show_status(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- char prodstr[25];
- int version;
- i2o_status_block *sb = c->status_block.virt;
-
- i2o_status_get(c); // reread the status block
-
- seq_printf(seq, "Organization ID : %0#6x\n", sb->org_id);
-
- version = sb->i2o_version;
-
-/* FIXME for Spec 2.0
- if (version == 0x02) {
- seq_printf(seq, "Lowest I2O version supported: ");
- switch(workspace[2]) {
- case 0x00:
- seq_printf(seq, "1.0\n");
- break;
- case 0x01:
- seq_printf(seq, "1.5\n");
- break;
- case 0x02:
- seq_printf(seq, "2.0\n");
- break;
- }
-
- seq_printf(seq, "Highest I2O version supported: ");
- switch(workspace[3]) {
- case 0x00:
- seq_printf(seq, "1.0\n");
- break;
- case 0x01:
- seq_printf(seq, "1.5\n");
- break;
- case 0x02:
- seq_printf(seq, "2.0\n");
- break;
- }
- }
-*/
- seq_printf(seq, "IOP ID : %0#5x\n", sb->iop_id);
- seq_printf(seq, "Host Unit ID : %0#6x\n", sb->host_unit_id);
- seq_printf(seq, "Segment Number : %0#5x\n", sb->segment_number);
-
- seq_printf(seq, "I2O version : ");
- switch (version) {
- case 0x00:
- seq_printf(seq, "1.0\n");
- break;
- case 0x01:
- seq_printf(seq, "1.5\n");
- break;
- case 0x02:
- seq_printf(seq, "2.0\n");
- break;
- default:
- seq_printf(seq, "Unknown version\n");
- }
-
- seq_printf(seq, "IOP State : ");
- switch (sb->iop_state) {
- case 0x01:
- seq_printf(seq, "INIT\n");
- break;
-
- case 0x02:
- seq_printf(seq, "RESET\n");
- break;
-
- case 0x04:
- seq_printf(seq, "HOLD\n");
- break;
-
- case 0x05:
- seq_printf(seq, "READY\n");
- break;
-
- case 0x08:
- seq_printf(seq, "OPERATIONAL\n");
- break;
-
- case 0x10:
- seq_printf(seq, "FAILED\n");
- break;
-
- case 0x11:
- seq_printf(seq, "FAULTED\n");
- break;
-
- default:
- seq_printf(seq, "Unknown\n");
- break;
- }
-
- seq_printf(seq, "Messenger Type : ");
- switch (sb->msg_type) {
- case 0x00:
- seq_printf(seq, "Memory mapped\n");
- break;
- case 0x01:
- seq_printf(seq, "Memory mapped only\n");
- break;
- case 0x02:
- seq_printf(seq, "Remote only\n");
- break;
- case 0x03:
- seq_printf(seq, "Memory mapped and remote\n");
- break;
- default:
- seq_printf(seq, "Unknown\n");
- }
-
- seq_printf(seq, "Inbound Frame Size : %d bytes\n",
- sb->inbound_frame_size << 2);
- seq_printf(seq, "Max Inbound Frames : %d\n",
- sb->max_inbound_frames);
- seq_printf(seq, "Current Inbound Frames : %d\n",
- sb->cur_inbound_frames);
- seq_printf(seq, "Max Outbound Frames : %d\n",
- sb->max_outbound_frames);
-
- /* Spec doesn't say if NULL terminated or not... */
- memcpy(prodstr, sb->product_id, 24);
- prodstr[24] = '\0';
- seq_printf(seq, "Product ID : %s\n", prodstr);
- seq_printf(seq, "Expected LCT Size : %d bytes\n",
- sb->expected_lct_size);
-
- seq_printf(seq, "IOP Capabilities\n");
- seq_printf(seq, " Context Field Size Support : ");
- switch (sb->iop_capabilities & 0x0000003) {
- case 0:
- seq_printf(seq, "Supports only 32-bit context fields\n");
- break;
- case 1:
- seq_printf(seq, "Supports only 64-bit context fields\n");
- break;
- case 2:
- seq_printf(seq, "Supports 32-bit and 64-bit context fields, "
- "but not concurrently\n");
- break;
- case 3:
- seq_printf(seq, "Supports 32-bit and 64-bit context fields "
- "concurrently\n");
- break;
- default:
- seq_printf(seq, "0x%08x\n", sb->iop_capabilities);
- }
- seq_printf(seq, " Current Context Field Size : ");
- switch (sb->iop_capabilities & 0x0000000C) {
- case 0:
- seq_printf(seq, "not configured\n");
- break;
- case 4:
- seq_printf(seq, "Supports only 32-bit context fields\n");
- break;
- case 8:
- seq_printf(seq, "Supports only 64-bit context fields\n");
- break;
- case 12:
- seq_printf(seq, "Supports both 32-bit or 64-bit context fields "
- "concurrently\n");
- break;
- default:
- seq_printf(seq, "\n");
- }
- seq_printf(seq, " Inbound Peer Support : %s\n",
- (sb->
- iop_capabilities & 0x00000010) ? "Supported" :
- "Not supported");
- seq_printf(seq, " Outbound Peer Support : %s\n",
- (sb->
- iop_capabilities & 0x00000020) ? "Supported" :
- "Not supported");
- seq_printf(seq, " Peer to Peer Support : %s\n",
- (sb->
- iop_capabilities & 0x00000040) ? "Supported" :
- "Not supported");
-
- seq_printf(seq, "Desired private memory size : %d kB\n",
- sb->desired_mem_size >> 10);
- seq_printf(seq, "Allocated private memory size : %d kB\n",
- sb->current_mem_size >> 10);
- seq_printf(seq, "Private memory base address : %0#10x\n",
- sb->current_mem_base);
- seq_printf(seq, "Desired private I/O size : %d kB\n",
- sb->desired_io_size >> 10);
- seq_printf(seq, "Allocated private I/O size : %d kB\n",
- sb->current_io_size >> 10);
- seq_printf(seq, "Private I/O base address : %0#10x\n",
- sb->current_io_base);
-
- return 0;
-}
-
-static int i2o_seq_show_hw(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- static u32 work32[5];
- static u8 *work8 = (u8 *) work32;
- static u16 *work16 = (u16 *) work32;
- int token;
- u32 hwcap;
-
- static char *cpu_table[] = {
- "Intel 80960 series",
- "AMD2900 series",
- "Motorola 68000 series",
- "ARM series",
- "MIPS series",
- "Sparc series",
- "PowerPC series",
- "Intel x86 series"
- };
-
- token =
- i2o_parm_field_get(c->exec, 0x0000, -1, &work32, sizeof(work32));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0x0000 IOP Hardware");
- return 0;
- }
-
- seq_printf(seq, "I2O Vendor ID : %0#6x\n", work16[0]);
- seq_printf(seq, "Product ID : %0#6x\n", work16[1]);
- seq_printf(seq, "CPU : ");
- if (work8[16] > 8)
- seq_printf(seq, "Unknown\n");
- else
- seq_printf(seq, "%s\n", cpu_table[work8[16]]);
- /* Anyone using ProcessorVersion? */
-
- seq_printf(seq, "RAM : %dkB\n", work32[1] >> 10);
- seq_printf(seq, "Non-Volatile Mem : %dkB\n", work32[2] >> 10);
-
- hwcap = work32[3];
- seq_printf(seq, "Capabilities : 0x%08x\n", hwcap);
- seq_printf(seq, " [%s] Self booting\n",
- (hwcap & 0x00000001) ? "+" : "-");
- seq_printf(seq, " [%s] Upgradable IRTOS\n",
- (hwcap & 0x00000002) ? "+" : "-");
- seq_printf(seq, " [%s] Supports downloading DDMs\n",
- (hwcap & 0x00000004) ? "+" : "-");
- seq_printf(seq, " [%s] Supports installing DDMs\n",
- (hwcap & 0x00000008) ? "+" : "-");
- seq_printf(seq, " [%s] Battery-backed RAM\n",
- (hwcap & 0x00000010) ? "+" : "-");
-
- return 0;
-}
-
-/* Executive group 0003h - Executing DDM List (table) */
-static int i2o_seq_show_ddm_table(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- int token;
- int i;
-
- typedef struct _i2o_exec_execute_ddm_table {
- u16 ddm_tid;
- u8 module_type;
- u8 reserved;
- u16 i2o_vendor_id;
- u16 module_id;
- u8 module_name_version[28];
- u32 data_size;
- u32 code_size;
- } i2o_exec_execute_ddm_table;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_exec_execute_ddm_table ddm_table[I2O_MAX_MODULES];
- } *result;
-
- i2o_exec_execute_ddm_table ddm_table;
- char tmp[28 + 1];
-
- result = kmalloc(sizeof(*result), GFP_KERNEL);
- if (!result)
- return -ENOMEM;
-
- token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0003, -1,
- NULL, 0, result, sizeof(*result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0x0003 Executing DDM List");
- goto out;
- }
-
- seq_printf(seq,
- "Tid Module_type Vendor Mod_id Module_name Vrs Data_size Code_size\n");
- ddm_table = result->ddm_table[0];
-
- for (i = 0; i < result->row_count; ddm_table = result->ddm_table[++i]) {
- seq_printf(seq, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
-
- switch (ddm_table.module_type) {
- case 0x01:
- seq_printf(seq, "Downloaded DDM ");
- break;
- case 0x22:
- seq_printf(seq, "Embedded DDM ");
- break;
- default:
- seq_printf(seq, " ");
- }
-
- seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
- seq_printf(seq, "%-#8x", ddm_table.module_id);
- seq_printf(seq, "%-29s",
- chtostr(tmp, ddm_table.module_name_version, 28));
- seq_printf(seq, "%9d ", ddm_table.data_size);
- seq_printf(seq, "%8d", ddm_table.code_size);
-
- seq_printf(seq, "\n");
- }
- out:
- kfree(result);
- return 0;
-}
-
-/* Executive group 0004h - Driver Store (scalar) */
-static int i2o_seq_show_driver_store(struct seq_file *seq, void *v)
-{
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- u32 work32[8];
- int token;
-
- token =
- i2o_parm_field_get(c->exec, 0x0004, -1, &work32, sizeof(work32));
- if (token < 0) {
- i2o_report_query_status(seq, token, "0x0004 Driver Store");
- return 0;
- }
-
- seq_printf(seq, "Module limit : %d\n"
- "Module count : %d\n"
- "Current space : %d kB\n"
- "Free space : %d kB\n",
- work32[0], work32[1], work32[2] >> 10, work32[3] >> 10);
-
- return 0;
-}
-
-/* Executive group 0005h - Driver Store Table (table) */
-static int i2o_seq_show_drivers_stored(struct seq_file *seq, void *v)
-{
- typedef struct _i2o_driver_store {
- u16 stored_ddm_index;
- u8 module_type;
- u8 reserved;
- u16 i2o_vendor_id;
- u16 module_id;
- u8 module_name_version[28];
- u8 date[8];
- u32 module_size;
- u32 mpb_size;
- u32 module_flags;
- } i2o_driver_store_table;
-
- struct i2o_controller *c = (struct i2o_controller *)seq->private;
- int token;
- int i;
-
- typedef struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_driver_store_table dst[I2O_MAX_MODULES];
- } i2o_driver_result_table;
-
- i2o_driver_result_table *result;
- i2o_driver_store_table *dst;
- char tmp[28 + 1];
-
- result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL);
- if (result == NULL)
- return -ENOMEM;
-
- token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0005, -1,
- NULL, 0, result, sizeof(*result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0x0005 DRIVER STORE TABLE");
- kfree(result);
- return 0;
- }
-
- seq_printf(seq,
- "# Module_type Vendor Mod_id Module_name Vrs"
- "Date Mod_size Par_size Flags\n");
- for (i = 0, dst = &result->dst[0]; i < result->row_count;
- dst = &result->dst[++i]) {
- seq_printf(seq, "%-3d", dst->stored_ddm_index);
- switch (dst->module_type) {
- case 0x01:
- seq_printf(seq, "Downloaded DDM ");
- break;
- case 0x22:
- seq_printf(seq, "Embedded DDM ");
- break;
- default:
- seq_printf(seq, " ");
- }
-
- seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
- seq_printf(seq, "%-#8x", dst->module_id);
- seq_printf(seq, "%-29s",
- chtostr(tmp, dst->module_name_version, 28));
- seq_printf(seq, "%-9s", chtostr(tmp, dst->date, 8));
- seq_printf(seq, "%8d ", dst->module_size);
- seq_printf(seq, "%8d ", dst->mpb_size);
- seq_printf(seq, "0x%04x", dst->module_flags);
- seq_printf(seq, "\n");
- }
-
- kfree(result);
- return 0;
-}
-
-/* Generic group F000h - Params Descriptor (table) */
-static int i2o_seq_show_groups(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
- u8 properties;
-
- typedef struct _i2o_group_info {
- u16 group_number;
- u16 field_count;
- u16 row_count;
- u8 properties;
- u8 reserved;
- } i2o_group_info;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_group_info group[256];
- } *result;
-
- result = kmalloc(sizeof(*result), GFP_KERNEL);
- if (!result)
- return -ENOMEM;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0,
- result, sizeof(*result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF000 Params Descriptor");
- goto out;
- }
-
- seq_printf(seq,
- "# Group FieldCount RowCount Type Add Del Clear\n");
-
- for (i = 0; i < result->row_count; i++) {
- seq_printf(seq, "%-3d", i);
- seq_printf(seq, "0x%04X ", result->group[i].group_number);
- seq_printf(seq, "%10d ", result->group[i].field_count);
- seq_printf(seq, "%8d ", result->group[i].row_count);
-
- properties = result->group[i].properties;
- if (properties & 0x1)
- seq_printf(seq, "Table ");
- else
- seq_printf(seq, "Scalar ");
- if (properties & 0x2)
- seq_printf(seq, " + ");
- else
- seq_printf(seq, " - ");
- if (properties & 0x4)
- seq_printf(seq, " + ");
- else
- seq_printf(seq, " - ");
- if (properties & 0x8)
- seq_printf(seq, " + ");
- else
- seq_printf(seq, " - ");
-
- seq_printf(seq, "\n");
- }
-
- if (result->more_flag)
- seq_printf(seq, "There is more...\n");
- out:
- kfree(result);
- return 0;
-}
-
-/* Generic group F001h - Physical Device Table (table) */
-static int i2o_seq_show_phys_device(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u32 adapter_id[64];
- } result;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF001, -1, NULL, 0,
- &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0xF001 Physical Device Table");
- return 0;
- }
-
- if (result.row_count)
- seq_printf(seq, "# AdapterId\n");
-
- for (i = 0; i < result.row_count; i++) {
- seq_printf(seq, "%-2d", i);
- seq_printf(seq, "%#7x\n", result.adapter_id[i]);
- }
-
- if (result.more_flag)
- seq_printf(seq, "There is more...\n");
-
- return 0;
-}
-
-/* Generic group F002h - Claimed Table (table) */
-static int i2o_seq_show_claimed(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u16 claimed_tid[64];
- } result;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF002, -1, NULL, 0,
- &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF002 Claimed Table");
- return 0;
- }
-
- if (result.row_count)
- seq_printf(seq, "# ClaimedTid\n");
-
- for (i = 0; i < result.row_count; i++) {
- seq_printf(seq, "%-2d", i);
- seq_printf(seq, "%#7x\n", result.claimed_tid[i]);
- }
-
- if (result.more_flag)
- seq_printf(seq, "There is more...\n");
-
- return 0;
-}
-
-/* Generic group F003h - User Table (table) */
-static int i2o_seq_show_users(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
-
- typedef struct _i2o_user_table {
- u16 instance;
- u16 user_tid;
- u8 claim_type;
- u8 reserved1;
- u16 reserved2;
- } i2o_user_table;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_user_table user[64];
- } *result;
-
- result = kmalloc(sizeof(*result), GFP_KERNEL);
- if (!result)
- return -ENOMEM;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF003, -1, NULL, 0,
- result, sizeof(*result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF003 User Table");
- goto out;
- }
-
- seq_printf(seq, "# Instance UserTid ClaimType\n");
-
- for (i = 0; i < result->row_count; i++) {
- seq_printf(seq, "%-3d", i);
- seq_printf(seq, "%#8x ", result->user[i].instance);
- seq_printf(seq, "%#7x ", result->user[i].user_tid);
- seq_printf(seq, "%#9x\n", result->user[i].claim_type);
- }
-
- if (result->more_flag)
- seq_printf(seq, "There is more...\n");
- out:
- kfree(result);
- return 0;
-}
-
-/* Generic group F005h - Private message extensions (table) (optional) */
-static int i2o_seq_show_priv_msgs(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
-
- typedef struct _i2o_private {
- u16 ext_instance;
- u16 organization_id;
- u16 x_function_code;
- } i2o_private;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- i2o_private extension[64];
- } result;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0,
- &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0xF005 Private Message Extensions (optional)");
- return 0;
- }
-
- seq_printf(seq, "Instance# OrgId FunctionCode\n");
-
- for (i = 0; i < result.row_count; i++) {
- seq_printf(seq, "%0#9x ", result.extension[i].ext_instance);
- seq_printf(seq, "%0#6x ", result.extension[i].organization_id);
- seq_printf(seq, "%0#6x", result.extension[i].x_function_code);
-
- seq_printf(seq, "\n");
- }
-
- if (result.more_flag)
- seq_printf(seq, "There is more...\n");
-
- return 0;
-}
-
-/* Generic group F006h - Authorized User Table (table) */
-static int i2o_seq_show_authorized_users(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
- int i;
-
- struct {
- u16 result_count;
- u16 pad;
- u16 block_size;
- u8 block_status;
- u8 error_info_size;
- u16 row_count;
- u16 more_flag;
- u32 alternate_tid[64];
- } result;
-
- token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF006, -1, NULL, 0,
- &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0xF006 Autohorized User Table");
- return 0;
- }
-
- if (result.row_count)
- seq_printf(seq, "# AlternateTid\n");
-
- for (i = 0; i < result.row_count; i++) {
- seq_printf(seq, "%-2d", i);
- seq_printf(seq, "%#7x ", result.alternate_tid[i]);
- }
-
- if (result.more_flag)
- seq_printf(seq, "There is more...\n");
-
- return 0;
-}
-
-/* Generic group F100h - Device Identity (scalar) */
-static int i2o_seq_show_dev_identity(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number
- // == (allow) 512d bytes (max)
- static u16 *work16 = (u16 *) work32;
- int token;
- char tmp[16 + 1];
-
- token = i2o_parm_field_get(d, 0xF100, -1, &work32, sizeof(work32));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF100 Device Identity");
- return 0;
- }
-
- seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0]));
- seq_printf(seq, "Owner TID : %0#5x\n", work16[2]);
- seq_printf(seq, "Parent TID : %0#5x\n", work16[3]);
- seq_printf(seq, "Vendor info : %s\n",
- chtostr(tmp, (u8 *) (work32 + 2), 16));
- seq_printf(seq, "Product info : %s\n",
- chtostr(tmp, (u8 *) (work32 + 6), 16));
- seq_printf(seq, "Description : %s\n",
- chtostr(tmp, (u8 *) (work32 + 10), 16));
- seq_printf(seq, "Product rev. : %s\n",
- chtostr(tmp, (u8 *) (work32 + 14), 8));
-
- seq_printf(seq, "Serial number : ");
- print_serial_number(seq, (u8 *) (work32 + 16),
- /* allow for SNLen plus
- * possible trailing '\0'
- */
- sizeof(work32) - (16 * sizeof(u32)) - 2);
- seq_printf(seq, "\n");
-
- return 0;
-}
-
-static int i2o_seq_show_dev_name(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
-
- seq_printf(seq, "%s\n", dev_name(&d->device));
-
- return 0;
-}
-
-/* Generic group F101h - DDM Identity (scalar) */
-static int i2o_seq_show_ddm_identity(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
-
- struct {
- u16 ddm_tid;
- u8 module_name[24];
- u8 module_rev[8];
- u8 sn_format;
- u8 serial_number[12];
- u8 pad[256]; // allow up to 256 byte (max) serial number
- } result;
-
- char tmp[24 + 1];
-
- token = i2o_parm_field_get(d, 0xF101, -1, &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF101 DDM Identity");
- return 0;
- }
-
- seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
- seq_printf(seq, "Module name : %s\n",
- chtostr(tmp, result.module_name, 24));
- seq_printf(seq, "Module revision : %s\n",
- chtostr(tmp, result.module_rev, 8));
-
- seq_printf(seq, "Serial number : ");
- print_serial_number(seq, result.serial_number, sizeof(result) - 36);
- /* allow for SNLen plus possible trailing '\0' */
-
- seq_printf(seq, "\n");
-
- return 0;
-}
-
-/* Generic group F102h - User Information (scalar) */
-static int i2o_seq_show_uinfo(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
-
- struct {
- u8 device_name[64];
- u8 service_name[64];
- u8 physical_location[64];
- u8 instance_number[4];
- } result;
-
- char tmp[64 + 1];
-
- token = i2o_parm_field_get(d, 0xF102, -1, &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token, "0xF102 User Information");
- return 0;
- }
-
- seq_printf(seq, "Device name : %s\n",
- chtostr(tmp, result.device_name, 64));
- seq_printf(seq, "Service name : %s\n",
- chtostr(tmp, result.service_name, 64));
- seq_printf(seq, "Physical name : %s\n",
- chtostr(tmp, result.physical_location, 64));
- seq_printf(seq, "Instance number : %s\n",
- chtostr(tmp, result.instance_number, 4));
-
- return 0;
-}
-
-/* Generic group F103h - SGL Operating Limits (scalar) */
-static int i2o_seq_show_sgl_limits(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- static u32 work32[12];
- static u16 *work16 = (u16 *) work32;
- static u8 *work8 = (u8 *) work32;
- int token;
-
- token = i2o_parm_field_get(d, 0xF103, -1, &work32, sizeof(work32));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0xF103 SGL Operating Limits");
- return 0;
- }
-
- seq_printf(seq, "SGL chain size : %d\n", work32[0]);
- seq_printf(seq, "Max SGL chain size : %d\n", work32[1]);
- seq_printf(seq, "SGL chain size target : %d\n", work32[2]);
- seq_printf(seq, "SGL frag count : %d\n", work16[6]);
- seq_printf(seq, "Max SGL frag count : %d\n", work16[7]);
- seq_printf(seq, "SGL frag count target : %d\n", work16[8]);
-
-/* FIXME
- if (d->i2oversion == 0x02)
- {
-*/
- seq_printf(seq, "SGL data alignment : %d\n", work16[8]);
- seq_printf(seq, "SGL addr limit : %d\n", work8[20]);
- seq_printf(seq, "SGL addr sizes supported : ");
- if (work8[21] & 0x01)
- seq_printf(seq, "32 bit ");
- if (work8[21] & 0x02)
- seq_printf(seq, "64 bit ");
- if (work8[21] & 0x04)
- seq_printf(seq, "96 bit ");
- if (work8[21] & 0x08)
- seq_printf(seq, "128 bit ");
- seq_printf(seq, "\n");
-/*
- }
-*/
-
- return 0;
-}
-
-/* Generic group F200h - Sensors (scalar) */
-static int i2o_seq_show_sensors(struct seq_file *seq, void *v)
-{
- struct i2o_device *d = (struct i2o_device *)seq->private;
- int token;
-
- struct {
- u16 sensor_instance;
- u8 component;
- u16 component_instance;
- u8 sensor_class;
- u8 sensor_type;
- u8 scaling_exponent;
- u32 actual_reading;
- u32 minimum_reading;
- u32 low2lowcat_treshold;
- u32 lowcat2low_treshold;
- u32 lowwarn2low_treshold;
- u32 low2lowwarn_treshold;
- u32 norm2lowwarn_treshold;
- u32 lowwarn2norm_treshold;
- u32 nominal_reading;
- u32 hiwarn2norm_treshold;
- u32 norm2hiwarn_treshold;
- u32 high2hiwarn_treshold;
- u32 hiwarn2high_treshold;
- u32 hicat2high_treshold;
- u32 hi2hicat_treshold;
- u32 maximum_reading;
- u8 sensor_state;
- u16 event_enable;
- } result;
-
- token = i2o_parm_field_get(d, 0xF200, -1, &result, sizeof(result));
-
- if (token < 0) {
- i2o_report_query_status(seq, token,
- "0xF200 Sensors (optional)");
- return 0;
- }
-
- seq_printf(seq, "Sensor instance : %d\n", result.sensor_instance);
-
- seq_printf(seq, "Component : %d = ", result.component);
- switch (result.component) {
- case 0:
- seq_printf(seq, "Other");
- break;
- case 1:
- seq_printf(seq, "Planar logic Board");
- break;
- case 2:
- seq_printf(seq, "CPU");
- break;
- case 3:
- seq_printf(seq, "Chassis");
- break;
- case 4:
- seq_printf(seq, "Power Supply");
- break;
- case 5:
- seq_printf(seq, "Storage");
- break;
- case 6:
- seq_printf(seq, "External");
- break;
- }
- seq_printf(seq, "\n");
-
- seq_printf(seq, "Component instance : %d\n",
- result.component_instance);
- seq_printf(seq, "Sensor class : %s\n",
- result.sensor_class ? "Analog" : "Digital");
-
- seq_printf(seq, "Sensor type : %d = ", result.sensor_type);
- switch (result.sensor_type) {
- case 0:
- seq_printf(seq, "Other\n");
- break;
- case 1:
- seq_printf(seq, "Thermal\n");
- break;
- case 2:
- seq_printf(seq, "DC voltage (DC volts)\n");
- break;
- case 3:
- seq_printf(seq, "AC voltage (AC volts)\n");
- break;
- case 4:
- seq_printf(seq, "DC current (DC amps)\n");
- break;
- case 5:
- seq_printf(seq, "AC current (AC volts)\n");
- break;
- case 6:
- seq_printf(seq, "Door open\n");
- break;
- case 7:
- seq_printf(seq, "Fan operational\n");
- break;
- }
-
- seq_printf(seq, "Scaling exponent : %d\n",
- result.scaling_exponent);
- seq_printf(seq, "Actual reading : %d\n", result.actual_reading);
- seq_printf(seq, "Minimum reading : %d\n", result.minimum_reading);
- seq_printf(seq, "Low2LowCat treshold : %d\n",
- result.low2lowcat_treshold);
- seq_printf(seq, "LowCat2Low treshold : %d\n",
- result.lowcat2low_treshold);
- seq_printf(seq, "LowWarn2Low treshold : %d\n",
- result.lowwarn2low_treshold);
- seq_printf(seq, "Low2LowWarn treshold : %d\n",
- result.low2lowwarn_treshold);
- seq_printf(seq, "Norm2LowWarn treshold : %d\n",
- result.norm2lowwarn_treshold);
- seq_printf(seq, "LowWarn2Norm treshold : %d\n",
- result.lowwarn2norm_treshold);
- seq_printf(seq, "Nominal reading : %d\n", result.nominal_reading);
- seq_printf(seq, "HiWarn2Norm treshold : %d\n",
- result.hiwarn2norm_treshold);
- seq_printf(seq, "Norm2HiWarn treshold : %d\n",
- result.norm2hiwarn_treshold);
- seq_printf(seq, "High2HiWarn treshold : %d\n",
- result.high2hiwarn_treshold);
- seq_printf(seq, "HiWarn2High treshold : %d\n",
- result.hiwarn2high_treshold);
- seq_printf(seq, "HiCat2High treshold : %d\n",
- result.hicat2high_treshold);
- seq_printf(seq, "High2HiCat treshold : %d\n",
- result.hi2hicat_treshold);
- seq_printf(seq, "Maximum reading : %d\n", result.maximum_reading);
-
- seq_printf(seq, "Sensor state : %d = ", result.sensor_state);
- switch (result.sensor_state) {
- case 0:
- seq_printf(seq, "Normal\n");
- break;
- case 1:
- seq_printf(seq, "Abnormal\n");
- break;
- case 2:
- seq_printf(seq, "Unknown\n");
- break;
- case 3:
- seq_printf(seq, "Low Catastrophic (LoCat)\n");
- break;
- case 4:
- seq_printf(seq, "Low (Low)\n");
- break;
- case 5:
- seq_printf(seq, "Low Warning (LoWarn)\n");
- break;
- case 6:
- seq_printf(seq, "High Warning (HiWarn)\n");
- break;
- case 7:
- seq_printf(seq, "High (High)\n");
- break;
- case 8:
- seq_printf(seq, "High Catastrophic (HiCat)\n");
- break;
- }
-
- seq_printf(seq, "Event_enable : 0x%02X\n", result.event_enable);
- seq_printf(seq, " [%s] Operational state change. \n",
- (result.event_enable & 0x01) ? "+" : "-");
- seq_printf(seq, " [%s] Low catastrophic. \n",
- (result.event_enable & 0x02) ? "+" : "-");
- seq_printf(seq, " [%s] Low reading. \n",
- (result.event_enable & 0x04) ? "+" : "-");
- seq_printf(seq, " [%s] Low warning. \n",
- (result.event_enable & 0x08) ? "+" : "-");
- seq_printf(seq,
- " [%s] Change back to normal from out of range state. \n",
- (result.event_enable & 0x10) ? "+" : "-");
- seq_printf(seq, " [%s] High warning. \n",
- (result.event_enable & 0x20) ? "+" : "-");
- seq_printf(seq, " [%s] High reading. \n",
- (result.event_enable & 0x40) ? "+" : "-");
- seq_printf(seq, " [%s] High catastrophic. \n",
- (result.event_enable & 0x80) ? "+" : "-");
-
- return 0;
-}
-
-static int i2o_seq_open_hrt(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_hrt, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_lct(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_lct, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_status(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_status, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_hw(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_hw, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_ddm_table(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_ddm_table, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_driver_store(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_driver_store, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_drivers_stored(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_drivers_stored, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_groups(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_groups, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_phys_device(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_phys_device, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_claimed(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_claimed, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_users(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_users, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_priv_msgs(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_priv_msgs, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_authorized_users(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_authorized_users,
- PDE_DATA(inode));
-};
-
-static int i2o_seq_open_dev_identity(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_dev_identity, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_ddm_identity(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_ddm_identity, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_uinfo(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_uinfo, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_sgl_limits(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_sgl_limits, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_sensors(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_sensors, PDE_DATA(inode));
-};
-
-static int i2o_seq_open_dev_name(struct inode *inode, struct file *file)
-{
- return single_open(file, i2o_seq_show_dev_name, PDE_DATA(inode));
-};
-
-static const struct file_operations i2o_seq_fops_lct = {
- .open = i2o_seq_open_lct,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_hrt = {
- .open = i2o_seq_open_hrt,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_status = {
- .open = i2o_seq_open_status,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_hw = {
- .open = i2o_seq_open_hw,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_ddm_table = {
- .open = i2o_seq_open_ddm_table,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_driver_store = {
- .open = i2o_seq_open_driver_store,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_drivers_stored = {
- .open = i2o_seq_open_drivers_stored,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_groups = {
- .open = i2o_seq_open_groups,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_phys_device = {
- .open = i2o_seq_open_phys_device,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_claimed = {
- .open = i2o_seq_open_claimed,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_users = {
- .open = i2o_seq_open_users,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_priv_msgs = {
- .open = i2o_seq_open_priv_msgs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_authorized_users = {
- .open = i2o_seq_open_authorized_users,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_dev_name = {
- .open = i2o_seq_open_dev_name,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_dev_identity = {
- .open = i2o_seq_open_dev_identity,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_ddm_identity = {
- .open = i2o_seq_open_ddm_identity,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_uinfo = {
- .open = i2o_seq_open_uinfo,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_sgl_limits = {
- .open = i2o_seq_open_sgl_limits,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations i2o_seq_fops_sensors = {
- .open = i2o_seq_open_sensors,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/*
- * IOP specific entries...write field just in case someone
- * ever wants one.
- */
-static i2o_proc_entry i2o_proc_generic_iop_entries[] = {
- {"hrt", S_IFREG | S_IRUGO, &i2o_seq_fops_hrt},
- {"lct", S_IFREG | S_IRUGO, &i2o_seq_fops_lct},
- {"status", S_IFREG | S_IRUGO, &i2o_seq_fops_status},
- {"hw", S_IFREG | S_IRUGO, &i2o_seq_fops_hw},
- {"ddm_table", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_table},
- {"driver_store", S_IFREG | S_IRUGO, &i2o_seq_fops_driver_store},
- {"drivers_stored", S_IFREG | S_IRUGO, &i2o_seq_fops_drivers_stored},
- {NULL, 0, NULL}
-};
-
-/*
- * Device specific entries
- */
-static i2o_proc_entry generic_dev_entries[] = {
- {"groups", S_IFREG | S_IRUGO, &i2o_seq_fops_groups},
- {"phys_dev", S_IFREG | S_IRUGO, &i2o_seq_fops_phys_device},
- {"claimed", S_IFREG | S_IRUGO, &i2o_seq_fops_claimed},
- {"users", S_IFREG | S_IRUGO, &i2o_seq_fops_users},
- {"priv_msgs", S_IFREG | S_IRUGO, &i2o_seq_fops_priv_msgs},
- {"authorized_users", S_IFREG | S_IRUGO, &i2o_seq_fops_authorized_users},
- {"dev_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_identity},
- {"ddm_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_identity},
- {"user_info", S_IFREG | S_IRUGO, &i2o_seq_fops_uinfo},
- {"sgl_limits", S_IFREG | S_IRUGO, &i2o_seq_fops_sgl_limits},
- {"sensors", S_IFREG | S_IRUGO, &i2o_seq_fops_sensors},
- {NULL, 0, NULL}
-};
-
-/*
- * Storage unit specific entries (SCSI Periph, BS) with device names
- */
-static i2o_proc_entry rbs_dev_entries[] = {
- {"dev_name", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_name},
- {NULL, 0, NULL}
-};
-
-/**
- * i2o_proc_create_entries - Creates proc dir entries
- * @dir: proc dir entry under which the entries should be placed
- * @i2o_pe: pointer to the entries which should be added
- * @data: pointer to I2O controller or device
- *
- * Create proc dir entries for a I2O controller or I2O device.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_proc_create_entries(struct proc_dir_entry *dir,
- i2o_proc_entry * i2o_pe, void *data)
-{
- struct proc_dir_entry *tmp;
-
- while (i2o_pe->name) {
- tmp = proc_create_data(i2o_pe->name, i2o_pe->mode, dir,
- i2o_pe->fops, data);
- if (!tmp)
- return -1;
-
- i2o_pe++;
- }
-
- return 0;
-}
-
-/**
- * i2o_proc_device_add - Add an I2O device to the proc dir
- * @dir: proc dir entry to which the device should be added
- * @dev: I2O device which should be added
- *
- * Add an I2O device to the proc dir entry dir and create the entries for
- * the device depending on the class of the I2O device.
- */
-static void i2o_proc_device_add(struct proc_dir_entry *dir,
- struct i2o_device *dev)
-{
- char buff[10];
- struct proc_dir_entry *devdir;
- i2o_proc_entry *i2o_pe = NULL;
-
- sprintf(buff, "%03x", dev->lct_data.tid);
-
- osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff);
-
- devdir = proc_mkdir_data(buff, 0, dir, dev);
- if (!devdir) {
- osm_warn("Could not allocate procdir!\n");
- return;
- }
-
- i2o_proc_create_entries(devdir, generic_dev_entries, dev);
-
- /* Inform core that we want updates about this device's status */
- switch (dev->lct_data.class_id) {
- case I2O_CLASS_SCSI_PERIPHERAL:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- i2o_pe = rbs_dev_entries;
- break;
- default:
- break;
- }
- if (i2o_pe)
- i2o_proc_create_entries(devdir, i2o_pe, dev);
-}
-
-/**
- * i2o_proc_iop_add - Add an I2O controller to the i2o proc tree
- * @dir: parent proc dir entry
- * @c: I2O controller which should be added
- *
- * Add the entries to the parent proc dir entry. Also each device is added
- * to the controllers proc dir entry.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_proc_iop_add(struct proc_dir_entry *dir,
- struct i2o_controller *c)
-{
- struct proc_dir_entry *iopdir;
- struct i2o_device *dev;
-
- osm_debug("adding IOP /proc/i2o/%s\n", c->name);
-
- iopdir = proc_mkdir_data(c->name, 0, dir, c);
- if (!iopdir)
- return -1;
-
- i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c);
-
- list_for_each_entry(dev, &c->devices, list)
- i2o_proc_device_add(iopdir, dev);
-
- return 0;
-}
-
-/**
- * i2o_proc_fs_create - Create the i2o proc fs.
- *
- * Iterate over each I2O controller and create the entries for it.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_proc_fs_create(void)
-{
- struct i2o_controller *c;
-
- i2o_proc_dir_root = proc_mkdir("i2o", NULL);
- if (!i2o_proc_dir_root)
- return -1;
-
- list_for_each_entry(c, &i2o_controllers, list)
- i2o_proc_iop_add(i2o_proc_dir_root, c);
-
- return 0;
-};
-
-/**
- * i2o_proc_fs_destroy - Cleanup the all i2o proc entries
- *
- * Iterate over each I2O controller and remove the entries for it.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __exit i2o_proc_fs_destroy(void)
-{
- remove_proc_subtree("i2o", NULL);
-
- return 0;
-};
-
-/**
- * i2o_proc_init - Init function for procfs
- *
- * Registers Proc OSM and creates procfs entries.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_proc_init(void)
-{
- int rc;
-
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- rc = i2o_driver_register(&i2o_proc_driver);
- if (rc)
- return rc;
-
- rc = i2o_proc_fs_create();
- if (rc) {
- i2o_driver_unregister(&i2o_proc_driver);
- return rc;
- }
-
- return 0;
-};
-
-/**
- * i2o_proc_exit - Exit function for procfs
- *
- * Unregisters Proc OSM and removes procfs entries.
- */
-static void __exit i2o_proc_exit(void)
-{
- i2o_driver_unregister(&i2o_proc_driver);
- i2o_proc_fs_destroy();
-};
-
-MODULE_AUTHOR("Deepak Saxena");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_proc_init);
-module_exit(i2o_proc_exit);
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
deleted file mode 100644
index 1d31d7284cbd..000000000000
--- a/drivers/message/i2o/i2o_scsi.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * For the avoidance of doubt the "preferred form" of this code is one which
- * is in an open non patent encumbered format. Where cryptographic key signing
- * forms part of the process of creating an executable the information
- * including keys needed to generate an equivalently functional executable
- * are deemed to be part of the source code.
- *
- * Complications for I2O scsi
- *
- * o Each (bus,lun) is a logical device in I2O. We keep a map
- * table. We spoof failed selection for unmapped units
- * o Request sense buffers can come back for free.
- * o Scatter gather is a bit dynamic. We have to investigate at
- * setup time.
- * o Some of our resources are dynamically shared. The i2o core
- * needs a message reservation protocol to avoid swap v net
- * deadlocking. We need to back off queue requests.
- *
- * In general the firmware wants to help. Where its help isn't performance
- * useful we just ignore the aid. Its not worth the code in truth.
- *
- * Fixes/additions:
- * Steve Ralston:
- * Scatter gather now works
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor fixes for 2.6.
- *
- * To Do:
- * 64bit cleanups
- * Fix the resource management problems.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/jiffies.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/prefetch.h>
-#include <linux/pci.h>
-#include <linux/blkdev.h>
-#include <linux/i2o.h>
-#include <linux/scatterlist.h>
-
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/sg.h>
-
-#define OSM_NAME "scsi-osm"
-#define OSM_VERSION "1.316"
-#define OSM_DESCRIPTION "I2O SCSI Peripheral OSM"
-
-static struct i2o_driver i2o_scsi_driver;
-
-static unsigned int i2o_scsi_max_id = 16;
-static unsigned int i2o_scsi_max_lun = 255;
-
-struct i2o_scsi_host {
- struct Scsi_Host *scsi_host; /* pointer to the SCSI host */
- struct i2o_controller *iop; /* pointer to the I2O controller */
- unsigned int lun; /* lun's used for block devices */
- struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */
-};
-
-static struct scsi_host_template i2o_scsi_host_template;
-
-#define I2O_SCSI_CAN_QUEUE 4
-
-/* SCSI OSM class handling definition */
-static struct i2o_class_id i2o_scsi_class_id[] = {
- {I2O_CLASS_SCSI_PERIPHERAL},
- {I2O_CLASS_END}
-};
-
-static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
-{
- struct i2o_scsi_host *i2o_shost;
- struct i2o_device *i2o_dev;
- struct Scsi_Host *scsi_host;
- int max_channel = 0;
- u8 type;
- int i;
- size_t size;
- u16 body_size = 6;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- if (c->adaptec)
- body_size = 8;
-#endif
-
- list_for_each_entry(i2o_dev, &c->devices, list)
- if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
- if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
- && (type == 0x01)) /* SCSI bus */
- max_channel++;
- }
-
- if (!max_channel) {
- osm_warn("no channels found on %s\n", c->name);
- return ERR_PTR(-EFAULT);
- }
-
- size = max_channel * sizeof(struct i2o_device *)
- + sizeof(struct i2o_scsi_host);
-
- scsi_host = scsi_host_alloc(&i2o_scsi_host_template, size);
- if (!scsi_host) {
- osm_warn("Could not allocate SCSI host\n");
- return ERR_PTR(-ENOMEM);
- }
-
- scsi_host->max_channel = max_channel - 1;
- scsi_host->max_id = i2o_scsi_max_id;
- scsi_host->max_lun = i2o_scsi_max_lun;
- scsi_host->this_id = c->unit;
- scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size);
-
- i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata;
- i2o_shost->scsi_host = scsi_host;
- i2o_shost->iop = c;
- i2o_shost->lun = 1;
-
- i = 0;
- list_for_each_entry(i2o_dev, &c->devices, list)
- if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
- if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
- && (type == 0x01)) /* only SCSI bus */
- i2o_shost->channel[i++] = i2o_dev;
-
- if (i >= max_channel)
- break;
- }
-
- return i2o_shost;
-};
-
-/**
- * i2o_scsi_get_host - Get an I2O SCSI host
- * @c: I2O controller to for which to get the SCSI host
- *
- * If the I2O controller already exists as SCSI host, the SCSI host
- * is returned, otherwise the I2O controller is added to the SCSI
- * core.
- *
- * Returns pointer to the I2O SCSI host on success or NULL on failure.
- */
-static struct i2o_scsi_host *i2o_scsi_get_host(struct i2o_controller *c)
-{
- return c->driver_data[i2o_scsi_driver.context];
-};
-
-/**
- * i2o_scsi_remove - Remove I2O device from SCSI core
- * @dev: device which should be removed
- *
- * Removes the I2O device from the SCSI core again.
- *
- * Returns 0 on success.
- */
-static int i2o_scsi_remove(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_controller *c = i2o_dev->iop;
- struct i2o_scsi_host *i2o_shost;
- struct scsi_device *scsi_dev;
-
- osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
-
- i2o_shost = i2o_scsi_get_host(c);
-
- shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
- if (scsi_dev->hostdata == i2o_dev) {
- sysfs_remove_link(&i2o_dev->device.kobj, "scsi");
- scsi_remove_device(scsi_dev);
- scsi_device_put(scsi_dev);
- break;
- }
-
- return 0;
-};
-
-/**
- * i2o_scsi_probe - verify if dev is a I2O SCSI device and install it
- * @dev: device to verify if it is a I2O SCSI device
- *
- * Retrieve channel, id and lun for I2O device. If everything goes well
- * register the I2O device as SCSI device on the I2O SCSI controller.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_scsi_probe(struct device *dev)
-{
- struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_controller *c = i2o_dev->iop;
- struct i2o_scsi_host *i2o_shost;
- struct Scsi_Host *scsi_host;
- struct i2o_device *parent;
- struct scsi_device *scsi_dev;
- u32 id = -1;
- u64 lun = -1;
- int channel = -1;
- int i, rc;
-
- i2o_shost = i2o_scsi_get_host(c);
- if (!i2o_shost)
- return -EFAULT;
-
- scsi_host = i2o_shost->scsi_host;
-
- switch (i2o_dev->lct_data.class_id) {
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- case I2O_CLASS_EXECUTIVE:
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- if (c->adaptec) {
- u8 type;
- struct i2o_device *d = i2o_shost->channel[0];
-
- if (!i2o_parm_field_get(d, 0x0000, 0, &type, 1)
- && (type == 0x01)) /* SCSI bus */
- if (!i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
- channel = 0;
- if (i2o_dev->lct_data.class_id ==
- I2O_CLASS_RANDOM_BLOCK_STORAGE)
- lun =
- cpu_to_le64(i2o_shost->
- lun++);
- else
- lun = 0;
- }
- }
-#endif
- break;
-
- case I2O_CLASS_SCSI_PERIPHERAL:
- if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4))
- return -EFAULT;
-
- if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8))
- return -EFAULT;
-
- parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
- if (!parent) {
- osm_warn("can not find parent of device %03x\n",
- i2o_dev->lct_data.tid);
- return -EFAULT;
- }
-
- for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
- if (i2o_shost->channel[i] == parent)
- channel = i;
- break;
-
- default:
- return -EFAULT;
- }
-
- if (channel == -1) {
- osm_warn("can not find channel of device %03x\n",
- i2o_dev->lct_data.tid);
- return -EFAULT;
- }
-
- if (le32_to_cpu(id) >= scsi_host->max_id) {
- osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)",
- le32_to_cpu(id), scsi_host->max_id);
- return -EFAULT;
- }
-
- if (le64_to_cpu(lun) >= scsi_host->max_lun) {
- osm_warn("SCSI device lun (%lu) >= max_lun of I2O host (%d)",
- (long unsigned int)le64_to_cpu(lun),
- scsi_host->max_lun);
- return -EFAULT;
- }
-
- scsi_dev =
- __scsi_add_device(i2o_shost->scsi_host, channel, le32_to_cpu(id),
- le64_to_cpu(lun), i2o_dev);
-
- if (IS_ERR(scsi_dev)) {
- osm_warn("can not add SCSI device %03x\n",
- i2o_dev->lct_data.tid);
- return PTR_ERR(scsi_dev);
- }
-
- rc = sysfs_create_link(&i2o_dev->device.kobj,
- &scsi_dev->sdev_gendev.kobj, "scsi");
- if (rc)
- goto err;
-
- osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %ld\n",
- i2o_dev->lct_data.tid, channel, le32_to_cpu(id),
- (long unsigned int)le64_to_cpu(lun));
-
- return 0;
-
-err:
- scsi_remove_device(scsi_dev);
- return rc;
-};
-
-static const char *i2o_scsi_info(struct Scsi_Host *SChost)
-{
- struct i2o_scsi_host *hostdata;
- hostdata = (struct i2o_scsi_host *)SChost->hostdata;
- return hostdata->iop->name;
-}
-
-/**
- * i2o_scsi_reply - SCSI OSM message reply handler
- * @c: controller issuing the reply
- * @m: message id for flushing
- * @msg: the message from the controller
- *
- * Process reply messages (interrupts in normal scsi controller think).
- * We can get a variety of messages to process. The normal path is
- * scsi command completions. We must also deal with IOP failures,
- * the reply to a bus reset and the reply to a LUN query.
- *
- * Returns 0 on success and if the reply should not be flushed or > 0
- * on success and if the reply should be flushed. Returns negative error
- * code on failure and if the reply should be flushed.
- */
-static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
- struct i2o_message *msg)
-{
- struct scsi_cmnd *cmd;
- u32 error;
- struct device *dev;
-
- cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
- if (unlikely(!cmd)) {
- osm_err("NULL reply received!\n");
- return -1;
- }
-
- /*
- * Low byte is device status, next is adapter status,
- * (then one byte reserved), then request status.
- */
- error = le32_to_cpu(msg->body[0]);
-
- osm_debug("Completed %0x%p\n", cmd);
-
- cmd->result = error & 0xff;
- /*
- * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let
- * the SCSI layer handle the error
- */
- if (cmd->result)
- memcpy(cmd->sense_buffer, &msg->body[3],
- min(SCSI_SENSE_BUFFERSIZE, 40));
-
- /* only output error code if AdapterStatus is not HBA_SUCCESS */
- if ((error >> 8) & 0xff)
- osm_err("SCSI error %08x\n", error);
-
- dev = &c->pdev->dev;
-
- scsi_dma_unmap(cmd);
-
- cmd->scsi_done(cmd);
-
- return 1;
-};
-
-/**
- * i2o_scsi_notify_device_add - Retrieve notifications of added devices
- * @i2o_dev: the I2O device which was added
- *
- * If a I2O device is added we catch the notification, because I2O classes
- * other than SCSI peripheral will not be received through
- * i2o_scsi_probe().
- */
-static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
-{
- switch (i2o_dev->lct_data.class_id) {
- case I2O_CLASS_EXECUTIVE:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- i2o_scsi_probe(&i2o_dev->device);
- break;
-
- default:
- break;
- }
-};
-
-/**
- * i2o_scsi_notify_device_remove - Retrieve notifications of removed devices
- * @i2o_dev: the I2O device which was removed
- *
- * If a I2O device is removed, we catch the notification to remove the
- * corresponding SCSI device.
- */
-static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
-{
- switch (i2o_dev->lct_data.class_id) {
- case I2O_CLASS_EXECUTIVE:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- i2o_scsi_remove(&i2o_dev->device);
- break;
-
- default:
- break;
- }
-};
-
-/**
- * i2o_scsi_notify_controller_add - Retrieve notifications of added controllers
- * @c: the controller which was added
- *
- * If a I2O controller is added, we catch the notification to add a
- * corresponding Scsi_Host.
- */
-static void i2o_scsi_notify_controller_add(struct i2o_controller *c)
-{
- struct i2o_scsi_host *i2o_shost;
- int rc;
-
- i2o_shost = i2o_scsi_host_alloc(c);
- if (IS_ERR(i2o_shost)) {
- osm_err("Could not initialize SCSI host\n");
- return;
- }
-
- rc = scsi_add_host(i2o_shost->scsi_host, &c->device);
- if (rc) {
- osm_err("Could not add SCSI host\n");
- scsi_host_put(i2o_shost->scsi_host);
- return;
- }
-
- c->driver_data[i2o_scsi_driver.context] = i2o_shost;
-
- osm_debug("new I2O SCSI host added\n");
-};
-
-/**
- * i2o_scsi_notify_controller_remove - Retrieve notifications of removed controllers
- * @c: the controller which was removed
- *
- * If a I2O controller is removed, we catch the notification to remove the
- * corresponding Scsi_Host.
- */
-static void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
-{
- struct i2o_scsi_host *i2o_shost;
- i2o_shost = i2o_scsi_get_host(c);
- if (!i2o_shost)
- return;
-
- c->driver_data[i2o_scsi_driver.context] = NULL;
-
- scsi_remove_host(i2o_shost->scsi_host);
- scsi_host_put(i2o_shost->scsi_host);
- osm_debug("I2O SCSI host removed\n");
-};
-
-/* SCSI OSM driver struct */
-static struct i2o_driver i2o_scsi_driver = {
- .name = OSM_NAME,
- .reply = i2o_scsi_reply,
- .classes = i2o_scsi_class_id,
- .notify_device_add = i2o_scsi_notify_device_add,
- .notify_device_remove = i2o_scsi_notify_device_remove,
- .notify_controller_add = i2o_scsi_notify_controller_add,
- .notify_controller_remove = i2o_scsi_notify_controller_remove,
- .driver = {
- .probe = i2o_scsi_probe,
- .remove = i2o_scsi_remove,
- },
-};
-
-/**
- * i2o_scsi_queuecommand - queue a SCSI command
- * @SCpnt: scsi command pointer
- * @done: callback for completion
- *
- * Issue a scsi command asynchronously. Return 0 on success or 1 if
- * we hit an error (normally message queue congestion). The only
- * minor complication here is that I2O deals with the device addressing
- * so we have to map the bus/dev/lun back to an I2O handle as well
- * as faking absent devices ourself.
- *
- * Locks: takes the controller lock on error path only
- */
-
-static int i2o_scsi_queuecommand_lck(struct scsi_cmnd *SCpnt,
- void (*done) (struct scsi_cmnd *))
-{
- struct i2o_controller *c;
- struct i2o_device *i2o_dev;
- int tid;
- struct i2o_message *msg;
- /*
- * ENABLE_DISCONNECT
- * SIMPLE_TAG
- * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
- */
- u32 scsi_flags = 0x20a00000;
- u32 sgl_offset;
- u32 *mptr;
- u32 cmd = I2O_CMD_SCSI_EXEC << 24;
- int rc = 0;
-
- /*
- * Do the incoming paperwork
- */
- i2o_dev = SCpnt->device->hostdata;
-
- SCpnt->scsi_done = done;
-
- if (unlikely(!i2o_dev)) {
- osm_warn("no I2O device in request\n");
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
- goto exit;
- }
- c = i2o_dev->iop;
- tid = i2o_dev->lct_data.tid;
-
- osm_debug("qcmd: Tid = %03x\n", tid);
- osm_debug("Real scsi messages.\n");
-
- /*
- * Put together a scsi execscb message
- */
- switch (SCpnt->sc_data_direction) {
- case PCI_DMA_NONE:
- /* DATA NO XFER */
- sgl_offset = SGL_OFFSET_0;
- break;
-
- case PCI_DMA_TODEVICE:
- /* DATA OUT (iop-->dev) */
- scsi_flags |= 0x80000000;
- sgl_offset = SGL_OFFSET_10;
- break;
-
- case PCI_DMA_FROMDEVICE:
- /* DATA IN (iop<--dev) */
- scsi_flags |= 0x40000000;
- sgl_offset = SGL_OFFSET_10;
- break;
-
- default:
- /* Unknown - kill the command */
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
- goto exit;
- }
-
- /*
- * Obtain an I2O message. If there are none free then
- * throw it back to the scsi layer
- */
-
- msg = i2o_msg_get(c);
- if (IS_ERR(msg)) {
- rc = SCSI_MLQUEUE_HOST_BUSY;
- goto exit;
- }
-
- mptr = &msg->body[0];
-
-#if 0 /* this code can't work */
-#ifdef CONFIG_I2O_EXT_ADAPTEC
- if (c->adaptec) {
- u32 adpt_flags = 0;
-
- if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) {
- i2o_sg_io_hdr_t __user *usr_ptr =
- ((Sg_request *) (SCpnt->sc_request->
- upper_private_data))->header.
- usr_ptr;
-
- if (usr_ptr)
- get_user(adpt_flags, &usr_ptr->flags);
- }
-
- switch (i2o_dev->lct_data.class_id) {
- case I2O_CLASS_EXECUTIVE:
- case I2O_CLASS_RANDOM_BLOCK_STORAGE:
- /* interpret flag has to be set for executive */
- adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET;
- break;
-
- default:
- break;
- }
-
- /*
- * for Adaptec controllers we use the PRIVATE command, because
- * the normal SCSI EXEC doesn't support all SCSI commands on
- * all controllers (for example READ CAPACITY).
- */
- if (sgl_offset == SGL_OFFSET_10)
- sgl_offset = SGL_OFFSET_12;
- cmd = I2O_CMD_PRIVATE << 24;
- *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
- *mptr++ = cpu_to_le32(adpt_flags | tid);
- }
-#endif
-#endif
-
- msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
- msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context);
-
- /* We want the SCSI control block back */
- msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, SCpnt));
-
- /* LSI_920_PCI_QUIRK
- *
- * Intermittant observations of msg frame word data corruption
- * observed on msg[4] after:
- * WRITE, READ-MODIFY-WRITE
- * operations. 19990606 -sralston
- *
- * (Hence we build this word via tag. Its good practice anyway
- * we don't want fetches over PCI needlessly)
- */
-
- /* Attach tags to the devices */
- /* FIXME: implement
- if(SCpnt->device->tagged_supported) {
- if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
- scsi_flags |= 0x01000000;
- else if(SCpnt->tag == ORDERED_QUEUE_TAG)
- scsi_flags |= 0x01800000;
- }
- */
-
- *mptr++ = cpu_to_le32(scsi_flags | SCpnt->cmd_len);
-
- /* Write SCSI command into the message - always 16 byte block */
- memcpy(mptr, SCpnt->cmnd, 16);
- mptr += 4;
-
- if (sgl_offset != SGL_OFFSET_0) {
- /* write size of data addressed by SGL */
- *mptr++ = cpu_to_le32(scsi_bufflen(SCpnt));
-
- /* Now fill in the SGList and command */
-
- if (scsi_sg_count(SCpnt)) {
- if (!i2o_dma_map_sg(c, scsi_sglist(SCpnt),
- scsi_sg_count(SCpnt),
- SCpnt->sc_data_direction, &mptr))
- goto nomem;
- }
- }
-
- /* Stick the headers on */
- msg->u.head[0] =
- cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset);
-
- /* Queue the message */
- i2o_msg_post(c, msg);
-
- osm_debug("Issued %0x%p\n", SCpnt);
-
- return 0;
-
- nomem:
- rc = -ENOMEM;
- i2o_msg_nop(c, msg);
-
- exit:
- return rc;
-}
-
-static DEF_SCSI_QCMD(i2o_scsi_queuecommand)
-
-/**
- * i2o_scsi_abort - abort a running command
- * @SCpnt: command to abort
- *
- * Ask the I2O controller to abort a command. This is an asynchrnous
- * process and our callback handler will see the command complete with an
- * aborted message if it succeeds.
- *
- * Returns 0 if the command is successfully aborted or negative error code
- * on failure.
- */
-static int i2o_scsi_abort(struct scsi_cmnd *SCpnt)
-{
- struct i2o_device *i2o_dev;
- struct i2o_controller *c;
- struct i2o_message *msg;
- int tid;
- int status = FAILED;
-
- osm_warn("Aborting command block.\n");
-
- i2o_dev = SCpnt->device->hostdata;
- c = i2o_dev->iop;
- tid = i2o_dev->lct_data.tid;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return SCSI_MLQUEUE_HOST_BUSY;
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid);
- msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt));
-
- if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
- status = SUCCESS;
-
- return status;
-}
-
-/**
- * i2o_scsi_bios_param - Invent disk geometry
- * @sdev: scsi device
- * @dev: block layer device
- * @capacity: size in sectors
- * @ip: geometry array
- *
- * This is anyone's guess quite frankly. We use the same rules everyone
- * else appears to and hope. It seems to work.
- */
-
-static int i2o_scsi_bios_param(struct scsi_device *sdev,
- struct block_device *dev, sector_t capacity,
- int *ip)
-{
- int size;
-
- size = capacity;
- ip[0] = 64; /* heads */
- ip[1] = 32; /* sectors */
- if ((ip[2] = size >> 11) > 1024) { /* cylinders, test for big disk */
- ip[0] = 255; /* heads */
- ip[1] = 63; /* sectors */
- ip[2] = size / (255 * 63); /* cylinders */
- }
- return 0;
-}
-
-static struct scsi_host_template i2o_scsi_host_template = {
- .proc_name = OSM_NAME,
- .name = OSM_DESCRIPTION,
- .info = i2o_scsi_info,
- .queuecommand = i2o_scsi_queuecommand,
- .eh_abort_handler = i2o_scsi_abort,
- .bios_param = i2o_scsi_bios_param,
- .can_queue = I2O_SCSI_CAN_QUEUE,
- .sg_tablesize = 8,
- .cmd_per_lun = 6,
- .use_clustering = ENABLE_CLUSTERING,
-};
-
-/**
- * i2o_scsi_init - SCSI OSM initialization function
- *
- * Register SCSI OSM into I2O core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_scsi_init(void)
-{
- int rc;
-
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- /* Register SCSI OSM into I2O core */
- rc = i2o_driver_register(&i2o_scsi_driver);
- if (rc) {
- osm_err("Could not register SCSI driver\n");
- return rc;
- }
-
- return 0;
-};
-
-/**
- * i2o_scsi_exit - SCSI OSM exit function
- *
- * Unregisters SCSI OSM from I2O core.
- */
-static void __exit i2o_scsi_exit(void)
-{
- /* Unregister I2O SCSI OSM from I2O core */
- i2o_driver_unregister(&i2o_scsi_driver);
-};
-
-MODULE_AUTHOR("Red Hat Software");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_scsi_init);
-module_exit(i2o_scsi_exit);
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
deleted file mode 100644
index a8c08f332da0..000000000000
--- a/drivers/message/i2o/iop.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Functions to handle I2O controllers and I2O message handling
- *
- * Copyright (C) 1999-2002 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * A lot of the I2O message side code from this is taken from the
- * Red Creek RCPCI45 adapter driver by Red Creek Communications
- *
- * Fixes/additions:
- * Philipp Rumpf
- * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Deepak Saxena <deepak@plexity.net>
- * Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
- * Alan Cox <alan@lxorguk.ukuu.org.uk>:
- * Ported to Linux 2.5.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor fixes for 2.6.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "core.h"
-
-#define OSM_NAME "i2o"
-#define OSM_VERSION "1.325"
-#define OSM_DESCRIPTION "I2O subsystem"
-
-/* global I2O controller list */
-LIST_HEAD(i2o_controllers);
-
-/*
- * global I2O System Table. Contains information about all the IOPs in the
- * system. Used to inform IOPs about each others existence.
- */
-static struct i2o_dma i2o_systab;
-
-static int i2o_hrt_get(struct i2o_controller *c);
-
-/**
- * i2o_msg_get_wait - obtain an I2O message from the IOP
- * @c: I2O controller
- * @wait: how long to wait until timeout
- *
- * This function waits up to wait seconds for a message slot to be
- * available.
- *
- * On a success the message is returned and the pointer to the message is
- * set in msg. The returned message is the physical page frame offset
- * address from the read port (see the i2o spec). If no message is
- * available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
- */
-struct i2o_message *i2o_msg_get_wait(struct i2o_controller *c, int wait)
-{
- unsigned long timeout = jiffies + wait * HZ;
- struct i2o_message *msg;
-
- while (IS_ERR(msg = i2o_msg_get(c))) {
- if (time_after(jiffies, timeout)) {
- osm_debug("%s: Timeout waiting for message frame.\n",
- c->name);
- return ERR_PTR(-ETIMEDOUT);
- }
- schedule_timeout_uninterruptible(1);
- }
-
- return msg;
-};
-
-#if BITS_PER_LONG == 64
-/**
- * i2o_cntxt_list_add - Append a pointer to context list and return a id
- * @c: controller to which the context list belong
- * @ptr: pointer to add to the context list
- *
- * Because the context field in I2O is only 32-bit large, on 64-bit the
- * pointer is to large to fit in the context field. The i2o_cntxt_list
- * functions therefore map pointers to context fields.
- *
- * Returns context id > 0 on success or 0 on failure.
- */
-u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
-{
- struct i2o_context_list_element *entry;
- unsigned long flags;
-
- if (!ptr)
- osm_err("%s: couldn't add NULL pointer to context list!\n",
- c->name);
-
- entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- osm_err("%s: Could not allocate memory for context list element"
- "\n", c->name);
- return 0;
- }
-
- entry->ptr = ptr;
- entry->timestamp = jiffies;
- INIT_LIST_HEAD(&entry->list);
-
- spin_lock_irqsave(&c->context_list_lock, flags);
-
- if (unlikely(atomic_inc_and_test(&c->context_list_counter)))
- atomic_inc(&c->context_list_counter);
-
- entry->context = atomic_read(&c->context_list_counter);
-
- list_add(&entry->list, &c->context_list);
-
- spin_unlock_irqrestore(&c->context_list_lock, flags);
-
- osm_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
-
- return entry->context;
-};
-
-/**
- * i2o_cntxt_list_remove - Remove a pointer from the context list
- * @c: controller to which the context list belong
- * @ptr: pointer which should be removed from the context list
- *
- * Removes a previously added pointer from the context list and returns
- * the matching context id.
- *
- * Returns context id on success or 0 on failure.
- */
-u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
-{
- struct i2o_context_list_element *entry;
- u32 context = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&c->context_list_lock, flags);
- list_for_each_entry(entry, &c->context_list, list)
- if (entry->ptr == ptr) {
- list_del(&entry->list);
- context = entry->context;
- kfree(entry);
- break;
- }
- spin_unlock_irqrestore(&c->context_list_lock, flags);
-
- if (!context)
- osm_warn("%s: Could not remove nonexistent ptr %p\n", c->name,
- ptr);
-
- osm_debug("%s: remove ptr from context list %d -> %p\n", c->name,
- context, ptr);
-
- return context;
-};
-
-/**
- * i2o_cntxt_list_get - Get a pointer from the context list and remove it
- * @c: controller to which the context list belong
- * @context: context id to which the pointer belong
- *
- * Returns pointer to the matching context id on success or NULL on
- * failure.
- */
-void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
-{
- struct i2o_context_list_element *entry;
- unsigned long flags;
- void *ptr = NULL;
-
- spin_lock_irqsave(&c->context_list_lock, flags);
- list_for_each_entry(entry, &c->context_list, list)
- if (entry->context == context) {
- list_del(&entry->list);
- ptr = entry->ptr;
- kfree(entry);
- break;
- }
- spin_unlock_irqrestore(&c->context_list_lock, flags);
-
- if (!ptr)
- osm_warn("%s: context id %d not found\n", c->name, context);
-
- osm_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
- ptr);
-
- return ptr;
-};
-
-/**
- * i2o_cntxt_list_get_ptr - Get a context id from the context list
- * @c: controller to which the context list belong
- * @ptr: pointer to which the context id should be fetched
- *
- * Returns context id which matches to the pointer on success or 0 on
- * failure.
- */
-u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
-{
- struct i2o_context_list_element *entry;
- u32 context = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&c->context_list_lock, flags);
- list_for_each_entry(entry, &c->context_list, list)
- if (entry->ptr == ptr) {
- context = entry->context;
- break;
- }
- spin_unlock_irqrestore(&c->context_list_lock, flags);
-
- if (!context)
- osm_warn("%s: Could not find nonexistent ptr %p\n", c->name,
- ptr);
-
- osm_debug("%s: get context id from context list %p -> %d\n", c->name,
- ptr, context);
-
- return context;
-};
-#endif
-
-/**
- * i2o_iop_find - Find an I2O controller by id
- * @unit: unit number of the I2O controller to search for
- *
- * Lookup the I2O controller on the controller list.
- *
- * Returns pointer to the I2O controller on success or NULL if not found.
- */
-struct i2o_controller *i2o_find_iop(int unit)
-{
- struct i2o_controller *c;
-
- list_for_each_entry(c, &i2o_controllers, list) {
- if (c->unit == unit)
- return c;
- }
-
- return NULL;
-};
-
-/**
- * i2o_iop_find_device - Find a I2O device on an I2O controller
- * @c: I2O controller where the I2O device hangs on
- * @tid: TID of the I2O device to search for
- *
- * Searches the devices of the I2O controller for a device with TID tid and
- * returns it.
- *
- * Returns a pointer to the I2O device if found, otherwise NULL.
- */
-struct i2o_device *i2o_iop_find_device(struct i2o_controller *c, u16 tid)
-{
- struct i2o_device *dev;
-
- list_for_each_entry(dev, &c->devices, list)
- if (dev->lct_data.tid == tid)
- return dev;
-
- return NULL;
-};
-
-/**
- * i2o_quiesce_controller - quiesce controller
- * @c: controller
- *
- * Quiesce an IOP. Causes IOP to make external operation quiescent
- * (i2o 'READY' state). Internal operation of the IOP continues normally.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_quiesce(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- i2o_status_block *sb = c->status_block.virt;
- int rc;
-
- i2o_status_get(c);
-
- /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
- if ((sb->iop_state != ADAPTER_STATE_READY) &&
- (sb->iop_state != ADAPTER_STATE_OPERATIONAL))
- return 0;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SYS_QUIESCE << 24 | HOST_TID << 12 |
- ADAPTER_TID);
-
- /* Long timeout needed for quiesce if lots of devices */
- if ((rc = i2o_msg_post_wait(c, msg, 240)))
- osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc);
- else
- osm_debug("%s: Quiesced.\n", c->name);
-
- i2o_status_get(c); // Entered READY state
-
- return rc;
-};
-
-/**
- * i2o_iop_enable - move controller from ready to OPERATIONAL
- * @c: I2O controller
- *
- * Enable IOP. This allows the IOP to resume external operations and
- * reverses the effect of a quiesce. Returns zero or an error code if
- * an error occurs.
- */
-static int i2o_iop_enable(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- i2o_status_block *sb = c->status_block.virt;
- int rc;
-
- i2o_status_get(c);
-
- /* Enable only allowed on READY state */
- if (sb->iop_state != ADAPTER_STATE_READY)
- return -EINVAL;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SYS_ENABLE << 24 | HOST_TID << 12 |
- ADAPTER_TID);
-
- /* How long of a timeout do we need? */
- if ((rc = i2o_msg_post_wait(c, msg, 240)))
- osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc);
- else
- osm_debug("%s: Enabled.\n", c->name);
-
- i2o_status_get(c); // entered OPERATIONAL state
-
- return rc;
-};
-
-/**
- * i2o_iop_quiesce_all - Quiesce all I2O controllers on the system
- *
- * Quiesce all I2O controllers which are connected to the system.
- */
-static inline void i2o_iop_quiesce_all(void)
-{
- struct i2o_controller *c, *tmp;
-
- list_for_each_entry_safe(c, tmp, &i2o_controllers, list) {
- if (!c->no_quiesce)
- i2o_iop_quiesce(c);
- }
-};
-
-/**
- * i2o_iop_enable_all - Enables all controllers on the system
- *
- * Enables all I2O controllers which are connected to the system.
- */
-static inline void i2o_iop_enable_all(void)
-{
- struct i2o_controller *c, *tmp;
-
- list_for_each_entry_safe(c, tmp, &i2o_controllers, list)
- i2o_iop_enable(c);
-};
-
-/**
- * i2o_clear_controller - Bring I2O controller into HOLD state
- * @c: controller
- *
- * Clear an IOP to HOLD state, ie. terminate external operations, clear all
- * input queues and prepare for a system restart. IOP's internal operation
- * continues normally and the outbound queue is alive. The IOP is not
- * expected to rebuild its LCT.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_clear(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- int rc;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- /* Quiesce all IOPs first */
- i2o_iop_quiesce_all();
-
- msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_ADAPTER_CLEAR << 24 | HOST_TID << 12 |
- ADAPTER_TID);
-
- if ((rc = i2o_msg_post_wait(c, msg, 30)))
- osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc);
- else
- osm_debug("%s: Cleared.\n", c->name);
-
- /* Enable all IOPs */
- i2o_iop_enable_all();
-
- return rc;
-}
-
-/**
- * i2o_iop_init_outbound_queue - setup the outbound message queue
- * @c: I2O controller
- *
- * Clear and (re)initialize IOP's outbound queue and post the message
- * frames to the IOP.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
-{
- u32 m;
- volatile u8 *status = c->status.virt;
- struct i2o_message *msg;
- ulong timeout;
- int i;
-
- osm_debug("%s: Initializing Outbound Queue...\n", c->name);
-
- memset(c->status.virt, 0, 4);
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(0x00000000);
- msg->body[0] = cpu_to_le32(PAGE_SIZE);
- /* Outbound msg frame size in words and Initcode */
- msg->body[1] = cpu_to_le32(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80);
- msg->body[2] = cpu_to_le32(0xd0000004);
- msg->body[3] = cpu_to_le32(i2o_dma_low(c->status.phys));
- msg->body[4] = cpu_to_le32(i2o_dma_high(c->status.phys));
-
- i2o_msg_post(c, msg);
-
- timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
- while (*status <= I2O_CMD_IN_PROGRESS) {
- if (time_after(jiffies, timeout)) {
- osm_warn("%s: Timeout Initializing\n", c->name);
- return -ETIMEDOUT;
- }
- schedule_timeout_uninterruptible(1);
- }
-
- m = c->out_queue.phys;
-
- /* Post frames */
- for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) {
- i2o_flush_reply(c, m);
- udelay(1); /* Promise */
- m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32);
- }
-
- return 0;
-}
-
-/**
- * i2o_iop_reset - reset an I2O controller
- * @c: controller to reset
- *
- * Reset the IOP into INIT state and wait until IOP gets into RESET state.
- * Terminate all external operations, clear IOP's inbound and outbound
- * queues, terminate all DDMs, and reload the IOP's operating environment
- * and all local DDMs. The IOP rebuilds its LCT.
- */
-static int i2o_iop_reset(struct i2o_controller *c)
-{
- volatile u8 *status = c->status.virt;
- struct i2o_message *msg;
- unsigned long timeout;
- i2o_status_block *sb = c->status_block.virt;
- int rc = 0;
-
- osm_debug("%s: Resetting controller\n", c->name);
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- memset(c->status_block.virt, 0, 8);
-
- /* Quiesce all IOPs first */
- i2o_iop_quiesce_all();
-
- msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_ADAPTER_RESET << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(0x00000000);
- msg->body[0] = cpu_to_le32(0x00000000);
- msg->body[1] = cpu_to_le32(0x00000000);
- msg->body[2] = cpu_to_le32(i2o_dma_low(c->status.phys));
- msg->body[3] = cpu_to_le32(i2o_dma_high(c->status.phys));
-
- i2o_msg_post(c, msg);
-
- /* Wait for a reply */
- timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
- while (!*status) {
- if (time_after(jiffies, timeout))
- break;
-
- schedule_timeout_uninterruptible(1);
- }
-
- switch (*status) {
- case I2O_CMD_REJECTED:
- osm_warn("%s: IOP reset rejected\n", c->name);
- rc = -EPERM;
- break;
-
- case I2O_CMD_IN_PROGRESS:
- /*
- * Once the reset is sent, the IOP goes into the INIT state
- * which is indeterminate. We need to wait until the IOP has
- * rebooted before we can let the system talk to it. We read
- * the inbound Free_List until a message is available. If we
- * can't read one in the given amount of time, we assume the
- * IOP could not reboot properly.
- */
- osm_debug("%s: Reset in progress, waiting for reboot...\n",
- c->name);
-
- while (IS_ERR(msg = i2o_msg_get_wait(c, I2O_TIMEOUT_RESET))) {
- if (time_after(jiffies, timeout)) {
- osm_err("%s: IOP reset timeout.\n", c->name);
- rc = PTR_ERR(msg);
- goto exit;
- }
- schedule_timeout_uninterruptible(1);
- }
- i2o_msg_nop(c, msg);
-
- /* from here all quiesce commands are safe */
- c->no_quiesce = 0;
-
- /* verify if controller is in state RESET */
- i2o_status_get(c);
-
- if (!c->promise && (sb->iop_state != ADAPTER_STATE_RESET))
- osm_warn("%s: reset completed, but adapter not in RESET"
- " state.\n", c->name);
- else
- osm_debug("%s: reset completed.\n", c->name);
-
- break;
-
- default:
- osm_err("%s: IOP reset timeout.\n", c->name);
- rc = -ETIMEDOUT;
- break;
- }
-
- exit:
- /* Enable all IOPs */
- i2o_iop_enable_all();
-
- return rc;
-};
-
-/**
- * i2o_iop_activate - Bring controller up to HOLD
- * @c: controller
- *
- * This function brings an I2O controller into HOLD state. The adapter
- * is reset if necessary and then the queues and resource table are read.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_activate(struct i2o_controller *c)
-{
- i2o_status_block *sb = c->status_block.virt;
- int rc;
- int state;
-
- /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
- /* In READY state, Get status */
-
- rc = i2o_status_get(c);
- if (rc) {
- osm_info("%s: Unable to obtain status, attempting a reset.\n",
- c->name);
- rc = i2o_iop_reset(c);
- if (rc)
- return rc;
- }
-
- if (sb->i2o_version > I2OVER15) {
- osm_err("%s: Not running version 1.5 of the I2O Specification."
- "\n", c->name);
- return -ENODEV;
- }
-
- switch (sb->iop_state) {
- case ADAPTER_STATE_FAULTED:
- osm_err("%s: hardware fault\n", c->name);
- return -EFAULT;
-
- case ADAPTER_STATE_READY:
- case ADAPTER_STATE_OPERATIONAL:
- case ADAPTER_STATE_HOLD:
- case ADAPTER_STATE_FAILED:
- osm_debug("%s: already running, trying to reset...\n", c->name);
- rc = i2o_iop_reset(c);
- if (rc)
- return rc;
- }
-
- /* preserve state */
- state = sb->iop_state;
-
- rc = i2o_iop_init_outbound_queue(c);
- if (rc)
- return rc;
-
- /* if adapter was not in RESET state clear now */
- if (state != ADAPTER_STATE_RESET)
- i2o_iop_clear(c);
-
- i2o_status_get(c);
-
- if (sb->iop_state != ADAPTER_STATE_HOLD) {
- osm_err("%s: failed to bring IOP into HOLD state\n", c->name);
- return -EIO;
- }
-
- return i2o_hrt_get(c);
-};
-
-/**
- * i2o_iop_systab_set - Set the I2O System Table of the specified IOP
- * @c: I2O controller to which the system table should be send
- *
- * Before the systab could be set i2o_systab_build() must be called.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_systab_set(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- i2o_status_block *sb = c->status_block.virt;
- struct device *dev = &c->pdev->dev;
- struct resource *root;
- int rc;
-
- if (sb->current_mem_size < sb->desired_mem_size) {
- struct resource *res = &c->mem_resource;
- res->name = c->pdev->bus->name;
- res->flags = IORESOURCE_MEM;
- res->start = 0;
- res->end = 0;
- osm_info("%s: requires private memory resources.\n", c->name);
- root = pci_find_parent_resource(c->pdev, res);
- if (root == NULL)
- osm_warn("%s: Can't find parent resource!\n", c->name);
- if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
- NULL, NULL) >= 0) {
- c->mem_alloc = 1;
- sb->current_mem_size = resource_size(res);
- sb->current_mem_base = res->start;
- osm_info("%s: allocated %llu bytes of PCI memory at "
- "0x%016llX.\n", c->name,
- (unsigned long long)resource_size(res),
- (unsigned long long)res->start);
- }
- }
-
- if (sb->current_io_size < sb->desired_io_size) {
- struct resource *res = &c->io_resource;
- res->name = c->pdev->bus->name;
- res->flags = IORESOURCE_IO;
- res->start = 0;
- res->end = 0;
- osm_info("%s: requires private memory resources.\n", c->name);
- root = pci_find_parent_resource(c->pdev, res);
- if (root == NULL)
- osm_warn("%s: Can't find parent resource!\n", c->name);
- if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
- NULL, NULL) >= 0) {
- c->io_alloc = 1;
- sb->current_io_size = resource_size(res);
- sb->current_mem_base = res->start;
- osm_info("%s: allocated %llu bytes of PCI I/O at "
- "0x%016llX.\n", c->name,
- (unsigned long long)resource_size(res),
- (unsigned long long)res->start);
- }
- }
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- i2o_systab.phys = dma_map_single(dev, i2o_systab.virt, i2o_systab.len,
- PCI_DMA_TODEVICE);
- if (!i2o_systab.phys) {
- i2o_msg_nop(c, msg);
- return -ENOMEM;
- }
-
- msg->u.head[0] = cpu_to_le32(I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_SYS_TAB_SET << 24 | HOST_TID << 12 |
- ADAPTER_TID);
-
- /*
- * Provide three SGL-elements:
- * System table (SysTab), Private memory space declaration and
- * Private i/o space declaration
- */
-
- msg->body[0] = cpu_to_le32(c->unit + 2);
- msg->body[1] = cpu_to_le32(0x00000000);
- msg->body[2] = cpu_to_le32(0x54000000 | i2o_systab.len);
- msg->body[3] = cpu_to_le32(i2o_systab.phys);
- msg->body[4] = cpu_to_le32(0x54000000 | sb->current_mem_size);
- msg->body[5] = cpu_to_le32(sb->current_mem_base);
- msg->body[6] = cpu_to_le32(0xd4000000 | sb->current_io_size);
- msg->body[6] = cpu_to_le32(sb->current_io_base);
-
- rc = i2o_msg_post_wait(c, msg, 120);
-
- dma_unmap_single(dev, i2o_systab.phys, i2o_systab.len,
- PCI_DMA_TODEVICE);
-
- if (rc < 0)
- osm_err("%s: Unable to set SysTab (status=%#x).\n", c->name,
- -rc);
- else
- osm_debug("%s: SysTab set.\n", c->name);
-
- return rc;
-}
-
-/**
- * i2o_iop_online - Bring a controller online into OPERATIONAL state.
- * @c: I2O controller
- *
- * Send the system table and enable the I2O controller.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_iop_online(struct i2o_controller *c)
-{
- int rc;
-
- rc = i2o_iop_systab_set(c);
- if (rc)
- return rc;
-
- /* In READY state */
- osm_debug("%s: Attempting to enable...\n", c->name);
- rc = i2o_iop_enable(c);
- if (rc)
- return rc;
-
- return 0;
-};
-
-/**
- * i2o_iop_remove - Remove the I2O controller from the I2O core
- * @c: I2O controller
- *
- * Remove the I2O controller from the I2O core. If devices are attached to
- * the controller remove these also and finally reset the controller.
- */
-void i2o_iop_remove(struct i2o_controller *c)
-{
- struct i2o_device *dev, *tmp;
-
- osm_debug("%s: deleting controller\n", c->name);
-
- i2o_driver_notify_controller_remove_all(c);
-
- list_del(&c->list);
-
- list_for_each_entry_safe(dev, tmp, &c->devices, list)
- i2o_device_remove(dev);
-
- device_del(&c->device);
-
- /* Ask the IOP to switch to RESET state */
- i2o_iop_reset(c);
-}
-
-/**
- * i2o_systab_build - Build system table
- *
- * The system table contains information about all the IOPs in the system
- * (duh) and is used by the Executives on the IOPs to establish peer2peer
- * connections. We're not supporting peer2peer at the moment, but this
- * will be needed down the road for things like lan2lan forwarding.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_systab_build(void)
-{
- struct i2o_controller *c, *tmp;
- int num_controllers = 0;
- u32 change_ind = 0;
- int count = 0;
- struct i2o_sys_tbl *systab = i2o_systab.virt;
-
- list_for_each_entry_safe(c, tmp, &i2o_controllers, list)
- num_controllers++;
-
- if (systab) {
- change_ind = systab->change_ind;
- kfree(i2o_systab.virt);
- }
-
- /* Header + IOPs */
- i2o_systab.len = sizeof(struct i2o_sys_tbl) + num_controllers *
- sizeof(struct i2o_sys_tbl_entry);
-
- systab = i2o_systab.virt = kzalloc(i2o_systab.len, GFP_KERNEL);
- if (!systab) {
- osm_err("unable to allocate memory for System Table\n");
- return -ENOMEM;
- }
-
- systab->version = I2OVERSION;
- systab->change_ind = change_ind + 1;
-
- list_for_each_entry_safe(c, tmp, &i2o_controllers, list) {
- i2o_status_block *sb;
-
- if (count >= num_controllers) {
- osm_err("controller added while building system table"
- "\n");
- break;
- }
-
- sb = c->status_block.virt;
-
- /*
- * Get updated IOP state so we have the latest information
- *
- * We should delete the controller at this point if it
- * doesn't respond since if it's not on the system table
- * it is techninically not part of the I2O subsystem...
- */
- if (unlikely(i2o_status_get(c))) {
- osm_err("%s: Deleting b/c could not get status while "
- "attempting to build system table\n", c->name);
- i2o_iop_remove(c);
- continue; // try the next one
- }
-
- systab->iops[count].org_id = sb->org_id;
- systab->iops[count].iop_id = c->unit + 2;
- systab->iops[count].seg_num = 0;
- systab->iops[count].i2o_version = sb->i2o_version;
- systab->iops[count].iop_state = sb->iop_state;
- systab->iops[count].msg_type = sb->msg_type;
- systab->iops[count].frame_size = sb->inbound_frame_size;
- systab->iops[count].last_changed = change_ind;
- systab->iops[count].iop_capabilities = sb->iop_capabilities;
- systab->iops[count].inbound_low =
- i2o_dma_low(c->base.phys + I2O_IN_PORT);
- systab->iops[count].inbound_high =
- i2o_dma_high(c->base.phys + I2O_IN_PORT);
-
- count++;
- }
-
- systab->num_entries = count;
-
- return 0;
-};
-
-/**
- * i2o_parse_hrt - Parse the hardware resource table.
- * @c: I2O controller
- *
- * We don't do anything with it except dumping it (in debug mode).
- *
- * Returns 0.
- */
-static int i2o_parse_hrt(struct i2o_controller *c)
-{
- i2o_dump_hrt(c);
- return 0;
-};
-
-/**
- * i2o_status_get - Get the status block from the I2O controller
- * @c: I2O controller
- *
- * Issue a status query on the controller. This updates the attached
- * status block. The status block could then be accessed through
- * c->status_block.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_status_get(struct i2o_controller *c)
-{
- struct i2o_message *msg;
- volatile u8 *status_block;
- unsigned long timeout;
-
- status_block = (u8 *) c->status_block.virt;
- memset(c->status_block.virt, 0, sizeof(i2o_status_block));
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_STATUS_GET << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(0x00000000);
- msg->body[0] = cpu_to_le32(0x00000000);
- msg->body[1] = cpu_to_le32(0x00000000);
- msg->body[2] = cpu_to_le32(i2o_dma_low(c->status_block.phys));
- msg->body[3] = cpu_to_le32(i2o_dma_high(c->status_block.phys));
- msg->body[4] = cpu_to_le32(sizeof(i2o_status_block)); /* always 88 bytes */
-
- i2o_msg_post(c, msg);
-
- /* Wait for a reply */
- timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;
- while (status_block[87] != 0xFF) {
- if (time_after(jiffies, timeout)) {
- osm_err("%s: Get status timeout.\n", c->name);
- return -ETIMEDOUT;
- }
-
- schedule_timeout_uninterruptible(1);
- }
-
-#ifdef DEBUG
- i2o_debug_state(c);
-#endif
-
- return 0;
-}
-
-/*
- * i2o_hrt_get - Get the Hardware Resource Table from the I2O controller
- * @c: I2O controller from which the HRT should be fetched
- *
- * The HRT contains information about possible hidden devices but is
- * mostly useless to us.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_hrt_get(struct i2o_controller *c)
-{
- int rc;
- int i;
- i2o_hrt *hrt = c->hrt.virt;
- u32 size = sizeof(i2o_hrt);
- struct device *dev = &c->pdev->dev;
-
- for (i = 0; i < I2O_HRT_GET_TRIES; i++) {
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(SIX_WORD_MSG_SIZE | SGL_OFFSET_4);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_HRT_GET << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->body[0] = cpu_to_le32(0xd0000000 | c->hrt.len);
- msg->body[1] = cpu_to_le32(c->hrt.phys);
-
- rc = i2o_msg_post_wait_mem(c, msg, 20, &c->hrt);
-
- if (rc < 0) {
- osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,
- -rc);
- return rc;
- }
-
- size = hrt->num_entries * hrt->entry_len << 2;
- if (size > c->hrt.len) {
- if (i2o_dma_realloc(dev, &c->hrt, size))
- return -ENOMEM;
- else
- hrt = c->hrt.virt;
- } else
- return i2o_parse_hrt(c);
- }
-
- osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name,
- I2O_HRT_GET_TRIES);
-
- return -EBUSY;
-}
-
-/**
- * i2o_iop_release - release the memory for a I2O controller
- * @dev: I2O controller which should be released
- *
- * Release the allocated memory. This function is called if refcount of
- * device reaches 0 automatically.
- */
-static void i2o_iop_release(struct device *dev)
-{
- struct i2o_controller *c = to_i2o_controller(dev);
-
- i2o_iop_free(c);
-};
-
-/**
- * i2o_iop_alloc - Allocate and initialize a i2o_controller struct
- *
- * Allocate the necessary memory for a i2o_controller struct and
- * initialize the lists and message mempool.
- *
- * Returns a pointer to the I2O controller or a negative error code on
- * failure.
- */
-struct i2o_controller *i2o_iop_alloc(void)
-{
- static int unit = 0; /* 0 and 1 are NULL IOP and Local Host */
- struct i2o_controller *c;
- char poolname[32];
-
- c = kzalloc(sizeof(*c), GFP_KERNEL);
- if (!c) {
- osm_err("i2o: Insufficient memory to allocate a I2O controller."
- "\n");
- return ERR_PTR(-ENOMEM);
- }
-
- c->unit = unit++;
- sprintf(c->name, "iop%d", c->unit);
-
- snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name);
- if (i2o_pool_alloc
- (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32),
- I2O_MSG_INPOOL_MIN)) {
- kfree(c);
- return ERR_PTR(-ENOMEM);
- };
-
- INIT_LIST_HEAD(&c->devices);
- spin_lock_init(&c->lock);
- mutex_init(&c->lct_lock);
-
- device_initialize(&c->device);
-
- c->device.release = &i2o_iop_release;
-
- dev_set_name(&c->device, "iop%d", c->unit);
-
-#if BITS_PER_LONG == 64
- spin_lock_init(&c->context_list_lock);
- atomic_set(&c->context_list_counter, 0);
- INIT_LIST_HEAD(&c->context_list);
-#endif
-
- return c;
-};
-
-/**
- * i2o_iop_add - Initialize the I2O controller and add him to the I2O core
- * @c: controller
- *
- * Initialize the I2O controller and if no error occurs add him to the I2O
- * core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_iop_add(struct i2o_controller *c)
-{
- int rc;
-
- if ((rc = device_add(&c->device))) {
- osm_err("%s: could not add controller\n", c->name);
- goto iop_reset;
- }
-
- osm_info("%s: Activating I2O controller...\n", c->name);
- osm_info("%s: This may take a few minutes if there are many devices\n",
- c->name);
-
- if ((rc = i2o_iop_activate(c))) {
- osm_err("%s: could not activate controller\n", c->name);
- goto device_del;
- }
-
- osm_debug("%s: building sys table...\n", c->name);
-
- if ((rc = i2o_systab_build()))
- goto device_del;
-
- osm_debug("%s: online controller...\n", c->name);
-
- if ((rc = i2o_iop_online(c)))
- goto device_del;
-
- osm_debug("%s: getting LCT...\n", c->name);
-
- if ((rc = i2o_exec_lct_get(c)))
- goto device_del;
-
- list_add(&c->list, &i2o_controllers);
-
- i2o_driver_notify_controller_add_all(c);
-
- osm_info("%s: Controller added\n", c->name);
-
- return 0;
-
- device_del:
- device_del(&c->device);
-
- iop_reset:
- i2o_iop_reset(c);
-
- return rc;
-};
-
-/**
- * i2o_event_register - Turn on/off event notification for a I2O device
- * @dev: I2O device which should receive the event registration request
- * @drv: driver which want to get notified
- * @tcntxt: transaction context to use with this notifier
- * @evt_mask: mask of events
- *
- * Create and posts an event registration message to the task. No reply
- * is waited for, or expected. If you do not want further notifications,
- * call the i2o_event_register again with a evt_mask of 0.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_event_register(struct i2o_device *dev, struct i2o_driver *drv,
- int tcntxt, u32 evt_mask)
-{
- struct i2o_controller *c = dev->iop;
- struct i2o_message *msg;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
- msg->u.head[1] =
- cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | dev->
- lct_data.tid);
- msg->u.s.icntxt = cpu_to_le32(drv->context);
- msg->u.s.tcntxt = cpu_to_le32(tcntxt);
- msg->body[0] = cpu_to_le32(evt_mask);
-
- i2o_msg_post(c, msg);
-
- return 0;
-};
-
-/**
- * i2o_iop_init - I2O main initialization function
- *
- * Initialize the I2O drivers (OSM) functions, register the Executive OSM,
- * initialize the I2O PCI part and finally initialize I2O device stuff.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int __init i2o_iop_init(void)
-{
- int rc = 0;
-
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
- if ((rc = i2o_driver_init()))
- goto exit;
-
- if ((rc = i2o_exec_init()))
- goto driver_exit;
-
- if ((rc = i2o_pci_init()))
- goto exec_exit;
-
- return 0;
-
- exec_exit:
- i2o_exec_exit();
-
- driver_exit:
- i2o_driver_exit();
-
- exit:
- return rc;
-}
-
-/**
- * i2o_iop_exit - I2O main exit function
- *
- * Removes I2O controllers from PCI subsystem and shut down OSMs.
- */
-static void __exit i2o_iop_exit(void)
-{
- i2o_pci_exit();
- i2o_exec_exit();
- i2o_driver_exit();
-};
-
-module_init(i2o_iop_init);
-module_exit(i2o_iop_exit);
-
-MODULE_AUTHOR("Red Hat Software");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-#if BITS_PER_LONG == 64
-EXPORT_SYMBOL(i2o_cntxt_list_add);
-EXPORT_SYMBOL(i2o_cntxt_list_get);
-EXPORT_SYMBOL(i2o_cntxt_list_remove);
-EXPORT_SYMBOL(i2o_cntxt_list_get_ptr);
-#endif
-EXPORT_SYMBOL(i2o_msg_get_wait);
-EXPORT_SYMBOL(i2o_find_iop);
-EXPORT_SYMBOL(i2o_iop_find_device);
-EXPORT_SYMBOL(i2o_event_register);
-EXPORT_SYMBOL(i2o_status_get);
-EXPORT_SYMBOL(i2o_controllers);
diff --git a/drivers/message/i2o/memory.c b/drivers/message/i2o/memory.c
deleted file mode 100644
index 292b41e49fbd..000000000000
--- a/drivers/message/i2o/memory.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Functions to handle I2O memory
- *
- * Pulled from the inlines in i2o headers and uninlined
- *
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/i2o.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "core.h"
-
-/* Protects our 32/64bit mask switching */
-static DEFINE_MUTEX(mem_lock);
-
-/**
- * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
- * @c: I2O controller for which the calculation should be done
- * @body_size: maximum body size used for message in 32-bit words.
- *
- * Return the maximum number of SG elements in a SG list.
- */
-u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
-{
- i2o_status_block *sb = c->status_block.virt;
- u16 sg_count =
- (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
- body_size;
-
- if (c->pae_support) {
- /*
- * for 64-bit a SG attribute element must be added and each
- * SG element needs 12 bytes instead of 8.
- */
- sg_count -= 2;
- sg_count /= 3;
- } else
- sg_count /= 2;
-
- if (c->short_req && (sg_count > 8))
- sg_count = 8;
-
- return sg_count;
-}
-EXPORT_SYMBOL_GPL(i2o_sg_tablesize);
-
-
-/**
- * i2o_dma_map_single - Map pointer to controller and fill in I2O message.
- * @c: I2O controller
- * @ptr: pointer to the data which should be mapped
- * @size: size of data in bytes
- * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- * @sg_ptr: pointer to the SG list inside the I2O message
- *
- * This function does all necessary DMA handling and also writes the I2O
- * SGL elements into the I2O message. For details on DMA handling see also
- * dma_map_single(). The pointer sg_ptr will only be set to the end of the
- * SG list if the allocation was successful.
- *
- * Returns DMA address which must be checked for failures using
- * dma_mapping_error().
- */
-dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
- size_t size,
- enum dma_data_direction direction,
- u32 ** sg_ptr)
-{
- u32 sg_flags;
- u32 *mptr = *sg_ptr;
- dma_addr_t dma_addr;
-
- switch (direction) {
- case DMA_TO_DEVICE:
- sg_flags = 0xd4000000;
- break;
- case DMA_FROM_DEVICE:
- sg_flags = 0xd0000000;
- break;
- default:
- return 0;
- }
-
- dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
- if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
- *mptr++ = cpu_to_le32(0x7C020002);
- *mptr++ = cpu_to_le32(PAGE_SIZE);
- }
-#endif
-
- *mptr++ = cpu_to_le32(sg_flags | size);
- *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support)
- *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
-#endif
- *sg_ptr = mptr;
- }
- return dma_addr;
-}
-EXPORT_SYMBOL_GPL(i2o_dma_map_single);
-
-/**
- * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
- * @c: I2O controller
- * @sg: SG list to be mapped
- * @sg_count: number of elements in the SG list
- * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- * @sg_ptr: pointer to the SG list inside the I2O message
- *
- * This function does all necessary DMA handling and also writes the I2O
- * SGL elements into the I2O message. For details on DMA handling see also
- * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
- * list if the allocation was successful.
- *
- * Returns 0 on failure or 1 on success.
- */
-int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg,
- int sg_count, enum dma_data_direction direction, u32 ** sg_ptr)
-{
- u32 sg_flags;
- u32 *mptr = *sg_ptr;
-
- switch (direction) {
- case DMA_TO_DEVICE:
- sg_flags = 0x14000000;
- break;
- case DMA_FROM_DEVICE:
- sg_flags = 0x10000000;
- break;
- default:
- return 0;
- }
-
- sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
- if (!sg_count)
- return 0;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
- *mptr++ = cpu_to_le32(0x7C020002);
- *mptr++ = cpu_to_le32(PAGE_SIZE);
- }
-#endif
-
- while (sg_count-- > 0) {
- if (!sg_count)
- sg_flags |= 0xC0000000;
- *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
- *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support)
- *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
-#endif
- sg = sg_next(sg);
- }
- *sg_ptr = mptr;
-
- return 1;
-}
-EXPORT_SYMBOL_GPL(i2o_dma_map_sg);
-
-/**
- * i2o_dma_alloc - Allocate DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: i2o_dma struct which should get the DMA buffer
- * @len: length of the new DMA memory
- *
- * Allocate a coherent DMA memory and write the pointers into addr.
- *
- * Returns 0 on success or -ENOMEM on failure.
- */
-int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- int dma_64 = 0;
-
- mutex_lock(&mem_lock);
- if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_BIT_MASK(64))) {
- dma_64 = 1;
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- mutex_unlock(&mem_lock);
- return -ENOMEM;
- }
- }
-
- addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL);
-
- if ((sizeof(dma_addr_t) > 4) && dma_64)
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
- printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
- mutex_unlock(&mem_lock);
-
- if (!addr->virt)
- return -ENOMEM;
-
- memset(addr->virt, 0, len);
- addr->len = len;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(i2o_dma_alloc);
-
-
-/**
- * i2o_dma_free - Free DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: i2o_dma struct which contains the DMA buffer
- *
- * Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
- if (addr->virt) {
- if (addr->phys)
- dma_free_coherent(dev, addr->len, addr->virt,
- addr->phys);
- else
- kfree(addr->virt);
- addr->virt = NULL;
- }
-}
-EXPORT_SYMBOL_GPL(i2o_dma_free);
-
-
-/**
- * i2o_dma_realloc - Realloc DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: pointer to a i2o_dma struct DMA buffer
- * @len: new length of memory
- *
- * If there was something allocated in the addr, free it first. If len > 0
- * than try to allocate it and write the addresses back to the addr
- * structure. If len == 0 set the virtual address to NULL.
- *
- * Returns the 0 on success or negative error code on failure.
- */
-int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len)
-{
- i2o_dma_free(dev, addr);
-
- if (len)
- return i2o_dma_alloc(dev, addr, len);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(i2o_dma_realloc);
-
-/*
- * i2o_pool_alloc - Allocate an slab cache and mempool
- * @mempool: pointer to struct i2o_pool to write data into.
- * @name: name which is used to identify cache
- * @size: size of each object
- * @min_nr: minimum number of objects
- *
- * First allocates a slab cache with name and size. Then allocates a
- * mempool which uses the slab cache for allocation and freeing.
- *
- * Returns 0 on success or negative error code on failure.
- */
-int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
- size_t size, int min_nr)
-{
- pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
- if (!pool->name)
- goto exit;
- strcpy(pool->name, name);
-
- pool->slab =
- kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
- if (!pool->slab)
- goto free_name;
-
- pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
- if (!pool->mempool)
- goto free_slab;
-
- return 0;
-
-free_slab:
- kmem_cache_destroy(pool->slab);
-
-free_name:
- kfree(pool->name);
-
-exit:
- return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(i2o_pool_alloc);
-
-/*
- * i2o_pool_free - Free slab cache and mempool again
- * @mempool: pointer to struct i2o_pool which should be freed
- *
- * Note that you have to return all objects to the mempool again before
- * calling i2o_pool_free().
- */
-void i2o_pool_free(struct i2o_pool *pool)
-{
- mempool_destroy(pool->mempool);
- kmem_cache_destroy(pool->slab);
- kfree(pool->name);
-};
-EXPORT_SYMBOL_GPL(i2o_pool_free);
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
deleted file mode 100644
index 0f9f3e1a2b6b..000000000000
--- a/drivers/message/i2o/pci.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * PCI handling of I2O controller
- *
- * Copyright (C) 1999-2002 Red Hat Software
- *
- * Written by Alan Cox, Building Number Three Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * A lot of the I2O message side code from this is taken from the Red
- * Creek RCPCI45 adapter driver by Red Creek Communications
- *
- * Fixes/additions:
- * Philipp Rumpf
- * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Deepak Saxena <deepak@plexity.net>
- * Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
- * Alan Cox <alan@lxorguk.ukuu.org.uk>:
- * Ported to Linux 2.5.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Minor fixes for 2.6.
- * Markus Lidel <Markus.Lidel@shadowconnect.com>:
- * Support for sysfs included.
- */
-
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/i2o.h>
-#include <linux/module.h>
-#include "core.h"
-
-#define OSM_DESCRIPTION "I2O-subsystem"
-
-/* PCI device id table for all I2O controllers */
-static struct pci_device_id i2o_pci_ids[] = {
- {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)},
- {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)},
- {.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962,
- .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID},
- {0}
-};
-
-/**
- * i2o_pci_free - Frees the DMA memory for the I2O controller
- * @c: I2O controller to free
- *
- * Remove all allocated DMA memory and unmap memory IO regions. If MTRR
- * is enabled, also remove it again.
- */
-static void i2o_pci_free(struct i2o_controller *c)
-{
- struct device *dev;
-
- dev = &c->pdev->dev;
-
- i2o_dma_free(dev, &c->out_queue);
- i2o_dma_free(dev, &c->status_block);
- kfree(c->lct);
- i2o_dma_free(dev, &c->dlct);
- i2o_dma_free(dev, &c->hrt);
- i2o_dma_free(dev, &c->status);
-
- if (c->raptor && c->in_queue.virt)
- iounmap(c->in_queue.virt);
-
- if (c->base.virt)
- iounmap(c->base.virt);
-
- pci_release_regions(c->pdev);
-}
-
-/**
- * i2o_pci_alloc - Allocate DMA memory, map IO memory for I2O controller
- * @c: I2O controller
- *
- * Allocate DMA memory for a PCI (or in theory AGP) I2O controller. All
- * IO mappings are also done here. If MTRR is enabled, also do add memory
- * regions here.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_pci_alloc(struct i2o_controller *c)
-{
- struct pci_dev *pdev = c->pdev;
- struct device *dev = &pdev->dev;
- int i;
-
- if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
- printk(KERN_ERR "%s: device already claimed\n", c->name);
- return -ENODEV;
- }
-
- for (i = 0; i < 6; i++) {
- /* Skip I/O spaces */
- if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
- if (!c->base.phys) {
- c->base.phys = pci_resource_start(pdev, i);
- c->base.len = pci_resource_len(pdev, i);
-
- /*
- * If we know what card it is, set the size
- * correctly. Code is taken from dpt_i2o.c
- */
- if (pdev->device == 0xa501) {
- if (pdev->subsystem_device >= 0xc032 &&
- pdev->subsystem_device <= 0xc03b) {
- if (c->base.len > 0x400000)
- c->base.len = 0x400000;
- } else {
- if (c->base.len > 0x100000)
- c->base.len = 0x100000;
- }
- }
- if (!c->raptor)
- break;
- } else {
- c->in_queue.phys = pci_resource_start(pdev, i);
- c->in_queue.len = pci_resource_len(pdev, i);
- break;
- }
- }
- }
-
- if (i == 6) {
- printk(KERN_ERR "%s: I2O controller has no memory regions"
- " defined.\n", c->name);
- i2o_pci_free(c);
- return -EINVAL;
- }
-
- /* Map the I2O controller */
- if (c->raptor) {
- printk(KERN_INFO "%s: PCI I2O controller\n", c->name);
- printk(KERN_INFO " BAR0 at 0x%08lX size=%ld\n",
- (unsigned long)c->base.phys, (unsigned long)c->base.len);
- printk(KERN_INFO " BAR1 at 0x%08lX size=%ld\n",
- (unsigned long)c->in_queue.phys,
- (unsigned long)c->in_queue.len);
- } else
- printk(KERN_INFO "%s: PCI I2O controller at %08lX size=%ld\n",
- c->name, (unsigned long)c->base.phys,
- (unsigned long)c->base.len);
-
- c->base.virt = ioremap_nocache(c->base.phys, c->base.len);
- if (!c->base.virt) {
- printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- if (c->raptor) {
- c->in_queue.virt =
- ioremap_nocache(c->in_queue.phys, c->in_queue.len);
- if (!c->in_queue.virt) {
- printk(KERN_ERR "%s: Unable to map controller.\n",
- c->name);
- i2o_pci_free(c);
- return -ENOMEM;
- }
- } else
- c->in_queue = c->base;
-
- c->irq_status = c->base.virt + I2O_IRQ_STATUS;
- c->irq_mask = c->base.virt + I2O_IRQ_MASK;
- c->in_port = c->base.virt + I2O_IN_PORT;
- c->out_port = c->base.virt + I2O_OUT_PORT;
-
- /* Motorola/Freescale chip does not follow spec */
- if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) {
- /* Check if CPU is enabled */
- if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) {
- printk(KERN_INFO "%s: MPC82XX needs CPU running to "
- "service I2O.\n", c->name);
- i2o_pci_free(c);
- return -ENODEV;
- } else {
- c->irq_status += I2O_MOTOROLA_PORT_OFFSET;
- c->irq_mask += I2O_MOTOROLA_PORT_OFFSET;
- c->in_port += I2O_MOTOROLA_PORT_OFFSET;
- c->out_port += I2O_MOTOROLA_PORT_OFFSET;
- printk(KERN_INFO "%s: MPC82XX workarounds activated.\n",
- c->name);
- }
- }
-
- if (i2o_dma_alloc(dev, &c->status, 8)) {
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) {
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- if (i2o_dma_alloc(dev, &c->dlct, 8192)) {
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) {
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- if (i2o_dma_alloc(dev, &c->out_queue,
- I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
- sizeof(u32))) {
- i2o_pci_free(c);
- return -ENOMEM;
- }
-
- pci_set_drvdata(pdev, c);
-
- return 0;
-}
-
-/**
- * i2o_pci_interrupt - Interrupt handler for I2O controller
- * @irq: interrupt line
- * @dev_id: pointer to the I2O controller
- *
- * Handle an interrupt from a PCI based I2O controller. This turns out
- * to be rather simple. We keep the controller pointer in the cookie.
- */
-static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id)
-{
- struct i2o_controller *c = dev_id;
- u32 m;
- irqreturn_t rc = IRQ_NONE;
-
- while (readl(c->irq_status) & I2O_IRQ_OUTBOUND_POST) {
- m = readl(c->out_port);
- if (m == I2O_QUEUE_EMPTY) {
- /*
- * Old 960 steppings had a bug in the I2O unit that
- * caused the queue to appear empty when it wasn't.
- */
- m = readl(c->out_port);
- if (unlikely(m == I2O_QUEUE_EMPTY))
- break;
- }
-
- /* dispatch it */
- if (i2o_driver_dispatch(c, m))
- /* flush it if result != 0 */
- i2o_flush_reply(c, m);
-
- rc = IRQ_HANDLED;
- }
-
- return rc;
-}
-
-/**
- * i2o_pci_irq_enable - Allocate interrupt for I2O controller
- * @c: i2o_controller that the request is for
- *
- * Allocate an interrupt for the I2O controller, and activate interrupts
- * on the I2O controller.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_pci_irq_enable(struct i2o_controller *c)
-{
- struct pci_dev *pdev = c->pdev;
- int rc;
-
- writel(0xffffffff, c->irq_mask);
-
- if (pdev->irq) {
- rc = request_irq(pdev->irq, i2o_pci_interrupt, IRQF_SHARED,
- c->name, c);
- if (rc < 0) {
- printk(KERN_ERR "%s: unable to allocate interrupt %d."
- "\n", c->name, pdev->irq);
- return rc;
- }
- }
-
- writel(0x00000000, c->irq_mask);
-
- printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
-
- return 0;
-}
-
-/**
- * i2o_pci_irq_disable - Free interrupt for I2O controller
- * @c: I2O controller
- *
- * Disable interrupts in I2O controller and then free interrupt.
- */
-static void i2o_pci_irq_disable(struct i2o_controller *c)
-{
- writel(0xffffffff, c->irq_mask);
-
- if (c->pdev->irq > 0)
- free_irq(c->pdev->irq, c);
-}
-
-/**
- * i2o_pci_probe - Probe the PCI device for an I2O controller
- * @pdev: PCI device to test
- * @id: id which matched with the PCI device id table
- *
- * Probe the PCI device for any device which is a memory of the
- * Intelligent, I2O class or an Adaptec Zero Channel Controller. We
- * attempt to set up each such device and register it with the core.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static int i2o_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- struct i2o_controller *c;
- int rc;
- struct pci_dev *i960 = NULL;
-
- printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
-
- if ((pdev->class & 0xff) > 1) {
- printk(KERN_WARNING "i2o: %s does not support I2O 1.5 "
- "(skipping).\n", pci_name(pdev));
- return -ENODEV;
- }
-
- if ((rc = pci_enable_device(pdev))) {
- printk(KERN_WARNING "i2o: couldn't enable device %s\n",
- pci_name(pdev));
- return rc;
- }
-
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
- pci_name(pdev));
- rc = -ENODEV;
- goto disable;
- }
-
- pci_set_master(pdev);
-
- c = i2o_iop_alloc();
- if (IS_ERR(c)) {
- printk(KERN_ERR "i2o: couldn't allocate memory for %s\n",
- pci_name(pdev));
- rc = PTR_ERR(c);
- goto disable;
- } else
- printk(KERN_INFO "%s: controller found (%s)\n", c->name,
- pci_name(pdev));
-
- c->pdev = pdev;
- c->device.parent = &pdev->dev;
-
- /* Cards that fall apart if you hit them with large I/O loads... */
- if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
- c->short_req = 1;
- printk(KERN_INFO "%s: Symbios FC920 workarounds activated.\n",
- c->name);
- }
-
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
- /*
- * Expose the ship behind i960 for initialization, or it will
- * failed
- */
- i960 = pci_get_slot(c->pdev->bus,
- PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
-
- if (i960) {
- pci_write_config_word(i960, 0x42, 0);
- pci_dev_put(i960);
- }
-
- c->promise = 1;
- c->limit_sectors = 1;
- }
-
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_DPT)
- c->adaptec = 1;
-
- /* Cards that go bananas if you quiesce them before you reset them. */
- if (pdev->vendor == PCI_VENDOR_ID_DPT) {
- c->no_quiesce = 1;
- if (pdev->device == 0xa511)
- c->raptor = 1;
-
- if (pdev->subsystem_device == 0xc05a) {
- c->limit_sectors = 1;
- printk(KERN_INFO
- "%s: limit sectors per request to %d\n", c->name,
- I2O_MAX_SECTORS_LIMITED);
- }
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if (sizeof(dma_addr_t) > 4) {
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
- printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
- c->name);
- else {
- c->pae_support = 1;
- printk(KERN_INFO "%s: using 64-bit DMA\n",
- c->name);
- }
- }
-#endif
- }
-
- if ((rc = i2o_pci_alloc(c))) {
- printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
- "failed\n", c->name);
- goto free_controller;
- }
-
- if (i2o_pci_irq_enable(c)) {
- printk(KERN_ERR "%s: unable to enable interrupts for I2O "
- "controller\n", c->name);
- goto free_pci;
- }
-
- if ((rc = i2o_iop_add(c)))
- goto uninstall;
-
- if (i960)
- pci_write_config_word(i960, 0x42, 0x03ff);
-
- return 0;
-
- uninstall:
- i2o_pci_irq_disable(c);
-
- free_pci:
- i2o_pci_free(c);
-
- free_controller:
- i2o_iop_free(c);
-
- disable:
- pci_disable_device(pdev);
-
- return rc;
-}
-
-/**
- * i2o_pci_remove - Removes a I2O controller from the system
- * @pdev: I2O controller which should be removed
- *
- * Reset the I2O controller, disable interrupts and remove all allocated
- * resources.
- */
-static void i2o_pci_remove(struct pci_dev *pdev)
-{
- struct i2o_controller *c;
- c = pci_get_drvdata(pdev);
-
- i2o_iop_remove(c);
- i2o_pci_irq_disable(c);
- i2o_pci_free(c);
-
- pci_disable_device(pdev);
-
- printk(KERN_INFO "%s: Controller removed.\n", c->name);
-
- put_device(&c->device);
-};
-
-/* PCI driver for I2O controller */
-static struct pci_driver i2o_pci_driver = {
- .name = "PCI_I2O",
- .id_table = i2o_pci_ids,
- .probe = i2o_pci_probe,
- .remove = i2o_pci_remove,
-};
-
-/**
- * i2o_pci_init - registers I2O PCI driver in PCI subsystem
- *
- * Returns > 0 on success or negative error code on failure.
- */
-int __init i2o_pci_init(void)
-{
- return pci_register_driver(&i2o_pci_driver);
-};
-
-/**
- * i2o_pci_exit - unregisters I2O PCI driver from PCI subsystem
- */
-void __exit i2o_pci_exit(void)
-{
- pci_unregister_driver(&i2o_pci_driver);
-};
-
-MODULE_DEVICE_TABLE(pci, i2o_pci_ids);