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