aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorMichael Reed <mdr@sgi.com>2006-01-13 15:31:54 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-14 11:55:02 -0500
commit05e8ec17f4d11ba13795e878fc389cb04d1fdadd (patch)
tree0b7a7360e37be4851ce823450cabbce97bc28eea /drivers/message
parentd158d26167a3f6a910ec3e0eda23cc0cd437c689 (diff)
[SCSI] mptfusion - fc transport attributes
Signed-off-by: Michael Reed <mdr@sgi.com> Signed-off-by: Eric Moore <Eric.Moore@lsil.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c33
-rw-r--r--drivers/message/fusion/mptbase.h28
-rw-r--r--drivers/message/fusion/mptfc.c551
-rw-r--r--drivers/message/fusion/mptscsih.c28
4 files changed, 613 insertions, 27 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 80ec89c505d2..8c26f093fb65 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -148,7 +148,6 @@ static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
148static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 148static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 149static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150static int GetLanConfigPages(MPT_ADAPTER *ioc); 150static int GetLanConfigPages(MPT_ADAPTER *ioc);
151static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
152static int GetIoUnitPage2(MPT_ADAPTER *ioc); 151static int GetIoUnitPage2(MPT_ADAPTER *ioc);
153int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 152int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
154static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 153static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
@@ -1244,6 +1243,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1244 ioc->pcidev = pdev; 1243 ioc->pcidev = pdev;
1245 ioc->diagPending = 0; 1244 ioc->diagPending = 0;
1246 spin_lock_init(&ioc->diagLock); 1245 spin_lock_init(&ioc->diagLock);
1246 spin_lock_init(&ioc->fc_rescan_work_lock);
1247 spin_lock_init(&ioc->fc_rport_lock);
1247 spin_lock_init(&ioc->initializing_hba_lock); 1248 spin_lock_init(&ioc->initializing_hba_lock);
1248 1249
1249 /* Initialize the event logging. 1250 /* Initialize the event logging.
@@ -1267,6 +1268,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1267 */ 1268 */
1268 INIT_LIST_HEAD(&ioc->configQ); 1269 INIT_LIST_HEAD(&ioc->configQ);
1269 1270
1271 /* Initialize the fc rport list head.
1272 */
1273 INIT_LIST_HEAD(&ioc->fc_rports);
1274
1270 /* Find lookup slot. */ 1275 /* Find lookup slot. */
1271 INIT_LIST_HEAD(&ioc->list); 1276 INIT_LIST_HEAD(&ioc->list);
1272 ioc->id = mpt_ids++; 1277 ioc->id = mpt_ids++;
@@ -1879,7 +1884,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1879 * (FCPortPage0_t stuff) 1884 * (FCPortPage0_t stuff)
1880 */ 1885 */
1881 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 1886 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1882 (void) GetFcPortPage0(ioc, ii); 1887 (void) mptbase_GetFcPortPage0(ioc, ii);
1883 } 1888 }
1884 1889
1885 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 1890 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
@@ -4198,7 +4203,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
4198 4203
4199/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4204/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4200/* 4205/*
4201 * GetFcPortPage0 - Fetch FCPort config Page0. 4206 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4202 * @ioc: Pointer to MPT_ADAPTER structure 4207 * @ioc: Pointer to MPT_ADAPTER structure
4203 * @portnum: IOC Port number 4208 * @portnum: IOC Port number
4204 * 4209 *
@@ -4208,8 +4213,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
4208 * -EAGAIN if no msg frames currently available 4213 * -EAGAIN if no msg frames currently available
4209 * -EFAULT for non-successful reply or no reply (timeout) 4214 * -EFAULT for non-successful reply or no reply (timeout)
4210 */ 4215 */
4211static int 4216int
4212GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) 4217mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4213{ 4218{
4214 ConfigPageHeader_t hdr; 4219 ConfigPageHeader_t hdr;
4215 CONFIGPARMS cfg; 4220 CONFIGPARMS cfg;
@@ -4219,6 +4224,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4219 int data_sz; 4224 int data_sz;
4220 int copy_sz; 4225 int copy_sz;
4221 int rc; 4226 int rc;
4227 int count = 400;
4228
4222 4229
4223 /* Get FCPort Page 0 header */ 4230 /* Get FCPort Page 0 header */
4224 hdr.PageVersion = 0; 4231 hdr.PageVersion = 0;
@@ -4242,6 +4249,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4242 rc = -ENOMEM; 4249 rc = -ENOMEM;
4243 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); 4250 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4244 if (ppage0_alloc) { 4251 if (ppage0_alloc) {
4252
4253 try_again:
4245 memset((u8 *)ppage0_alloc, 0, data_sz); 4254 memset((u8 *)ppage0_alloc, 0, data_sz);
4246 cfg.physAddr = page0_dma; 4255 cfg.physAddr = page0_dma;
4247 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4256 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
@@ -4273,6 +4282,19 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4273 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount); 4282 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4274 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators); 4283 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4275 4284
4285 /*
4286 * if still doing discovery,
4287 * hang loose a while until finished
4288 */
4289 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4290 if (count-- > 0) {
4291 msleep_interruptible(100);
4292 goto try_again;
4293 }
4294 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4295 " complete.\n",
4296 ioc->name);
4297 }
4276 } 4298 }
4277 4299
4278 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); 4300 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
@@ -6357,6 +6379,7 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
6357EXPORT_SYMBOL(mpt_free_fw_memory); 6379EXPORT_SYMBOL(mpt_free_fw_memory);
6358EXPORT_SYMBOL(mptbase_sas_persist_operation); 6380EXPORT_SYMBOL(mptbase_sas_persist_operation);
6359EXPORT_SYMBOL(mpt_alt_ioc_wait); 6381EXPORT_SYMBOL(mpt_alt_ioc_wait);
6382EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6360 6383
6361 6384
6362/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6385/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 74355f2eca00..25f44064b96c 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.05" 79#define MPT_LINUX_VERSION_COMMON "3.03.06"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -499,6 +499,22 @@ typedef struct _RaidCfgData {
499 int isRaid; /* bit field, 1 if RAID */ 499 int isRaid; /* bit field, 1 if RAID */
500}RaidCfgData; 500}RaidCfgData;
501 501
502#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
503#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
504#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */
505
506/*
507 * data allocated for each fc rport device
508 */
509struct mptfc_rport_info
510{
511 struct list_head list;
512 struct fc_rport *rport;
513 VirtDevice *vdev;
514 FCDevicePage0_t pg0;
515 u8 flags;
516};
517
502/* 518/*
503 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 519 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
504 */ 520 */
@@ -614,6 +630,13 @@ typedef struct _MPT_ADAPTER
614 struct list_head sas_topology; 630 struct list_head sas_topology;
615 struct mutex sas_topology_mutex; 631 struct mutex sas_topology_mutex;
616 MPT_SAS_MGMT sas_mgmt; 632 MPT_SAS_MGMT sas_mgmt;
633
634 struct list_head fc_rports;
635 spinlock_t fc_rport_lock; /* list and ri flags */
636 spinlock_t fc_rescan_work_lock;
637 int fc_rescan_work_count;
638 struct work_struct fc_rescan_work;
639
617} MPT_ADAPTER; 640} MPT_ADAPTER;
618 641
619/* 642/*
@@ -1000,6 +1023,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1000extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1023extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1001extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1024extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
1002extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1025extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1026extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
1003extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); 1027extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
1004 1028
1005/* 1029/*
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 5083a556a258..a380fe105a22 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -55,12 +55,14 @@
55#include <linux/reboot.h> /* notifier code */ 55#include <linux/reboot.h> /* notifier code */
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/workqueue.h> 57#include <linux/workqueue.h>
58#include <linux/sort.h>
58 59
59#include <scsi/scsi.h> 60#include <scsi/scsi.h>
60#include <scsi/scsi_cmnd.h> 61#include <scsi/scsi_cmnd.h>
61#include <scsi/scsi_device.h> 62#include <scsi/scsi_device.h>
62#include <scsi/scsi_host.h> 63#include <scsi/scsi_host.h>
63#include <scsi/scsi_tcq.h> 64#include <scsi/scsi_tcq.h>
65#include <scsi/scsi_transport_fc.h>
64 66
65#include "mptbase.h" 67#include "mptbase.h"
66#include "mptscsih.h" 68#include "mptscsih.h"
@@ -79,19 +81,34 @@ static int mpt_pq_filter = 0;
79module_param(mpt_pq_filter, int, 0); 81module_param(mpt_pq_filter, int, 0);
80MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); 82MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
81 83
84#define MPTFC_DEV_LOSS_TMO (60)
85static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
86module_param(mptfc_dev_loss_tmo, int, 0);
87MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
88 " transport to wait for an rport to "
89 " return following a device loss event."
90 " Default=60.");
91
82static int mptfcDoneCtx = -1; 92static int mptfcDoneCtx = -1;
83static int mptfcTaskCtx = -1; 93static int mptfcTaskCtx = -1;
84static int mptfcInternalCtx = -1; /* Used only for internal commands */ 94static int mptfcInternalCtx = -1; /* Used only for internal commands */
85 95
96int mptfc_slave_alloc(struct scsi_device *device);
97static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
98 void (*done)(struct scsi_cmnd *));
99
100static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
101static void __devexit mptfc_remove(struct pci_dev *pdev);
102
86static struct scsi_host_template mptfc_driver_template = { 103static struct scsi_host_template mptfc_driver_template = {
87 .module = THIS_MODULE, 104 .module = THIS_MODULE,
88 .proc_name = "mptfc", 105 .proc_name = "mptfc",
89 .proc_info = mptscsih_proc_info, 106 .proc_info = mptscsih_proc_info,
90 .name = "MPT FC Host", 107 .name = "MPT FC Host",
91 .info = mptscsih_info, 108 .info = mptscsih_info,
92 .queuecommand = mptscsih_qcmd, 109 .queuecommand = mptfc_qcmd,
93 .target_alloc = mptscsih_target_alloc, 110 .target_alloc = mptscsih_target_alloc,
94 .slave_alloc = mptscsih_slave_alloc, 111 .slave_alloc = mptfc_slave_alloc,
95 .slave_configure = mptscsih_slave_configure, 112 .slave_configure = mptscsih_slave_configure,
96 .target_destroy = mptscsih_target_destroy, 113 .target_destroy = mptscsih_target_destroy,
97 .slave_destroy = mptscsih_slave_destroy, 114 .slave_destroy = mptscsih_slave_destroy,
@@ -132,15 +149,472 @@ static struct pci_device_id mptfc_pci_table[] = {
132}; 149};
133MODULE_DEVICE_TABLE(pci, mptfc_pci_table); 150MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
134 151
135/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 152static struct scsi_transport_template *mptfc_transport_template = NULL;
136/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 153
154struct fc_function_template mptfc_transport_functions = {
155 .dd_fcrport_size = 8,
156 .show_host_node_name = 1,
157 .show_host_port_name = 1,
158 .show_host_supported_classes = 1,
159 .show_host_port_id = 1,
160 .show_rport_supported_classes = 1,
161 .show_starget_node_name = 1,
162 .show_starget_port_name = 1,
163 .show_starget_port_id = 1,
164 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
165 .show_rport_dev_loss_tmo = 1,
166
167};
168
169/* FIXME! values controlling firmware RESCAN event
170 * need to be set low to allow dev_loss_tmo to
171 * work as expected. Currently, firmware doesn't
172 * notify driver of RESCAN event until some number
173 * of seconds elapse. This value can be set via
174 * lsiutil.
175 */
176static void
177mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
178{
179 if (timeout > 0)
180 rport->dev_loss_tmo = timeout;
181 else
182 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
183}
184
185static int
186mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
187{
188 FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
189 FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
190
191 if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
192 if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
193 return 0;
194 if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
195 return -1;
196 return 1;
197 }
198 if ((*aa)->CurrentBus < (*bb)->CurrentBus)
199 return -1;
200 return 1;
201}
202
203static int
204mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
205 void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
206{
207 ConfigPageHeader_t hdr;
208 CONFIGPARMS cfg;
209 FCDevicePage0_t *ppage0_alloc, *fc;
210 dma_addr_t page0_dma;
211 int data_sz;
212 int ii;
213
214 FCDevicePage0_t *p0_array=NULL, *p_p0;
215 FCDevicePage0_t **pp0_array=NULL, **p_pp0;
216
217 int rc = -ENOMEM;
218 U32 port_id = 0xffffff;
219 int num_targ = 0;
220 int max_bus = ioc->facts.MaxBuses;
221 int max_targ = ioc->facts.MaxDevices;
222
223 if (max_bus == 0 || max_targ == 0)
224 goto out;
225
226 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
227 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
228 if (!p0_array)
229 goto out;
230
231 data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
232 p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
233 if (!pp0_array)
234 goto out;
235
236 do {
237 /* Get FC Device Page 0 header */
238 hdr.PageVersion = 0;
239 hdr.PageLength = 0;
240 hdr.PageNumber = 0;
241 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
242 cfg.cfghdr.hdr = &hdr;
243 cfg.physAddr = -1;
244 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
245 cfg.dir = 0;
246 cfg.pageAddr = port_id;
247 cfg.timeout = 0;
248
249 if ((rc = mpt_config(ioc, &cfg)) != 0)
250 break;
251
252 if (hdr.PageLength <= 0)
253 break;
254
255 data_sz = hdr.PageLength * 4;
256 ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
257 &page0_dma);
258 rc = -ENOMEM;
259 if (!ppage0_alloc)
260 break;
261
262 cfg.physAddr = page0_dma;
263 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
264
265 if ((rc = mpt_config(ioc, &cfg)) == 0) {
266 ppage0_alloc->PortIdentifier =
267 le32_to_cpu(ppage0_alloc->PortIdentifier);
268
269 ppage0_alloc->WWNN.Low =
270 le32_to_cpu(ppage0_alloc->WWNN.Low);
271
272 ppage0_alloc->WWNN.High =
273 le32_to_cpu(ppage0_alloc->WWNN.High);
274
275 ppage0_alloc->WWPN.Low =
276 le32_to_cpu(ppage0_alloc->WWPN.Low);
277
278 ppage0_alloc->WWPN.High =
279 le32_to_cpu(ppage0_alloc->WWPN.High);
280
281 ppage0_alloc->BBCredit =
282 le16_to_cpu(ppage0_alloc->BBCredit);
283
284 ppage0_alloc->MaxRxFrameSize =
285 le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
286
287 port_id = ppage0_alloc->PortIdentifier;
288 num_targ++;
289 *p_p0 = *ppage0_alloc; /* save data */
290 *p_pp0++ = p_p0++; /* save addr */
291 }
292 pci_free_consistent(ioc->pcidev, data_sz,
293 (u8 *) ppage0_alloc, page0_dma);
294 if (rc != 0)
295 break;
296
297 } while (port_id <= 0xff0000);
298
299 if (num_targ) {
300 /* sort array */
301 if (num_targ > 1)
302 sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
303 mptfc_FcDevPage0_cmp_func, NULL);
304 /* call caller's func for each targ */
305 for (ii = 0; ii < num_targ; ii++) {
306 fc = *(pp0_array+ii);
307 func(ioc, ioc_port, fc);
308 }
309 }
310
311 out:
312 if (pp0_array)
313 kfree(pp0_array);
314 if (p0_array)
315 kfree(p0_array);
316 return rc;
317}
318
319static int
320mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
321{
322 /* not currently usable */
323 if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
324 MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
325 return -1;
326
327 if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
328 return -1;
329
330 if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
331 return -1;
332
333 /*
334 * board data structure already normalized to platform endianness
335 * shifted to avoid unaligned access on 64 bit architecture
336 */
337 rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
338 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
339 rid->port_id = pg0->PortIdentifier;
340 rid->roles = FC_RPORT_ROLE_UNKNOWN;
341 rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
342 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
343 rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
344
345 return 0;
346}
347
348static void
349mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
350{
351 struct fc_rport_identifiers rport_ids;
352 struct fc_rport *rport;
353 struct mptfc_rport_info *ri;
354 int match = 0;
355 u64 port_name;
356 unsigned long flags;
357
358 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
359 return;
360
361 /* scan list looking for a match */
362 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
363 list_for_each_entry(ri, &ioc->fc_rports, list) {
364 port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
365 if (port_name == rport_ids.port_name) { /* match */
366 list_move_tail(&ri->list, &ioc->fc_rports);
367 match = 1;
368 break;
369 }
370 }
371 if (!match) { /* allocate one */
372 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
373 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
374 if (!ri)
375 return;
376 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
377 list_add_tail(&ri->list, &ioc->fc_rports);
378 }
379
380 ri->pg0 = *pg0; /* add/update pg0 data */
381 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
382
383 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
384 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
385 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
386 rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
387 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
388 if (rport) {
389 if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
390 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
391 ri->vdev = NULL;
392 ri->rport = rport;
393 *((struct mptfc_rport_info **)rport->dd_data) = ri;
394 }
395 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
396 /*
397 * if already mapped, remap here. If not mapped,
398 * slave_alloc will allocate vdev and map
399 */
400 if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
401 ri->vdev->target_id = ri->pg0.CurrentTargetID;
402 ri->vdev->bus_id = ri->pg0.CurrentBus;
403 ri->vdev->vtarget->target_id = ri->vdev->target_id;
404 ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
405 }
406 #ifdef MPT_DEBUG
407 printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
408 "rport tid %d, tmo %d\n",
409 ioc->sh->host_no,
410 pg0->PortIdentifier,
411 pg0->WWNN,
412 pg0->WWPN,
413 pg0->CurrentTargetID,
414 ri->rport->scsi_target_id,
415 ri->rport->dev_loss_tmo);
416 #endif
417 } else {
418 list_del(&ri->list);
419 kfree(ri);
420 ri = NULL;
421 }
422 }
423 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
424
425}
426
137/* 427/*
138 * mptfc_probe - Installs scsi devices per bus. 428 * OS entry point to allow host driver to alloc memory
139 * @pdev: Pointer to pci_dev structure 429 * for each scsi device. Called once per device the bus scan.
140 * 430 * Return non-zero if allocation fails.
141 * Returns 0 for success, non-zero for failure. 431 * Init memory once per LUN.
142 *
143 */ 432 */
433int
434mptfc_slave_alloc(struct scsi_device *sdev)
435{
436 MPT_SCSI_HOST *hd;
437 VirtTarget *vtarget;
438 VirtDevice *vdev;
439 struct scsi_target *starget;
440 struct fc_rport *rport;
441 struct mptfc_rport_info *ri;
442 unsigned long flags;
443
444
445 rport = starget_to_rport(scsi_target(sdev));
446
447 if (!rport || fc_remote_port_chkready(rport))
448 return -ENXIO;
449
450 hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
451
452 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
453 if (!vdev) {
454 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
455 hd->ioc->name, sizeof(VirtDevice));
456 return -ENOMEM;
457 }
458 memset(vdev, 0, sizeof(VirtDevice));
459
460 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
461
462 if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
463 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
464 kfree(vdev);
465 return -ENODEV;
466 }
467
468 sdev->hostdata = vdev;
469 starget = scsi_target(sdev);
470 vtarget = starget->hostdata;
471 if (vtarget->num_luns == 0) {
472 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
473 MPT_TARGET_FLAGS_VALID_INQUIRY;
474 hd->Targets[sdev->id] = vtarget;
475 }
476
477 vtarget->target_id = vdev->target_id;
478 vtarget->bus_id = vdev->bus_id;
479
480 vdev->vtarget = vtarget;
481 vdev->ioc_id = hd->ioc->id;
482 vdev->lun = sdev->lun;
483 vdev->target_id = ri->pg0.CurrentTargetID;
484 vdev->bus_id = ri->pg0.CurrentBus;
485
486 ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
487 ri->vdev = vdev;
488
489 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
490
491 vtarget->num_luns++;
492
493#ifdef MPT_DEBUG
494 printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
495 "CurrentTargetID %d, %x %llx %llx\n",
496 sdev->host->host_no,
497 vtarget->num_luns,
498 sdev->id, ri->pg0.CurrentTargetID,
499 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);
500#endif
501
502 return 0;
503}
504
505static int
506mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
507{
508 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
509 int err;
510
511 err = fc_remote_port_chkready(rport);
512 if (unlikely(err)) {
513 SCpnt->result = err;
514 done(SCpnt);
515 return 0;
516 }
517 return mptscsih_qcmd(SCpnt,done);
518}
519
520static void
521mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
522{
523 unsigned class = 0, cos = 0;
524
525 /* don't know what to do as only one scsi (fc) host was allocated */
526 if (portnum != 0)
527 return;
528
529 class = ioc->fc_port_page0[portnum].SupportedServiceClass;
530 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
531 cos |= FC_COS_CLASS1;
532 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
533 cos |= FC_COS_CLASS2;
534 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
535 cos |= FC_COS_CLASS3;
536
537 fc_host_node_name(ioc->sh) =
538 (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
539 | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
540
541 fc_host_port_name(ioc->sh) =
542 (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
543 | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
544
545 fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
546
547 fc_host_supported_classes(ioc->sh) = cos;
548
549 fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
550}
551
552static void
553mptfc_rescan_devices(void *arg)
554{
555 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
556 int ii;
557 int work_to_do;
558 unsigned long flags;
559 struct mptfc_rport_info *ri;
560
561 do {
562 /* start by tagging all ports as missing */
563 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
564 list_for_each_entry(ri, &ioc->fc_rports, list) {
565 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
566 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
567 }
568 }
569 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
570
571 /*
572 * now rescan devices known to adapter,
573 * will reregister existing rports
574 */
575 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
576 (void) mptbase_GetFcPortPage0(ioc, ii);
577 mptfc_init_host_attr(ioc,ii); /* refresh */
578 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
579 }
580
581 /* delete devices still missing */
582 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
583 list_for_each_entry(ri, &ioc->fc_rports, list) {
584 /* if newly missing, delete it */
585 if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
586 MPT_RPORT_INFO_FLAGS_MISSING))
587 == (MPT_RPORT_INFO_FLAGS_REGISTERED |
588 MPT_RPORT_INFO_FLAGS_MISSING)) {
589
590 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
591 MPT_RPORT_INFO_FLAGS_MISSING);
592 fc_remote_port_delete(ri->rport);
593 /*
594 * remote port not really deleted 'cause
595 * binding is by WWPN and driver only
596 * registers FCP_TARGETs
597 */
598 #ifdef MPT_DEBUG
599 printk ("mptfc_rescan.%d: %llx deleted\n",
600 ioc->sh->host_no, ri->pg0.WWPN);
601 #endif
602 }
603 }
604 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
605
606 /*
607 * allow multiple passes as target state
608 * might have changed during scan
609 */
610 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
611 if (ioc->fc_rescan_work_count > 2) /* only need one more */
612 ioc->fc_rescan_work_count = 2;
613 work_to_do = --ioc->fc_rescan_work_count;
614 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
615 } while (work_to_do);
616}
617
144static int 618static int
145mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) 619mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
146{ 620{
@@ -154,10 +628,10 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
154 int ioc_cap; 628 int ioc_cap;
155 int error=0; 629 int error=0;
156 int r; 630 int r;
157 631
158 if ((r = mpt_attach(pdev,id)) != 0) 632 if ((r = mpt_attach(pdev,id)) != 0)
159 return r; 633 return r;
160 634
161 ioc = pci_get_drvdata(pdev); 635 ioc = pci_get_drvdata(pdev);
162 ioc->DoneCtx = mptfcDoneCtx; 636 ioc->DoneCtx = mptfcDoneCtx;
163 ioc->TaskCtx = mptfcTaskCtx; 637 ioc->TaskCtx = mptfcTaskCtx;
@@ -193,7 +667,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
193 printk(MYIOC_s_WARN_FMT 667 printk(MYIOC_s_WARN_FMT
194 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 668 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
195 ioc->name, ioc); 669 ioc->name, ioc);
196 return 0; 670 return -ENODEV;
197 } 671 }
198 672
199 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 673 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
@@ -206,6 +680,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
206 goto out_mptfc_probe; 680 goto out_mptfc_probe;
207 } 681 }
208 682
683 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
684
209 spin_lock_irqsave(&ioc->FreeQlock, flags); 685 spin_lock_irqsave(&ioc->FreeQlock, flags);
210 686
211 /* Attach the SCSI Host to the IOC structure 687 /* Attach the SCSI Host to the IOC structure
@@ -322,6 +798,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
322 hd->scandv_wait_done = 0; 798 hd->scandv_wait_done = 0;
323 hd->last_queue_full = 0; 799 hd->last_queue_full = 0;
324 800
801 sh->transportt = mptfc_transport_template;
325 error = scsi_add_host (sh, &ioc->pcidev->dev); 802 error = scsi_add_host (sh, &ioc->pcidev->dev);
326 if(error) { 803 if(error) {
327 dprintk((KERN_ERR MYNAM 804 dprintk((KERN_ERR MYNAM
@@ -329,7 +806,11 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
329 goto out_mptfc_probe; 806 goto out_mptfc_probe;
330 } 807 }
331 808
332 scsi_scan_host(sh); 809 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
810 mptfc_init_host_attr(ioc,ii);
811 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
812 }
813
333 return 0; 814 return 0;
334 815
335out_mptfc_probe: 816out_mptfc_probe:
@@ -342,7 +823,7 @@ static struct pci_driver mptfc_driver = {
342 .name = "mptfc", 823 .name = "mptfc",
343 .id_table = mptfc_pci_table, 824 .id_table = mptfc_pci_table,
344 .probe = mptfc_probe, 825 .probe = mptfc_probe,
345 .remove = __devexit_p(mptscsih_remove), 826 .remove = __devexit_p(mptfc_remove),
346 .shutdown = mptscsih_shutdown, 827 .shutdown = mptscsih_shutdown,
347#ifdef CONFIG_PM 828#ifdef CONFIG_PM
348 .suspend = mptscsih_suspend, 829 .suspend = mptscsih_suspend,
@@ -360,9 +841,20 @@ static struct pci_driver mptfc_driver = {
360static int __init 841static int __init
361mptfc_init(void) 842mptfc_init(void)
362{ 843{
844 int error;
363 845
364 show_mptmod_ver(my_NAME, my_VERSION); 846 show_mptmod_ver(my_NAME, my_VERSION);
365 847
848 /* sanity check module parameter */
849 if (mptfc_dev_loss_tmo == 0)
850 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
851
852 mptfc_transport_template =
853 fc_attach_transport(&mptfc_transport_functions);
854
855 if (!mptfc_transport_template)
856 return -ENODEV;
857
366 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 858 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
367 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 859 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
368 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 860 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
@@ -377,7 +869,33 @@ mptfc_init(void)
377 ": Registered for IOC reset notifications\n")); 869 ": Registered for IOC reset notifications\n"));
378 } 870 }
379 871
380 return pci_register_driver(&mptfc_driver); 872 error = pci_register_driver(&mptfc_driver);
873 if (error) {
874 fc_release_transport(mptfc_transport_template);
875 }
876
877 return error;
878}
879
880/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
881/**
882 * mptfc_remove - Removed fc infrastructure for devices
883 * @pdev: Pointer to pci_dev structure
884 *
885 */
886static void __devexit mptfc_remove(struct pci_dev *pdev)
887{
888 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
889 struct mptfc_rport_info *p, *n;
890
891 fc_remove_host(ioc->sh);
892
893 list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
894 list_del(&p->list);
895 kfree(p);
896 }
897
898 mptscsih_remove(pdev);
381} 899}
382 900
383/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 901/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -390,7 +908,8 @@ static void __exit
390mptfc_exit(void) 908mptfc_exit(void)
391{ 909{
392 pci_unregister_driver(&mptfc_driver); 910 pci_unregister_driver(&mptfc_driver);
393 911 fc_release_transport(mptfc_transport_template);
912
394 mpt_reset_deregister(mptfcDoneCtx); 913 mpt_reset_deregister(mptfcDoneCtx);
395 dprintk((KERN_INFO MYNAM 914 dprintk((KERN_INFO MYNAM
396 ": Deregistered for IOC reset notifications\n")); 915 ": Deregistered for IOC reset notifications\n"));
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 525d9aea2012..cdac5578fdf2 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -893,6 +893,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
893 * when a lun is disable by mid-layer. 893 * when a lun is disable by mid-layer.
894 * Do NOT access the referenced scsi_cmnd structure or 894 * Do NOT access the referenced scsi_cmnd structure or
895 * members. Will cause either a paging or NULL ptr error. 895 * members. Will cause either a paging or NULL ptr error.
896 * (BUT, BUT, BUT, the code does reference it! - mdr)
896 * @hd: Pointer to a SCSI HOST structure 897 * @hd: Pointer to a SCSI HOST structure
897 * @vdevice: per device private data 898 * @vdevice: per device private data
898 * 899 *
@@ -2557,13 +2558,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2557 hd->cmdPtr = NULL; 2558 hd->cmdPtr = NULL;
2558 } 2559 }
2559 2560
2560 /* 7. Set flag to force DV and re-read IOC Page 3 2561 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2561 */ 2562 */
2562 if (ioc->bus_type == SPI) { 2563 if (ioc->bus_type == SPI) {
2563 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; 2564 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2564 ddvtprintk(("Set reload IOC Pg3 Flag\n")); 2565 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2565 } 2566 }
2566 2567
2568 /* 7. FC: Rescan for blocked rports which might have returned.
2569 */
2570 else if (ioc->bus_type == FC) {
2571 int work_count;
2572 unsigned long flags;
2573
2574 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2575 work_count = ++ioc->fc_rescan_work_count;
2576 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2577 if (work_count == 1)
2578 schedule_work(&ioc->fc_rescan_work);
2579 }
2567 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2580 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2568 2581
2569 } 2582 }
@@ -2587,6 +2600,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2587{ 2600{
2588 MPT_SCSI_HOST *hd; 2601 MPT_SCSI_HOST *hd;
2589 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2602 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2603 int work_count;
2604 unsigned long flags;
2590 2605
2591 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2606 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2592 ioc->name, event)); 2607 ioc->name, event));
@@ -2608,11 +2623,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2608 /* FIXME! */ 2623 /* FIXME! */
2609 break; 2624 break;
2610 2625
2626 case MPI_EVENT_RESCAN: /* 06 */
2627 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2628 work_count = ++ioc->fc_rescan_work_count;
2629 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2630 if (work_count == 1)
2631 schedule_work(&ioc->fc_rescan_work);
2632 break;
2633
2611 /* 2634 /*
2612 * CHECKME! Don't think we need to do 2635 * CHECKME! Don't think we need to do
2613 * anything for these, but... 2636 * anything for these, but...
2614 */ 2637 */
2615 case MPI_EVENT_RESCAN: /* 06 */
2616 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */ 2638 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2617 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */ 2639 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2618 /* 2640 /*
@@ -3952,8 +3974,6 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3952 3974
3953/* Search IOC page 3 to determine if this is hidden physical disk 3975/* Search IOC page 3 to determine if this is hidden physical disk
3954 */ 3976 */
3955/* Search IOC page 3 to determine if this is hidden physical disk
3956 */
3957static int 3977static int
3958mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 3978mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3959{ 3979{