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