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