Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mpt2sas_transport.c
Go to the documentation of this file.
1 /*
2  * SAS Transport Layer for MPT (Message Passing Technology) based controllers
3  *
4  * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
5  * Copyright (C) 2007-2012 LSI Corporation
6  * (mailto:[email protected])
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * NO WARRANTY
19  * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20  * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21  * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23  * solely responsible for determining the appropriateness of using and
24  * distributing the Program and assumes all risks associated with its
25  * exercise of rights under this Agreement, including but not limited to
26  * the risks and costs of program errors, damage to or loss of data,
27  * programs or equipment, and unavailability or interruption of operations.
28 
29  * DISCLAIMER OF LIABILITY
30  * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35  * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36  * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37 
38  * You should have received a copy of the GNU General Public License
39  * along with this program; if not, write to the Free Software
40  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41  * USA.
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>
59 #include <scsi/scsi_dbg.h>
60 
61 #include "mpt2sas_base.h"
71 static struct _sas_node *
72 _transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc,
74 {
75  if (ioc->sas_hba.sas_address == sas_address)
76  return &ioc->sas_hba;
77  else
79  sas_address);
80 }
81 
88 static enum sas_linkrate
89 _transport_convert_phy_link_rate(u8 link_rate)
90 {
91  enum sas_linkrate rc;
92 
93  switch (link_rate) {
96  break;
99  break;
102  break;
104  rc = SAS_PHY_DISABLED;
105  break;
108  break;
111  break;
114  break;
115  default:
119  break;
120  }
121  return rc;
122 }
123 
134 static 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;
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,
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) &
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(struct sas_identify));
167  device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
168 
169  /* sas_address */
170  identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
171 
172  /* phy number of the parent device this device is linked to */
173  identify->phy_identifier = sas_device_pg0.PhyNum;
174 
175  /* device_type */
176  switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
178  identify->device_type = SAS_PHY_UNUSED;
179  break;
181  identify->device_type = SAS_END_DEVICE;
182  break;
185  break;
188  break;
189  }
190 
191  /* initiator_port_protocols */
192  if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
194  if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
196  if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
198  if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
200 
201  /* target_port_protocols */
202  if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
204  if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
206  if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
208  if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
210 
211  return 0;
212 }
213 
227 u8
228 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
229  u32 reply)
230 {
231  MPI2DefaultReply_t *mpi_reply;
232 
233  mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
234  if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
235  return 1;
236  if (ioc->transport_cmds.smid != smid)
237  return 1;
238  ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
239  if (mpi_reply) {
240  memcpy(ioc->transport_cmds.reply, mpi_reply,
241  mpi_reply->MsgLength*4);
242  ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID;
243  }
244  ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
245  complete(&ioc->transport_cmds.done);
246  return 1;
247 }
248 
249 /* report manufacture request structure */
250 struct rep_manu_request{
252  u8 function;
253  u8 reserved;
255 };
256 
257 /* report manufacture reply structure */
258 struct rep_manu_reply{
259  u8 smp_frame_type; /* 0x41 */
260  u8 function; /* 0x01 */
264  u8 reserved0[2];
265  u8 sas_format;
266  u8 reserved2[3];
273  u8 reserved3;
274  u8 vendor_specific[8];
275 };
276 
287 static int
288 _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
289  u64 sas_address, struct sas_expander_device *edev)
290 {
291  Mpi2SmpPassthroughRequest_t *mpi_request;
292  Mpi2SmpPassthroughReply_t *mpi_reply;
293  struct rep_manu_reply *manufacture_reply;
294  struct rep_manu_request *manufacture_request;
295  int rc;
296  u16 smid;
297  u32 ioc_state;
298  unsigned long timeleft;
299  void *psge;
300  u32 sgl_flags;
301  u8 issue_reset = 0;
302  void *data_out = NULL;
303  dma_addr_t data_out_dma;
304  u32 sz;
305  u16 wait_state_count;
306 
307  if (ioc->shost_recovery || ioc->pci_error_recovery) {
308  printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
309  __func__, ioc->name);
310  return -EFAULT;
311  }
312 
313  mutex_lock(&ioc->transport_cmds.mutex);
314 
315  if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
316  printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
317  ioc->name, __func__);
318  rc = -EAGAIN;
319  goto out;
320  }
321  ioc->transport_cmds.status = MPT2_CMD_PENDING;
322 
323  wait_state_count = 0;
324  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
325  while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
326  if (wait_state_count++ == 10) {
328  "%s: failed due to ioc not operational\n",
329  ioc->name, __func__);
330  rc = -EFAULT;
331  goto out;
332  }
333  ssleep(1);
334  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
335  printk(MPT2SAS_INFO_FMT "%s: waiting for "
336  "operational state(count=%d)\n", ioc->name,
337  __func__, wait_state_count);
338  }
339  if (wait_state_count)
340  printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
341  ioc->name, __func__);
342 
343  smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
344  if (!smid) {
345  printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
346  ioc->name, __func__);
347  rc = -EAGAIN;
348  goto out;
349  }
350 
351  rc = 0;
352  mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
353  ioc->transport_cmds.smid = smid;
354 
355  sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
356  data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
357 
358  if (!data_out) {
359  printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
360  __LINE__, __func__);
361  rc = -ENOMEM;
362  mpt2sas_base_free_smid(ioc, smid);
363  goto out;
364  }
365 
366  manufacture_request = data_out;
367  manufacture_request->smp_frame_type = 0x40;
368  manufacture_request->function = 1;
369  manufacture_request->reserved = 0;
370  manufacture_request->request_length = 0;
371 
372  memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
374  mpi_request->PhysicalPort = 0xFF;
375  mpi_request->VF_ID = 0; /* TODO */
376  mpi_request->VP_ID = 0;
377  mpi_request->SASAddress = cpu_to_le64(sas_address);
378  mpi_request->RequestDataLength =
379  cpu_to_le16(sizeof(struct rep_manu_request));
380  psge = &mpi_request->SGL;
381 
382  /* WRITE sgel first */
383  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
385  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
386  ioc->base_add_sg_single(psge, sgl_flags |
387  sizeof(struct rep_manu_request), data_out_dma);
388 
389  /* incr sgel */
390  psge += ioc->sge_size;
391 
392  /* READ sgel last */
393  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
396  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
397  ioc->base_add_sg_single(psge, sgl_flags |
398  sizeof(struct rep_manu_reply), data_out_dma +
399  sizeof(struct rep_manu_request));
400 
401  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
402  "send to sas_addr(0x%016llx)\n", ioc->name,
403  (unsigned long long)sas_address));
404  init_completion(&ioc->transport_cmds.done);
406  timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
407  10*HZ);
408 
409  if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
410  printk(MPT2SAS_ERR_FMT "%s: timeout\n",
411  ioc->name, __func__);
412  _debug_dump_mf(mpi_request,
413  sizeof(Mpi2SmpPassthroughRequest_t)/4);
414  if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
415  issue_reset = 1;
416  goto issue_host_reset;
417  }
418 
419  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - "
420  "complete\n", ioc->name));
421 
422  if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
423  u8 *tmp;
424 
425  mpi_reply = ioc->transport_cmds.reply;
426 
428  "report_manufacture - reply data transfer size(%d)\n",
429  ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
430 
431  if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
432  sizeof(struct rep_manu_reply))
433  goto out;
434 
435  manufacture_reply = data_out + sizeof(struct rep_manu_request);
436  strncpy(edev->vendor_id, manufacture_reply->vendor_id,
438  strncpy(edev->product_id, manufacture_reply->product_id,
440  strncpy(edev->product_rev, manufacture_reply->product_rev,
442  edev->level = manufacture_reply->sas_format & 1;
443  if (edev->level) {
445  manufacture_reply->component_vendor_id,
447  tmp = (u8 *)&manufacture_reply->component_id;
448  edev->component_id = tmp[0] << 8 | tmp[1];
449  edev->component_revision_id =
450  manufacture_reply->component_revision_id;
451  }
452  } else
454  "report_manufacture - no reply\n", ioc->name));
455 
456  issue_host_reset:
457  if (issue_reset)
460  out:
461  ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
462  if (data_out)
463  pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
464 
465  mutex_unlock(&ioc->transport_cmds.mutex);
466  return rc;
467 }
468 
476 static void
477 _transport_delete_port(struct MPT2SAS_ADAPTER *ioc,
478  struct _sas_port *mpt2sas_port)
479 {
480  u64 sas_address = mpt2sas_port->remote_identify.sas_address;
482  mpt2sas_port->remote_identify.device_type;
483 
484  dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
485  "remove: sas_addr(0x%016llx)\n",
486  (unsigned long long) sas_address);
487 
489  if (device_type == SAS_END_DEVICE)
490  mpt2sas_device_remove_by_sas_address(ioc, sas_address);
491  else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
492  device_type == SAS_FANOUT_EXPANDER_DEVICE)
493  mpt2sas_expander_remove(ioc, sas_address);
495 }
496 
505 static void
506 _transport_delete_phy(struct MPT2SAS_ADAPTER *ioc,
507  struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy)
508 {
509  u64 sas_address = mpt2sas_port->remote_identify.sas_address;
510 
511  dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
512  "remove: sas_addr(0x%016llx), phy(%d)\n",
513  (unsigned long long) sas_address, mpt2sas_phy->phy_id);
514 
515  list_del(&mpt2sas_phy->port_siblings);
516  mpt2sas_port->num_phys--;
517  sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
518  mpt2sas_phy->phy_belongs_to_port = 0;
519 }
520 
529 static void
530 _transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port,
531  struct _sas_phy *mpt2sas_phy)
532 {
533  u64 sas_address = mpt2sas_port->remote_identify.sas_address;
534 
535  dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
536  "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
537  sas_address, mpt2sas_phy->phy_id);
538 
539  list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list);
540  mpt2sas_port->num_phys++;
541  sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy);
542  mpt2sas_phy->phy_belongs_to_port = 1;
543 }
544 
554 static void
555 _transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
556 struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address)
557 {
558  struct _sas_port *mpt2sas_port;
559  struct _sas_phy *phy_srch;
560 
561  if (mpt2sas_phy->phy_belongs_to_port == 1)
562  return;
563 
564  list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list,
565  port_list) {
566  if (mpt2sas_port->remote_identify.sas_address !=
567  sas_address)
568  continue;
569  list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
570  port_siblings) {
571  if (phy_srch == mpt2sas_phy)
572  return;
573  }
574  _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy);
575  return;
576  }
577 
578 }
579 
588 static void
589 _transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc,
590  struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy)
591 {
592  struct _sas_port *mpt2sas_port, *next;
593  struct _sas_phy *phy_srch;
594 
595  if (mpt2sas_phy->phy_belongs_to_port == 0)
596  return;
597 
598  list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
599  port_list) {
600  list_for_each_entry(phy_srch, &mpt2sas_port->phy_list,
601  port_siblings) {
602  if (phy_srch != mpt2sas_phy)
603  continue;
604  if (mpt2sas_port->num_phys == 1)
605  _transport_delete_port(ioc, mpt2sas_port);
606  else
607  _transport_delete_phy(ioc, mpt2sas_port,
608  mpt2sas_phy);
609  return;
610  }
611  }
612 }
613 
622 static void
623 _transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node,
624  u64 sas_address)
625 {
626  int i;
627 
628  for (i = 0; i < sas_node->num_phys; i++) {
629  if (sas_node->phy[i].remote_identify.sas_address != sas_address)
630  continue;
631  if (sas_node->phy[i].phy_belongs_to_port == 1)
632  _transport_del_phy_from_an_existing_port(ioc, sas_node,
633  &sas_node->phy[i]);
634  }
635 }
636 
648 struct _sas_port *
650  u64 sas_address)
651 {
652  struct _sas_phy *mpt2sas_phy, *next;
653  struct _sas_port *mpt2sas_port;
654  unsigned long flags;
655  struct _sas_node *sas_node;
656  struct sas_rphy *rphy;
657  int i;
658  struct sas_port *port;
659 
660  mpt2sas_port = kzalloc(sizeof(struct _sas_port),
661  GFP_KERNEL);
662  if (!mpt2sas_port) {
663  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
664  ioc->name, __FILE__, __LINE__, __func__);
665  return NULL;
666  }
667 
668  INIT_LIST_HEAD(&mpt2sas_port->port_list);
669  INIT_LIST_HEAD(&mpt2sas_port->phy_list);
670  spin_lock_irqsave(&ioc->sas_node_lock, flags);
671  sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
672  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
673 
674  if (!sas_node) {
675  printk(MPT2SAS_ERR_FMT "%s: Could not find "
676  "parent sas_address(0x%016llx)!\n", ioc->name,
677  __func__, (unsigned long long)sas_address);
678  goto out_fail;
679  }
680 
681  if ((_transport_set_identify(ioc, handle,
682  &mpt2sas_port->remote_identify))) {
683  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
684  ioc->name, __FILE__, __LINE__, __func__);
685  goto out_fail;
686  }
687 
688  if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
689  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
690  ioc->name, __FILE__, __LINE__, __func__);
691  goto out_fail;
692  }
693 
694  _transport_sanity_check(ioc, sas_node,
695  mpt2sas_port->remote_identify.sas_address);
696 
697  for (i = 0; i < sas_node->num_phys; i++) {
698  if (sas_node->phy[i].remote_identify.sas_address !=
699  mpt2sas_port->remote_identify.sas_address)
700  continue;
701  list_add_tail(&sas_node->phy[i].port_siblings,
702  &mpt2sas_port->phy_list);
703  mpt2sas_port->num_phys++;
704  }
705 
706  if (!mpt2sas_port->num_phys) {
707  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
708  ioc->name, __FILE__, __LINE__, __func__);
709  goto out_fail;
710  }
711 
712  port = sas_port_alloc_num(sas_node->parent_dev);
713  if ((sas_port_add(port))) {
714  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
715  ioc->name, __FILE__, __LINE__, __func__);
716  goto out_fail;
717  }
718 
719  list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list,
720  port_siblings) {
721  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
722  dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)"
723  ", sas_addr(0x%016llx), phy(%d)\n", handle,
724  (unsigned long long)
725  mpt2sas_port->remote_identify.sas_address,
726  mpt2sas_phy->phy_id);
727  sas_port_add_phy(port, mpt2sas_phy->phy);
728  mpt2sas_phy->phy_belongs_to_port = 1;
729  }
730 
731  mpt2sas_port->port = port;
732  if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE)
733  rphy = sas_end_device_alloc(port);
734  else
735  rphy = sas_expander_alloc(port,
736  mpt2sas_port->remote_identify.device_type);
737 
738  rphy->identify = mpt2sas_port->remote_identify;
739  if ((sas_rphy_add(rphy))) {
740  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
741  ioc->name, __FILE__, __LINE__, __func__);
742  }
743  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
744  dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
745  "sas_addr(0x%016llx)\n", handle,
746  (unsigned long long)
747  mpt2sas_port->remote_identify.sas_address);
748  mpt2sas_port->rphy = rphy;
749  spin_lock_irqsave(&ioc->sas_node_lock, flags);
750  list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list);
751  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
752 
753  /* fill in report manufacture */
754  if (mpt2sas_port->remote_identify.device_type ==
756  mpt2sas_port->remote_identify.device_type ==
758  _transport_expander_report_manufacture(ioc,
759  mpt2sas_port->remote_identify.sas_address,
761 
762  return mpt2sas_port;
763 
764  out_fail:
765  list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list,
766  port_siblings)
767  list_del(&mpt2sas_phy->port_siblings);
768  kfree(mpt2sas_port);
769  return NULL;
770 }
771 
784 void
786  u64 sas_address_parent)
787 {
788  int i;
789  unsigned long flags;
790  struct _sas_port *mpt2sas_port, *next;
791  struct _sas_node *sas_node;
792  u8 found = 0;
793  struct _sas_phy *mpt2sas_phy, *next_phy;
794 
795  spin_lock_irqsave(&ioc->sas_node_lock, flags);
796  sas_node = _transport_sas_node_find_by_sas_address(ioc,
797  sas_address_parent);
798  if (!sas_node) {
799  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
800  return;
801  }
802  list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list,
803  port_list) {
804  if (mpt2sas_port->remote_identify.sas_address != sas_address)
805  continue;
806  found = 1;
807  list_del(&mpt2sas_port->port_list);
808  goto out;
809  }
810  out:
811  if (!found) {
812  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
813  return;
814  }
815 
816  for (i = 0; i < sas_node->num_phys; i++) {
817  if (sas_node->phy[i].remote_identify.sas_address == sas_address)
818  memset(&sas_node->phy[i].remote_identify, 0 ,
819  sizeof(struct sas_identify));
820  }
821 
822  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
823  list_for_each_entry_safe(mpt2sas_phy, next_phy,
824  &mpt2sas_port->phy_list, port_siblings) {
825  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
826  dev_printk(KERN_INFO, &mpt2sas_port->port->dev,
827  "remove: sas_addr(0x%016llx), phy(%d)\n",
828  (unsigned long long)
829  mpt2sas_port->remote_identify.sas_address,
830  mpt2sas_phy->phy_id);
831  mpt2sas_phy->phy_belongs_to_port = 0;
832  sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy);
833  list_del(&mpt2sas_phy->port_siblings);
834  }
835  sas_port_delete(mpt2sas_port->port);
836  kfree(mpt2sas_port);
837 }
838 
848 int
850  *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
851 {
852  struct sas_phy *phy;
853  int phy_index = mpt2sas_phy->phy_id;
854 
855 
856  INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
857  phy = sas_phy_alloc(parent_dev, phy_index);
858  if (!phy) {
859  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
860  ioc->name, __FILE__, __LINE__, __func__);
861  return -1;
862  }
863  if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
864  &mpt2sas_phy->identify))) {
865  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
866  ioc->name, __FILE__, __LINE__, __func__);
867  return -1;
868  }
869  phy->identify = mpt2sas_phy->identify;
870  mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
871  if (mpt2sas_phy->attached_handle)
872  _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
873  &mpt2sas_phy->remote_identify);
874  phy->identify.phy_identifier = mpt2sas_phy->phy_id;
875  phy->negotiated_linkrate = _transport_convert_phy_link_rate(
877  phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
879  phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
880  phy_pg0.HwLinkRate >> 4);
881  phy->minimum_linkrate = _transport_convert_phy_link_rate(
883  phy->maximum_linkrate = _transport_convert_phy_link_rate(
884  phy_pg0.ProgrammedLinkRate >> 4);
885 
886  if ((sas_phy_add(phy))) {
887  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
888  ioc->name, __FILE__, __LINE__, __func__);
889  sas_phy_free(phy);
890  return -1;
891  }
892  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
893  dev_printk(KERN_INFO, &phy->dev,
894  "add: handle(0x%04x), sas_addr(0x%016llx)\n"
895  "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
896  mpt2sas_phy->handle, (unsigned long long)
897  mpt2sas_phy->identify.sas_address,
898  mpt2sas_phy->attached_handle,
899  (unsigned long long)
900  mpt2sas_phy->remote_identify.sas_address);
901  mpt2sas_phy->phy = phy;
902  return 0;
903 }
904 
905 
915 int
917  *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev)
918 {
919  struct sas_phy *phy;
920  int phy_index = mpt2sas_phy->phy_id;
921 
922  INIT_LIST_HEAD(&mpt2sas_phy->port_siblings);
923  phy = sas_phy_alloc(parent_dev, phy_index);
924  if (!phy) {
925  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
926  ioc->name, __FILE__, __LINE__, __func__);
927  return -1;
928  }
929  if ((_transport_set_identify(ioc, mpt2sas_phy->handle,
930  &mpt2sas_phy->identify))) {
931  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
932  ioc->name, __FILE__, __LINE__, __func__);
933  return -1;
934  }
935  phy->identify = mpt2sas_phy->identify;
936  mpt2sas_phy->attached_handle =
937  le16_to_cpu(expander_pg1.AttachedDevHandle);
938  if (mpt2sas_phy->attached_handle)
939  _transport_set_identify(ioc, mpt2sas_phy->attached_handle,
940  &mpt2sas_phy->remote_identify);
941  phy->identify.phy_identifier = mpt2sas_phy->phy_id;
942  phy->negotiated_linkrate = _transport_convert_phy_link_rate(
943  expander_pg1.NegotiatedLinkRate &
945  phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
947  phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
948  expander_pg1.HwLinkRate >> 4);
949  phy->minimum_linkrate = _transport_convert_phy_link_rate(
951  phy->maximum_linkrate = _transport_convert_phy_link_rate(
952  expander_pg1.ProgrammedLinkRate >> 4);
953 
954  if ((sas_phy_add(phy))) {
955  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
956  ioc->name, __FILE__, __LINE__, __func__);
957  sas_phy_free(phy);
958  return -1;
959  }
960  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
961  dev_printk(KERN_INFO, &phy->dev,
962  "add: handle(0x%04x), sas_addr(0x%016llx)\n"
963  "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
964  mpt2sas_phy->handle, (unsigned long long)
965  mpt2sas_phy->identify.sas_address,
966  mpt2sas_phy->attached_handle,
967  (unsigned long long)
968  mpt2sas_phy->remote_identify.sas_address);
969  mpt2sas_phy->phy = phy;
970  return 0;
971 }
972 
983 void
985  u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
986 {
987  unsigned long flags;
988  struct _sas_node *sas_node;
989  struct _sas_phy *mpt2sas_phy;
990 
991  if (ioc->shost_recovery || ioc->pci_error_recovery)
992  return;
993 
994  spin_lock_irqsave(&ioc->sas_node_lock, flags);
995  sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
996  if (!sas_node) {
997  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
998  return;
999  }
1000 
1001  mpt2sas_phy = &sas_node->phy[phy_number];
1002  mpt2sas_phy->attached_handle = handle;
1003  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1004  if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
1005  _transport_set_identify(ioc, handle,
1006  &mpt2sas_phy->remote_identify);
1007  _transport_add_phy_to_an_existing_port(ioc, sas_node,
1008  mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address);
1009  } else
1010  memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct
1011  sas_identify));
1012 
1013  if (mpt2sas_phy->phy)
1014  mpt2sas_phy->phy->negotiated_linkrate =
1015  _transport_convert_phy_link_rate(link_rate);
1016 
1017  if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
1018  dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev,
1019  "refresh: parent sas_addr(0x%016llx),\n"
1020  "\tlink_rate(0x%02x), phy(%d)\n"
1021  "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1022  (unsigned long long)sas_address,
1023  link_rate, phy_number, handle, (unsigned long long)
1024  mpt2sas_phy->remote_identify.sas_address);
1025 }
1026 
1027 static inline void *
1028 phy_to_ioc(struct sas_phy *phy)
1029 {
1030  struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1031  return shost_priv(shost);
1032 }
1033 
1034 static inline void *
1035 rphy_to_ioc(struct sas_rphy *rphy)
1036 {
1037  struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
1038  return shost_priv(shost);
1039 }
1040 
1041 
1042 /* report phy error log structure */
1044  u8 smp_frame_type; /* 0x40 */
1045  u8 function; /* 0x11 */
1047  u8 request_length; /* 02 */
1051 };
1052 
1053 /* report phy error log reply structure */
1055  u8 smp_frame_type; /* 0x41 */
1056  u8 function; /* 0x11 */
1067 };
1068 
1077 static int
1078 _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc,
1079  struct sas_phy *phy)
1080 {
1081  Mpi2SmpPassthroughRequest_t *mpi_request;
1082  Mpi2SmpPassthroughReply_t *mpi_reply;
1085  int rc;
1086  u16 smid;
1087  u32 ioc_state;
1088  unsigned long timeleft;
1089  void *psge;
1090  u32 sgl_flags;
1091  u8 issue_reset = 0;
1092  void *data_out = NULL;
1093  dma_addr_t data_out_dma;
1094  u32 sz;
1095  u16 wait_state_count;
1096 
1097  if (ioc->shost_recovery || ioc->pci_error_recovery) {
1098  printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1099  __func__, ioc->name);
1100  return -EFAULT;
1101  }
1102 
1103  mutex_lock(&ioc->transport_cmds.mutex);
1104 
1105  if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1106  printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1107  ioc->name, __func__);
1108  rc = -EAGAIN;
1109  goto out;
1110  }
1111  ioc->transport_cmds.status = MPT2_CMD_PENDING;
1112 
1113  wait_state_count = 0;
1114  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1115  while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1116  if (wait_state_count++ == 10) {
1118  "%s: failed due to ioc not operational\n",
1119  ioc->name, __func__);
1120  rc = -EFAULT;
1121  goto out;
1122  }
1123  ssleep(1);
1124  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1125  printk(MPT2SAS_INFO_FMT "%s: waiting for "
1126  "operational state(count=%d)\n", ioc->name,
1127  __func__, wait_state_count);
1128  }
1129  if (wait_state_count)
1130  printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1131  ioc->name, __func__);
1132 
1133  smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1134  if (!smid) {
1135  printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1136  ioc->name, __func__);
1137  rc = -EAGAIN;
1138  goto out;
1139  }
1140 
1141  mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1142  ioc->transport_cmds.smid = smid;
1143 
1144  sz = sizeof(struct phy_error_log_request) +
1145  sizeof(struct phy_error_log_reply);
1146  data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1147  if (!data_out) {
1148  printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1149  __LINE__, __func__);
1150  rc = -ENOMEM;
1151  mpt2sas_base_free_smid(ioc, smid);
1152  goto out;
1153  }
1154 
1155  rc = -EINVAL;
1156  memset(data_out, 0, sz);
1157  phy_error_log_request = data_out;
1158  phy_error_log_request->smp_frame_type = 0x40;
1159  phy_error_log_request->function = 0x11;
1160  phy_error_log_request->request_length = 2;
1161  phy_error_log_request->allocated_response_length = 0;
1162  phy_error_log_request->phy_identifier = phy->number;
1163 
1164  memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1165  mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1166  mpi_request->PhysicalPort = 0xFF;
1167  mpi_request->VF_ID = 0; /* TODO */
1168  mpi_request->VP_ID = 0;
1169  mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1170  mpi_request->RequestDataLength =
1171  cpu_to_le16(sizeof(struct phy_error_log_request));
1172  psge = &mpi_request->SGL;
1173 
1174  /* WRITE sgel first */
1175  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1177  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1178  ioc->base_add_sg_single(psge, sgl_flags |
1179  sizeof(struct phy_error_log_request), data_out_dma);
1180 
1181  /* incr sgel */
1182  psge += ioc->sge_size;
1183 
1184  /* READ sgel last */
1185  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1188  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1189  ioc->base_add_sg_single(psge, sgl_flags |
1190  sizeof(struct phy_error_log_reply), data_out_dma +
1191  sizeof(struct phy_error_log_request));
1192 
1193  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1194  "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name,
1195  (unsigned long long)phy->identify.sas_address, phy->number));
1196  init_completion(&ioc->transport_cmds.done);
1197  mpt2sas_base_put_smid_default(ioc, smid);
1198  timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1199  10*HZ);
1200 
1201  if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1202  printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1203  ioc->name, __func__);
1204  _debug_dump_mf(mpi_request,
1205  sizeof(Mpi2SmpPassthroughRequest_t)/4);
1206  if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1207  issue_reset = 1;
1208  goto issue_host_reset;
1209  }
1210 
1211  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - "
1212  "complete\n", ioc->name));
1213 
1214  if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1215 
1216  mpi_reply = ioc->transport_cmds.reply;
1217 
1219  "phy_error_log - reply data transfer size(%d)\n",
1220  ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1221 
1222  if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1223  sizeof(struct phy_error_log_reply))
1224  goto out;
1225 
1226  phy_error_log_reply = data_out +
1227  sizeof(struct phy_error_log_request);
1228 
1230  "phy_error_log - function_result(%d)\n",
1231  ioc->name, phy_error_log_reply->function_result));
1232 
1233  phy->invalid_dword_count =
1234  be32_to_cpu(phy_error_log_reply->invalid_dword);
1236  be32_to_cpu(phy_error_log_reply->running_disparity_error);
1238  be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1240  be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1241  rc = 0;
1242  } else
1244  "phy_error_log - no reply\n", ioc->name));
1245 
1246  issue_host_reset:
1247  if (issue_reset)
1250  out:
1251  ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1252  if (data_out)
1253  pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1254 
1255  mutex_unlock(&ioc->transport_cmds.mutex);
1256  return rc;
1257 }
1258 
1266 static int
1267 _transport_get_linkerrors(struct sas_phy *phy)
1268 {
1269  struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1270  unsigned long flags;
1271  Mpi2ConfigReply_t mpi_reply;
1272  Mpi2SasPhyPage1_t phy_pg1;
1273 
1274  spin_lock_irqsave(&ioc->sas_node_lock, flags);
1275  if (_transport_sas_node_find_by_sas_address(ioc,
1276  phy->identify.sas_address) == NULL) {
1277  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1278  return -EINVAL;
1279  }
1280  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1281 
1282  if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1283  return _transport_get_expander_phy_error_log(ioc, phy);
1284 
1285  /* get hba phy error logs */
1286  if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
1287  phy->number))) {
1288  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1289  ioc->name, __FILE__, __LINE__, __func__);
1290  return -ENXIO;
1291  }
1292 
1293  if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1294  printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1295  "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1296  phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1297  le32_to_cpu(mpi_reply.IOCLogInfo));
1298 
1306  return 0;
1307 }
1308 
1316 static int
1317 _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1318 {
1319  struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1320  struct _sas_device *sas_device;
1321  unsigned long flags;
1322  int rc;
1323 
1324  spin_lock_irqsave(&ioc->sas_device_lock, flags);
1326  rphy->identify.sas_address);
1327  if (sas_device) {
1328  *identifier = sas_device->enclosure_logical_id;
1329  rc = 0;
1330  } else {
1331  *identifier = 0;
1332  rc = -ENXIO;
1333  }
1334  spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1335  return rc;
1336 }
1337 
1344 static int
1345 _transport_get_bay_identifier(struct sas_rphy *rphy)
1346 {
1347  struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1348  struct _sas_device *sas_device;
1349  unsigned long flags;
1350  int rc;
1351 
1352  spin_lock_irqsave(&ioc->sas_device_lock, flags);
1354  rphy->identify.sas_address);
1355  if (sas_device)
1356  rc = sas_device->slot;
1357  else
1358  rc = -ENXIO;
1359  spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1360  return rc;
1361 }
1362 
1363 /* phy control request structure */
1365  u8 smp_frame_type; /* 0x40 */
1366  u8 function; /* 0x91 */
1368  u8 request_length; /* 0x09 */
1378 };
1379 
1380 /* phy control reply structure */
1382  u8 smp_frame_type; /* 0x41 */
1383  u8 function; /* 0x11 */
1386 };
1387 
1388 #define SMP_PHY_CONTROL_LINK_RESET (0x01)
1389 #define SMP_PHY_CONTROL_HARD_RESET (0x02)
1390 #define SMP_PHY_CONTROL_DISABLE (0x03)
1391 
1400 static int
1401 _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc,
1402  struct sas_phy *phy, u8 phy_operation)
1403 {
1404  Mpi2SmpPassthroughRequest_t *mpi_request;
1405  Mpi2SmpPassthroughReply_t *mpi_reply;
1408  int rc;
1409  u16 smid;
1410  u32 ioc_state;
1411  unsigned long timeleft;
1412  void *psge;
1413  u32 sgl_flags;
1414  u8 issue_reset = 0;
1415  void *data_out = NULL;
1416  dma_addr_t data_out_dma;
1417  u32 sz;
1418  u16 wait_state_count;
1419 
1420  if (ioc->shost_recovery) {
1421  printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1422  __func__, ioc->name);
1423  return -EFAULT;
1424  }
1425 
1426  mutex_lock(&ioc->transport_cmds.mutex);
1427 
1428  if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1429  printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n",
1430  ioc->name, __func__);
1431  rc = -EAGAIN;
1432  goto out;
1433  }
1434  ioc->transport_cmds.status = MPT2_CMD_PENDING;
1435 
1436  wait_state_count = 0;
1437  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1438  while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1439  if (wait_state_count++ == 10) {
1441  "%s: failed due to ioc not operational\n",
1442  ioc->name, __func__);
1443  rc = -EFAULT;
1444  goto out;
1445  }
1446  ssleep(1);
1447  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1448  printk(MPT2SAS_INFO_FMT "%s: waiting for "
1449  "operational state(count=%d)\n", ioc->name,
1450  __func__, wait_state_count);
1451  }
1452  if (wait_state_count)
1453  printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1454  ioc->name, __func__);
1455 
1456  smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1457  if (!smid) {
1458  printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1459  ioc->name, __func__);
1460  rc = -EAGAIN;
1461  goto out;
1462  }
1463 
1464  mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1465  ioc->transport_cmds.smid = smid;
1466 
1467  sz = sizeof(struct phy_control_request) +
1468  sizeof(struct phy_control_reply);
1469  data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1470  if (!data_out) {
1471  printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
1472  __LINE__, __func__);
1473  rc = -ENOMEM;
1474  mpt2sas_base_free_smid(ioc, smid);
1475  goto out;
1476  }
1477 
1478  rc = -EINVAL;
1479  memset(data_out, 0, sz);
1480  phy_control_request = data_out;
1481  phy_control_request->smp_frame_type = 0x40;
1482  phy_control_request->function = 0x91;
1483  phy_control_request->request_length = 9;
1484  phy_control_request->allocated_response_length = 0;
1485  phy_control_request->phy_identifier = phy->number;
1486  phy_control_request->phy_operation = phy_operation;
1487  phy_control_request->programmed_min_physical_link_rate =
1488  phy->minimum_linkrate << 4;
1489  phy_control_request->programmed_max_physical_link_rate =
1490  phy->maximum_linkrate << 4;
1491 
1492  memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1493  mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1494  mpi_request->PhysicalPort = 0xFF;
1495  mpi_request->VF_ID = 0; /* TODO */
1496  mpi_request->VP_ID = 0;
1497  mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1498  mpi_request->RequestDataLength =
1499  cpu_to_le16(sizeof(struct phy_error_log_request));
1500  psge = &mpi_request->SGL;
1501 
1502  /* WRITE sgel first */
1503  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1505  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1506  ioc->base_add_sg_single(psge, sgl_flags |
1507  sizeof(struct phy_control_request), data_out_dma);
1508 
1509  /* incr sgel */
1510  psge += ioc->sge_size;
1511 
1512  /* READ sgel last */
1513  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1516  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1517  ioc->base_add_sg_single(psge, sgl_flags |
1518  sizeof(struct phy_control_reply), data_out_dma +
1519  sizeof(struct phy_control_request));
1520 
1521  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1522  "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name,
1523  (unsigned long long)phy->identify.sas_address, phy->number,
1524  phy_operation));
1525 
1526  init_completion(&ioc->transport_cmds.done);
1527  mpt2sas_base_put_smid_default(ioc, smid);
1528  timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1529  10*HZ);
1530 
1531  if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1532  printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1533  ioc->name, __func__);
1534  _debug_dump_mf(mpi_request,
1535  sizeof(Mpi2SmpPassthroughRequest_t)/4);
1536  if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1537  issue_reset = 1;
1538  goto issue_host_reset;
1539  }
1540 
1541  dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1542  "complete\n", ioc->name));
1543 
1544  if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1545 
1546  mpi_reply = ioc->transport_cmds.reply;
1547 
1549  "phy_control - reply data transfer size(%d)\n",
1550  ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1551 
1552  if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1553  sizeof(struct phy_control_reply))
1554  goto out;
1555 
1556  phy_control_reply = data_out +
1557  sizeof(struct phy_control_request);
1558 
1560  "phy_control - function_result(%d)\n",
1561  ioc->name, phy_control_reply->function_result));
1562 
1563  rc = 0;
1564  } else
1566  "phy_control - no reply\n", ioc->name));
1567 
1568  issue_host_reset:
1569  if (issue_reset)
1572  out:
1573  ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1574  if (data_out)
1575  pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1576 
1577  mutex_unlock(&ioc->transport_cmds.mutex);
1578  return rc;
1579 }
1580 
1588 static int
1589 _transport_phy_reset(struct sas_phy *phy, int hard_reset)
1590 {
1591  struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1592  Mpi2SasIoUnitControlReply_t mpi_reply;
1593  Mpi2SasIoUnitControlRequest_t mpi_request;
1594  unsigned long flags;
1595 
1596  spin_lock_irqsave(&ioc->sas_node_lock, flags);
1597  if (_transport_sas_node_find_by_sas_address(ioc,
1598  phy->identify.sas_address) == NULL) {
1599  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1600  return -EINVAL;
1601  }
1602  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1603 
1604  /* handle expander phys */
1605  if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1606  return _transport_expander_phy_control(ioc, phy,
1607  (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1609 
1610  /* handle hba phys */
1611  memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
1613  mpi_request.Operation = hard_reset ?
1615  mpi_request.PhyNum = phy->number;
1616 
1617  if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
1618  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1619  ioc->name, __FILE__, __LINE__, __func__);
1620  return -ENXIO;
1621  }
1622 
1623  if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1624  printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1625  "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1626  phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1627  le32_to_cpu(mpi_reply.IOCLogInfo));
1628 
1629  return 0;
1630 }
1631 
1640 static int
1641 _transport_phy_enable(struct sas_phy *phy, int enable)
1642 {
1643  struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1644  Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1645  Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
1646  Mpi2ConfigReply_t mpi_reply;
1647  u16 ioc_status;
1648  u16 sz;
1649  int rc = 0;
1650  unsigned long flags;
1651  int i, discovery_active;
1652 
1653  spin_lock_irqsave(&ioc->sas_node_lock, flags);
1654  if (_transport_sas_node_find_by_sas_address(ioc,
1655  phy->identify.sas_address) == NULL) {
1656  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1657  return -EINVAL;
1658  }
1659  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1660 
1661  /* handle expander phys */
1662  if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1663  return _transport_expander_phy_control(ioc, phy,
1664  (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1666 
1667  /* handle hba phys */
1668 
1669  /* read sas_iounit page 0 */
1670  sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
1671  sizeof(Mpi2SasIOUnit0PhyData_t));
1672  sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
1673  if (!sas_iounit_pg0) {
1674  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1675  ioc->name, __FILE__, __LINE__, __func__);
1676  rc = -ENOMEM;
1677  goto out;
1678  }
1679  if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
1680  sas_iounit_pg0, sz))) {
1681  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1682  ioc->name, __FILE__, __LINE__, __func__);
1683  rc = -ENXIO;
1684  goto out;
1685  }
1686  ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1688  if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1689  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1690  ioc->name, __FILE__, __LINE__, __func__);
1691  rc = -EIO;
1692  goto out;
1693  }
1694 
1695  /* unable to enable/disable phys when when discovery is active */
1696  for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
1697  if (sas_iounit_pg0->PhyData[i].PortFlags &
1699  printk(MPT2SAS_ERR_FMT "discovery is active on "
1700  "port = %d, phy = %d: unable to enable/disable "
1701  "phys, try again later!\n", ioc->name,
1702  sas_iounit_pg0->PhyData[i].Port, i);
1703  discovery_active = 1;
1704  }
1705  }
1706 
1707  if (discovery_active) {
1708  rc = -EAGAIN;
1709  goto out;
1710  }
1711 
1712  /* read sas_iounit page 1 */
1713  sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1714  sizeof(Mpi2SasIOUnit1PhyData_t));
1715  sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1716  if (!sas_iounit_pg1) {
1717  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1718  ioc->name, __FILE__, __LINE__, __func__);
1719  rc = -ENOMEM;
1720  goto out;
1721  }
1722  if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1723  sas_iounit_pg1, sz))) {
1724  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1725  ioc->name, __FILE__, __LINE__, __func__);
1726  rc = -ENXIO;
1727  goto out;
1728  }
1729  ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1731  if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1732  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1733  ioc->name, __FILE__, __LINE__, __func__);
1734  rc = -EIO;
1735  goto out;
1736  }
1737  /* copy Port/PortFlags/PhyFlags from page 0 */
1738  for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
1739  sas_iounit_pg1->PhyData[i].Port =
1740  sas_iounit_pg0->PhyData[i].Port;
1741  sas_iounit_pg1->PhyData[i].PortFlags =
1742  (sas_iounit_pg0->PhyData[i].PortFlags &
1744  sas_iounit_pg1->PhyData[i].PhyFlags =
1745  (sas_iounit_pg0->PhyData[i].PhyFlags &
1748  }
1749  if (enable)
1750  sas_iounit_pg1->PhyData[phy->number].PhyFlags
1752  else
1753  sas_iounit_pg1->PhyData[phy->number].PhyFlags
1755 
1756  mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1757 
1758  /* link reset */
1759  if (enable)
1760  _transport_phy_reset(phy, 0);
1761 
1762  out:
1763  kfree(sas_iounit_pg1);
1764  kfree(sas_iounit_pg0);
1765  return rc;
1766 }
1767 
1776 static int
1777 _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1778 {
1779  struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1780  Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1781  Mpi2SasPhyPage0_t phy_pg0;
1782  Mpi2ConfigReply_t mpi_reply;
1783  u16 ioc_status;
1784  u16 sz;
1785  int i;
1786  int rc = 0;
1787  unsigned long flags;
1788 
1789  spin_lock_irqsave(&ioc->sas_node_lock, flags);
1790  if (_transport_sas_node_find_by_sas_address(ioc,
1791  phy->identify.sas_address) == NULL) {
1792  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1793  return -EINVAL;
1794  }
1795  spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1796 
1797  if (!rates->minimum_linkrate)
1798  rates->minimum_linkrate = phy->minimum_linkrate;
1799  else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1800  rates->minimum_linkrate = phy->minimum_linkrate_hw;
1801 
1802  if (!rates->maximum_linkrate)
1803  rates->maximum_linkrate = phy->maximum_linkrate;
1804  else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1805  rates->maximum_linkrate = phy->maximum_linkrate_hw;
1806 
1807  /* handle expander phys */
1808  if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1809  phy->minimum_linkrate = rates->minimum_linkrate;
1810  phy->maximum_linkrate = rates->maximum_linkrate;
1811  return _transport_expander_phy_control(ioc, phy,
1813  }
1814 
1815  /* handle hba phys */
1816 
1817  /* sas_iounit page 1 */
1818  sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1819  sizeof(Mpi2SasIOUnit1PhyData_t));
1820  sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1821  if (!sas_iounit_pg1) {
1822  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1823  ioc->name, __FILE__, __LINE__, __func__);
1824  rc = -ENOMEM;
1825  goto out;
1826  }
1827  if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1828  sas_iounit_pg1, sz))) {
1829  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1830  ioc->name, __FILE__, __LINE__, __func__);
1831  rc = -ENXIO;
1832  goto out;
1833  }
1834  ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1836  if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1837  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1838  ioc->name, __FILE__, __LINE__, __func__);
1839  rc = -EIO;
1840  goto out;
1841  }
1842 
1843  for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1844  if (phy->number != i) {
1845  sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1846  (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1847  (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1848  } else {
1849  sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1850  (rates->minimum_linkrate +
1851  (rates->maximum_linkrate << 4));
1852  }
1853  }
1854 
1855  if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1856  sz)) {
1857  printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1858  ioc->name, __FILE__, __LINE__, __func__);
1859  rc = -ENXIO;
1860  goto out;
1861  }
1862 
1863  /* link reset */
1864  _transport_phy_reset(phy, 0);
1865 
1866  /* read phy page 0, then update the rates in the sas transport phy */
1867  if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1868  phy->number)) {
1869  phy->minimum_linkrate = _transport_convert_phy_link_rate(
1871  phy->maximum_linkrate = _transport_convert_phy_link_rate(
1872  phy_pg0.ProgrammedLinkRate >> 4);
1873  phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1874  phy_pg0.NegotiatedLinkRate &
1876  }
1877 
1878  out:
1879  kfree(sas_iounit_pg1);
1880  return rc;
1881 }
1882 
1883 
1894 static int
1895 _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1896  struct request *req)
1897 {
1898  struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1899  Mpi2SmpPassthroughRequest_t *mpi_request;
1900  Mpi2SmpPassthroughReply_t *mpi_reply;
1901  int rc, i;
1902  u16 smid;
1903  u32 ioc_state;
1904  unsigned long timeleft;
1905  void *psge;
1906  u32 sgl_flags;
1907  u8 issue_reset = 0;
1908  dma_addr_t dma_addr_in = 0;
1909  dma_addr_t dma_addr_out = 0;
1910  dma_addr_t pci_dma_in = 0;
1911  dma_addr_t pci_dma_out = 0;
1912  void *pci_addr_in = NULL;
1913  void *pci_addr_out = NULL;
1914  u16 wait_state_count;
1915  struct request *rsp = req->next_rq;
1916  struct bio_vec *bvec = NULL;
1917 
1918  if (!rsp) {
1919  printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
1920  "missing\n", ioc->name, __func__);
1921  return -EINVAL;
1922  }
1923  if (ioc->shost_recovery || ioc->pci_error_recovery) {
1924  printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1925  __func__, ioc->name);
1926  return -EFAULT;
1927  }
1928 
1929  rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1930  if (rc)
1931  return rc;
1932 
1933  if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1934  printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
1935  __func__);
1936  rc = -EAGAIN;
1937  goto out;
1938  }
1939  ioc->transport_cmds.status = MPT2_CMD_PENDING;
1940 
1941  /* Check if the request is split across multiple segments */
1942  if (req->bio->bi_vcnt > 1) {
1943  u32 offset = 0;
1944 
1945  /* Allocate memory and copy the request */
1946  pci_addr_out = pci_alloc_consistent(ioc->pdev,
1947  blk_rq_bytes(req), &pci_dma_out);
1948  if (!pci_addr_out) {
1949  printk(MPT2SAS_INFO_FMT "%s(): PCI Addr out = NULL\n",
1950  ioc->name, __func__);
1951  rc = -ENOMEM;
1952  goto out;
1953  }
1954 
1955  bio_for_each_segment(bvec, req->bio, i) {
1956  memcpy(pci_addr_out + offset,
1957  page_address(bvec->bv_page) + bvec->bv_offset,
1958  bvec->bv_len);
1959  offset += bvec->bv_len;
1960  }
1961  } else {
1962  dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1963  blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
1964  if (!dma_addr_out) {
1965  printk(MPT2SAS_INFO_FMT "%s(): DMA Addr out = NULL\n",
1966  ioc->name, __func__);
1967  rc = -ENOMEM;
1968  goto free_pci;
1969  }
1970  }
1971 
1972  /* Check if the response needs to be populated across
1973  * multiple segments */
1974  if (rsp->bio->bi_vcnt > 1) {
1975  pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
1976  &pci_dma_in);
1977  if (!pci_addr_in) {
1978  printk(MPT2SAS_INFO_FMT "%s(): PCI Addr in = NULL\n",
1979  ioc->name, __func__);
1980  rc = -ENOMEM;
1981  goto unmap;
1982  }
1983  } else {
1984  dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
1985  blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
1986  if (!dma_addr_in) {
1987  printk(MPT2SAS_INFO_FMT "%s(): DMA Addr in = NULL\n",
1988  ioc->name, __func__);
1989  rc = -ENOMEM;
1990  goto unmap;
1991  }
1992  }
1993 
1994  wait_state_count = 0;
1995  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1996  while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1997  if (wait_state_count++ == 10) {
1999  "%s: failed due to ioc not operational\n",
2000  ioc->name, __func__);
2001  rc = -EFAULT;
2002  goto unmap;
2003  }
2004  ssleep(1);
2005  ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2006  printk(MPT2SAS_INFO_FMT "%s: waiting for "
2007  "operational state(count=%d)\n", ioc->name,
2008  __func__, wait_state_count);
2009  }
2010  if (wait_state_count)
2011  printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
2012  ioc->name, __func__);
2013 
2014  smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
2015  if (!smid) {
2016  printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2017  ioc->name, __func__);
2018  rc = -EAGAIN;
2019  goto unmap;
2020  }
2021 
2022  rc = 0;
2023  mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2024  ioc->transport_cmds.smid = smid;
2025 
2026  memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
2027  mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
2028  mpi_request->PhysicalPort = 0xFF;
2029  mpi_request->VF_ID = 0; /* TODO */
2030  mpi_request->VP_ID = 0;
2031  mpi_request->SASAddress = (rphy) ?
2032  cpu_to_le64(rphy->identify.sas_address) :
2033  cpu_to_le64(ioc->sas_hba.sas_address);
2034  mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2035  psge = &mpi_request->SGL;
2036 
2037  /* WRITE sgel first */
2038  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2040  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2041  if (req->bio->bi_vcnt > 1) {
2042  ioc->base_add_sg_single(psge, sgl_flags |
2043  (blk_rq_bytes(req) - 4), pci_dma_out);
2044  } else {
2045  ioc->base_add_sg_single(psge, sgl_flags |
2046  (blk_rq_bytes(req) - 4), dma_addr_out);
2047  }
2048 
2049  /* incr sgel */
2050  psge += ioc->sge_size;
2051 
2052  /* READ sgel last */
2053  sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2056  sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2057  if (rsp->bio->bi_vcnt > 1) {
2058  ioc->base_add_sg_single(psge, sgl_flags |
2059  (blk_rq_bytes(rsp) + 4), pci_dma_in);
2060  } else {
2061  ioc->base_add_sg_single(psge, sgl_flags |
2062  (blk_rq_bytes(rsp) + 4), dma_addr_in);
2063  }
2064 
2066  "sending smp request\n", ioc->name, __func__));
2067 
2068  init_completion(&ioc->transport_cmds.done);
2069  mpt2sas_base_put_smid_default(ioc, smid);
2070  timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
2071  10*HZ);
2072 
2073  if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
2074  printk(MPT2SAS_ERR_FMT "%s : timeout\n",
2075  __func__, ioc->name);
2076  _debug_dump_mf(mpi_request,
2077  sizeof(Mpi2SmpPassthroughRequest_t)/4);
2078  if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
2079  issue_reset = 1;
2080  goto issue_host_reset;
2081  }
2082 
2084  "complete\n", ioc->name, __func__));
2085 
2086  if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
2087 
2088  mpi_reply = ioc->transport_cmds.reply;
2089 
2091  "%s - reply data transfer size(%d)\n",
2092  ioc->name, __func__,
2093  le16_to_cpu(mpi_reply->ResponseDataLength)));
2094 
2095  memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
2096  req->sense_len = sizeof(*mpi_reply);
2097  req->resid_len = 0;
2098  rsp->resid_len -=
2099  le16_to_cpu(mpi_reply->ResponseDataLength);
2100  /* check if the resp needs to be copied from the allocated
2101  * pci mem */
2102  if (rsp->bio->bi_vcnt > 1) {
2103  u32 offset = 0;
2104  u32 bytes_to_copy =
2105  le16_to_cpu(mpi_reply->ResponseDataLength);
2106  bio_for_each_segment(bvec, rsp->bio, i) {
2107  if (bytes_to_copy <= bvec->bv_len) {
2108  memcpy(page_address(bvec->bv_page) +
2109  bvec->bv_offset, pci_addr_in +
2110  offset, bytes_to_copy);
2111  break;
2112  } else {
2113  memcpy(page_address(bvec->bv_page) +
2114  bvec->bv_offset, pci_addr_in +
2115  offset, bvec->bv_len);
2116  bytes_to_copy -= bvec->bv_len;
2117  }
2118  offset += bvec->bv_len;
2119  }
2120  }
2121  } else {
2123  "%s - no reply\n", ioc->name, __func__));
2124  rc = -ENXIO;
2125  }
2126 
2127  issue_host_reset:
2128  if (issue_reset) {
2131  rc = -ETIMEDOUT;
2132  }
2133 
2134  unmap:
2135  if (dma_addr_out)
2136  pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
2138  if (dma_addr_in)
2139  pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
2141 
2142  free_pci:
2143  if (pci_addr_out)
2144  pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out,
2145  pci_dma_out);
2146 
2147  if (pci_addr_in)
2148  pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in,
2149  pci_dma_in);
2150 
2151  out:
2152  ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
2153  mutex_unlock(&ioc->transport_cmds.mutex);
2154  return rc;
2155 }
2156 
2158  .get_linkerrors = _transport_get_linkerrors,
2159  .get_enclosure_identifier = _transport_get_enclosure_identifier,
2160  .get_bay_identifier = _transport_get_bay_identifier,
2161  .phy_reset = _transport_phy_reset,
2162  .phy_enable = _transport_phy_enable,
2163  .set_phy_speed = _transport_phy_speed,
2164  .smp_handler = _transport_smp_handler,
2165 };
2166