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#include <linux/module.h>
45#include <linux/kernel.h>
46#include <linux/init.h>
47#include <linux/errno.h>
48#include <linux/sched.h>
49#include <linux/workqueue.h>
50#include <linux/delay.h>
51#include <linux/pci.h>
52#include <linux/slab.h>
53
54#include <scsi/scsi.h>
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_device.h>
57#include <scsi/scsi_host.h>
58#include <scsi/scsi_transport_sas.h>
59#include <scsi/scsi_dbg.h>
60
61#include "mpt2sas_base.h"
62
63
64
65
66
67
68
69
70
71static struct _sas_node *
72_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
73 u64 sas_address)
74{
75 if (ioc->sas_hba.sas_address == sas_address)
76 return &ioc->sas_hba;
77 else
78 return mpt2sas_scsih_expander_find_by_sas_address(ioc,
79 sas_address);
80}
81
82
83
84
85
86
87
88static enum sas_linkrate
89_transport_convert_phy_link_rate(u8 link_rate)
90{
91 enum sas_linkrate rc;
92
93 switch (link_rate) {
94 case MPI2_SAS_NEG_LINK_RATE_1_5:
95 rc = SAS_LINK_RATE_1_5_GBPS;
96 break;
97 case MPI2_SAS_NEG_LINK_RATE_3_0:
98 rc = SAS_LINK_RATE_3_0_GBPS;
99 break;
100 case MPI2_SAS_NEG_LINK_RATE_6_0:
101 rc = SAS_LINK_RATE_6_0_GBPS;
102 break;
103 case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED:
104 rc = SAS_PHY_DISABLED;
105 break;
106 case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED:
107 rc = SAS_LINK_RATE_FAILED;
108 break;
109 case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR:
110 rc = SAS_SATA_PORT_SELECTOR;
111 break;
112 case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS:
113 rc = SAS_PHY_RESET_IN_PROGRESS;
114 break;
115 default:
116 case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE:
117 case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE:
118 rc = SAS_LINK_RATE_UNKNOWN;
119 break;
120 }
121 return rc;
122}
123
124
125
126
127
128
129
130
131
132
133
134static int
135_transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
136 struct sas_identify *identify)
137{
138 Mpi2SasDevicePage0_t sas_device_pg0;
139 Mpi2ConfigReply_t mpi_reply;
140 u32 device_info;
141 u32 ioc_status;
142
143 if (ioc->shost_recovery || ioc->pci_error_recovery) {
144 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
145 __func__, ioc->name);
146 return -EFAULT;
147 }
148
149 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
150 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
151 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
152
153 ioc->name, __FILE__, __LINE__, __func__);
154 return -ENXIO;
155 }
156
157 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
158 MPI2_IOCSTATUS_MASK;
159 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
160 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
161 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
162 __FILE__, __LINE__, __func__);
163 return -EIO;
164 }
165
166 memset(identify, 0, sizeof(*identify));
167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
168
169
170 identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
171
172
173 switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
174 case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
175 identify->device_type = SAS_PHY_UNUSED;
176 break;
177 case MPI2_SAS_DEVICE_INFO_END_DEVICE:
178 identify->device_type = SAS_END_DEVICE;
179 break;
180 case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
181 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
182 break;
183 case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
184 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
185 break;
186 }
187
188
189 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
190 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
191 if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
192 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
193 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
194 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
195 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
196 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
197
198
199 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
200 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
201 if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
202 identify->target_port_protocols |= SAS_PROTOCOL_STP;
203 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
204 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
205 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
206 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
207
208 return 0;
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224u8
225mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
226 u32 reply)
227{
228 MPI2DefaultReply_t *mpi_reply;
229
230 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
231 if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
232 return 1;
233 if (ioc->transport_cmds.smid != smid)
234 return 1;
235 ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
236 if (mpi_reply) {
237 memcpy(ioc->transport_cmds.reply, mpi_reply,
238 mpi_reply->MsgLength*4);
239 ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID;
240 }
241 ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
242 complete(&ioc->transport_cmds.done);
243 return 1;
244}
245
246
247struct rep_manu_request{
248 u8 smp_frame_type;
249 u8 function;
250 u8 reserved;
251 u8 request_length;
252};
253
254
255struct rep_manu_reply{
256 u8 smp_frame_type;
257 u8 function;
258 u8 function_result;
259 u8 response_length;
260 u16 expander_change_count;
261 u8 reserved0[2];
262 u8 sas_format;
263 u8 reserved2[3];
264 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
265 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
266 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
267 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
268 u16 component_id;
269 u8 component_revision_id;
270 u8 reserved3;
271 u8 vendor_specific[8];
272};
273
274
275
276
277
278
279
280
281
282
283
284static int
285_transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
286 u64 sas_address, struct sas_expander_device *edev)
287{
288 Mpi2SmpPassthroughRequest_t *mpi_request;
289 Mpi2SmpPassthroughReply_t *mpi_reply;
290 struct rep_manu_reply *manufacture_reply;
291 struct rep_manu_request *manufacture_request;
292 int rc;
293 u16 smid;
294 u32 ioc_state;
295 unsigned long timeleft;
296 void *psge;
297 u32 sgl_flags;
298 u8 issue_reset = 0;
299 void *data_out = NULL;
300 dma_addr_t data_out_dma;
301 u32 sz;
302 u16 wait_state_count;
303
304 if (ioc->shost_recovery || ioc->pci_error_recovery) {
305 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
306 __func__, ioc->name);
307 return -EFAULT;
308 }
309
310 mutex_lock(&ioc->transport_cmds.mutex);
311
312 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
313 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
314 ioc->name, __func__);
315 rc = -EAGAIN;
316 goto out;
317 }
318 ioc->transport_cmds.status = MPT2_CMD_PENDING;
319
320 wait_state_count = 0;
321 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
322 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
323 if (wait_state_count++ == 10) {
324 printk(MPT2SAS_ERR_FMT
325 "%s: failed due to ioc not operational\n",
326 ioc->name, __func__);
327 rc = -EFAULT;
328 goto out;
329 }
330 ssleep(1);
331 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
332 printk(MPT2SAS_INFO_FMT "%s: waiting for "
333 "operational state(count=%d)\n", ioc->name,
334 __func__, wait_state_count);
335 }
336 if (wait_state_count)
337 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
338 ioc->name, __func__);
339
340 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
341 if (!smid) {
342 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
343 ioc->name, __func__);
344 rc = -EAGAIN;
345 goto out;
346 }
347
348 rc = 0;
349 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
350 ioc->transport_cmds.smid = smid;
351
352 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
353 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
354
355 if (!data_out) {
356 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
357 __LINE__, __func__);
358 rc = -ENOMEM;
359 mpt2sas_base_free_smid(ioc, smid);
360 goto out;
361 }
362
363 manufacture_request = data_out;
364 manufacture_request->smp_frame_type = 0x40;
365 manufacture_request->function = 1;
366 manufacture_request->reserved = 0;
367 manufacture_request->request_length = 0;
368
369 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
370 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
371 mpi_request->PhysicalPort = 0xFF;
372 mpi_request->VF_ID = 0;
373 mpi_request->VP_ID = 0;
374 mpi_request->SASAddress = cpu_to_le64(sas_address);
375 mpi_request->RequestDataLength =
376 cpu_to_le16(sizeof(struct rep_manu_request));
377 psge = &mpi_request->SGL;
378
379
380 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
381 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
382 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
383 ioc->base_add_sg_single(psge, sgl_flags |
384 sizeof(struct rep_manu_request), data_out_dma);
385
386
387 psge += ioc->sge_size;
388
389
390 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
391 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
392 MPI2_SGE_FLAGS_END_OF_LIST);
393 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
394 ioc->base_add_sg_single(psge, sgl_flags |
395 sizeof(struct rep_manu_reply), data_out_dma +
396 sizeof(struct rep_manu_request));
397
398 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
399 "send to sas_addr(0x%016llx)\n", ioc->name,
400 (unsigned long long)sas_address));
401 mpt2sas_base_put_smid_default(ioc, smid);
402 init_completion(&ioc->transport_cmds.done);
403 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
404 10*HZ);
405
406 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
407 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
408 ioc->name, __func__);
409 _debug_dump_mf(mpi_request,
410 sizeof(Mpi2SmpPassthroughRequest_t)/4);
411 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
412 issue_reset = 1;
413 goto issue_host_reset;
414 }
415
416 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
417 "complete\n", ioc->name));
418
419 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
420 u8 *tmp;
421
422 mpi_reply = ioc->transport_cmds.reply;
423
424 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
425 "report_manufacture - reply data transfer size(%d)\n",
426 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
427
428 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
429 sizeof(struct rep_manu_reply))
430 goto out;
431
432 manufacture_reply = data_out + sizeof(struct rep_manu_request);
433 strncpy(edev->vendor_id, manufacture_reply->vendor_id,
434 SAS_EXPANDER_VENDOR_ID_LEN);
435 strncpy(edev->product_id, manufacture_reply->product_id,
436 SAS_EXPANDER_PRODUCT_ID_LEN);
437 strncpy(edev->product_rev, manufacture_reply->product_rev,
438 SAS_EXPANDER_PRODUCT_REV_LEN);
439 edev->level = manufacture_reply->sas_format & 1;
440 if (edev->level) {
441 strncpy(edev->component_vendor_id,
442 manufacture_reply->component_vendor_id,
443 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
444 tmp = (u8 *)&manufacture_reply->component_id;
445 edev->component_id = tmp[0] << 8 | tmp[1];
446 edev->component_revision_id =
447 manufacture_reply->component_revision_id;
448 }
449 } else
450 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
451 "report_manufacture - no reply\n", ioc->name));
452
453 issue_host_reset:
454 if (issue_reset)
455 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
456 FORCE_BIG_HAMMER);
457 out:
458 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
459 if (data_out)
460 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
461
462 mutex_unlock(&ioc->transport_cmds.mutex);
463 return rc;
464}
465
466
467
468
469
470
471
472
473static void
474_transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
475 struct _sas_port *mpt2sas_port)
476{
477 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
478 enum sas_device_type device_type =
479 mpt2sas_port->remote_identify.device_type;
480
481 dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
482 "remove: sas_addr(0x%016llx)\n",
483 (unsigned long long) sas_address);
484
485 ioc->logging_level |= MPT_DEBUG_TRANSPORT;
486 if (device_type == SAS_END_DEVICE)
487 mpt2sas_device_remove(ioc, sas_address);
488 else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
489 device_type == SAS_FANOUT_EXPANDER_DEVICE)
490 mpt2sas_expander_remove(ioc, sas_address);
491 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
492}
493
494
495
496
497
498
499
500
501
502static void
503_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
504 struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
505{
506 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
507
508 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
509 "remove: sas_addr(0x%016llx), phy(%d)\n",
510 (unsigned long long) sas_address, mpt2sas_phy->phy_id);
511
512 list_del(&mpt2sas_phy->port_siblings);
513 mpt2sas_port->num_phys--;
514 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
515 mpt2sas_phy->phy_belongs_to_port = 0;
516}
517
518
519
520
521
522
523
524
525
526static void
527_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
528 struct _sas_phy *mpt2sas_phy)
529{
530 u64 sas_address = mpt2sas_port->remote_identify.sas_address;
531
532 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
533 "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
534 sas_address, mpt2sas_phy->phy_id);
535
536 list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
537 mpt2sas_port->num_phys++;
538 sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
539 mpt2sas_phy->phy_belongs_to_port = 1;
540}
541
542
543
544
545
546
547
548
549
550
551static void
552_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
553struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
554{
555 struct _sas_port *mpt2sas_port;
556 struct _sas_phy *phy_srch;
557
558 if (mpt2sas_phy->phy_belongs_to_port == 1)
559 return;
560
561 list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
562 port_list) {
563 if (mpt2sas_port->remote_identify.sas_address !=
564 sas_address)
565 continue;
566 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
567 port_siblings) {
568 if (phy_srch == mpt2sas_phy)
569 return;
570 }
571 _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
572 return;
573 }
574
575}
576
577
578
579
580
581
582
583
584
585static void
586_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
587 struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
588{
589 struct _sas_port *mpt2sas_port, *next;
590 struct _sas_phy *phy_srch;
591
592 if (mpt2sas_phy->phy_belongs_to_port == 0)
593 return;
594
595 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
596 port_list) {
597 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
598 port_siblings) {
599 if (phy_srch != mpt2sas_phy)
600 continue;
601 if (mpt2sas_port->num_phys == 1)
602 _transport_delete_port(ioc, mpt2sas_port);
603 else
604 _transport_delete_phy(ioc, mpt2sas_port,
605 mpt2sas_phy);
606 return;
607 }
608 }
609}
610
611
612
613
614
615
616
617
618
619static void
620_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
621 u64 sas_address)
622{
623 int i;
624
625 for (i = 0; i < sas_node->num_phys; i++) {
626 if (sas_node->phy[i].remote_identify.sas_address != sas_address)
627 continue;
628 if (sas_node->phy[i].phy_belongs_to_port == 1)
629 _transport_del_phy_from_an_existing_port(ioc, sas_node,
630 &sas_node->phy[i]);
631 }
632}
633
634
635
636
637
638
639
640
641
642
643
644
645struct _sas_port *
646mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
647 u64 sas_address)
648{
649 struct _sas_phy *mpt2sas_phy, *next;
650 struct _sas_port *mpt2sas_port;
651 unsigned long flags;
652 struct _sas_node *sas_node;
653 struct sas_rphy *rphy;
654 int i;
655 struct sas_port *port;
656
657 mpt2sas_port = kzalloc(sizeof(struct _sas_port),
658 GFP_KERNEL);
659 if (!mpt2sas_port) {
660 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
661 ioc->name, __FILE__, __LINE__, __func__);
662 return NULL;
663 }
664
665 INIT_LIST_HEAD(&mpt2sas_port->port_list);
666 INIT_LIST_HEAD(&mpt2sas_port->phy_list);
667 spin_lock_irqsave(&ioc->sas_node_lock, flags);
668 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
669 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
670
671 if (!sas_node) {
672 printk(MPT2SAS_ERR_FMT "%s: Could not find "
673 "parent sas_address(0x%016llx)!\n", ioc->name,
674 __func__, (unsigned long long)sas_address);
675 goto out_fail;
676 }
677
678 if ((_transport_set_identify(ioc, handle,
679 &mpt2sas_port->remote_identify))) {
680 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
681 ioc->name, __FILE__, __LINE__, __func__);
682 goto out_fail;
683 }
684
685 if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
686 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
687 ioc->name, __FILE__, __LINE__, __func__);
688 goto out_fail;
689 }
690
691 _transport_sanity_check(ioc, sas_node,
692 mpt2sas_port->remote_identify.sas_address);
693
694 for (i = 0; i < sas_node->num_phys; i++) {
695 if (sas_node->phy[i].remote_identify.sas_address !=
696 mpt2sas_port->remote_identify.sas_address)
697 continue;
698 list_add_tail(&sas_node->phy[i].port_siblings,
699 &mpt2sas_port->phy_list);
700 mpt2sas_port->num_phys++;
701 }
702
703 if (!mpt2sas_port->num_phys) {
704 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
705 ioc->name, __FILE__, __LINE__, __func__);
706 goto out_fail;
707 }
708
709 port = sas_port_alloc_num(sas_node->parent_dev);
710 if ((sas_port_add(port))) {
711 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
712 ioc->name, __FILE__, __LINE__, __func__);
713 goto out_fail;
714 }
715
716 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
717 port_siblings) {
718 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
719 dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)"
720 ", sas_addr(0x%016llx), phy(%d)\n", handle,
721 (unsigned long long)
722 mpt2sas_port->remote_identify.sas_address,
723 mpt2sas_phy->phy_id);
724 sas_port_add_phy(port, mpt2sas_phy->phy);
725 mpt2sas_phy->phy_belongs_to_port = 1;
726 }
727
728 mpt2sas_port->port = port;
729 if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE)
730 rphy = sas_end_device_alloc(port);
731 else
732 rphy = sas_expander_alloc(port,
733 mpt2sas_port->remote_identify.device_type);
734
735 rphy->identify = mpt2sas_port->remote_identify;
736 if ((sas_rphy_add(rphy))) {
737 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
738 ioc->name, __FILE__, __LINE__, __func__);
739 }
740 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
741 dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
742 "sas_addr(0x%016llx)\n", handle,
743 (unsigned long long)
744 mpt2sas_port->remote_identify.sas_address);
745 mpt2sas_port->rphy = rphy;
746 spin_lock_irqsave(&ioc->sas_node_lock, flags);
747 list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list);
748 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
749
750
751 if (mpt2sas_port->remote_identify.device_type ==
752 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
753 mpt2sas_port->remote_identify.device_type ==
754 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
755 _transport_expander_report_manufacture(ioc,
756 mpt2sas_port->remote_identify.sas_address,
757 rphy_to_expander_device(rphy));
758
759 return mpt2sas_port;
760
761 out_fail:
762 list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list,
763 port_siblings)
764 list_del(&mpt2sas_phy->port_siblings);
765 kfree(mpt2sas_port);
766 return NULL;
767}
768
769
770
771
772
773
774
775
776
777
778
779
780
781void
782mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
783 u64 sas_address_parent)
784{
785 int i;
786 unsigned long flags;
787 struct _sas_port *mpt2sas_port, *next;
788 struct _sas_node *sas_node;
789 u8 found = 0;
790 struct _sas_phy *mpt2sas_phy, *next_phy;
791
792 spin_lock_irqsave(&ioc->sas_node_lock, flags);
793 sas_node = _transport_sas_node_find_by_sas_address(ioc,
794 sas_address_parent);
795 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
796 if (!sas_node)
797 return;
798 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
799 port_list) {
800 if (mpt2sas_port->remote_identify.sas_address != sas_address)
801 continue;
802 found = 1;
803 list_del(&mpt2sas_port->port_list);
804 goto out;
805 }
806 out:
807 if (!found)
808 return;
809
810 for (i = 0; i < sas_node->num_phys; i++) {
811 if (sas_node->phy[i].remote_identify.sas_address == sas_address)
812 memset(&sas_node->phy[i].remote_identify, 0 ,
813 sizeof(struct sas_identify));
814 }
815
816 list_for_each_entry_safe(mpt2sas_phy, next_phy,
817 &mpt2sas_port->phy_list, port_siblings) {
818 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
819 dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
820 "remove: sas_addr(0x%016llx), phy(%d)\n",
821 (unsigned long long)
822 mpt2sas_port->remote_identify.sas_address,
823 mpt2sas_phy->phy_id);
824 mpt2sas_phy->phy_belongs_to_port = 0;
825 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
826 list_del(&mpt2sas_phy->port_siblings);
827 }
828 sas_port_delete(mpt2sas_port->port);
829 kfree(mpt2sas_port);
830}
831
832
833
834
835
836
837
838
839
840
841int
842mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
843 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
844{
845 struct sas_phy *phy;
846 int phy_index = mpt2sas_phy->phy_id;
847
848
849 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
850 phy = sas_phy_alloc(parent_dev, phy_index);
851 if (!phy) {
852 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
853 ioc->name, __FILE__, __LINE__, __func__);
854 return -1;
855 }
856 if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
857 &mpt2sas_phy->identify))) {
858 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
859 ioc->name, __FILE__, __LINE__, __func__);
860 return -1;
861 }
862 phy->identify = mpt2sas_phy->identify;
863 mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
864 if (mpt2sas_phy->attached_handle)
865 _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
866 &mpt2sas_phy->remote_identify);
867 phy->identify.phy_identifier = mpt2sas_phy->phy_id;
868 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
869 phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
870 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
871 phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
872 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
873 phy_pg0.HwLinkRate >> 4);
874 phy->minimum_linkrate = _transport_convert_phy_link_rate(
875 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
876 phy->maximum_linkrate = _transport_convert_phy_link_rate(
877 phy_pg0.ProgrammedLinkRate >> 4);
878
879 if ((sas_phy_add(phy))) {
880 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
881 ioc->name, __FILE__, __LINE__, __func__);
882 sas_phy_free(phy);
883 return -1;
884 }
885 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
886 dev_printk(KERN_INFO, &phy->dev,
887 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
888 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
889 mpt2sas_phy->handle, (unsigned long long)
890 mpt2sas_phy->identify.sas_address,
891 mpt2sas_phy->attached_handle,
892 (unsigned long long)
893 mpt2sas_phy->remote_identify.sas_address);
894 mpt2sas_phy->phy = phy;
895 return 0;
896}
897
898
899
900
901
902
903
904
905
906
907
908int
909mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
910 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev)
911{
912 struct sas_phy *phy;
913 int phy_index = mpt2sas_phy->phy_id;
914
915 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
916 phy = sas_phy_alloc(parent_dev, phy_index);
917 if (!phy) {
918 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
919 ioc->name, __FILE__, __LINE__, __func__);
920 return -1;
921 }
922 if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
923 &mpt2sas_phy->identify))) {
924 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
925 ioc->name, __FILE__, __LINE__, __func__);
926 return -1;
927 }
928 phy->identify = mpt2sas_phy->identify;
929 mpt2sas_phy->attached_handle =
930 le16_to_cpu(expander_pg1.AttachedDevHandle);
931 if (mpt2sas_phy->attached_handle)
932 _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
933 &mpt2sas_phy->remote_identify);
934 phy->identify.phy_identifier = mpt2sas_phy->phy_id;
935 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
936 expander_pg1.NegotiatedLinkRate &
937 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
938 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
939 expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
940 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
941 expander_pg1.HwLinkRate >> 4);
942 phy->minimum_linkrate = _transport_convert_phy_link_rate(
943 expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
944 phy->maximum_linkrate = _transport_convert_phy_link_rate(
945 expander_pg1.ProgrammedLinkRate >> 4);
946
947 if ((sas_phy_add(phy))) {
948 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
949 ioc->name, __FILE__, __LINE__, __func__);
950 sas_phy_free(phy);
951 return -1;
952 }
953 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
954 dev_printk(KERN_INFO, &phy->dev,
955 "add: handle(0x%04x), sas_addr(0x%016llx)\n"
956 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
957 mpt2sas_phy->handle, (unsigned long long)
958 mpt2sas_phy->identify.sas_address,
959 mpt2sas_phy->attached_handle,
960 (unsigned long long)
961 mpt2sas_phy->remote_identify.sas_address);
962 mpt2sas_phy->phy = phy;
963 return 0;
964}
965
966
967
968
969
970
971
972
973
974
975
976void
977mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
978 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
979{
980 unsigned long flags;
981 struct _sas_node *sas_node;
982 struct _sas_phy *mpt2sas_phy;
983
984 if (ioc->shost_recovery || ioc->pci_error_recovery)
985 return;
986
987 spin_lock_irqsave(&ioc->sas_node_lock, flags);
988 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
989 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
990 if (!sas_node)
991 return;
992
993 mpt2sas_phy = &sas_node->phy[phy_number];
994 mpt2sas_phy->attached_handle = handle;
995 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
996 _transport_set_identify(ioc, handle,
997 &mpt2sas_phy->remote_identify);
998 _transport_add_phy_to_an_existing_port(ioc, sas_node,
999 mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
1000 } else
1001 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
1002 sas_identify));
1003
1004 if (mpt2sas_phy->phy)
1005 mpt2sas_phy->phy->negotiated_linkrate =
1006 _transport_convert_phy_link_rate(link_rate);
1007
1008 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
1009 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
1010 "refresh: parent sas_addr(0x%016llx),\n"
1011 "\tlink_rate(0x%02x), phy(%d)\n"
1012 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1013 (unsigned long long)sas_address,
1014 link_rate, phy_number, handle, (unsigned long long)
1015 mpt2sas_phy->remote_identify.sas_address);
1016}
1017
1018static inline void *
1019phy_to_ioc(struct sas_phy *phy)
1020{
1021 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1022 return shost_priv(shost);
1023}
1024
1025static inline void *
1026rphy_to_ioc(struct sas_rphy *rphy)
1027{
1028 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
1029 return shost_priv(shost);
1030}
1031
1032
1033
1034struct phy_error_log_request{
1035 u8 smp_frame_type;
1036 u8 function;
1037 u8 allocated_response_length;
1038 u8 request_length;
1039 u8 reserved_1[5];
1040 u8 phy_identifier;
1041 u8 reserved_2[2];
1042};
1043
1044
1045struct phy_error_log_reply{
1046 u8 smp_frame_type;
1047 u8 function;
1048 u8 function_result;
1049 u8 response_length;
1050 __be16 expander_change_count;
1051 u8 reserved_1[3];
1052 u8 phy_identifier;
1053 u8 reserved_2[2];
1054 __be32 invalid_dword;
1055 __be32 running_disparity_error;
1056 __be32 loss_of_dword_sync;
1057 __be32 phy_reset_problem;
1058};
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068static int
1069_transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc,
1070 struct sas_phy *phy)
1071{
1072 Mpi2SmpPassthroughRequest_t *mpi_request;
1073 Mpi2SmpPassthroughReply_t *mpi_reply;
1074 struct phy_error_log_request *phy_error_log_request;
1075 struct phy_error_log_reply *phy_error_log_reply;
1076 int rc;
1077 u16 smid;
1078 u32 ioc_state;
1079 unsigned long timeleft;
1080 void *psge;
1081 u32 sgl_flags;
1082 u8 issue_reset = 0;
1083 void *data_out = NULL;
1084 dma_addr_t data_out_dma;
1085 u32 sz;
1086 u16 wait_state_count;
1087
1088 if (ioc->shost_recovery || ioc->pci_error_recovery) {
1089 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1090 __func__, ioc->name);
1091 return -EFAULT;
1092 }
1093
1094 mutex_lock(&ioc->transport_cmds.mutex);
1095
1096 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1097 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1098 ioc->name, __func__);
1099 rc = -EAGAIN;
1100 goto out;
1101 }
1102 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1103
1104 wait_state_count = 0;
1105 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1106 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1107 if (wait_state_count++ == 10) {
1108 printk(MPT2SAS_ERR_FMT
1109 "%s: failed due to ioc not operational\n",
1110 ioc->name, __func__);
1111 rc = -EFAULT;
1112 goto out;
1113 }
1114 ssleep(1);
1115 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1116 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1117 "operational state(count=%d)\n", ioc->name,
1118 __func__, wait_state_count);
1119 }
1120 if (wait_state_count)
1121 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1122 ioc->name, __func__);
1123
1124 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1125 if (!smid) {
1126 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1127 ioc->name, __func__);
1128 rc = -EAGAIN;
1129 goto out;
1130 }
1131
1132 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1133 ioc->transport_cmds.smid = smid;
1134
1135 sz = sizeof(struct phy_error_log_request) +
1136 sizeof(struct phy_error_log_reply);
1137 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1138 if (!data_out) {
1139 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1140 __LINE__, __func__);
1141 rc = -ENOMEM;
1142 mpt2sas_base_free_smid(ioc, smid);
1143 goto out;
1144 }
1145
1146 rc = -EINVAL;
1147 memset(data_out, 0, sz);
1148 phy_error_log_request = data_out;
1149 phy_error_log_request->smp_frame_type = 0x40;
1150 phy_error_log_request->function = 0x11;
1151 phy_error_log_request->request_length = 2;
1152 phy_error_log_request->allocated_response_length = 0;
1153 phy_error_log_request->phy_identifier = phy->number;
1154
1155 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1156 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1157 mpi_request->PhysicalPort = 0xFF;
1158 mpi_request->VF_ID = 0;
1159 mpi_request->VP_ID = 0;
1160 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1161 mpi_request->RequestDataLength =
1162 cpu_to_le16(sizeof(struct phy_error_log_request));
1163 psge = &mpi_request->SGL;
1164
1165
1166 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1167 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1168 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1169 ioc->base_add_sg_single(psge, sgl_flags |
1170 sizeof(struct phy_error_log_request), data_out_dma);
1171
1172
1173 psge += ioc->sge_size;
1174
1175
1176 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1177 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1178 MPI2_SGE_FLAGS_END_OF_LIST);
1179 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1180 ioc->base_add_sg_single(psge, sgl_flags |
1181 sizeof(struct phy_error_log_reply), data_out_dma +
1182 sizeof(struct phy_error_log_request));
1183
1184 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1185 "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name,
1186 (unsigned long long)phy->identify.sas_address, phy->number));
1187 mpt2sas_base_put_smid_default(ioc, smid);
1188 init_completion(&ioc->transport_cmds.done);
1189 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1190 10*HZ);
1191
1192 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1193 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1194 ioc->name, __func__);
1195 _debug_dump_mf(mpi_request,
1196 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1197 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1198 issue_reset = 1;
1199 goto issue_host_reset;
1200 }
1201
1202 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1203 "complete\n", ioc->name));
1204
1205 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1206
1207 mpi_reply = ioc->transport_cmds.reply;
1208
1209 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1210 "phy_error_log - reply data transfer size(%d)\n",
1211 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1212
1213 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1214 sizeof(struct phy_error_log_reply))
1215 goto out;
1216
1217 phy_error_log_reply = data_out +
1218 sizeof(struct phy_error_log_request);
1219
1220 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1221 "phy_error_log - function_result(%d)\n",
1222 ioc->name, phy_error_log_reply->function_result));
1223
1224 phy->invalid_dword_count =
1225 be32_to_cpu(phy_error_log_reply->invalid_dword);
1226 phy->running_disparity_error_count =
1227 be32_to_cpu(phy_error_log_reply->running_disparity_error);
1228 phy->loss_of_dword_sync_count =
1229 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1230 phy->phy_reset_problem_count =
1231 be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1232 rc = 0;
1233 } else
1234 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1235 "phy_error_log - no reply\n", ioc->name));
1236
1237 issue_host_reset:
1238 if (issue_reset)
1239 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1240 FORCE_BIG_HAMMER);
1241 out:
1242 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1243 if (data_out)
1244 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1245
1246 mutex_unlock(&ioc->transport_cmds.mutex);
1247 return rc;
1248}
1249
1250
1251
1252
1253
1254
1255
1256
1257static int
1258_transport_get_linkerrors(struct sas_phy *phy)
1259{
1260 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1261 unsigned long flags;
1262 Mpi2ConfigReply_t mpi_reply;
1263 Mpi2SasPhyPage1_t phy_pg1;
1264
1265 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1266 if (_transport_sas_node_find_by_sas_address(ioc,
1267 phy->identify.sas_address) == NULL) {
1268 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1269 return -EINVAL;
1270 }
1271 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1272
1273 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1274 return _transport_get_expander_phy_error_log(ioc, phy);
1275
1276
1277 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
1278 phy->number))) {
1279 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1280 ioc->name, __FILE__, __LINE__, __func__);
1281 return -ENXIO;
1282 }
1283
1284 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1285 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1286 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1287 phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1288 le32_to_cpu(mpi_reply.IOCLogInfo));
1289
1290 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
1291 phy->running_disparity_error_count =
1292 le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
1293 phy->loss_of_dword_sync_count =
1294 le32_to_cpu(phy_pg1.LossDwordSynchCount);
1295 phy->phy_reset_problem_count =
1296 le32_to_cpu(phy_pg1.PhyResetProblemCount);
1297 return 0;
1298}
1299
1300
1301
1302
1303
1304
1305
1306
1307static int
1308_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1309{
1310 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1311 struct _sas_device *sas_device;
1312 unsigned long flags;
1313
1314 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1315 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1316 rphy->identify.sas_address);
1317 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1318
1319 if (!sas_device)
1320 return -ENXIO;
1321
1322 *identifier = sas_device->enclosure_logical_id;
1323 return 0;
1324}
1325
1326
1327
1328
1329
1330
1331
1332static int
1333_transport_get_bay_identifier(struct sas_rphy *rphy)
1334{
1335 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1336 struct _sas_device *sas_device;
1337 unsigned long flags;
1338
1339 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1340 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1341 rphy->identify.sas_address);
1342 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1343
1344 if (!sas_device)
1345 return -ENXIO;
1346
1347 return sas_device->slot;
1348}
1349
1350
1351struct phy_control_request{
1352 u8 smp_frame_type;
1353 u8 function;
1354 u8 allocated_response_length;
1355 u8 request_length;
1356 u16 expander_change_count;
1357 u8 reserved_1[3];
1358 u8 phy_identifier;
1359 u8 phy_operation;
1360 u8 reserved_2[13];
1361 u64 attached_device_name;
1362 u8 programmed_min_physical_link_rate;
1363 u8 programmed_max_physical_link_rate;
1364 u8 reserved_3[6];
1365};
1366
1367
1368struct phy_control_reply{
1369 u8 smp_frame_type;
1370 u8 function;
1371 u8 function_result;
1372 u8 response_length;
1373};
1374
1375#define SMP_PHY_CONTROL_LINK_RESET (0x01)
1376#define SMP_PHY_CONTROL_HARD_RESET (0x02)
1377#define SMP_PHY_CONTROL_DISABLE (0x03)
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387static int
1388_transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc,
1389 struct sas_phy *phy, u8 phy_operation)
1390{
1391 Mpi2SmpPassthroughRequest_t *mpi_request;
1392 Mpi2SmpPassthroughReply_t *mpi_reply;
1393 struct phy_control_request *phy_control_request;
1394 struct phy_control_reply *phy_control_reply;
1395 int rc;
1396 u16 smid;
1397 u32 ioc_state;
1398 unsigned long timeleft;
1399 void *psge;
1400 u32 sgl_flags;
1401 u8 issue_reset = 0;
1402 void *data_out = NULL;
1403 dma_addr_t data_out_dma;
1404 u32 sz;
1405 u16 wait_state_count;
1406
1407 if (ioc->shost_recovery) {
1408 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1409 __func__, ioc->name);
1410 return -EFAULT;
1411 }
1412
1413 mutex_lock(&ioc->transport_cmds.mutex);
1414
1415 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1416 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1417 ioc->name, __func__);
1418 rc = -EAGAIN;
1419 goto out;
1420 }
1421 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1422
1423 wait_state_count = 0;
1424 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1425 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1426 if (wait_state_count++ == 10) {
1427 printk(MPT2SAS_ERR_FMT
1428 "%s: failed due to ioc not operational\n",
1429 ioc->name, __func__);
1430 rc = -EFAULT;
1431 goto out;
1432 }
1433 ssleep(1);
1434 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1435 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1436 "operational state(count=%d)\n", ioc->name,
1437 __func__, wait_state_count);
1438 }
1439 if (wait_state_count)
1440 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1441 ioc->name, __func__);
1442
1443 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1444 if (!smid) {
1445 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1446 ioc->name, __func__);
1447 rc = -EAGAIN;
1448 goto out;
1449 }
1450
1451 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1452 ioc->transport_cmds.smid = smid;
1453
1454 sz = sizeof(struct phy_control_request) +
1455 sizeof(struct phy_control_reply);
1456 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1457 if (!data_out) {
1458 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1459 __LINE__, __func__);
1460 rc = -ENOMEM;
1461 mpt2sas_base_free_smid(ioc, smid);
1462 goto out;
1463 }
1464
1465 rc = -EINVAL;
1466 memset(data_out, 0, sz);
1467 phy_control_request = data_out;
1468 phy_control_request->smp_frame_type = 0x40;
1469 phy_control_request->function = 0x91;
1470 phy_control_request->request_length = 9;
1471 phy_control_request->allocated_response_length = 0;
1472 phy_control_request->phy_identifier = phy->number;
1473 phy_control_request->phy_operation = phy_operation;
1474 phy_control_request->programmed_min_physical_link_rate =
1475 phy->minimum_linkrate << 4;
1476 phy_control_request->programmed_max_physical_link_rate =
1477 phy->maximum_linkrate << 4;
1478
1479 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1480 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1481 mpi_request->PhysicalPort = 0xFF;
1482 mpi_request->VF_ID = 0;
1483 mpi_request->VP_ID = 0;
1484 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1485 mpi_request->RequestDataLength =
1486 cpu_to_le16(sizeof(struct phy_error_log_request));
1487 psge = &mpi_request->SGL;
1488
1489
1490 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1491 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1492 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1493 ioc->base_add_sg_single(psge, sgl_flags |
1494 sizeof(struct phy_control_request), data_out_dma);
1495
1496
1497 psge += ioc->sge_size;
1498
1499
1500 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1501 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1502 MPI2_SGE_FLAGS_END_OF_LIST);
1503 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1504 ioc->base_add_sg_single(psge, sgl_flags |
1505 sizeof(struct phy_control_reply), data_out_dma +
1506 sizeof(struct phy_control_request));
1507
1508 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1509 "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name,
1510 (unsigned long long)phy->identify.sas_address, phy->number,
1511 phy_operation));
1512 mpt2sas_base_put_smid_default(ioc, smid);
1513 init_completion(&ioc->transport_cmds.done);
1514 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1515 10*HZ);
1516
1517 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1518 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1519 ioc->name, __func__);
1520 _debug_dump_mf(mpi_request,
1521 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1522 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1523 issue_reset = 1;
1524 goto issue_host_reset;
1525 }
1526
1527 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1528 "complete\n", ioc->name));
1529
1530 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1531
1532 mpi_reply = ioc->transport_cmds.reply;
1533
1534 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1535 "phy_control - reply data transfer size(%d)\n",
1536 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1537
1538 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1539 sizeof(struct phy_control_reply))
1540 goto out;
1541
1542 phy_control_reply = data_out +
1543 sizeof(struct phy_control_request);
1544
1545 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1546 "phy_control - function_result(%d)\n",
1547 ioc->name, phy_control_reply->function_result));
1548
1549 rc = 0;
1550 } else
1551 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1552 "phy_control - no reply\n", ioc->name));
1553
1554 issue_host_reset:
1555 if (issue_reset)
1556 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1557 FORCE_BIG_HAMMER);
1558 out:
1559 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1560 if (data_out)
1561 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1562
1563 mutex_unlock(&ioc->transport_cmds.mutex);
1564 return rc;
1565}
1566
1567
1568
1569
1570
1571
1572
1573
1574static int
1575_transport_phy_reset(struct sas_phy *phy, int hard_reset)
1576{
1577 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1578 Mpi2SasIoUnitControlReply_t mpi_reply;
1579 Mpi2SasIoUnitControlRequest_t mpi_request;
1580 unsigned long flags;
1581
1582 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1583 if (_transport_sas_node_find_by_sas_address(ioc,
1584 phy->identify.sas_address) == NULL) {
1585 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1586 return -EINVAL;
1587 }
1588 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1589
1590
1591 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1592 return _transport_expander_phy_control(ioc, phy,
1593 (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1594 SMP_PHY_CONTROL_LINK_RESET);
1595
1596
1597 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
1598 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
1599 mpi_request.Operation = hard_reset ?
1600 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
1601 mpi_request.PhyNum = phy->number;
1602
1603 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
1604 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1605 ioc->name, __FILE__, __LINE__, __func__);
1606 return -ENXIO;
1607 }
1608
1609 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1610 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1611 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1612 phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1613 le32_to_cpu(mpi_reply.IOCLogInfo));
1614
1615 return 0;
1616}
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626static int
1627_transport_phy_enable(struct sas_phy *phy, int enable)
1628{
1629 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1630 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1631 Mpi2ConfigReply_t mpi_reply;
1632 u16 ioc_status;
1633 u16 sz;
1634 int rc = 0;
1635 unsigned long flags;
1636
1637 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1638 if (_transport_sas_node_find_by_sas_address(ioc,
1639 phy->identify.sas_address) == NULL) {
1640 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1641 return -EINVAL;
1642 }
1643 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1644
1645
1646 if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1647 return _transport_expander_phy_control(ioc, phy,
1648 (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1649 SMP_PHY_CONTROL_DISABLE);
1650
1651
1652
1653
1654 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1655 sizeof(Mpi2SasIOUnit1PhyData_t));
1656 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1657 if (!sas_iounit_pg1) {
1658 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1659 ioc->name, __FILE__, __LINE__, __func__);
1660 rc = -ENOMEM;
1661 goto out;
1662 }
1663 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1664 sas_iounit_pg1, sz))) {
1665 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1666 ioc->name, __FILE__, __LINE__, __func__);
1667 rc = -ENXIO;
1668 goto out;
1669 }
1670 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1671 MPI2_IOCSTATUS_MASK;
1672 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1673 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1674 ioc->name, __FILE__, __LINE__, __func__);
1675 rc = -EIO;
1676 goto out;
1677 }
1678
1679 if (enable)
1680 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1681 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1682 else
1683 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1684 |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1685
1686 mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1687
1688
1689 if (enable)
1690 _transport_phy_reset(phy, 0);
1691
1692 out:
1693 kfree(sas_iounit_pg1);
1694 return rc;
1695}
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705static int
1706_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1707{
1708 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1709 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1710 Mpi2SasPhyPage0_t phy_pg0;
1711 Mpi2ConfigReply_t mpi_reply;
1712 u16 ioc_status;
1713 u16 sz;
1714 int i;
1715 int rc = 0;
1716 unsigned long flags;
1717
1718 spin_lock_irqsave(&ioc->sas_node_lock, flags);
1719 if (_transport_sas_node_find_by_sas_address(ioc,
1720 phy->identify.sas_address) == NULL) {
1721 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1722 return -EINVAL;
1723 }
1724 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1725
1726 if (!rates->minimum_linkrate)
1727 rates->minimum_linkrate = phy->minimum_linkrate;
1728 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1729 rates->minimum_linkrate = phy->minimum_linkrate_hw;
1730
1731 if (!rates->maximum_linkrate)
1732 rates->maximum_linkrate = phy->maximum_linkrate;
1733 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1734 rates->maximum_linkrate = phy->maximum_linkrate_hw;
1735
1736
1737 if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1738 phy->minimum_linkrate = rates->minimum_linkrate;
1739 phy->maximum_linkrate = rates->maximum_linkrate;
1740 return _transport_expander_phy_control(ioc, phy,
1741 SMP_PHY_CONTROL_LINK_RESET);
1742 }
1743
1744
1745
1746
1747 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1748 sizeof(Mpi2SasIOUnit1PhyData_t));
1749 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1750 if (!sas_iounit_pg1) {
1751 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1752 ioc->name, __FILE__, __LINE__, __func__);
1753 rc = -ENOMEM;
1754 goto out;
1755 }
1756 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1757 sas_iounit_pg1, sz))) {
1758 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1759 ioc->name, __FILE__, __LINE__, __func__);
1760 rc = -ENXIO;
1761 goto out;
1762 }
1763 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1764 MPI2_IOCSTATUS_MASK;
1765 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1766 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1767 ioc->name, __FILE__, __LINE__, __func__);
1768 rc = -EIO;
1769 goto out;
1770 }
1771
1772 for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1773 if (phy->number != i) {
1774 sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1775 (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1776 (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1777 } else {
1778 sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1779 (rates->minimum_linkrate +
1780 (rates->maximum_linkrate << 4));
1781 }
1782 }
1783
1784 if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1785 sz)) {
1786 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1787 ioc->name, __FILE__, __LINE__, __func__);
1788 rc = -ENXIO;
1789 goto out;
1790 }
1791
1792
1793 _transport_phy_reset(phy, 0);
1794
1795
1796 if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1797 phy->number)) {
1798 phy->minimum_linkrate = _transport_convert_phy_link_rate(
1799 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
1800 phy->maximum_linkrate = _transport_convert_phy_link_rate(
1801 phy_pg0.ProgrammedLinkRate >> 4);
1802 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1803 phy_pg0.NegotiatedLinkRate &
1804 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1805 }
1806
1807 out:
1808 kfree(sas_iounit_pg1);
1809 return rc;
1810}
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823static int
1824_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1825 struct request *req)
1826{
1827 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1828 Mpi2SmpPassthroughRequest_t *mpi_request;
1829 Mpi2SmpPassthroughReply_t *mpi_reply;
1830 int rc;
1831 u16 smid;
1832 u32 ioc_state;
1833 unsigned long timeleft;
1834 void *psge;
1835 u32 sgl_flags;
1836 u8 issue_reset = 0;
1837 dma_addr_t dma_addr_in = 0;
1838 dma_addr_t dma_addr_out = 0;
1839 u16 wait_state_count;
1840 struct request *rsp = req->next_rq;
1841
1842 if (!rsp) {
1843 printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
1844 "missing\n", ioc->name, __func__);
1845 return -EINVAL;
1846 }
1847
1848
1849 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1850 printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, "
1851 "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt,
1852 blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
1853 return -EINVAL;
1854 }
1855
1856 if (ioc->shost_recovery) {
1857 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1858 __func__, ioc->name);
1859 return -EFAULT;
1860 }
1861
1862 rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1863 if (rc)
1864 return rc;
1865
1866 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1867 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
1868 __func__);
1869 rc = -EAGAIN;
1870 goto out;
1871 }
1872 ioc->transport_cmds.status = MPT2_CMD_PENDING;
1873
1874 wait_state_count = 0;
1875 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1876 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1877 if (wait_state_count++ == 10) {
1878 printk(MPT2SAS_ERR_FMT
1879 "%s: failed due to ioc not operational\n",
1880 ioc->name, __func__);
1881 rc = -EFAULT;
1882 goto out;
1883 }
1884 ssleep(1);
1885 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1886 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1887 "operational state(count=%d)\n", ioc->name,
1888 __func__, wait_state_count);
1889 }
1890 if (wait_state_count)
1891 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1892 ioc->name, __func__);
1893
1894 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1895 if (!smid) {
1896 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1897 ioc->name, __func__);
1898 rc = -EAGAIN;
1899 goto out;
1900 }
1901
1902 rc = 0;
1903 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1904 ioc->transport_cmds.smid = smid;
1905
1906 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1907 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1908 mpi_request->PhysicalPort = 0xFF;
1909 mpi_request->VF_ID = 0;
1910 mpi_request->VP_ID = 0;
1911 mpi_request->SASAddress = (rphy) ?
1912 cpu_to_le64(rphy->identify.sas_address) :
1913 cpu_to_le64(ioc->sas_hba.sas_address);
1914 mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
1915 psge = &mpi_request->SGL;
1916
1917
1918 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1919 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1920 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1921 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1922 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
1923 if (!dma_addr_out) {
1924 mpt2sas_base_free_smid(ioc, smid);
1925 goto unmap;
1926 }
1927
1928 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4),
1929 dma_addr_out);
1930
1931
1932 psge += ioc->sge_size;
1933
1934
1935 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1936 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1937 MPI2_SGE_FLAGS_END_OF_LIST);
1938 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1939 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
1940 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
1941 if (!dma_addr_in) {
1942 mpt2sas_base_free_smid(ioc, smid);
1943 goto unmap;
1944 }
1945
1946 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4),
1947 dma_addr_in);
1948
1949 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1950 "sending smp request\n", ioc->name, __func__));
1951
1952 mpt2sas_base_put_smid_default(ioc, smid);
1953 init_completion(&ioc->transport_cmds.done);
1954 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1955 10*HZ);
1956
1957 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1958 printk(MPT2SAS_ERR_FMT "%s : timeout\n",
1959 __func__, ioc->name);
1960 _debug_dump_mf(mpi_request,
1961 sizeof(Mpi2SmpPassthroughRequest_t)/4);
1962 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1963 issue_reset = 1;
1964 goto issue_host_reset;
1965 }
1966
1967 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1968 "complete\n", ioc->name, __func__));
1969
1970 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1971
1972 mpi_reply = ioc->transport_cmds.reply;
1973
1974 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1975 "%s - reply data transfer size(%d)\n",
1976 ioc->name, __func__,
1977 le16_to_cpu(mpi_reply->ResponseDataLength)));
1978
1979 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
1980 req->sense_len = sizeof(*mpi_reply);
1981 req->resid_len = 0;
1982 rsp->resid_len -=
1983 le16_to_cpu(mpi_reply->ResponseDataLength);
1984 } else {
1985 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1986 "%s - no reply\n", ioc->name, __func__));
1987 rc = -ENXIO;
1988 }
1989
1990 issue_host_reset:
1991 if (issue_reset) {
1992 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1993 FORCE_BIG_HAMMER);
1994 rc = -ETIMEDOUT;
1995 }
1996
1997 unmap:
1998 if (dma_addr_out)
1999 pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
2000 PCI_DMA_BIDIRECTIONAL);
2001 if (dma_addr_in)
2002 pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
2003 PCI_DMA_BIDIRECTIONAL);
2004
2005 out:
2006 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
2007 mutex_unlock(&ioc->transport_cmds.mutex);
2008 return rc;
2009}
2010
2011struct sas_function_template mpt2sas_transport_functions = {
2012 .get_linkerrors = _transport_get_linkerrors,
2013 .get_enclosure_identifier = _transport_get_enclosure_identifier,
2014 .get_bay_identifier = _transport_get_bay_identifier,
2015 .phy_reset = _transport_phy_reset,
2016 .phy_enable = _transport_phy_enable,
2017 .set_phy_speed = _transport_phy_speed,
2018 .smp_handler = _transport_smp_handler,
2019};
2020
2021struct scsi_transport_template *mpt2sas_transport_template;
2022