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