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