1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46#include <linux/module.h>
47#include <linux/kernel.h>
48#include <linux/init.h>
49#include <linux/errno.h>
50#include <linux/jiffies.h>
51#include <linux/workqueue.h>
52#include <linux/delay.h>
53
54#include <scsi/scsi.h>
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_device.h>
57#include <scsi/scsi_host.h>
58#include <scsi/scsi_transport_sas.h>
59#include <scsi/scsi_dbg.h>
60
61#include "mptbase.h"
62#include "mptscsih.h"
63#include "mptsas.h"
64
65
66#define my_NAME "Fusion MPT SAS Host driver"
67#define my_VERSION MPT_LINUX_VERSION_COMMON
68#define MYNAM "mptsas"
69
70
71
72
73#define MPTSAS_RAID_CHANNEL 1
74
75#define SAS_CONFIG_PAGE_TIMEOUT 30
76MODULE_AUTHOR(MODULEAUTHOR);
77MODULE_DESCRIPTION(my_NAME);
78MODULE_LICENSE("GPL");
79MODULE_VERSION(my_VERSION);
80
81static int mpt_pt_clear;
82module_param(mpt_pt_clear, int, 0);
83MODULE_PARM_DESC(mpt_pt_clear,
84 " Clear persistency table: enable=1 "
85 "(default=MPTSCSIH_PT_CLEAR=0)");
86
87
88#define MPTSAS_MAX_LUN (16895)
89static int max_lun = MPTSAS_MAX_LUN;
90module_param(max_lun, int, 0);
91MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92
93static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
94static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
95static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
96static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
97static u8 mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
98
99static void mptsas_firmware_event_work(struct work_struct *work);
100static void mptsas_send_sas_event(struct fw_event_work *fw_event);
101static void mptsas_send_raid_event(struct fw_event_work *fw_event);
102static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
103static void mptsas_parse_device_info(struct sas_identify *identify,
104 struct mptsas_devinfo *device_info);
105static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
106 struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
107static struct mptsas_phyinfo *mptsas_find_phyinfo_by_sas_address
108 (MPT_ADAPTER *ioc, u64 sas_address);
109static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
110 struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
111static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
112 struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
113static int mptsas_add_end_device(MPT_ADAPTER *ioc,
114 struct mptsas_phyinfo *phy_info);
115static void mptsas_del_end_device(MPT_ADAPTER *ioc,
116 struct mptsas_phyinfo *phy_info);
117static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
118static struct mptsas_portinfo *mptsas_find_portinfo_by_sas_address
119 (MPT_ADAPTER *ioc, u64 sas_address);
120static void mptsas_expander_delete(MPT_ADAPTER *ioc,
121 struct mptsas_portinfo *port_info, u8 force);
122static void mptsas_send_expander_event(struct fw_event_work *fw_event);
123static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
124static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
125static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
126static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
127static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
128
129static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
130 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
131{
132 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
133 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
134 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
135 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
136 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
137 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
138 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
139 ioc->name, phy_data->Port));
140 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
141 ioc->name, phy_data->PortFlags));
142 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
143 ioc->name, phy_data->PhyFlags));
144 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
145 ioc->name, phy_data->NegotiatedLinkRate));
146 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
147 "Controller PHY Device Info=0x%X\n", ioc->name,
148 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
149 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
150 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
151}
152
153static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
154{
155 __le64 sas_address;
156
157 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
158
159 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
160 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
161 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
162 "Attached Device Handle=0x%X\n", ioc->name,
163 le16_to_cpu(pg0->AttachedDevHandle)));
164 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
165 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
166 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
167 "Attached PHY Identifier=0x%X\n", ioc->name,
168 pg0->AttachedPhyIdentifier));
169 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
170 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
171 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
172 ioc->name, pg0->ProgrammedLinkRate));
173 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
174 ioc->name, pg0->ChangeCount));
175 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
176 ioc->name, le32_to_cpu(pg0->PhyInfo)));
177}
178
179static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
180{
181 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
182 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
183 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
184 ioc->name, pg1->InvalidDwordCount));
185 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
186 "Running Disparity Error Count=0x%x\n", ioc->name,
187 pg1->RunningDisparityErrorCount));
188 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
189 "Loss Dword Synch Count=0x%x\n", ioc->name,
190 pg1->LossDwordSynchCount));
191 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
192 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
193 pg1->PhyResetProblemCount));
194}
195
196static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
197{
198 __le64 sas_address;
199
200 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
201
202 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
203 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
204 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
205 ioc->name, le16_to_cpu(pg0->DevHandle)));
206 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
207 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
208 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
209 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
210 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
211 ioc->name, le16_to_cpu(pg0->Slot)));
212 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
213 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
214 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
215 ioc->name, pg0->TargetID));
216 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
217 ioc->name, pg0->Bus));
218 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
219 ioc->name, pg0->PhyNum));
220 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
221 ioc->name, le16_to_cpu(pg0->AccessStatus)));
222 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
223 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
224 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
225 ioc->name, le16_to_cpu(pg0->Flags)));
226 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
227 ioc->name, pg0->PhysicalPort));
228}
229
230static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
231{
232 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
233 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
234 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
235 ioc->name, pg1->PhysicalPort));
236 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
237 ioc->name, pg1->PhyIdentifier));
238 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
239 ioc->name, pg1->NegotiatedLinkRate));
240 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
241 ioc->name, pg1->ProgrammedLinkRate));
242 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
243 ioc->name, pg1->HwLinkRate));
244 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
245 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
246 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
247 "Attached Device Handle=0x%X\n\n", ioc->name,
248 le16_to_cpu(pg1->AttachedDevHandle)));
249}
250
251
252static void
253mptsas_fw_event_off(MPT_ADAPTER *ioc)
254{
255 unsigned long flags;
256
257 spin_lock_irqsave(&ioc->fw_event_lock, flags);
258 ioc->fw_events_off = 1;
259 ioc->sas_discovery_quiesce_io = 0;
260 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
261
262}
263
264
265static void
266mptsas_fw_event_on(MPT_ADAPTER *ioc)
267{
268 unsigned long flags;
269
270 spin_lock_irqsave(&ioc->fw_event_lock, flags);
271 ioc->fw_events_off = 0;
272 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
273}
274
275
276static void
277mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
278 unsigned long delay)
279{
280 unsigned long flags;
281
282 spin_lock_irqsave(&ioc->fw_event_lock, flags);
283 list_add_tail(&fw_event->list, &ioc->fw_event_list);
284 INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
285 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n",
286 ioc->name, __func__, fw_event));
287 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
288 delay);
289 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
290}
291
292
293static void
294mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
295 unsigned long delay)
296{
297 unsigned long flags;
298 spin_lock_irqsave(&ioc->fw_event_lock, flags);
299 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
300 "(fw_event=0x%p)\n", ioc->name, __func__, fw_event));
301 fw_event->retries++;
302 queue_delayed_work(ioc->fw_event_q, &fw_event->work,
303 msecs_to_jiffies(delay));
304 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
305}
306
307
308static void
309mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
310{
311 unsigned long flags;
312
313 spin_lock_irqsave(&ioc->fw_event_lock, flags);
314 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
315 ioc->name, __func__, fw_event));
316 list_del(&fw_event->list);
317 kfree(fw_event);
318 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
319}
320
321
322
323static void
324mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
325{
326 struct fw_event_work *fw_event, *next;
327 struct mptsas_target_reset_event *target_reset_list, *n;
328 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
329
330
331 if (!list_empty(&hd->target_reset_list)) {
332 list_for_each_entry_safe(target_reset_list, n,
333 &hd->target_reset_list, list) {
334 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
335 "%s: removing target reset for id=%d\n",
336 ioc->name, __func__,
337 target_reset_list->sas_event_data.TargetID));
338 list_del(&target_reset_list->list);
339 kfree(target_reset_list);
340 }
341 }
342
343 if (list_empty(&ioc->fw_event_list) ||
344 !ioc->fw_event_q || in_interrupt())
345 return;
346
347 list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
348 if (cancel_delayed_work(&fw_event->work))
349 mptsas_free_fw_event(ioc, fw_event);
350 }
351}
352
353
354static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
355{
356 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
357 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
358}
359
360static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
361{
362 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
363 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
364}
365
366
367
368
369
370
371static struct mptsas_portinfo *
372mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
373{
374 struct mptsas_portinfo *port_info, *rc=NULL;
375 int i;
376
377 list_for_each_entry(port_info, &ioc->sas_topology, list)
378 for (i = 0; i < port_info->num_phys; i++)
379 if (port_info->phy_info[i].identify.handle == handle) {
380 rc = port_info;
381 goto out;
382 }
383 out:
384 return rc;
385}
386
387
388
389
390
391
392
393
394
395static struct mptsas_portinfo *
396mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
397{
398 struct mptsas_portinfo *port_info, *rc = NULL;
399 int i;
400
401 if (sas_address >= ioc->hba_port_sas_addr &&
402 sas_address < (ioc->hba_port_sas_addr +
403 ioc->hba_port_num_phy))
404 return ioc->hba_port_info;
405
406 mutex_lock(&ioc->sas_topology_mutex);
407 list_for_each_entry(port_info, &ioc->sas_topology, list)
408 for (i = 0; i < port_info->num_phys; i++)
409 if (port_info->phy_info[i].identify.sas_address ==
410 sas_address) {
411 rc = port_info;
412 goto out;
413 }
414 out:
415 mutex_unlock(&ioc->sas_topology_mutex);
416 return rc;
417}
418
419
420
421
422static inline int
423mptsas_is_end_device(struct mptsas_devinfo * attached)
424{
425 if ((attached->sas_address) &&
426 (attached->device_info &
427 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
428 ((attached->device_info &
429 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
430 (attached->device_info &
431 MPI_SAS_DEVICE_INFO_STP_TARGET) |
432 (attached->device_info &
433 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
434 return 1;
435 else
436 return 0;
437}
438
439
440static void
441mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
442{
443 struct mptsas_portinfo *port_info;
444 struct mptsas_phyinfo *phy_info;
445 u8 i;
446
447 if (!port_details)
448 return;
449
450 port_info = port_details->port_info;
451 phy_info = port_info->phy_info;
452
453 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
454 "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
455 port_details->num_phys, (unsigned long long)
456 port_details->phy_bitmask));
457
458 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
459 if(phy_info->port_details != port_details)
460 continue;
461 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
462 mptsas_set_rphy(ioc, phy_info, NULL);
463 phy_info->port_details = NULL;
464 }
465 kfree(port_details);
466}
467
468static inline struct sas_rphy *
469mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
470{
471 if (phy_info->port_details)
472 return phy_info->port_details->rphy;
473 else
474 return NULL;
475}
476
477static inline void
478mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
479{
480 if (phy_info->port_details) {
481 phy_info->port_details->rphy = rphy;
482 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
483 ioc->name, rphy));
484 }
485
486 if (rphy) {
487 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
488 &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
489 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
490 ioc->name, rphy, rphy->dev.release));
491 }
492}
493
494static inline struct sas_port *
495mptsas_get_port(struct mptsas_phyinfo *phy_info)
496{
497 if (phy_info->port_details)
498 return phy_info->port_details->port;
499 else
500 return NULL;
501}
502
503static inline void
504mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
505{
506 if (phy_info->port_details)
507 phy_info->port_details->port = port;
508
509 if (port) {
510 dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
511 &port->dev, MYIOC_s_FMT "add:", ioc->name));
512 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
513 ioc->name, port, port->dev.release));
514 }
515}
516
517static inline struct scsi_target *
518mptsas_get_starget(struct mptsas_phyinfo *phy_info)
519{
520 if (phy_info->port_details)
521 return phy_info->port_details->starget;
522 else
523 return NULL;
524}
525
526static inline void
527mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
528starget)
529{
530 if (phy_info->port_details)
531 phy_info->port_details->starget = starget;
532}
533
534
535
536
537
538
539
540
541
542
543static void
544mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
545 u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
546{
547 struct mptsas_device_info *sas_info, *next;
548 struct scsi_device *sdev;
549 struct scsi_target *starget;
550 struct sas_rphy *rphy;
551
552
553
554
555 mutex_lock(&ioc->sas_device_info_mutex);
556 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
557 list) {
558 if (!sas_info->is_logical_volume &&
559 (sas_info->sas_address == sas_address ||
560 (sas_info->fw.channel == channel &&
561 sas_info->fw.id == id))) {
562 list_del(&sas_info->list);
563 kfree(sas_info);
564 }
565 }
566
567 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
568 if (!sas_info)
569 goto out;
570
571
572
573
574 sas_info->fw.id = id;
575 sas_info->fw.channel = channel;
576
577 sas_info->sas_address = sas_address;
578 sas_info->device_info = device_info;
579 sas_info->slot = slot;
580 sas_info->enclosure_logical_id = enclosure_logical_id;
581 INIT_LIST_HEAD(&sas_info->list);
582 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
583
584
585
586
587 shost_for_each_device(sdev, ioc->sh) {
588 starget = scsi_target(sdev);
589 rphy = dev_to_rphy(starget->dev.parent);
590 if (rphy->identify.sas_address == sas_address) {
591 sas_info->os.id = starget->id;
592 sas_info->os.channel = starget->channel;
593 }
594 }
595
596 out:
597 mutex_unlock(&ioc->sas_device_info_mutex);
598 return;
599}
600
601
602
603
604
605
606
607
608static void
609mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
610{
611 struct mptsas_devinfo sas_device;
612 struct mptsas_enclosure enclosure_info;
613 int rc;
614
615 rc = mptsas_sas_device_pg0(ioc, &sas_device,
616 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
617 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
618 (channel << 8) + id);
619 if (rc)
620 return;
621
622 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
623 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
624 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
625 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
626 sas_device.handle_enclosure);
627
628 mptsas_add_device_component(ioc, sas_device.channel,
629 sas_device.id, sas_device.sas_address, sas_device.device_info,
630 sas_device.slot, enclosure_info.enclosure_logical_id);
631}
632
633
634
635
636
637
638
639
640static void
641mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
642 struct scsi_target *starget)
643{
644 CONFIGPARMS cfg;
645 ConfigPageHeader_t hdr;
646 dma_addr_t dma_handle;
647 pRaidVolumePage0_t buffer = NULL;
648 int i;
649 RaidPhysDiskPage0_t phys_disk;
650 struct mptsas_device_info *sas_info, *next;
651
652 memset(&cfg, 0 , sizeof(CONFIGPARMS));
653 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
654 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
655
656 cfg.pageAddr = starget->id;
657 cfg.cfghdr.hdr = &hdr;
658 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
659 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
660
661 if (mpt_config(ioc, &cfg) != 0)
662 goto out;
663
664 if (!hdr.PageLength)
665 goto out;
666
667 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
668 &dma_handle);
669
670 if (!buffer)
671 goto out;
672
673 cfg.physAddr = dma_handle;
674 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
675
676 if (mpt_config(ioc, &cfg) != 0)
677 goto out;
678
679 if (!buffer->NumPhysDisks)
680 goto out;
681
682
683
684
685 for (i = 0; i < buffer->NumPhysDisks; i++) {
686
687 if (mpt_raid_phys_disk_pg0(ioc,
688 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
689 continue;
690
691 mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
692 phys_disk.PhysDiskID);
693
694 mutex_lock(&ioc->sas_device_info_mutex);
695 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
696 list) {
697 if (!sas_info->is_logical_volume &&
698 (sas_info->fw.channel == phys_disk.PhysDiskBus &&
699 sas_info->fw.id == phys_disk.PhysDiskID)) {
700 sas_info->is_hidden_raid_component = 1;
701 sas_info->volume_id = starget->id;
702 }
703 }
704 mutex_unlock(&ioc->sas_device_info_mutex);
705
706 }
707
708
709
710
711 mutex_lock(&ioc->sas_device_info_mutex);
712 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
713 list) {
714 if (sas_info->is_logical_volume && sas_info->fw.id ==
715 starget->id) {
716 list_del(&sas_info->list);
717 kfree(sas_info);
718 }
719 }
720
721 sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
722 if (sas_info) {
723 sas_info->fw.id = starget->id;
724 sas_info->os.id = starget->id;
725 sas_info->os.channel = starget->channel;
726 sas_info->is_logical_volume = 1;
727 INIT_LIST_HEAD(&sas_info->list);
728 list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
729 }
730 mutex_unlock(&ioc->sas_device_info_mutex);
731
732 out:
733 if (buffer)
734 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
735 dma_handle);
736}
737
738
739
740
741
742
743
744static void
745mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
746 struct scsi_target *starget)
747{
748 VirtTarget *vtarget;
749 struct sas_rphy *rphy;
750 struct mptsas_phyinfo *phy_info = NULL;
751 struct mptsas_enclosure enclosure_info;
752
753 rphy = dev_to_rphy(starget->dev.parent);
754 vtarget = starget->hostdata;
755 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
756 rphy->identify.sas_address);
757 if (!phy_info)
758 return;
759
760 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
761 mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
762 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
763 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
764 phy_info->attached.handle_enclosure);
765
766 mptsas_add_device_component(ioc, phy_info->attached.channel,
767 phy_info->attached.id, phy_info->attached.sas_address,
768 phy_info->attached.device_info,
769 phy_info->attached.slot, enclosure_info.enclosure_logical_id);
770}
771
772
773
774
775
776
777
778
779static void
780mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
781{
782 struct mptsas_device_info *sas_info, *next;
783
784
785
786
787 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
788 list) {
789 if (sas_info->os.channel == channel && sas_info->os.id == id)
790 sas_info->is_cached = 1;
791 }
792}
793
794
795
796
797
798
799static void
800mptsas_del_device_components(MPT_ADAPTER *ioc)
801{
802 struct mptsas_device_info *sas_info, *next;
803
804 mutex_lock(&ioc->sas_device_info_mutex);
805 list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
806 list) {
807 list_del(&sas_info->list);
808 kfree(sas_info);
809 }
810 mutex_unlock(&ioc->sas_device_info_mutex);
811}
812
813
814
815
816
817
818
819
820static void
821mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
822{
823 struct mptsas_portinfo_details * port_details;
824 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
825 u64 sas_address;
826 int i, j;
827
828 mutex_lock(&ioc->sas_topology_mutex);
829
830 phy_info = port_info->phy_info;
831 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
832 if (phy_info->attached.handle)
833 continue;
834 port_details = phy_info->port_details;
835 if (!port_details)
836 continue;
837 if (port_details->num_phys < 2)
838 continue;
839
840
841
842
843 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
844 "%s: [%p]: deleting phy = %d\n",
845 ioc->name, __func__, port_details, i));
846 port_details->num_phys--;
847 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
848 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
849 if (phy_info->phy) {
850 devtprintk(ioc, dev_printk(KERN_DEBUG,
851 &phy_info->phy->dev, MYIOC_s_FMT
852 "delete phy %d, phy-obj (0x%p)\n", ioc->name,
853 phy_info->phy_id, phy_info->phy));
854 sas_port_delete_phy(port_details->port, phy_info->phy);
855 }
856 phy_info->port_details = NULL;
857 }
858
859
860
861
862 phy_info = port_info->phy_info;
863 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
864 sas_address = phy_info->attached.sas_address;
865 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
866 ioc->name, i, (unsigned long long)sas_address));
867 if (!sas_address)
868 continue;
869 port_details = phy_info->port_details;
870
871
872
873 if (!port_details) {
874 port_details = kzalloc(sizeof(struct
875 mptsas_portinfo_details), GFP_KERNEL);
876 if (!port_details)
877 goto out;
878 port_details->num_phys = 1;
879 port_details->port_info = port_info;
880 if (phy_info->phy_id < 64 )
881 port_details->phy_bitmask |=
882 (1 << phy_info->phy_id);
883 phy_info->sas_port_add_phy=1;
884 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
885 "phy_id=%d sas_address=0x%018llX\n",
886 ioc->name, i, (unsigned long long)sas_address));
887 phy_info->port_details = port_details;
888 }
889
890 if (i == port_info->num_phys - 1)
891 continue;
892 phy_info_cmp = &port_info->phy_info[i + 1];
893 for (j = i + 1 ; j < port_info->num_phys ; j++,
894 phy_info_cmp++) {
895 if (!phy_info_cmp->attached.sas_address)
896 continue;
897 if (sas_address != phy_info_cmp->attached.sas_address)
898 continue;
899 if (phy_info_cmp->port_details == port_details )
900 continue;
901 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
902 "\t\tphy_id=%d sas_address=0x%018llX\n",
903 ioc->name, j, (unsigned long long)
904 phy_info_cmp->attached.sas_address));
905 if (phy_info_cmp->port_details) {
906 port_details->rphy =
907 mptsas_get_rphy(phy_info_cmp);
908 port_details->port =
909 mptsas_get_port(phy_info_cmp);
910 port_details->starget =
911 mptsas_get_starget(phy_info_cmp);
912 port_details->num_phys =
913 phy_info_cmp->port_details->num_phys;
914 if (!phy_info_cmp->port_details->num_phys)
915 kfree(phy_info_cmp->port_details);
916 } else
917 phy_info_cmp->sas_port_add_phy=1;
918
919
920
921 phy_info_cmp->port_details = port_details;
922 if (phy_info_cmp->phy_id < 64 )
923 port_details->phy_bitmask |=
924 (1 << phy_info_cmp->phy_id);
925 port_details->num_phys++;
926 }
927 }
928
929 out:
930
931 for (i = 0; i < port_info->num_phys; i++) {
932 port_details = port_info->phy_info[i].port_details;
933 if (!port_details)
934 continue;
935 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
936 "%s: [%p]: phy_id=%02d num_phys=%02d "
937 "bitmask=0x%016llX\n", ioc->name, __func__,
938 port_details, i, port_details->num_phys,
939 (unsigned long long)port_details->phy_bitmask));
940 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
941 ioc->name, port_details->port, port_details->rphy));
942 }
943 dsaswideprintk(ioc, printk("\n"));
944 mutex_unlock(&ioc->sas_topology_mutex);
945}
946
947
948
949
950
951
952
953
954
955static VirtTarget *
956mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
957{
958 struct scsi_device *sdev;
959 VirtDevice *vdevice;
960 VirtTarget *vtarget = NULL;
961
962 shost_for_each_device(sdev, ioc->sh) {
963 vdevice = sdev->hostdata;
964 if ((vdevice == NULL) ||
965 (vdevice->vtarget == NULL))
966 continue;
967 if ((vdevice->vtarget->tflags &
968 MPT_TARGET_FLAGS_RAID_COMPONENT ||
969 vdevice->vtarget->raidVolume))
970 continue;
971 if (vdevice->vtarget->id == id &&
972 vdevice->vtarget->channel == channel)
973 vtarget = vdevice->vtarget;
974 }
975 return vtarget;
976}
977
978static void
979mptsas_queue_device_delete(MPT_ADAPTER *ioc,
980 MpiEventDataSasDeviceStatusChange_t *sas_event_data)
981{
982 struct fw_event_work *fw_event;
983 int sz;
984
985 sz = offsetof(struct fw_event_work, event_data) +
986 sizeof(MpiEventDataSasDeviceStatusChange_t);
987 fw_event = kzalloc(sz, GFP_ATOMIC);
988 if (!fw_event) {
989 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
990 ioc->name, __func__, __LINE__);
991 return;
992 }
993 memcpy(fw_event->event_data, sas_event_data,
994 sizeof(MpiEventDataSasDeviceStatusChange_t));
995 fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
996 fw_event->ioc = ioc;
997 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
998}
999
1000static void
1001mptsas_queue_rescan(MPT_ADAPTER *ioc)
1002{
1003 struct fw_event_work *fw_event;
1004 int sz;
1005
1006 sz = offsetof(struct fw_event_work, event_data);
1007 fw_event = kzalloc(sz, GFP_ATOMIC);
1008 if (!fw_event) {
1009 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1010 ioc->name, __func__, __LINE__);
1011 return;
1012 }
1013 fw_event->event = -1;
1014 fw_event->ioc = ioc;
1015 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1016}
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032static int
1033mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1034{
1035 MPT_FRAME_HDR *mf;
1036 SCSITaskMgmt_t *pScsiTm;
1037 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1038 return 0;
1039
1040
1041 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1042 if (mf == NULL) {
1043 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1044 "%s, no msg frames @%d!!\n", ioc->name,
1045 __func__, __LINE__));
1046 goto out_fail;
1047 }
1048
1049 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1050 ioc->name, mf));
1051
1052
1053
1054 pScsiTm = (SCSITaskMgmt_t *) mf;
1055 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1056 pScsiTm->TargetID = id;
1057 pScsiTm->Bus = channel;
1058 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1059 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1060 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1061
1062 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1063
1064 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1065 "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1066 ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1067
1068 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1069
1070 return 1;
1071
1072 out_fail:
1073
1074 mpt_clear_taskmgmt_in_progress_flag(ioc);
1075 return 0;
1076}
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089static void
1090mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1091 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1092{
1093 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1094 VirtTarget *vtarget = NULL;
1095 struct mptsas_target_reset_event *target_reset_list;
1096 u8 id, channel;
1097
1098 id = sas_event_data->TargetID;
1099 channel = sas_event_data->Bus;
1100
1101 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
1102 return;
1103
1104 vtarget->deleted = 1;
1105
1106 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1107 GFP_ATOMIC);
1108 if (!target_reset_list) {
1109 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1110 "%s, failed to allocate mem @%d..!!\n",
1111 ioc->name, __func__, __LINE__));
1112 return;
1113 }
1114
1115 memcpy(&target_reset_list->sas_event_data, sas_event_data,
1116 sizeof(*sas_event_data));
1117 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1118
1119 target_reset_list->time_count = jiffies;
1120
1121 if (mptsas_target_reset(ioc, channel, id)) {
1122 target_reset_list->target_reset_issued = 1;
1123 }
1124}
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134static int
1135mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1136{
1137 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
1138 struct list_head *head = &hd->target_reset_list;
1139 u8 id, channel;
1140 struct mptsas_target_reset_event *target_reset_list;
1141 SCSITaskMgmtReply_t *pScsiTmReply;
1142
1143 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1144 "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1145
1146 pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1147 if (pScsiTmReply) {
1148 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1149 "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1150 "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1151 "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1152 "term_cmnds = %d\n", ioc->name,
1153 pScsiTmReply->Bus, pScsiTmReply->TargetID,
1154 pScsiTmReply->TaskType,
1155 le16_to_cpu(pScsiTmReply->IOCStatus),
1156 le32_to_cpu(pScsiTmReply->IOCLogInfo),
1157 pScsiTmReply->ResponseCode,
1158 le32_to_cpu(pScsiTmReply->TerminationCount)));
1159
1160 if (pScsiTmReply->ResponseCode)
1161 mptscsih_taskmgmt_response_code(ioc,
1162 pScsiTmReply->ResponseCode);
1163 }
1164
1165 if (pScsiTmReply && (pScsiTmReply->TaskType ==
1166 MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1167 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1168 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1169 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1170 memcpy(ioc->taskmgmt_cmds.reply, mr,
1171 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1172 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1173 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1174 complete(&ioc->taskmgmt_cmds.done);
1175 return 1;
1176 }
1177 return 0;
1178 }
1179
1180 mpt_clear_taskmgmt_in_progress_flag(ioc);
1181
1182 if (list_empty(head))
1183 return 1;
1184
1185 target_reset_list = list_entry(head->next,
1186 struct mptsas_target_reset_event, list);
1187
1188 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1189 "TaskMgmt: completed (%d seconds)\n",
1190 ioc->name, jiffies_to_msecs(jiffies -
1191 target_reset_list->time_count)/1000));
1192
1193 id = pScsiTmReply->TargetID;
1194 channel = pScsiTmReply->Bus;
1195 target_reset_list->time_count = jiffies;
1196
1197
1198
1199
1200 if (!target_reset_list->target_reset_issued) {
1201 if (mptsas_target_reset(ioc, channel, id))
1202 target_reset_list->target_reset_issued = 1;
1203 return 1;
1204 }
1205
1206
1207
1208
1209 list_del(&target_reset_list->list);
1210 if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
1211 mptsas_queue_device_delete(ioc,
1212 &target_reset_list->sas_event_data);
1213
1214
1215
1216
1217
1218
1219 head = &hd->target_reset_list;
1220 if (list_empty(head))
1221 return 1;
1222
1223 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
1224 list);
1225
1226 id = target_reset_list->sas_event_data.TargetID;
1227 channel = target_reset_list->sas_event_data.Bus;
1228 target_reset_list->time_count = jiffies;
1229
1230 if (mptsas_target_reset(ioc, channel, id))
1231 target_reset_list->target_reset_issued = 1;
1232
1233 return 1;
1234}
1235
1236
1237
1238
1239
1240
1241
1242
1243static int
1244mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1245{
1246 MPT_SCSI_HOST *hd;
1247 int rc;
1248
1249 rc = mptscsih_ioc_reset(ioc, reset_phase);
1250 if ((ioc->bus_type != SAS) || (!rc))
1251 return rc;
1252
1253 hd = shost_priv(ioc->sh);
1254 if (!hd->ioc)
1255 goto out;
1256
1257 switch (reset_phase) {
1258 case MPT_IOC_SETUP_RESET:
1259 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1260 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1261 mptsas_fw_event_off(ioc);
1262 break;
1263 case MPT_IOC_PRE_RESET:
1264 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1265 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1266 break;
1267 case MPT_IOC_POST_RESET:
1268 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1269 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1270 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1271 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1272 complete(&ioc->sas_mgmt.done);
1273 }
1274 mptsas_cleanup_fw_event_q(ioc);
1275 mptsas_queue_rescan(ioc);
1276 break;
1277 default:
1278 break;
1279 }
1280
1281 out:
1282 return rc;
1283}
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293enum device_state{
1294 DEVICE_RETRY,
1295 DEVICE_ERROR,
1296 DEVICE_READY,
1297};
1298
1299static int
1300mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1301 u32 form, u32 form_specific)
1302{
1303 ConfigExtendedPageHeader_t hdr;
1304 CONFIGPARMS cfg;
1305 SasEnclosurePage0_t *buffer;
1306 dma_addr_t dma_handle;
1307 int error;
1308 __le64 le_identifier;
1309
1310 memset(&hdr, 0, sizeof(hdr));
1311 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1312 hdr.PageNumber = 0;
1313 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1314 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1315
1316 cfg.cfghdr.ehdr = &hdr;
1317 cfg.physAddr = -1;
1318 cfg.pageAddr = form + form_specific;
1319 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1320 cfg.dir = 0;
1321 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1322
1323 error = mpt_config(ioc, &cfg);
1324 if (error)
1325 goto out;
1326 if (!hdr.ExtPageLength) {
1327 error = -ENXIO;
1328 goto out;
1329 }
1330
1331 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1332 &dma_handle);
1333 if (!buffer) {
1334 error = -ENOMEM;
1335 goto out;
1336 }
1337
1338 cfg.physAddr = dma_handle;
1339 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1340
1341 error = mpt_config(ioc, &cfg);
1342 if (error)
1343 goto out_free_consistent;
1344
1345
1346 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1347 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1348 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1349 enclosure->flags = le16_to_cpu(buffer->Flags);
1350 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1351 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1352 enclosure->start_id = buffer->StartTargetID;
1353 enclosure->start_channel = buffer->StartBus;
1354 enclosure->sep_id = buffer->SEPTargetID;
1355 enclosure->sep_channel = buffer->SEPBus;
1356
1357 out_free_consistent:
1358 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1359 buffer, dma_handle);
1360 out:
1361 return error;
1362}
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372static int
1373mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1374{
1375 struct sas_rphy *rphy;
1376 struct sas_port *port;
1377 struct sas_identify identify;
1378 char *ds = NULL;
1379 u8 fw_id;
1380
1381 if (!phy_info) {
1382 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1383 "%s: exit at line=%d\n", ioc->name,
1384 __func__, __LINE__));
1385 return 1;
1386 }
1387
1388 fw_id = phy_info->attached.id;
1389
1390 if (mptsas_get_rphy(phy_info)) {
1391 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1392 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1393 __func__, fw_id, __LINE__));
1394 return 2;
1395 }
1396
1397 port = mptsas_get_port(phy_info);
1398 if (!port) {
1399 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1400 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1401 __func__, fw_id, __LINE__));
1402 return 3;
1403 }
1404
1405 if (phy_info->attached.device_info &
1406 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1407 ds = "ssp";
1408 if (phy_info->attached.device_info &
1409 MPI_SAS_DEVICE_INFO_STP_TARGET)
1410 ds = "stp";
1411 if (phy_info->attached.device_info &
1412 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1413 ds = "sata";
1414
1415 printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1416 " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1417 phy_info->attached.channel, phy_info->attached.id,
1418 phy_info->attached.phy_id, (unsigned long long)
1419 phy_info->attached.sas_address);
1420
1421 mptsas_parse_device_info(&identify, &phy_info->attached);
1422 rphy = sas_end_device_alloc(port);
1423 if (!rphy) {
1424 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1425 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1426 __func__, fw_id, __LINE__));
1427 return 5;
1428 }
1429
1430 rphy->identify = identify;
1431 if (sas_rphy_add(rphy)) {
1432 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1433 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1434 __func__, fw_id, __LINE__));
1435 sas_rphy_free(rphy);
1436 return 6;
1437 }
1438 mptsas_set_rphy(ioc, phy_info, rphy);
1439 return 0;
1440}
1441
1442
1443
1444
1445
1446
1447
1448static void
1449mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1450{
1451 struct sas_rphy *rphy;
1452 struct sas_port *port;
1453 struct mptsas_portinfo *port_info;
1454 struct mptsas_phyinfo *phy_info_parent;
1455 int i;
1456 char *ds = NULL;
1457 u8 fw_id;
1458 u64 sas_address;
1459
1460 if (!phy_info)
1461 return;
1462
1463 fw_id = phy_info->attached.id;
1464 sas_address = phy_info->attached.sas_address;
1465
1466 if (!phy_info->port_details) {
1467 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1468 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1469 __func__, fw_id, __LINE__));
1470 return;
1471 }
1472 rphy = mptsas_get_rphy(phy_info);
1473 if (!rphy) {
1474 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1475 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1476 __func__, fw_id, __LINE__));
1477 return;
1478 }
1479
1480 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1481 || phy_info->attached.device_info
1482 & MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1483 || phy_info->attached.device_info
1484 & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1485 ds = "initiator";
1486 if (phy_info->attached.device_info &
1487 MPI_SAS_DEVICE_INFO_SSP_TARGET)
1488 ds = "ssp";
1489 if (phy_info->attached.device_info &
1490 MPI_SAS_DEVICE_INFO_STP_TARGET)
1491 ds = "stp";
1492 if (phy_info->attached.device_info &
1493 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1494 ds = "sata";
1495
1496 dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1497 "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1498 "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1499 phy_info->attached.id, phy_info->attached.phy_id,
1500 (unsigned long long) sas_address);
1501
1502 port = mptsas_get_port(phy_info);
1503 if (!port) {
1504 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1505 "%s: fw_id=%d exit at line=%d\n", ioc->name,
1506 __func__, fw_id, __LINE__));
1507 return;
1508 }
1509 port_info = phy_info->portinfo;
1510 phy_info_parent = port_info->phy_info;
1511 for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1512 if (!phy_info_parent->phy)
1513 continue;
1514 if (phy_info_parent->attached.sas_address !=
1515 sas_address)
1516 continue;
1517 dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1518 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1519 ioc->name, phy_info_parent->phy_id,
1520 phy_info_parent->phy);
1521 sas_port_delete_phy(port, phy_info_parent->phy);
1522 }
1523
1524 dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1525 "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1526 port->port_identifier, (unsigned long long)sas_address);
1527 sas_port_delete(port);
1528 mptsas_set_port(ioc, phy_info, NULL);
1529 mptsas_port_delete(ioc, phy_info->port_details);
1530}
1531
1532struct mptsas_phyinfo *
1533mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1534 struct mptsas_devinfo *sas_device)
1535{
1536 struct mptsas_phyinfo *phy_info;
1537 struct mptsas_portinfo *port_info;
1538 int i;
1539
1540 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1541 sas_device->sas_address);
1542 if (!phy_info)
1543 goto out;
1544 port_info = phy_info->portinfo;
1545 if (!port_info)
1546 goto out;
1547 mutex_lock(&ioc->sas_topology_mutex);
1548 for (i = 0; i < port_info->num_phys; i++) {
1549 if (port_info->phy_info[i].attached.sas_address !=
1550 sas_device->sas_address)
1551 continue;
1552 port_info->phy_info[i].attached.channel = sas_device->channel;
1553 port_info->phy_info[i].attached.id = sas_device->id;
1554 port_info->phy_info[i].attached.sas_address =
1555 sas_device->sas_address;
1556 port_info->phy_info[i].attached.handle = sas_device->handle;
1557 port_info->phy_info[i].attached.handle_parent =
1558 sas_device->handle_parent;
1559 port_info->phy_info[i].attached.handle_enclosure =
1560 sas_device->handle_enclosure;
1561 }
1562 mutex_unlock(&ioc->sas_topology_mutex);
1563 out:
1564 return phy_info;
1565}
1566
1567
1568
1569
1570
1571
1572
1573static void
1574mptsas_firmware_event_work(struct work_struct *work)
1575{
1576 struct fw_event_work *fw_event =
1577 container_of(work, struct fw_event_work, work.work);
1578 MPT_ADAPTER *ioc = fw_event->ioc;
1579
1580
1581 if (fw_event->event == -1) {
1582 if (ioc->in_rescan) {
1583 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1584 "%s: rescan ignored as it is in progress\n",
1585 ioc->name, __func__));
1586 return;
1587 }
1588 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1589 "reset\n", ioc->name, __func__));
1590 ioc->in_rescan = 1;
1591 mptsas_not_responding_devices(ioc);
1592 mptsas_scan_sas_topology(ioc);
1593 ioc->in_rescan = 0;
1594 mptsas_free_fw_event(ioc, fw_event);
1595 mptsas_fw_event_on(ioc);
1596 return;
1597 }
1598
1599
1600 if (ioc->fw_events_off) {
1601 mptsas_free_fw_event(ioc, fw_event);
1602 return;
1603 }
1604
1605 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1606 "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1607 (fw_event->event & 0xFF)));
1608
1609 switch (fw_event->event) {
1610 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1611 mptsas_send_sas_event(fw_event);
1612 break;
1613 case MPI_EVENT_INTEGRATED_RAID:
1614 mptsas_send_raid_event(fw_event);
1615 break;
1616 case MPI_EVENT_IR2:
1617 mptsas_send_ir2_event(fw_event);
1618 break;
1619 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1620 mptbase_sas_persist_operation(ioc,
1621 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1622 mptsas_free_fw_event(ioc, fw_event);
1623 break;
1624 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1625 mptsas_broadcast_primative_work(fw_event);
1626 break;
1627 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1628 mptsas_send_expander_event(fw_event);
1629 break;
1630 case MPI_EVENT_SAS_PHY_LINK_STATUS:
1631 mptsas_send_link_status_event(fw_event);
1632 break;
1633 case MPI_EVENT_QUEUE_FULL:
1634 mptsas_handle_queue_full_event(fw_event);
1635 break;
1636 }
1637}
1638
1639
1640
1641static int
1642mptsas_slave_configure(struct scsi_device *sdev)
1643{
1644 struct Scsi_Host *host = sdev->host;
1645 MPT_SCSI_HOST *hd = shost_priv(host);
1646 MPT_ADAPTER *ioc = hd->ioc;
1647 VirtDevice *vdevice = sdev->hostdata;
1648
1649 if (vdevice->vtarget->deleted) {
1650 sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1651 vdevice->vtarget->deleted = 0;
1652 }
1653
1654
1655
1656
1657
1658 if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1659 mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1660 goto out;
1661 }
1662
1663 sas_read_port_mode_page(sdev);
1664
1665 mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1666
1667 out:
1668 return mptscsih_slave_configure(sdev);
1669}
1670
1671static int
1672mptsas_target_alloc(struct scsi_target *starget)
1673{
1674 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1675 MPT_SCSI_HOST *hd = shost_priv(host);
1676 VirtTarget *vtarget;
1677 u8 id, channel;
1678 struct sas_rphy *rphy;
1679 struct mptsas_portinfo *p;
1680 int i;
1681 MPT_ADAPTER *ioc = hd->ioc;
1682
1683 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1684 if (!vtarget)
1685 return -ENOMEM;
1686
1687 vtarget->starget = starget;
1688 vtarget->ioc_id = ioc->id;
1689 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1690 id = starget->id;
1691 channel = 0;
1692
1693
1694
1695
1696 if (starget->channel == MPTSAS_RAID_CHANNEL) {
1697 if (!ioc->raid_data.pIocPg2) {
1698 kfree(vtarget);
1699 return -ENXIO;
1700 }
1701 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1702 if (id == ioc->raid_data.pIocPg2->
1703 RaidVolume[i].VolumeID) {
1704 channel = ioc->raid_data.pIocPg2->
1705 RaidVolume[i].VolumeBus;
1706 }
1707 }
1708 vtarget->raidVolume = 1;
1709 goto out;
1710 }
1711
1712 rphy = dev_to_rphy(starget->dev.parent);
1713 mutex_lock(&ioc->sas_topology_mutex);
1714 list_for_each_entry(p, &ioc->sas_topology, list) {
1715 for (i = 0; i < p->num_phys; i++) {
1716 if (p->phy_info[i].attached.sas_address !=
1717 rphy->identify.sas_address)
1718 continue;
1719 id = p->phy_info[i].attached.id;
1720 channel = p->phy_info[i].attached.channel;
1721 mptsas_set_starget(&p->phy_info[i], starget);
1722
1723
1724
1725
1726 if (mptscsih_is_phys_disk(ioc, channel, id)) {
1727 id = mptscsih_raid_id_to_num(ioc,
1728 channel, id);
1729 vtarget->tflags |=
1730 MPT_TARGET_FLAGS_RAID_COMPONENT;
1731 p->phy_info[i].attached.phys_disk_num = id;
1732 }
1733 mutex_unlock(&ioc->sas_topology_mutex);
1734 goto out;
1735 }
1736 }
1737 mutex_unlock(&ioc->sas_topology_mutex);
1738
1739 kfree(vtarget);
1740 return -ENXIO;
1741
1742 out:
1743 vtarget->id = id;
1744 vtarget->channel = channel;
1745 starget->hostdata = vtarget;
1746 return 0;
1747}
1748
1749static void
1750mptsas_target_destroy(struct scsi_target *starget)
1751{
1752 struct Scsi_Host *host = dev_to_shost(&starget->dev);
1753 MPT_SCSI_HOST *hd = shost_priv(host);
1754 struct sas_rphy *rphy;
1755 struct mptsas_portinfo *p;
1756 int i;
1757 MPT_ADAPTER *ioc = hd->ioc;
1758 VirtTarget *vtarget;
1759
1760 if (!starget->hostdata)
1761 return;
1762
1763 vtarget = starget->hostdata;
1764
1765 mptsas_del_device_component_by_os(ioc, starget->channel,
1766 starget->id);
1767
1768
1769 if (starget->channel == MPTSAS_RAID_CHANNEL)
1770 goto out;
1771
1772 rphy = dev_to_rphy(starget->dev.parent);
1773 list_for_each_entry(p, &ioc->sas_topology, list) {
1774 for (i = 0; i < p->num_phys; i++) {
1775 if (p->phy_info[i].attached.sas_address !=
1776 rphy->identify.sas_address)
1777 continue;
1778
1779 starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1780 "delete device: fw_channel %d, fw_id %d, phy %d, "
1781 "sas_addr 0x%llx\n", ioc->name,
1782 p->phy_info[i].attached.channel,
1783 p->phy_info[i].attached.id,
1784 p->phy_info[i].attached.phy_id, (unsigned long long)
1785 p->phy_info[i].attached.sas_address);
1786
1787 mptsas_set_starget(&p->phy_info[i], NULL);
1788 }
1789 }
1790
1791 out:
1792 vtarget->starget = NULL;
1793 kfree(starget->hostdata);
1794 starget->hostdata = NULL;
1795}
1796
1797
1798static int
1799mptsas_slave_alloc(struct scsi_device *sdev)
1800{
1801 struct Scsi_Host *host = sdev->host;
1802 MPT_SCSI_HOST *hd = shost_priv(host);
1803 struct sas_rphy *rphy;
1804 struct mptsas_portinfo *p;
1805 VirtDevice *vdevice;
1806 struct scsi_target *starget;
1807 int i;
1808 MPT_ADAPTER *ioc = hd->ioc;
1809
1810 vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1811 if (!vdevice) {
1812 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1813 ioc->name, sizeof(VirtDevice));
1814 return -ENOMEM;
1815 }
1816 starget = scsi_target(sdev);
1817 vdevice->vtarget = starget->hostdata;
1818
1819 if (sdev->channel == MPTSAS_RAID_CHANNEL)
1820 goto out;
1821
1822 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1823 mutex_lock(&ioc->sas_topology_mutex);
1824 list_for_each_entry(p, &ioc->sas_topology, list) {
1825 for (i = 0; i < p->num_phys; i++) {
1826 if (p->phy_info[i].attached.sas_address !=
1827 rphy->identify.sas_address)
1828 continue;
1829 vdevice->lun = sdev->lun;
1830
1831
1832
1833 if (mptscsih_is_phys_disk(ioc,
1834 p->phy_info[i].attached.channel,
1835 p->phy_info[i].attached.id))
1836 sdev->no_uld_attach = 1;
1837 mutex_unlock(&ioc->sas_topology_mutex);
1838 goto out;
1839 }
1840 }
1841 mutex_unlock(&ioc->sas_topology_mutex);
1842
1843 kfree(vdevice);
1844 return -ENXIO;
1845
1846 out:
1847 vdevice->vtarget->num_luns++;
1848 sdev->hostdata = vdevice;
1849 return 0;
1850}
1851
1852static int
1853mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1854{
1855 MPT_SCSI_HOST *hd;
1856 MPT_ADAPTER *ioc;
1857 VirtDevice *vdevice = SCpnt->device->hostdata;
1858
1859 if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1860 SCpnt->result = DID_NO_CONNECT << 16;
1861 done(SCpnt);
1862 return 0;
1863 }
1864
1865 hd = shost_priv(SCpnt->device->host);
1866 ioc = hd->ioc;
1867
1868 if (ioc->sas_discovery_quiesce_io)
1869 return SCSI_MLQUEUE_HOST_BUSY;
1870
1871
1872
1873 return mptscsih_qcmd(SCpnt,done);
1874}
1875
1876
1877static struct scsi_host_template mptsas_driver_template = {
1878 .module = THIS_MODULE,
1879 .proc_name = "mptsas",
1880 .proc_info = mptscsih_proc_info,
1881 .name = "MPT SPI Host",
1882 .info = mptscsih_info,
1883 .queuecommand = mptsas_qcmd,
1884 .target_alloc = mptsas_target_alloc,
1885 .slave_alloc = mptsas_slave_alloc,
1886 .slave_configure = mptsas_slave_configure,
1887 .target_destroy = mptsas_target_destroy,
1888 .slave_destroy = mptscsih_slave_destroy,
1889 .change_queue_depth = mptscsih_change_queue_depth,
1890 .eh_abort_handler = mptscsih_abort,
1891 .eh_device_reset_handler = mptscsih_dev_reset,
1892 .eh_bus_reset_handler = mptscsih_bus_reset,
1893 .eh_host_reset_handler = mptscsih_host_reset,
1894 .bios_param = mptscsih_bios_param,
1895 .can_queue = MPT_SAS_CAN_QUEUE,
1896 .this_id = -1,
1897 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1898 .max_sectors = 8192,
1899 .cmd_per_lun = 7,
1900 .use_clustering = ENABLE_CLUSTERING,
1901 .shost_attrs = mptscsih_host_attrs,
1902};
1903
1904static int mptsas_get_linkerrors(struct sas_phy *phy)
1905{
1906 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1907 ConfigExtendedPageHeader_t hdr;
1908 CONFIGPARMS cfg;
1909 SasPhyPage1_t *buffer;
1910 dma_addr_t dma_handle;
1911 int error;
1912
1913
1914 if (!scsi_is_sas_phy_local(phy))
1915 return -EINVAL;
1916
1917 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1918 hdr.ExtPageLength = 0;
1919 hdr.PageNumber = 1 ;
1920 hdr.Reserved1 = 0;
1921 hdr.Reserved2 = 0;
1922 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1923 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1924
1925 cfg.cfghdr.ehdr = &hdr;
1926 cfg.physAddr = -1;
1927 cfg.pageAddr = phy->identify.phy_identifier;
1928 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1929 cfg.dir = 0;
1930 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1931
1932 error = mpt_config(ioc, &cfg);
1933 if (error)
1934 return error;
1935 if (!hdr.ExtPageLength)
1936 return -ENXIO;
1937
1938 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1939 &dma_handle);
1940 if (!buffer)
1941 return -ENOMEM;
1942
1943 cfg.physAddr = dma_handle;
1944 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1945
1946 error = mpt_config(ioc, &cfg);
1947 if (error)
1948 goto out_free_consistent;
1949
1950 mptsas_print_phy_pg1(ioc, buffer);
1951
1952 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1953 phy->running_disparity_error_count =
1954 le32_to_cpu(buffer->RunningDisparityErrorCount);
1955 phy->loss_of_dword_sync_count =
1956 le32_to_cpu(buffer->LossDwordSynchCount);
1957 phy->phy_reset_problem_count =
1958 le32_to_cpu(buffer->PhyResetProblemCount);
1959
1960 out_free_consistent:
1961 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1962 buffer, dma_handle);
1963 return error;
1964}
1965
1966static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1967 MPT_FRAME_HDR *reply)
1968{
1969 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1970 if (reply != NULL) {
1971 ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
1972 memcpy(ioc->sas_mgmt.reply, reply,
1973 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1974 }
1975
1976 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1977 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
1978 complete(&ioc->sas_mgmt.done);
1979 return 1;
1980 }
1981 return 0;
1982}
1983
1984static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1985{
1986 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1987 SasIoUnitControlRequest_t *req;
1988 SasIoUnitControlReply_t *reply;
1989 MPT_FRAME_HDR *mf;
1990 MPIHeader_t *hdr;
1991 unsigned long timeleft;
1992 int error = -ERESTARTSYS;
1993
1994
1995 if (!scsi_is_sas_phy_local(phy))
1996 return -EINVAL;
1997
1998
1999 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2000 return -ENXIO;
2001
2002 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2003 goto out;
2004
2005 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2006 if (!mf) {
2007 error = -ENOMEM;
2008 goto out_unlock;
2009 }
2010
2011 hdr = (MPIHeader_t *) mf;
2012 req = (SasIoUnitControlRequest_t *)mf;
2013 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2014 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2015 req->MsgContext = hdr->MsgContext;
2016 req->Operation = hard_reset ?
2017 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2018 req->PhyNum = phy->identify.phy_identifier;
2019
2020 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2021 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2022
2023 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2024 10 * HZ);
2025 if (!timeleft) {
2026
2027 mpt_free_msg_frame(ioc, mf);
2028 mpt_HardResetHandler(ioc, CAN_SLEEP);
2029 error = -ETIMEDOUT;
2030 goto out_unlock;
2031 }
2032
2033
2034 if ((ioc->sas_mgmt.status &
2035 MPT_MGMT_STATUS_RF_VALID) == 0) {
2036 error = -ENXIO;
2037 goto out_unlock;
2038 }
2039
2040
2041 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2042 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2043 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2044 ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2045 error = -ENXIO;
2046 goto out_unlock;
2047 }
2048
2049 error = 0;
2050
2051 out_unlock:
2052 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2053 mutex_unlock(&ioc->sas_mgmt.mutex);
2054 out:
2055 return error;
2056}
2057
2058static int
2059mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2060{
2061 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2062 int i, error;
2063 struct mptsas_portinfo *p;
2064 struct mptsas_enclosure enclosure_info;
2065 u64 enclosure_handle;
2066
2067 mutex_lock(&ioc->sas_topology_mutex);
2068 list_for_each_entry(p, &ioc->sas_topology, list) {
2069 for (i = 0; i < p->num_phys; i++) {
2070 if (p->phy_info[i].attached.sas_address ==
2071 rphy->identify.sas_address) {
2072 enclosure_handle = p->phy_info[i].
2073 attached.handle_enclosure;
2074 goto found_info;
2075 }
2076 }
2077 }
2078 mutex_unlock(&ioc->sas_topology_mutex);
2079 return -ENXIO;
2080
2081 found_info:
2082 mutex_unlock(&ioc->sas_topology_mutex);
2083 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2084 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2085 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2086 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2087 if (!error)
2088 *identifier = enclosure_info.enclosure_logical_id;
2089 return error;
2090}
2091
2092static int
2093mptsas_get_bay_identifier(struct sas_rphy *rphy)
2094{
2095 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2096 struct mptsas_portinfo *p;
2097 int i, rc;
2098
2099 mutex_lock(&ioc->sas_topology_mutex);
2100 list_for_each_entry(p, &ioc->sas_topology, list) {
2101 for (i = 0; i < p->num_phys; i++) {
2102 if (p->phy_info[i].attached.sas_address ==
2103 rphy->identify.sas_address) {
2104 rc = p->phy_info[i].attached.slot;
2105 goto out;
2106 }
2107 }
2108 }
2109 rc = -ENXIO;
2110 out:
2111 mutex_unlock(&ioc->sas_topology_mutex);
2112 return rc;
2113}
2114
2115static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2116 struct request *req)
2117{
2118 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2119 MPT_FRAME_HDR *mf;
2120 SmpPassthroughRequest_t *smpreq;
2121 struct request *rsp = req->next_rq;
2122 int ret;
2123 int flagsLength;
2124 unsigned long timeleft;
2125 char *psge;
2126 dma_addr_t dma_addr_in = 0;
2127 dma_addr_t dma_addr_out = 0;
2128 u64 sas_address = 0;
2129
2130 if (!rsp) {
2131 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2132 ioc->name, __func__);
2133 return -EINVAL;
2134 }
2135
2136
2137 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2138 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2139 ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2140 rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2141 return -EINVAL;
2142 }
2143
2144 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2145 if (ret)
2146 goto out;
2147
2148 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2149 if (!mf) {
2150 ret = -ENOMEM;
2151 goto out_unlock;
2152 }
2153
2154 smpreq = (SmpPassthroughRequest_t *)mf;
2155 memset(smpreq, 0, sizeof(*smpreq));
2156
2157 smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2158 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2159
2160 if (rphy)
2161 sas_address = rphy->identify.sas_address;
2162 else {
2163 struct mptsas_portinfo *port_info;
2164
2165 mutex_lock(&ioc->sas_topology_mutex);
2166 port_info = ioc->hba_port_info;
2167 if (port_info && port_info->phy_info)
2168 sas_address =
2169 port_info->phy_info[0].phy->identify.sas_address;
2170 mutex_unlock(&ioc->sas_topology_mutex);
2171 }
2172
2173 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2174
2175 psge = (char *)
2176 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2177
2178
2179 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2180 MPI_SGE_FLAGS_END_OF_BUFFER |
2181 MPI_SGE_FLAGS_DIRECTION)
2182 << MPI_SGE_FLAGS_SHIFT;
2183 flagsLength |= (blk_rq_bytes(req) - 4);
2184
2185 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2186 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2187 if (!dma_addr_out)
2188 goto put_mf;
2189 ioc->add_sge(psge, flagsLength, dma_addr_out);
2190 psge += ioc->SGE_size;
2191
2192
2193 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2194 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2195 MPI_SGE_FLAGS_IOC_TO_HOST |
2196 MPI_SGE_FLAGS_END_OF_BUFFER;
2197
2198 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2199 flagsLength |= blk_rq_bytes(rsp) + 4;
2200 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2201 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2202 if (!dma_addr_in)
2203 goto unmap;
2204 ioc->add_sge(psge, flagsLength, dma_addr_in);
2205
2206 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2207 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2208
2209 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2210 if (!timeleft) {
2211 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2212
2213 mpt_HardResetHandler(ioc, CAN_SLEEP);
2214 ret = -ETIMEDOUT;
2215 goto unmap;
2216 }
2217 mf = NULL;
2218
2219 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2220 SmpPassthroughReply_t *smprep;
2221
2222 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2223 memcpy(req->sense, smprep, sizeof(*smprep));
2224 req->sense_len = sizeof(*smprep);
2225 req->resid_len = 0;
2226 rsp->resid_len -= smprep->ResponseDataLength;
2227 } else {
2228 printk(MYIOC_s_ERR_FMT
2229 "%s: smp passthru reply failed to be returned\n",
2230 ioc->name, __func__);
2231 ret = -ENXIO;
2232 }
2233unmap:
2234 if (dma_addr_out)
2235 pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2236 PCI_DMA_BIDIRECTIONAL);
2237 if (dma_addr_in)
2238 pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2239 PCI_DMA_BIDIRECTIONAL);
2240put_mf:
2241 if (mf)
2242 mpt_free_msg_frame(ioc, mf);
2243out_unlock:
2244 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2245 mutex_unlock(&ioc->sas_mgmt.mutex);
2246out:
2247 return ret;
2248}
2249
2250static struct sas_function_template mptsas_transport_functions = {
2251 .get_linkerrors = mptsas_get_linkerrors,
2252 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
2253 .get_bay_identifier = mptsas_get_bay_identifier,
2254 .phy_reset = mptsas_phy_reset,
2255 .smp_handler = mptsas_smp_handler,
2256};
2257
2258static struct scsi_transport_template *mptsas_transport_template;
2259
2260static int
2261mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2262{
2263 ConfigExtendedPageHeader_t hdr;
2264 CONFIGPARMS cfg;
2265 SasIOUnitPage0_t *buffer;
2266 dma_addr_t dma_handle;
2267 int error, i;
2268
2269 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2270 hdr.ExtPageLength = 0;
2271 hdr.PageNumber = 0;
2272 hdr.Reserved1 = 0;
2273 hdr.Reserved2 = 0;
2274 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2275 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2276
2277 cfg.cfghdr.ehdr = &hdr;
2278 cfg.physAddr = -1;
2279 cfg.pageAddr = 0;
2280 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2281 cfg.dir = 0;
2282 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2283
2284 error = mpt_config(ioc, &cfg);
2285 if (error)
2286 goto out;
2287 if (!hdr.ExtPageLength) {
2288 error = -ENXIO;
2289 goto out;
2290 }
2291
2292 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2293 &dma_handle);
2294 if (!buffer) {
2295 error = -ENOMEM;
2296 goto out;
2297 }
2298
2299 cfg.physAddr = dma_handle;
2300 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2301
2302 error = mpt_config(ioc, &cfg);
2303 if (error)
2304 goto out_free_consistent;
2305
2306 port_info->num_phys = buffer->NumPhys;
2307 port_info->phy_info = kcalloc(port_info->num_phys,
2308 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2309 if (!port_info->phy_info) {
2310 error = -ENOMEM;
2311 goto out_free_consistent;
2312 }
2313
2314 ioc->nvdata_version_persistent =
2315 le16_to_cpu(buffer->NvdataVersionPersistent);
2316 ioc->nvdata_version_default =
2317 le16_to_cpu(buffer->NvdataVersionDefault);
2318
2319 for (i = 0; i < port_info->num_phys; i++) {
2320 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2321 port_info->phy_info[i].phy_id = i;
2322 port_info->phy_info[i].port_id =
2323 buffer->PhyData[i].Port;
2324 port_info->phy_info[i].negotiated_link_rate =
2325 buffer->PhyData[i].NegotiatedLinkRate;
2326 port_info->phy_info[i].portinfo = port_info;
2327 port_info->phy_info[i].handle =
2328 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2329 }
2330
2331 out_free_consistent:
2332 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2333 buffer, dma_handle);
2334 out:
2335 return error;
2336}
2337
2338static int
2339mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2340{
2341 ConfigExtendedPageHeader_t hdr;
2342 CONFIGPARMS cfg;
2343 SasIOUnitPage1_t *buffer;
2344 dma_addr_t dma_handle;
2345 int error;
2346 u16 device_missing_delay;
2347
2348 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2349 memset(&cfg, 0, sizeof(CONFIGPARMS));
2350
2351 cfg.cfghdr.ehdr = &hdr;
2352 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2353 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2354 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2355 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2356 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2357 cfg.cfghdr.ehdr->PageNumber = 1;
2358
2359 error = mpt_config(ioc, &cfg);
2360 if (error)
2361 goto out;
2362 if (!hdr.ExtPageLength) {
2363 error = -ENXIO;
2364 goto out;
2365 }
2366
2367 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2368 &dma_handle);
2369 if (!buffer) {
2370 error = -ENOMEM;
2371 goto out;
2372 }
2373
2374 cfg.physAddr = dma_handle;
2375 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2376
2377 error = mpt_config(ioc, &cfg);
2378 if (error)
2379 goto out_free_consistent;
2380
2381 ioc->io_missing_delay =
2382 le16_to_cpu(buffer->IODeviceMissingDelay);
2383 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
2384 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2385 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2386 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2387
2388 out_free_consistent:
2389 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2390 buffer, dma_handle);
2391 out:
2392 return error;
2393}
2394
2395static int
2396mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2397 u32 form, u32 form_specific)
2398{
2399 ConfigExtendedPageHeader_t hdr;
2400 CONFIGPARMS cfg;
2401 SasPhyPage0_t *buffer;
2402 dma_addr_t dma_handle;
2403 int error;
2404
2405 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2406 hdr.ExtPageLength = 0;
2407 hdr.PageNumber = 0;
2408 hdr.Reserved1 = 0;
2409 hdr.Reserved2 = 0;
2410 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2411 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2412
2413 cfg.cfghdr.ehdr = &hdr;
2414 cfg.dir = 0;
2415 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2416
2417
2418 cfg.physAddr = -1;
2419 cfg.pageAddr = form + form_specific;
2420 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2421
2422 error = mpt_config(ioc, &cfg);
2423 if (error)
2424 goto out;
2425
2426 if (!hdr.ExtPageLength) {
2427 error = -ENXIO;
2428 goto out;
2429 }
2430
2431 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2432 &dma_handle);
2433 if (!buffer) {
2434 error = -ENOMEM;
2435 goto out;
2436 }
2437
2438 cfg.physAddr = dma_handle;
2439 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2440
2441 error = mpt_config(ioc, &cfg);
2442 if (error)
2443 goto out_free_consistent;
2444
2445 mptsas_print_phy_pg0(ioc, buffer);
2446
2447 phy_info->hw_link_rate = buffer->HwLinkRate;
2448 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2449 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2450 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2451
2452 out_free_consistent:
2453 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2454 buffer, dma_handle);
2455 out:
2456 return error;
2457}
2458
2459static int
2460mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2461 u32 form, u32 form_specific)
2462{
2463 ConfigExtendedPageHeader_t hdr;
2464 CONFIGPARMS cfg;
2465 SasDevicePage0_t *buffer;
2466 dma_addr_t dma_handle;
2467 __le64 sas_address;
2468 int error=0;
2469
2470 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2471 hdr.ExtPageLength = 0;
2472 hdr.PageNumber = 0;
2473 hdr.Reserved1 = 0;
2474 hdr.Reserved2 = 0;
2475 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2476 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2477
2478 cfg.cfghdr.ehdr = &hdr;
2479 cfg.pageAddr = form + form_specific;
2480 cfg.physAddr = -1;
2481 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2482 cfg.dir = 0;
2483 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2484
2485 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2486 error = mpt_config(ioc, &cfg);
2487 if (error)
2488 goto out;
2489 if (!hdr.ExtPageLength) {
2490 error = -ENXIO;
2491 goto out;
2492 }
2493
2494 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2495 &dma_handle);
2496 if (!buffer) {
2497 error = -ENOMEM;
2498 goto out;
2499 }
2500
2501 cfg.physAddr = dma_handle;
2502 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2503
2504 error = mpt_config(ioc, &cfg);
2505 if (error)
2506 goto out_free_consistent;
2507
2508 mptsas_print_device_pg0(ioc, buffer);
2509
2510 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2511 device_info->handle = le16_to_cpu(buffer->DevHandle);
2512 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2513 device_info->handle_enclosure =
2514 le16_to_cpu(buffer->EnclosureHandle);
2515 device_info->slot = le16_to_cpu(buffer->Slot);
2516 device_info->phy_id = buffer->PhyNum;
2517 device_info->port_id = buffer->PhysicalPort;
2518 device_info->id = buffer->TargetID;
2519 device_info->phys_disk_num = ~0;
2520 device_info->channel = buffer->Bus;
2521 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2522 device_info->sas_address = le64_to_cpu(sas_address);
2523 device_info->device_info =
2524 le32_to_cpu(buffer->DeviceInfo);
2525
2526 out_free_consistent:
2527 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2528 buffer, dma_handle);
2529 out:
2530 return error;
2531}
2532
2533static int
2534mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2535 u32 form, u32 form_specific)
2536{
2537 ConfigExtendedPageHeader_t hdr;
2538 CONFIGPARMS cfg;
2539 SasExpanderPage0_t *buffer;
2540 dma_addr_t dma_handle;
2541 int i, error;
2542 __le64 sas_address;
2543
2544 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2545 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2546 hdr.ExtPageLength = 0;
2547 hdr.PageNumber = 0;
2548 hdr.Reserved1 = 0;
2549 hdr.Reserved2 = 0;
2550 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2551 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2552
2553 cfg.cfghdr.ehdr = &hdr;
2554 cfg.physAddr = -1;
2555 cfg.pageAddr = form + form_specific;
2556 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2557 cfg.dir = 0;
2558 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2559
2560 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2561 error = mpt_config(ioc, &cfg);
2562 if (error)
2563 goto out;
2564
2565 if (!hdr.ExtPageLength) {
2566 error = -ENXIO;
2567 goto out;
2568 }
2569
2570 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2571 &dma_handle);
2572 if (!buffer) {
2573 error = -ENOMEM;
2574 goto out;
2575 }
2576
2577 cfg.physAddr = dma_handle;
2578 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2579
2580 error = mpt_config(ioc, &cfg);
2581 if (error)
2582 goto out_free_consistent;
2583
2584 if (!buffer->NumPhys) {
2585 error = -ENODEV;
2586 goto out_free_consistent;
2587 }
2588
2589
2590 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2591 port_info->phy_info = kcalloc(port_info->num_phys,
2592 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2593 if (!port_info->phy_info) {
2594 error = -ENOMEM;
2595 goto out_free_consistent;
2596 }
2597
2598 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2599 for (i = 0; i < port_info->num_phys; i++) {
2600 port_info->phy_info[i].portinfo = port_info;
2601 port_info->phy_info[i].handle =
2602 le16_to_cpu(buffer->DevHandle);
2603 port_info->phy_info[i].identify.sas_address =
2604 le64_to_cpu(sas_address);
2605 port_info->phy_info[i].identify.handle_parent =
2606 le16_to_cpu(buffer->ParentDevHandle);
2607 }
2608
2609 out_free_consistent:
2610 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2611 buffer, dma_handle);
2612 out:
2613 return error;
2614}
2615
2616static int
2617mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2618 u32 form, u32 form_specific)
2619{
2620 ConfigExtendedPageHeader_t hdr;
2621 CONFIGPARMS cfg;
2622 SasExpanderPage1_t *buffer;
2623 dma_addr_t dma_handle;
2624 int error=0;
2625
2626 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2627 hdr.ExtPageLength = 0;
2628 hdr.PageNumber = 1;
2629 hdr.Reserved1 = 0;
2630 hdr.Reserved2 = 0;
2631 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2632 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2633
2634 cfg.cfghdr.ehdr = &hdr;
2635 cfg.physAddr = -1;
2636 cfg.pageAddr = form + form_specific;
2637 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2638 cfg.dir = 0;
2639 cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2640
2641 error = mpt_config(ioc, &cfg);
2642 if (error)
2643 goto out;
2644
2645 if (!hdr.ExtPageLength) {
2646 error = -ENXIO;
2647 goto out;
2648 }
2649
2650 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2651 &dma_handle);
2652 if (!buffer) {
2653 error = -ENOMEM;
2654 goto out;
2655 }
2656
2657 cfg.physAddr = dma_handle;
2658 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2659
2660 error = mpt_config(ioc, &cfg);
2661
2662 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2663 error = -ENODEV;
2664 goto out;
2665 }
2666
2667 if (error)
2668 goto out_free_consistent;
2669
2670
2671 mptsas_print_expander_pg1(ioc, buffer);
2672
2673
2674 phy_info->phy_id = buffer->PhyIdentifier;
2675 phy_info->port_id = buffer->PhysicalPort;
2676 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2677 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2678 phy_info->hw_link_rate = buffer->HwLinkRate;
2679 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2680 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2681
2682 out_free_consistent:
2683 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2684 buffer, dma_handle);
2685 out:
2686 return error;
2687}
2688
2689static void
2690mptsas_parse_device_info(struct sas_identify *identify,
2691 struct mptsas_devinfo *device_info)
2692{
2693 u16 protocols;
2694
2695 identify->sas_address = device_info->sas_address;
2696 identify->phy_identifier = device_info->phy_id;
2697
2698
2699
2700
2701
2702 protocols = device_info->device_info & 0x78;
2703 identify->initiator_port_protocols = 0;
2704 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2705 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2706 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2707 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2708 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2709 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2710 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2711 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2712
2713
2714
2715
2716
2717 protocols = device_info->device_info & 0x780;
2718 identify->target_port_protocols = 0;
2719 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2720 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2721 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2722 identify->target_port_protocols |= SAS_PROTOCOL_STP;
2723 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
2724 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
2725 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2726 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
2727
2728
2729
2730
2731 switch (device_info->device_info &
2732 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
2733 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
2734 identify->device_type = SAS_PHY_UNUSED;
2735 break;
2736 case MPI_SAS_DEVICE_INFO_END_DEVICE:
2737 identify->device_type = SAS_END_DEVICE;
2738 break;
2739 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
2740 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
2741 break;
2742 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
2743 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
2744 break;
2745 }
2746}
2747
2748static int mptsas_probe_one_phy(struct device *dev,
2749 struct mptsas_phyinfo *phy_info, int index, int local)
2750{
2751 MPT_ADAPTER *ioc;
2752 struct sas_phy *phy;
2753 struct sas_port *port;
2754 int error = 0;
2755
2756 if (!dev) {
2757 error = -ENODEV;
2758 goto out;
2759 }
2760
2761 if (!phy_info->phy) {
2762 phy = sas_phy_alloc(dev, index);
2763 if (!phy) {
2764 error = -ENOMEM;
2765 goto out;
2766 }
2767 } else
2768 phy = phy_info->phy;
2769
2770 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
2771
2772
2773
2774
2775 switch (phy_info->negotiated_link_rate) {
2776 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
2777 phy->negotiated_linkrate = SAS_PHY_DISABLED;
2778 break;
2779 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
2780 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
2781 break;
2782 case MPI_SAS_IOUNIT0_RATE_1_5:
2783 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
2784 break;
2785 case MPI_SAS_IOUNIT0_RATE_3_0:
2786 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
2787 break;
2788 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
2789 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
2790 default:
2791 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
2792 break;
2793 }
2794
2795
2796
2797
2798 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2799 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
2800 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2801 break;
2802 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2803 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2804 break;
2805 default:
2806 break;
2807 }
2808
2809
2810
2811
2812 switch (phy_info->programmed_link_rate &
2813 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
2814 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
2815 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2816 break;
2817 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
2818 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2819 break;
2820 default:
2821 break;
2822 }
2823
2824
2825
2826
2827 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
2828 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
2829 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
2830 break;
2831 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2832 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
2833 break;
2834 default:
2835 break;
2836 }
2837
2838
2839
2840
2841 switch (phy_info->programmed_link_rate &
2842 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
2843 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
2844 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
2845 break;
2846 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
2847 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
2848 break;
2849 default:
2850 break;
2851 }
2852
2853 if (!phy_info->phy) {
2854
2855 error = sas_phy_add(phy);
2856 if (error) {
2857 sas_phy_free(phy);
2858 goto out;
2859 }
2860 phy_info->phy = phy;
2861 }
2862
2863 if (!phy_info->attached.handle ||
2864 !phy_info->port_details)
2865 goto out;
2866
2867 port = mptsas_get_port(phy_info);
2868 ioc = phy_to_ioc(phy_info->phy);
2869
2870 if (phy_info->sas_port_add_phy) {
2871
2872 if (!port) {
2873 port = sas_port_alloc_num(dev);
2874 if (!port) {
2875 error = -ENOMEM;
2876 goto out;
2877 }
2878 error = sas_port_add(port);
2879 if (error) {
2880 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2881 "%s: exit at line=%d\n", ioc->name,
2882 __func__, __LINE__));
2883 goto out;
2884 }
2885 mptsas_set_port(ioc, phy_info, port);
2886 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
2887 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
2888 ioc->name, port->port_identifier,
2889 (unsigned long long)phy_info->
2890 attached.sas_address));
2891 }
2892 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2893 "sas_port_add_phy: phy_id=%d\n",
2894 ioc->name, phy_info->phy_id));
2895 sas_port_add_phy(port, phy_info->phy);
2896 phy_info->sas_port_add_phy = 0;
2897 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
2898 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
2899 phy_info->phy_id, phy_info->phy));
2900 }
2901 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2902
2903 struct sas_rphy *rphy;
2904 struct device *parent;
2905 struct sas_identify identify;
2906
2907 parent = dev->parent->parent;
2908
2909
2910
2911
2912
2913 if (mptsas_is_end_device(&phy_info->attached) &&
2914 phy_info->attached.handle_parent) {
2915 goto out;
2916 }
2917
2918 mptsas_parse_device_info(&identify, &phy_info->attached);
2919 if (scsi_is_host_device(parent)) {
2920 struct mptsas_portinfo *port_info;
2921 int i;
2922
2923 port_info = ioc->hba_port_info;
2924
2925 for (i = 0; i < port_info->num_phys; i++)
2926 if (port_info->phy_info[i].identify.sas_address ==
2927 identify.sas_address) {
2928 sas_port_mark_backlink(port);
2929 goto out;
2930 }
2931
2932 } else if (scsi_is_sas_rphy(parent)) {
2933 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2934 if (identify.sas_address ==
2935 parent_rphy->identify.sas_address) {
2936 sas_port_mark_backlink(port);
2937 goto out;
2938 }
2939 }
2940
2941 switch (identify.device_type) {
2942 case SAS_END_DEVICE:
2943 rphy = sas_end_device_alloc(port);
2944 break;
2945 case SAS_EDGE_EXPANDER_DEVICE:
2946 case SAS_FANOUT_EXPANDER_DEVICE:
2947 rphy = sas_expander_alloc(port, identify.device_type);
2948 break;
2949 default:
2950 rphy = NULL;
2951 break;
2952 }
2953 if (!rphy) {
2954 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2955 "%s: exit at line=%d\n", ioc->name,
2956 __func__, __LINE__));
2957 goto out;
2958 }
2959
2960 rphy->identify = identify;
2961 error = sas_rphy_add(rphy);
2962 if (error) {
2963 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2964 "%s: exit at line=%d\n", ioc->name,
2965 __func__, __LINE__));
2966 sas_rphy_free(rphy);
2967 goto out;
2968 }
2969 mptsas_set_rphy(ioc, phy_info, rphy);
2970 }
2971
2972 out:
2973 return error;
2974}
2975
2976static int
2977mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2978{
2979 struct mptsas_portinfo *port_info, *hba;
2980 int error = -ENOMEM, i;
2981
2982 hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
2983 if (! hba)
2984 goto out;
2985
2986 error = mptsas_sas_io_unit_pg0(ioc, hba);
2987 if (error)
2988 goto out_free_port_info;
2989
2990 mptsas_sas_io_unit_pg1(ioc);
2991 mutex_lock(&ioc->sas_topology_mutex);
2992 port_info = ioc->hba_port_info;
2993 if (!port_info) {
2994 ioc->hba_port_info = port_info = hba;
2995 ioc->hba_port_num_phy = port_info->num_phys;
2996 list_add_tail(&port_info->list, &ioc->sas_topology);
2997 } else {
2998 for (i = 0; i < hba->num_phys; i++) {
2999 port_info->phy_info[i].negotiated_link_rate =
3000 hba->phy_info[i].negotiated_link_rate;
3001 port_info->phy_info[i].handle =
3002 hba->phy_info[i].handle;
3003 port_info->phy_info[i].port_id =
3004 hba->phy_info[i].port_id;
3005 }
3006 kfree(hba->phy_info);
3007 kfree(hba);
3008 hba = NULL;
3009 }
3010 mutex_unlock(&ioc->sas_topology_mutex);
3011#if defined(CPQ_CIM)
3012 ioc->num_ports = port_info->num_phys;
3013#endif
3014 for (i = 0; i < port_info->num_phys; i++) {
3015 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3016 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3017 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3018 port_info->phy_info[i].identify.handle =
3019 port_info->phy_info[i].handle;
3020 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3021 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3022 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3023 port_info->phy_info[i].identify.handle);
3024 if (!ioc->hba_port_sas_addr)
3025 ioc->hba_port_sas_addr =
3026 port_info->phy_info[i].identify.sas_address;
3027 port_info->phy_info[i].identify.phy_id =
3028 port_info->phy_info[i].phy_id = i;
3029 if (port_info->phy_info[i].attached.handle)
3030 mptsas_sas_device_pg0(ioc,
3031 &port_info->phy_info[i].attached,
3032 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3033 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3034 port_info->phy_info[i].attached.handle);
3035 }
3036
3037 mptsas_setup_wide_ports(ioc, port_info);
3038
3039 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3040 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3041 &port_info->phy_info[i], ioc->sas_index, 1);
3042
3043 return 0;
3044
3045 out_free_port_info:
3046 kfree(hba);
3047 out:
3048 return error;
3049}
3050
3051static void
3052mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3053{
3054 struct mptsas_portinfo *parent;
3055 struct device *parent_dev;
3056 struct sas_rphy *rphy;
3057 int i;
3058 u64 sas_address;
3059 u32 handle;
3060
3061 handle = port_info->phy_info[0].handle;
3062 sas_address = port_info->phy_info[0].identify.sas_address;
3063 for (i = 0; i < port_info->num_phys; i++) {
3064 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3065 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3066 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3067
3068 mptsas_sas_device_pg0(ioc,
3069 &port_info->phy_info[i].identify,
3070 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3071 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3072 port_info->phy_info[i].identify.handle);
3073 port_info->phy_info[i].identify.phy_id =
3074 port_info->phy_info[i].phy_id;
3075
3076 if (port_info->phy_info[i].attached.handle) {
3077 mptsas_sas_device_pg0(ioc,
3078 &port_info->phy_info[i].attached,
3079 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3080 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3081 port_info->phy_info[i].attached.handle);
3082 port_info->phy_info[i].attached.phy_id =
3083 port_info->phy_info[i].phy_id;
3084 }
3085 }
3086
3087 mutex_lock(&ioc->sas_topology_mutex);
3088 parent = mptsas_find_portinfo_by_handle(ioc,
3089 port_info->phy_info[0].identify.handle_parent);
3090 if (!parent) {
3091 mutex_unlock(&ioc->sas_topology_mutex);
3092 return;
3093 }
3094 for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3095 i++) {
3096 if (parent->phy_info[i].attached.sas_address == sas_address) {
3097 rphy = mptsas_get_rphy(&parent->phy_info[i]);
3098 parent_dev = &rphy->dev;
3099 }
3100 }
3101 mutex_unlock(&ioc->sas_topology_mutex);
3102
3103 mptsas_setup_wide_ports(ioc, port_info);
3104 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3105 mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3106 ioc->sas_index, 0);
3107}
3108
3109static void
3110mptsas_expander_event_add(MPT_ADAPTER *ioc,
3111 MpiEventDataSasExpanderStatusChange_t *expander_data)
3112{
3113 struct mptsas_portinfo *port_info;
3114 int i;
3115 __le64 sas_address;
3116
3117 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3118 if (!port_info)
3119 BUG();
3120 port_info->num_phys = (expander_data->NumPhys) ?
3121 expander_data->NumPhys : 1;
3122 port_info->phy_info = kcalloc(port_info->num_phys,
3123 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3124 if (!port_info->phy_info)
3125 BUG();
3126 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3127 for (i = 0; i < port_info->num_phys; i++) {
3128 port_info->phy_info[i].portinfo = port_info;
3129 port_info->phy_info[i].handle =
3130 le16_to_cpu(expander_data->DevHandle);
3131 port_info->phy_info[i].identify.sas_address =
3132 le64_to_cpu(sas_address);
3133 port_info->phy_info[i].identify.handle_parent =
3134 le16_to_cpu(expander_data->ParentDevHandle);
3135 }
3136
3137 mutex_lock(&ioc->sas_topology_mutex);
3138 list_add_tail(&port_info->list, &ioc->sas_topology);
3139 mutex_unlock(&ioc->sas_topology_mutex);
3140
3141 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3142 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3143 (unsigned long long)sas_address);
3144
3145 mptsas_expander_refresh(ioc, port_info);
3146}
3147
3148
3149
3150
3151
3152
3153
3154static void
3155mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3156 *parent, struct mptsas_portinfo *expander)
3157{
3158 struct mptsas_phyinfo *phy_info;
3159 struct mptsas_portinfo *port_info;
3160 struct sas_rphy *rphy;
3161 int i;
3162
3163 phy_info = expander->phy_info;
3164 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3165 rphy = mptsas_get_rphy(phy_info);
3166 if (!rphy)
3167 continue;
3168 if (rphy->identify.device_type == SAS_END_DEVICE)
3169 mptsas_del_end_device(ioc, phy_info);
3170 }
3171
3172 phy_info = expander->phy_info;
3173 for (i = 0; i < expander->num_phys; i++, phy_info++) {
3174 rphy = mptsas_get_rphy(phy_info);
3175 if (!rphy)
3176 continue;
3177 if (rphy->identify.device_type ==
3178 MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3179 rphy->identify.device_type ==
3180 MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3181 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3182 rphy->identify.sas_address);
3183 if (!port_info)
3184 continue;
3185 if (port_info == parent)
3186 continue;
3187
3188
3189
3190
3191 mptsas_expander_delete(ioc, port_info, 1);
3192 }
3193 }
3194}
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3206 struct mptsas_portinfo *port_info, u8 force)
3207{
3208
3209 struct mptsas_portinfo *parent;
3210 int i;
3211 u64 expander_sas_address;
3212 struct mptsas_phyinfo *phy_info;
3213 struct mptsas_portinfo buffer;
3214 struct mptsas_portinfo_details *port_details;
3215 struct sas_port *port;
3216
3217 if (!port_info)
3218 return;
3219
3220
3221 mptsas_sas_expander_pg0(ioc, &buffer,
3222 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3223 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3224 port_info->phy_info[0].identify.handle);
3225
3226 if (buffer.num_phys) {
3227 kfree(buffer.phy_info);
3228 if (!force)
3229 return;
3230 }
3231
3232
3233
3234
3235
3236 port_details = NULL;
3237 expander_sas_address =
3238 port_info->phy_info[0].identify.sas_address;
3239 parent = mptsas_find_portinfo_by_handle(ioc,
3240 port_info->phy_info[0].identify.handle_parent);
3241 mptsas_delete_expander_siblings(ioc, parent, port_info);
3242 if (!parent)
3243 goto out;
3244
3245
3246
3247
3248
3249 phy_info = parent->phy_info;
3250 port = NULL;
3251 for (i = 0; i < parent->num_phys; i++, phy_info++) {
3252 if (!phy_info->phy)
3253 continue;
3254 if (phy_info->attached.sas_address !=
3255 expander_sas_address)
3256 continue;
3257 if (!port) {
3258 port = mptsas_get_port(phy_info);
3259 port_details = phy_info->port_details;
3260 }
3261 dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3262 MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3263 phy_info->phy_id, phy_info->phy);
3264 sas_port_delete_phy(port, phy_info->phy);
3265 }
3266 if (port) {
3267 dev_printk(KERN_DEBUG, &port->dev,
3268 MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3269 ioc->name, port->port_identifier,
3270 (unsigned long long)expander_sas_address);
3271 sas_port_delete(port);
3272 mptsas_port_delete(ioc, port_details);
3273 }
3274 out:
3275
3276 printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3277 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3278 (unsigned long long)expander_sas_address);
3279
3280
3281
3282
3283 list_del(&port_info->list);
3284 kfree(port_info->phy_info);
3285 kfree(port_info);
3286}
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298static void
3299mptsas_send_expander_event(struct fw_event_work *fw_event)
3300{
3301 MPT_ADAPTER *ioc;
3302 MpiEventDataSasExpanderStatusChange_t *expander_data;
3303 struct mptsas_portinfo *port_info;
3304 __le64 sas_address;
3305 int i;
3306
3307 ioc = fw_event->ioc;
3308 expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3309 fw_event->event_data;
3310 memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3311 sas_address = le64_to_cpu(sas_address);
3312 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3313
3314 if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3315 if (port_info) {
3316 for (i = 0; i < port_info->num_phys; i++) {
3317 port_info->phy_info[i].portinfo = port_info;
3318 port_info->phy_info[i].handle =
3319 le16_to_cpu(expander_data->DevHandle);
3320 port_info->phy_info[i].identify.sas_address =
3321 le64_to_cpu(sas_address);
3322 port_info->phy_info[i].identify.handle_parent =
3323 le16_to_cpu(expander_data->ParentDevHandle);
3324 }
3325 mptsas_expander_refresh(ioc, port_info);
3326 } else if (!port_info && expander_data->NumPhys)
3327 mptsas_expander_event_add(ioc, expander_data);
3328 } else if (expander_data->ReasonCode ==
3329 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3330 mptsas_expander_delete(ioc, port_info, 0);
3331
3332 mptsas_free_fw_event(ioc, fw_event);
3333}
3334
3335
3336
3337
3338
3339
3340
3341
3342struct mptsas_portinfo *
3343mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3344{
3345 struct mptsas_portinfo buffer, *port_info;
3346 int i;
3347
3348 if ((mptsas_sas_expander_pg0(ioc, &buffer,
3349 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3350 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3351 return NULL;
3352
3353 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3354 if (!port_info) {
3355 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3356 "%s: exit at line=%d\n", ioc->name,
3357 __func__, __LINE__));
3358 return NULL;
3359 }
3360 port_info->num_phys = buffer.num_phys;
3361 port_info->phy_info = buffer.phy_info;
3362 for (i = 0; i < port_info->num_phys; i++)
3363 port_info->phy_info[i].portinfo = port_info;
3364 mutex_lock(&ioc->sas_topology_mutex);
3365 list_add_tail(&port_info->list, &ioc->sas_topology);
3366 mutex_unlock(&ioc->sas_topology_mutex);
3367 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3368 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3369 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3370 mptsas_expander_refresh(ioc, port_info);
3371 return port_info;
3372}
3373
3374static void
3375mptsas_send_link_status_event(struct fw_event_work *fw_event)
3376{
3377 MPT_ADAPTER *ioc;
3378 MpiEventDataSasPhyLinkStatus_t *link_data;
3379 struct mptsas_portinfo *port_info;
3380 struct mptsas_phyinfo *phy_info = NULL;
3381 __le64 sas_address;
3382 u8 phy_num;
3383 u8 link_rate;
3384
3385 ioc = fw_event->ioc;
3386 link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3387
3388 memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3389 sas_address = le64_to_cpu(sas_address);
3390 link_rate = link_data->LinkRates >> 4;
3391 phy_num = link_data->PhyNum;
3392
3393 port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3394 if (port_info) {
3395 phy_info = &port_info->phy_info[phy_num];
3396 if (phy_info)
3397 phy_info->negotiated_link_rate = link_rate;
3398 }
3399
3400 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3401 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3402
3403 if (!port_info) {
3404 if (ioc->old_sas_discovery_protocal) {
3405 port_info = mptsas_expander_add(ioc,
3406 le16_to_cpu(link_data->DevHandle));
3407 if (port_info)
3408 goto out;
3409 }
3410 goto out;
3411 }
3412
3413 if (port_info == ioc->hba_port_info)
3414 mptsas_probe_hba_phys(ioc);
3415 else
3416 mptsas_expander_refresh(ioc, port_info);
3417 } else if (phy_info && phy_info->phy) {
3418 if (link_rate == MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3419 phy_info->phy->negotiated_linkrate =
3420 SAS_PHY_DISABLED;
3421 else if (link_rate ==
3422 MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3423 phy_info->phy->negotiated_linkrate =
3424 SAS_LINK_RATE_FAILED;
3425 else
3426 phy_info->phy->negotiated_linkrate =
3427 SAS_LINK_RATE_UNKNOWN;
3428 }
3429 out:
3430 mptsas_free_fw_event(ioc, fw_event);
3431}
3432
3433static void
3434mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3435{
3436 struct mptsas_portinfo buffer, *port_info;
3437 struct mptsas_device_info *sas_info;
3438 struct mptsas_devinfo sas_device;
3439 u32 handle;
3440 VirtTarget *vtarget = NULL;
3441 struct mptsas_phyinfo *phy_info;
3442 u8 found_expander;
3443 int retval, retry_count;
3444 unsigned long flags;
3445
3446 mpt_findImVolumes(ioc);
3447
3448 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3449 if (ioc->ioc_reset_in_progress) {
3450 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3451 "%s: exiting due to a parallel reset \n", ioc->name,
3452 __func__));
3453 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3454 return;
3455 }
3456 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3457
3458
3459 mutex_lock(&ioc->sas_device_info_mutex);
3460 redo_device_scan:
3461 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3462 if (sas_info->is_cached)
3463 continue;
3464 if (!sas_info->is_logical_volume) {
3465 sas_device.handle = 0;
3466 retry_count = 0;
3467retry_page:
3468 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3469 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3470 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3471 (sas_info->fw.channel << 8) +
3472 sas_info->fw.id);
3473
3474 if (sas_device.handle)
3475 continue;
3476 if (retval == -EBUSY) {
3477 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3478 if (ioc->ioc_reset_in_progress) {
3479 dfailprintk(ioc,
3480 printk(MYIOC_s_DEBUG_FMT
3481 "%s: exiting due to reset\n",
3482 ioc->name, __func__));
3483 spin_unlock_irqrestore
3484 (&ioc->taskmgmt_lock, flags);
3485 mutex_unlock(&ioc->
3486 sas_device_info_mutex);
3487 return;
3488 }
3489 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3490 flags);
3491 }
3492
3493 if (retval && (retval != -ENODEV)) {
3494 if (retry_count < 10) {
3495 retry_count++;
3496 goto retry_page;
3497 } else {
3498 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3499 "%s: Config page retry exceeded retry "
3500 "count deleting device 0x%llx\n",
3501 ioc->name, __func__,
3502 sas_info->sas_address));
3503 }
3504 }
3505
3506
3507 vtarget = mptsas_find_vtarget(ioc,
3508 sas_info->fw.channel, sas_info->fw.id);
3509
3510 if (vtarget)
3511 vtarget->deleted = 1;
3512
3513 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3514 sas_info->sas_address);
3515
3516 if (phy_info) {
3517 mptsas_del_end_device(ioc, phy_info);
3518 goto redo_device_scan;
3519 }
3520 } else
3521 mptsas_volume_delete(ioc, sas_info->fw.id);
3522 }
3523 mutex_unlock(&ioc->sas_device_info_mutex);
3524
3525
3526 mutex_lock(&ioc->sas_topology_mutex);
3527 redo_expander_scan:
3528 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3529
3530 if (port_info->phy_info &&
3531 (!(port_info->phy_info[0].identify.device_info &
3532 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3533 continue;
3534 found_expander = 0;
3535 handle = 0xFFFF;
3536 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3537 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3538 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3539 !found_expander) {
3540
3541 handle = buffer.phy_info[0].handle;
3542 if (buffer.phy_info[0].identify.sas_address ==
3543 port_info->phy_info[0].identify.sas_address) {
3544 found_expander = 1;
3545 }
3546 kfree(buffer.phy_info);
3547 }
3548
3549 if (!found_expander) {
3550 mptsas_expander_delete(ioc, port_info, 0);
3551 goto redo_expander_scan;
3552 }
3553 }
3554 mutex_unlock(&ioc->sas_topology_mutex);
3555}
3556
3557
3558
3559
3560
3561
3562static void
3563mptsas_probe_expanders(MPT_ADAPTER *ioc)
3564{
3565 struct mptsas_portinfo buffer, *port_info;
3566 u32 handle;
3567 int i;
3568
3569 handle = 0xFFFF;
3570 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3571 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3572 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3573
3574 handle = buffer.phy_info[0].handle;
3575 port_info = mptsas_find_portinfo_by_sas_address(ioc,
3576 buffer.phy_info[0].identify.sas_address);
3577
3578 if (port_info) {
3579
3580 for (i = 0; i < buffer.num_phys; i++) {
3581 port_info->phy_info[i].handle = handle;
3582 port_info->phy_info[i].identify.handle_parent =
3583 buffer.phy_info[0].identify.handle_parent;
3584 }
3585 mptsas_expander_refresh(ioc, port_info);
3586 kfree(buffer.phy_info);
3587 continue;
3588 }
3589
3590 port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3591 if (!port_info) {
3592 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3593 "%s: exit at line=%d\n", ioc->name,
3594 __func__, __LINE__));
3595 return;
3596 }
3597 port_info->num_phys = buffer.num_phys;
3598 port_info->phy_info = buffer.phy_info;
3599 for (i = 0; i < port_info->num_phys; i++)
3600 port_info->phy_info[i].portinfo = port_info;
3601 mutex_lock(&ioc->sas_topology_mutex);
3602 list_add_tail(&port_info->list, &ioc->sas_topology);
3603 mutex_unlock(&ioc->sas_topology_mutex);
3604 printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3605 "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3606 (unsigned long long)buffer.phy_info[0].identify.sas_address);
3607 mptsas_expander_refresh(ioc, port_info);
3608 }
3609}
3610
3611static void
3612mptsas_probe_devices(MPT_ADAPTER *ioc)
3613{
3614 u16 handle;
3615 struct mptsas_devinfo sas_device;
3616 struct mptsas_phyinfo *phy_info;
3617
3618 handle = 0xFFFF;
3619 while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3620 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3621
3622 handle = sas_device.handle;
3623
3624 if ((sas_device.device_info &
3625 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3626 MPI_SAS_DEVICE_INFO_STP_TARGET |
3627 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3628 continue;
3629
3630 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3631 if (!phy_info)
3632 continue;
3633
3634 if (mptsas_get_rphy(phy_info))
3635 continue;
3636
3637 mptsas_add_end_device(ioc, phy_info);
3638 }
3639}
3640
3641
3642
3643
3644
3645
3646
3647static void
3648mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3649{
3650 struct scsi_device *sdev;
3651 int i;
3652
3653 mptsas_probe_hba_phys(ioc);
3654 mptsas_probe_expanders(ioc);
3655 mptsas_probe_devices(ioc);
3656
3657
3658
3659
3660 if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3661 !ioc->raid_data.pIocPg2->NumActiveVolumes)
3662 return;
3663 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3664 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3665 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3666 if (sdev) {
3667 scsi_device_put(sdev);
3668 continue;
3669 }
3670 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
3671 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
3672 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
3673 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
3674 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3675 }
3676}
3677
3678
3679static void
3680mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
3681{
3682 MPT_ADAPTER *ioc;
3683 EventDataQueueFull_t *qfull_data;
3684 struct mptsas_device_info *sas_info;
3685 struct scsi_device *sdev;
3686 int depth;
3687 int id = -1;
3688 int channel = -1;
3689 int fw_id, fw_channel;
3690 u16 current_depth;
3691
3692
3693 ioc = fw_event->ioc;
3694 qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
3695 fw_id = qfull_data->TargetID;
3696 fw_channel = qfull_data->Bus;
3697 current_depth = le16_to_cpu(qfull_data->CurrentDepth);
3698
3699
3700 mutex_lock(&ioc->sas_device_info_mutex);
3701 if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
3702 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3703 list) {
3704 if (sas_info->is_cached ||
3705 sas_info->is_logical_volume)
3706 continue;
3707 if (sas_info->is_hidden_raid_component &&
3708 (sas_info->fw.channel == fw_channel &&
3709 sas_info->fw.id == fw_id)) {
3710 id = sas_info->volume_id;
3711 channel = MPTSAS_RAID_CHANNEL;
3712 goto out;
3713 }
3714 }
3715 } else {
3716 list_for_each_entry(sas_info, &ioc->sas_device_info_list,
3717 list) {
3718 if (sas_info->is_cached ||
3719 sas_info->is_hidden_raid_component ||
3720 sas_info->is_logical_volume)
3721 continue;
3722 if (sas_info->fw.channel == fw_channel &&
3723 sas_info->fw.id == fw_id) {
3724 id = sas_info->os.id;
3725 channel = sas_info->os.channel;
3726 goto out;
3727 }
3728 }
3729
3730 }
3731
3732 out:
3733 mutex_unlock(&ioc->sas_device_info_mutex);
3734
3735 if (id != -1) {
3736 shost_for_each_device(sdev, ioc->sh) {
3737 if (sdev->id == id && sdev->channel == channel) {
3738 if (current_depth > sdev->queue_depth) {
3739 sdev_printk(KERN_INFO, sdev,
3740 "strange observation, the queue "
3741 "depth is (%d) meanwhile fw queue "
3742 "depth (%d)\n", sdev->queue_depth,
3743 current_depth);
3744 continue;
3745 }
3746 depth = scsi_track_queue_full(sdev,
3747 current_depth - 1);
3748 if (depth > 0)
3749 sdev_printk(KERN_INFO, sdev,
3750 "Queue depth reduced to (%d)\n",
3751 depth);
3752 else if (depth < 0)
3753 sdev_printk(KERN_INFO, sdev,
3754 "Tagged Command Queueing is being "
3755 "disabled\n");
3756 else if (depth == 0)
3757 sdev_printk(KERN_INFO, sdev,
3758 "Queue depth not changed yet\n");
3759 }
3760 }
3761 }
3762
3763 mptsas_free_fw_event(ioc, fw_event);
3764}
3765
3766
3767static struct mptsas_phyinfo *
3768mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
3769{
3770 struct mptsas_portinfo *port_info;
3771 struct mptsas_phyinfo *phy_info = NULL;
3772 int i;
3773
3774 mutex_lock(&ioc->sas_topology_mutex);
3775 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3776 for (i = 0; i < port_info->num_phys; i++) {
3777 if (!mptsas_is_end_device(
3778 &port_info->phy_info[i].attached))
3779 continue;
3780 if (port_info->phy_info[i].attached.sas_address
3781 != sas_address)
3782 continue;
3783 phy_info = &port_info->phy_info[i];
3784 break;
3785 }
3786 }
3787 mutex_unlock(&ioc->sas_topology_mutex);
3788 return phy_info;
3789}
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799static struct mptsas_phyinfo *
3800mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
3801 u8 channel, u8 id)
3802{
3803 struct mptsas_phyinfo *phy_info = NULL;
3804 struct mptsas_portinfo *port_info;
3805 RaidPhysDiskPage1_t *phys_disk = NULL;
3806 int num_paths;
3807 u64 sas_address = 0;
3808 int i;
3809
3810 phy_info = NULL;
3811 if (!ioc->raid_data.pIocPg3)
3812 return NULL;
3813
3814 num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
3815 if (!num_paths)
3816 goto out;
3817 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
3818 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
3819 if (!phys_disk)
3820 goto out;
3821 mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
3822 for (i = 0; i < num_paths; i++) {
3823 if ((phys_disk->Path[i].Flags & 1) != 0)
3824
3825 continue;
3826 if ((id == phys_disk->Path[i].PhysDiskID) &&
3827 (channel == phys_disk->Path[i].PhysDiskBus)) {
3828 memcpy(&sas_address, &phys_disk->Path[i].WWID,
3829 sizeof(u64));
3830 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3831 sas_address);
3832 goto out;
3833 }
3834 }
3835
3836 out:
3837 kfree(phys_disk);
3838 if (phy_info)
3839 return phy_info;
3840
3841
3842
3843
3844
3845 mutex_lock(&ioc->sas_topology_mutex);
3846 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3847 for (i = 0; i < port_info->num_phys && !phy_info; i++) {
3848 if (!mptsas_is_end_device(
3849 &port_info->phy_info[i].attached))
3850 continue;
3851 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
3852 continue;
3853 if ((port_info->phy_info[i].attached.phys_disk_num ==
3854 phys_disk_num) &&
3855 (port_info->phy_info[i].attached.id == id) &&
3856 (port_info->phy_info[i].attached.channel ==
3857 channel))
3858 phy_info = &port_info->phy_info[i];
3859 }
3860 }
3861 mutex_unlock(&ioc->sas_topology_mutex);
3862 return phy_info;
3863}
3864
3865static void
3866mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
3867{
3868 int rc;
3869
3870 sdev->no_uld_attach = data ? 1 : 0;
3871 rc = scsi_device_reprobe(sdev);
3872}
3873
3874static void
3875mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
3876{
3877 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
3878 mptsas_reprobe_lun);
3879}
3880
3881static void
3882mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
3883{
3884 CONFIGPARMS cfg;
3885 ConfigPageHeader_t hdr;
3886 dma_addr_t dma_handle;
3887 pRaidVolumePage0_t buffer = NULL;
3888 RaidPhysDiskPage0_t phys_disk;
3889 int i;
3890 struct mptsas_phyinfo *phy_info;
3891 struct mptsas_devinfo sas_device;
3892
3893 memset(&cfg, 0 , sizeof(CONFIGPARMS));
3894 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
3895 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
3896 cfg.pageAddr = (channel << 8) + id;
3897 cfg.cfghdr.hdr = &hdr;
3898 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3899
3900 if (mpt_config(ioc, &cfg) != 0)
3901 goto out;
3902
3903 if (!hdr.PageLength)
3904 goto out;
3905
3906 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
3907 &dma_handle);
3908
3909 if (!buffer)
3910 goto out;
3911
3912 cfg.physAddr = dma_handle;
3913 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3914
3915 if (mpt_config(ioc, &cfg) != 0)
3916 goto out;
3917
3918 if (!(buffer->VolumeStatus.Flags &
3919 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
3920 goto out;
3921
3922 if (!buffer->NumPhysDisks)
3923 goto out;
3924
3925 for (i = 0; i < buffer->NumPhysDisks; i++) {
3926
3927 if (mpt_raid_phys_disk_pg0(ioc,
3928 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
3929 continue;
3930
3931 if (mptsas_sas_device_pg0(ioc, &sas_device,
3932 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3933 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3934 (phys_disk.PhysDiskBus << 8) +
3935 phys_disk.PhysDiskID))
3936 continue;
3937
3938 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3939 sas_device.sas_address);
3940 mptsas_add_end_device(ioc, phy_info);
3941 }
3942
3943 out:
3944 if (buffer)
3945 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
3946 dma_handle);
3947}
3948
3949
3950
3951static void
3952mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
3953 struct mptsas_hotplug_event *hot_plug_info)
3954{
3955 struct mptsas_phyinfo *phy_info;
3956 struct scsi_target * starget;
3957 struct mptsas_devinfo sas_device;
3958 VirtTarget *vtarget;
3959 int i;
3960
3961 switch (hot_plug_info->event_type) {
3962
3963 case MPTSAS_ADD_PHYSDISK:
3964
3965 if (!ioc->raid_data.pIocPg2)
3966 break;
3967
3968 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3969 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
3970 hot_plug_info->id) {
3971 printk(MYIOC_s_WARN_FMT "firmware bug: unable "
3972 "to add hidden disk - target_id matchs "
3973 "volume_id\n", ioc->name);
3974 mptsas_free_fw_event(ioc, fw_event);
3975 return;
3976 }
3977 }
3978 mpt_findImVolumes(ioc);
3979
3980 case MPTSAS_ADD_DEVICE:
3981 memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
3982 mptsas_sas_device_pg0(ioc, &sas_device,
3983 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
3984 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3985 (hot_plug_info->channel << 8) +
3986 hot_plug_info->id);
3987
3988 if (!sas_device.handle)
3989 return;
3990
3991 phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3992 if (!phy_info)
3993 break;
3994
3995 if (mptsas_get_rphy(phy_info))
3996 break;
3997
3998 mptsas_add_end_device(ioc, phy_info);
3999 break;
4000
4001 case MPTSAS_DEL_DEVICE:
4002 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4003 hot_plug_info->sas_address);
4004 mptsas_del_end_device(ioc, phy_info);
4005 break;
4006
4007 case MPTSAS_DEL_PHYSDISK:
4008
4009 mpt_findImVolumes(ioc);
4010
4011 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4012 ioc, hot_plug_info->phys_disk_num,
4013 hot_plug_info->channel,
4014 hot_plug_info->id);
4015 mptsas_del_end_device(ioc, phy_info);
4016 break;
4017
4018 case MPTSAS_ADD_PHYSDISK_REPROBE:
4019
4020 if (mptsas_sas_device_pg0(ioc, &sas_device,
4021 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4022 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4023 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4024 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4025 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4026 __func__, hot_plug_info->id, __LINE__));
4027 break;
4028 }
4029
4030 phy_info = mptsas_find_phyinfo_by_sas_address(
4031 ioc, sas_device.sas_address);
4032
4033 if (!phy_info) {
4034 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4035 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4036 __func__, hot_plug_info->id, __LINE__));
4037 break;
4038 }
4039
4040 starget = mptsas_get_starget(phy_info);
4041 if (!starget) {
4042 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4043 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4044 __func__, hot_plug_info->id, __LINE__));
4045 break;
4046 }
4047
4048 vtarget = starget->hostdata;
4049 if (!vtarget) {
4050 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4051 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4052 __func__, hot_plug_info->id, __LINE__));
4053 break;
4054 }
4055
4056 mpt_findImVolumes(ioc);
4057
4058 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4059 "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4060 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4061 hot_plug_info->phys_disk_num, (unsigned long long)
4062 sas_device.sas_address);
4063
4064 vtarget->id = hot_plug_info->phys_disk_num;
4065 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4066 phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4067 mptsas_reprobe_target(starget, 1);
4068 break;
4069
4070 case MPTSAS_DEL_PHYSDISK_REPROBE:
4071
4072 if (mptsas_sas_device_pg0(ioc, &sas_device,
4073 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4074 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4075 (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4076 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4077 "%s: fw_id=%d exit at line=%d\n",
4078 ioc->name, __func__,
4079 hot_plug_info->id, __LINE__));
4080 break;
4081 }
4082
4083 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4084 sas_device.sas_address);
4085 if (!phy_info) {
4086 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4087 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4088 __func__, hot_plug_info->id, __LINE__));
4089 break;
4090 }
4091
4092 starget = mptsas_get_starget(phy_info);
4093 if (!starget) {
4094 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4095 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4096 __func__, hot_plug_info->id, __LINE__));
4097 break;
4098 }
4099
4100 vtarget = starget->hostdata;
4101 if (!vtarget) {
4102 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4103 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4104 __func__, hot_plug_info->id, __LINE__));
4105 break;
4106 }
4107
4108 if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4109 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4110 "%s: fw_id=%d exit at line=%d\n", ioc->name,
4111 __func__, hot_plug_info->id, __LINE__));
4112 break;
4113 }
4114
4115 mpt_findImVolumes(ioc);
4116
4117 starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4118 " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4119 ioc->name, hot_plug_info->channel, hot_plug_info->id,
4120 hot_plug_info->phys_disk_num, (unsigned long long)
4121 sas_device.sas_address);
4122
4123 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4124 vtarget->id = hot_plug_info->id;
4125 phy_info->attached.phys_disk_num = ~0;
4126 mptsas_reprobe_target(starget, 0);
4127 mptsas_add_device_component_by_fw(ioc,
4128 hot_plug_info->channel, hot_plug_info->id);
4129 break;
4130
4131 case MPTSAS_ADD_RAID:
4132
4133 mpt_findImVolumes(ioc);
4134 printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4135 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4136 hot_plug_info->id);
4137 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4138 hot_plug_info->id, 0);
4139 break;
4140
4141 case MPTSAS_DEL_RAID:
4142
4143 mpt_findImVolumes(ioc);
4144 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4145 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4146 hot_plug_info->id);
4147 scsi_remove_device(hot_plug_info->sdev);
4148 scsi_device_put(hot_plug_info->sdev);
4149 break;
4150
4151 case MPTSAS_ADD_INACTIVE_VOLUME:
4152
4153 mpt_findImVolumes(ioc);
4154 mptsas_adding_inactive_raid_components(ioc,
4155 hot_plug_info->channel, hot_plug_info->id);
4156 break;
4157
4158 default:
4159 break;
4160 }
4161
4162 mptsas_free_fw_event(ioc, fw_event);
4163}
4164
4165static void
4166mptsas_send_sas_event(struct fw_event_work *fw_event)
4167{
4168 MPT_ADAPTER *ioc;
4169 struct mptsas_hotplug_event hot_plug_info;
4170 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4171 u32 device_info;
4172 u64 sas_address;
4173
4174 ioc = fw_event->ioc;
4175 sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4176 fw_event->event_data;
4177 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4178
4179 if ((device_info &
4180 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
4181 MPI_SAS_DEVICE_INFO_STP_TARGET |
4182 MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4183 mptsas_free_fw_event(ioc, fw_event);
4184 return;
4185 }
4186
4187 if (sas_event_data->ReasonCode ==
4188 MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4189 mptbase_sas_persist_operation(ioc,
4190 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4191 mptsas_free_fw_event(ioc, fw_event);
4192 return;
4193 }
4194
4195 switch (sas_event_data->ReasonCode) {
4196 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4197 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4198 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4199 hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4200 hot_plug_info.channel = sas_event_data->Bus;
4201 hot_plug_info.id = sas_event_data->TargetID;
4202 hot_plug_info.phy_id = sas_event_data->PhyNum;
4203 memcpy(&sas_address, &sas_event_data->SASAddress,
4204 sizeof(u64));
4205 hot_plug_info.sas_address = le64_to_cpu(sas_address);
4206 hot_plug_info.device_info = device_info;
4207 if (sas_event_data->ReasonCode &
4208 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4209 hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4210 else
4211 hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4212 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4213 break;
4214
4215 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4216 mptbase_sas_persist_operation(ioc,
4217 MPI_SAS_OP_CLEAR_NOT_PRESENT);
4218 mptsas_free_fw_event(ioc, fw_event);
4219 break;
4220
4221 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4222
4223 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4224
4225 default:
4226 mptsas_free_fw_event(ioc, fw_event);
4227 break;
4228 }
4229}
4230
4231static void
4232mptsas_send_raid_event(struct fw_event_work *fw_event)
4233{
4234 MPT_ADAPTER *ioc;
4235 EVENT_DATA_RAID *raid_event_data;
4236 struct mptsas_hotplug_event hot_plug_info;
4237 int status;
4238 int state;
4239 struct scsi_device *sdev = NULL;
4240 VirtDevice *vdevice = NULL;
4241 RaidPhysDiskPage0_t phys_disk;
4242
4243 ioc = fw_event->ioc;
4244 raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4245 status = le32_to_cpu(raid_event_data->SettingsStatus);
4246 state = (status >> 8) & 0xff;
4247
4248 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4249 hot_plug_info.id = raid_event_data->VolumeID;
4250 hot_plug_info.channel = raid_event_data->VolumeBus;
4251 hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4252
4253 if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4254 raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4255 raid_event_data->ReasonCode ==
4256 MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4257 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4258 hot_plug_info.id, 0);
4259 hot_plug_info.sdev = sdev;
4260 if (sdev)
4261 vdevice = sdev->hostdata;
4262 }
4263
4264 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4265 "ReasonCode=%02x\n", ioc->name, __func__,
4266 raid_event_data->ReasonCode));
4267
4268 switch (raid_event_data->ReasonCode) {
4269 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4270 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4271 break;
4272 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4273 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4274 break;
4275 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4276 switch (state) {
4277 case MPI_PD_STATE_ONLINE:
4278 case MPI_PD_STATE_NOT_COMPATIBLE:
4279 mpt_raid_phys_disk_pg0(ioc,
4280 raid_event_data->PhysDiskNum, &phys_disk);
4281 hot_plug_info.id = phys_disk.PhysDiskID;
4282 hot_plug_info.channel = phys_disk.PhysDiskBus;
4283 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4284 break;
4285 case MPI_PD_STATE_FAILED:
4286 case MPI_PD_STATE_MISSING:
4287 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4288 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4289 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4290 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4291 break;
4292 default:
4293 break;
4294 }
4295 break;
4296 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4297 if (!sdev)
4298 break;
4299 vdevice->vtarget->deleted = 1;
4300 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4301 break;
4302 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4303 if (sdev) {
4304 scsi_device_put(sdev);
4305 break;
4306 }
4307 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4308 break;
4309 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4310 if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4311 if (!sdev)
4312 break;
4313 vdevice->vtarget->deleted = 1;
4314 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4315 break;
4316 }
4317 switch (state) {
4318 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4319 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4320 if (!sdev)
4321 break;
4322 vdevice->vtarget->deleted = 1;
4323 hot_plug_info.event_type = MPTSAS_DEL_RAID;
4324 break;
4325 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4326 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4327 if (sdev) {
4328 scsi_device_put(sdev);
4329 break;
4330 }
4331 hot_plug_info.event_type = MPTSAS_ADD_RAID;
4332 break;
4333 default:
4334 break;
4335 }
4336 break;
4337 default:
4338 break;
4339 }
4340
4341 if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4342 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4343 else
4344 mptsas_free_fw_event(ioc, fw_event);
4345}
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360static int
4361mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4362 int task_context, ulong timeout, u8 *issue_reset)
4363{
4364 MPT_FRAME_HDR *mf;
4365 SCSITaskMgmt_t *pScsiTm;
4366 int retval;
4367 unsigned long timeleft;
4368
4369 *issue_reset = 0;
4370 mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4371 if (mf == NULL) {
4372 retval = -1;
4373 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4374 "msg frames!!\n", ioc->name));
4375 goto out;
4376 }
4377
4378 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4379 "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4380 "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4381 type, timeout, channel, id, (unsigned long long)lun,
4382 task_context));
4383
4384 pScsiTm = (SCSITaskMgmt_t *) mf;
4385 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4386 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4387 pScsiTm->TaskType = type;
4388 pScsiTm->MsgFlags = 0;
4389 pScsiTm->TargetID = id;
4390 pScsiTm->Bus = channel;
4391 pScsiTm->ChainOffset = 0;
4392 pScsiTm->Reserved = 0;
4393 pScsiTm->Reserved1 = 0;
4394 pScsiTm->TaskMsgContext = task_context;
4395 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4396
4397 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4398 CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4399 retval = 0;
4400 mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4401
4402
4403 timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4404 timeout*HZ);
4405 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4406 retval = -1;
4407 dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4408 "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4409 mpt_free_msg_frame(ioc, mf);
4410 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4411 goto out;
4412 *issue_reset = 1;
4413 goto out;
4414 }
4415
4416 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4417 retval = -1;
4418 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4419 "TaskMgmt request: failed with no reply\n", ioc->name));
4420 goto out;
4421 }
4422
4423 out:
4424 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4425 return retval;
4426}
4427
4428
4429
4430
4431
4432
4433
4434static void
4435mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4436{
4437 MPT_ADAPTER *ioc = fw_event->ioc;
4438 MPT_FRAME_HDR *mf;
4439 VirtDevice *vdevice;
4440 int ii;
4441 struct scsi_cmnd *sc;
4442 SCSITaskMgmtReply_t *pScsiTmReply;
4443 u8 issue_reset;
4444 int task_context;
4445 u8 channel, id;
4446 int lun;
4447 u32 termination_count;
4448 u32 query_count;
4449
4450 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4451 "%s - enter\n", ioc->name, __func__));
4452
4453 mutex_lock(&ioc->taskmgmt_cmds.mutex);
4454 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4455 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4456 mptsas_requeue_fw_event(ioc, fw_event, 1000);
4457 return;
4458 }
4459
4460 issue_reset = 0;
4461 termination_count = 0;
4462 query_count = 0;
4463 mpt_findImVolumes(ioc);
4464 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4465
4466 for (ii = 0; ii < ioc->req_depth; ii++) {
4467 if (ioc->fw_events_off)
4468 goto out;
4469 sc = mptscsih_get_scsi_lookup(ioc, ii);
4470 if (!sc)
4471 continue;
4472 mf = MPT_INDEX_2_MFPTR(ioc, ii);
4473 if (!mf)
4474 continue;
4475 task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4476 vdevice = sc->device->hostdata;
4477 if (!vdevice || !vdevice->vtarget)
4478 continue;
4479 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4480 continue;
4481 if (vdevice->vtarget->raidVolume)
4482 continue;
4483 channel = vdevice->vtarget->channel;
4484 id = vdevice->vtarget->id;
4485 lun = vdevice->lun;
4486 if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4487 channel, id, (u64)lun, task_context, 30, &issue_reset))
4488 goto out;
4489 query_count++;
4490 termination_count +=
4491 le32_to_cpu(pScsiTmReply->TerminationCount);
4492 if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4493 (pScsiTmReply->ResponseCode ==
4494 MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4495 pScsiTmReply->ResponseCode ==
4496 MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4497 continue;
4498 if (mptsas_issue_tm(ioc,
4499 MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4500 channel, id, (u64)lun, 0, 30, &issue_reset))
4501 goto out;
4502 termination_count +=
4503 le32_to_cpu(pScsiTmReply->TerminationCount);
4504 }
4505
4506 out:
4507 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4508 "%s - exit, query_count = %d termination_count = %d\n",
4509 ioc->name, __func__, query_count, termination_count));
4510
4511 ioc->broadcast_aen_busy = 0;
4512 mpt_clear_taskmgmt_in_progress_flag(ioc);
4513 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4514
4515 if (issue_reset) {
4516 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4517 ioc->name, __func__);
4518 mpt_HardResetHandler(ioc, CAN_SLEEP);
4519 }
4520 mptsas_free_fw_event(ioc, fw_event);
4521}
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531static void
4532mptsas_send_ir2_event(struct fw_event_work *fw_event)
4533{
4534 MPT_ADAPTER *ioc;
4535 struct mptsas_hotplug_event hot_plug_info;
4536 MPI_EVENT_DATA_IR2 *ir2_data;
4537 u8 reasonCode;
4538 RaidPhysDiskPage0_t phys_disk;
4539
4540 ioc = fw_event->ioc;
4541 ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4542 reasonCode = ir2_data->ReasonCode;
4543
4544 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4545 "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4546
4547 memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4548 hot_plug_info.id = ir2_data->TargetID;
4549 hot_plug_info.channel = ir2_data->Bus;
4550 switch (reasonCode) {
4551 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4552 hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4553 break;
4554 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4555 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4556 hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4557 break;
4558 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4559 hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4560 mpt_raid_phys_disk_pg0(ioc,
4561 ir2_data->PhysDiskNum, &phys_disk);
4562 hot_plug_info.id = phys_disk.PhysDiskID;
4563 hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4564 break;
4565 default:
4566 mptsas_free_fw_event(ioc, fw_event);
4567 return;
4568 }
4569 mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4570}
4571
4572static int
4573mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4574{
4575 u32 event = le32_to_cpu(reply->Event);
4576 int sz, event_data_sz;
4577 struct fw_event_work *fw_event;
4578 unsigned long delay;
4579
4580
4581 if (ioc->fw_events_off)
4582 return 0;
4583
4584 delay = msecs_to_jiffies(1);
4585 switch (event) {
4586 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4587 {
4588 EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4589 (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4590 if (broadcast_event_data->Primitive !=
4591 MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4592 return 0;
4593 if (ioc->broadcast_aen_busy)
4594 return 0;
4595 ioc->broadcast_aen_busy = 1;
4596 break;
4597 }
4598 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4599 {
4600 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4601 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4602
4603 if (sas_event_data->ReasonCode ==
4604 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
4605 mptsas_target_reset_queue(ioc, sas_event_data);
4606 return 0;
4607 }
4608 break;
4609 }
4610 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
4611 {
4612 MpiEventDataSasExpanderStatusChange_t *expander_data =
4613 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
4614
4615 if (ioc->old_sas_discovery_protocal)
4616 return 0;
4617
4618 if (expander_data->ReasonCode ==
4619 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
4620 ioc->device_missing_delay)
4621 delay = HZ * ioc->device_missing_delay;
4622 break;
4623 }
4624 case MPI_EVENT_SAS_DISCOVERY:
4625 {
4626 u32 discovery_status;
4627 EventDataSasDiscovery_t *discovery_data =
4628 (EventDataSasDiscovery_t *)reply->Data;
4629
4630 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
4631 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4632 if (ioc->old_sas_discovery_protocal && !discovery_status)
4633 mptsas_queue_rescan(ioc);
4634 return 0;
4635 }
4636 case MPI_EVENT_INTEGRATED_RAID:
4637 case MPI_EVENT_PERSISTENT_TABLE_FULL:
4638 case MPI_EVENT_IR2:
4639 case MPI_EVENT_SAS_PHY_LINK_STATUS:
4640 case MPI_EVENT_QUEUE_FULL:
4641 break;
4642 default:
4643 return 0;
4644 }
4645
4646 event_data_sz = ((reply->MsgLength * 4) -
4647 offsetof(EventNotificationReply_t, Data));
4648 sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
4649 fw_event = kzalloc(sz, GFP_ATOMIC);
4650 if (!fw_event) {
4651 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
4652 __func__, __LINE__);
4653 return 0;
4654 }
4655 memcpy(fw_event->event_data, reply->Data, event_data_sz);
4656 fw_event->event = event;
4657 fw_event->ioc = ioc;
4658 mptsas_add_fw_event(ioc, fw_event, delay);
4659 return 0;
4660}
4661
4662
4663
4664static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
4665{
4666 struct scsi_device *sdev;
4667 int i;
4668
4669 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
4670 if (!sdev)
4671 return;
4672 if (!ioc->raid_data.pIocPg2)
4673 goto out;
4674 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
4675 goto out;
4676 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
4677 if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
4678 goto release_sdev;
4679 out:
4680 printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4681 "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
4682 scsi_remove_device(sdev);
4683 release_sdev:
4684 scsi_device_put(sdev);
4685}
4686
4687static int
4688mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4689{
4690 struct Scsi_Host *sh;
4691 MPT_SCSI_HOST *hd;
4692 MPT_ADAPTER *ioc;
4693 unsigned long flags;
4694 int ii;
4695 int numSGE = 0;
4696 int scale;
4697 int ioc_cap;
4698 int error=0;
4699 int r;
4700
4701 r = mpt_attach(pdev,id);
4702 if (r)
4703 return r;
4704
4705 ioc = pci_get_drvdata(pdev);
4706 mptsas_fw_event_off(ioc);
4707 ioc->DoneCtx = mptsasDoneCtx;
4708 ioc->TaskCtx = mptsasTaskCtx;
4709 ioc->InternalCtx = mptsasInternalCtx;
4710
4711
4712
4713 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
4714 printk(MYIOC_s_WARN_FMT
4715 "Skipping because it's not operational!\n",
4716 ioc->name);
4717 error = -ENODEV;
4718 goto out_mptsas_probe;
4719 }
4720
4721 if (!ioc->active) {
4722 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
4723 ioc->name);
4724 error = -ENODEV;
4725 goto out_mptsas_probe;
4726 }
4727
4728
4729
4730 ioc_cap = 0;
4731 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
4732 if (ioc->pfacts[ii].ProtocolFlags &
4733 MPI_PORTFACTS_PROTOCOL_INITIATOR)
4734 ioc_cap++;
4735 }
4736
4737 if (!ioc_cap) {
4738 printk(MYIOC_s_WARN_FMT
4739 "Skipping ioc=%p because SCSI Initiator mode "
4740 "is NOT enabled!\n", ioc->name, ioc);
4741 return 0;
4742 }
4743
4744 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
4745 if (!sh) {
4746 printk(MYIOC_s_WARN_FMT
4747 "Unable to register controller with SCSI subsystem\n",
4748 ioc->name);
4749 error = -1;
4750 goto out_mptsas_probe;
4751 }
4752
4753 spin_lock_irqsave(&ioc->FreeQlock, flags);
4754
4755
4756
4757 ioc->sh = sh;
4758
4759 sh->io_port = 0;
4760 sh->n_io_port = 0;
4761 sh->irq = 0;
4762
4763
4764 sh->max_cmd_len = 16;
4765 sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
4766 sh->max_id = -1;
4767 sh->max_lun = max_lun;
4768 sh->transportt = mptsas_transport_template;
4769
4770
4771
4772 sh->unique_id = ioc->id;
4773
4774 INIT_LIST_HEAD(&ioc->sas_topology);
4775 mutex_init(&ioc->sas_topology_mutex);
4776 mutex_init(&ioc->sas_discovery_mutex);
4777 mutex_init(&ioc->sas_mgmt.mutex);
4778 init_completion(&ioc->sas_mgmt.done);
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789 scale = ioc->req_sz/ioc->SGE_size;
4790 if (ioc->sg_addr_size == sizeof(u64)) {
4791 numSGE = (scale - 1) *
4792 (ioc->facts.MaxChainDepth-1) + scale +
4793 (ioc->req_sz - 60) / ioc->SGE_size;
4794 } else {
4795 numSGE = 1 + (scale - 1) *
4796 (ioc->facts.MaxChainDepth-1) + scale +
4797 (ioc->req_sz - 64) / ioc->SGE_size;
4798 }
4799
4800 if (numSGE < sh->sg_tablesize) {
4801
4802 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4803 "Resetting sg_tablesize to %d from %d\n",
4804 ioc->name, numSGE, sh->sg_tablesize));
4805 sh->sg_tablesize = numSGE;
4806 }
4807
4808 hd = shost_priv(sh);
4809 hd->ioc = ioc;
4810
4811
4812
4813
4814 ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
4815 if (!ioc->ScsiLookup) {
4816 error = -ENOMEM;
4817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4818 goto out_mptsas_probe;
4819 }
4820 spin_lock_init(&ioc->scsi_lookup_lock);
4821
4822 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
4823 ioc->name, ioc->ScsiLookup));
4824
4825 ioc->sas_data.ptClear = mpt_pt_clear;
4826
4827 hd->last_queue_full = 0;
4828 INIT_LIST_HEAD(&hd->target_reset_list);
4829 INIT_LIST_HEAD(&ioc->sas_device_info_list);
4830 mutex_init(&ioc->sas_device_info_mutex);
4831
4832 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4833
4834 if (ioc->sas_data.ptClear==1) {
4835 mptbase_sas_persist_operation(
4836 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
4837 }
4838
4839 error = scsi_add_host(sh, &ioc->pcidev->dev);
4840 if (error) {
4841 dprintk(ioc, printk(MYIOC_s_ERR_FMT
4842 "scsi_add_host failed\n", ioc->name));
4843 goto out_mptsas_probe;
4844 }
4845
4846
4847 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
4848 ioc->old_sas_discovery_protocal = 1;
4849 mptsas_scan_sas_topology(ioc);
4850 mptsas_fw_event_on(ioc);
4851 return 0;
4852
4853 out_mptsas_probe:
4854
4855 mptscsih_remove(pdev);
4856 return error;
4857}
4858
4859void
4860mptsas_shutdown(struct pci_dev *pdev)
4861{
4862 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4863
4864 mptsas_fw_event_off(ioc);
4865 mptsas_cleanup_fw_event_q(ioc);
4866}
4867
4868static void __devexit mptsas_remove(struct pci_dev *pdev)
4869{
4870 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
4871 struct mptsas_portinfo *p, *n;
4872 int i;
4873
4874 mptsas_shutdown(pdev);
4875
4876 mptsas_del_device_components(ioc);
4877
4878 ioc->sas_discovery_ignore_events = 1;
4879 sas_remove_host(ioc->sh);
4880
4881 mutex_lock(&ioc->sas_topology_mutex);
4882 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
4883 list_del(&p->list);
4884 for (i = 0 ; i < p->num_phys ; i++)
4885 mptsas_port_delete(ioc, p->phy_info[i].port_details);
4886
4887 kfree(p->phy_info);
4888 kfree(p);
4889 }
4890 mutex_unlock(&ioc->sas_topology_mutex);
4891 ioc->hba_port_info = NULL;
4892 mptscsih_remove(pdev);
4893}
4894
4895static struct pci_device_id mptsas_pci_table[] = {
4896 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
4897 PCI_ANY_ID, PCI_ANY_ID },
4898 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
4899 PCI_ANY_ID, PCI_ANY_ID },
4900 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
4901 PCI_ANY_ID, PCI_ANY_ID },
4902 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
4903 PCI_ANY_ID, PCI_ANY_ID },
4904 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
4905 PCI_ANY_ID, PCI_ANY_ID },
4906 {0}
4907};
4908MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
4909
4910
4911static struct pci_driver mptsas_driver = {
4912 .name = "mptsas",
4913 .id_table = mptsas_pci_table,
4914 .probe = mptsas_probe,
4915 .remove = __devexit_p(mptsas_remove),
4916 .shutdown = mptsas_shutdown,
4917#ifdef CONFIG_PM
4918 .suspend = mptscsih_suspend,
4919 .resume = mptscsih_resume,
4920#endif
4921};
4922
4923static int __init
4924mptsas_init(void)
4925{
4926 int error;
4927
4928 show_mptmod_ver(my_NAME, my_VERSION);
4929
4930 mptsas_transport_template =
4931 sas_attach_transport(&mptsas_transport_functions);
4932 if (!mptsas_transport_template)
4933 return -ENODEV;
4934
4935 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
4936 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
4937 mptsasInternalCtx =
4938 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
4939 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
4940 mptsasDeviceResetCtx =
4941 mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
4942
4943 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
4944 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
4945
4946 error = pci_register_driver(&mptsas_driver);
4947 if (error)
4948 sas_release_transport(mptsas_transport_template);
4949
4950 return error;
4951}
4952
4953static void __exit
4954mptsas_exit(void)
4955{
4956 pci_unregister_driver(&mptsas_driver);
4957 sas_release_transport(mptsas_transport_template);
4958
4959 mpt_reset_deregister(mptsasDoneCtx);
4960 mpt_event_deregister(mptsasDoneCtx);
4961
4962 mpt_deregister(mptsasMgmtCtx);
4963 mpt_deregister(mptsasInternalCtx);
4964 mpt_deregister(mptsasTaskCtx);
4965 mpt_deregister(mptsasDoneCtx);
4966 mpt_deregister(mptsasDeviceResetCtx);
4967}
4968
4969module_init(mptsas_init);
4970module_exit(mptsas_exit);
4971