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