e689bf20a3ea541b93f94cb50cc900e5ade3a751
[cascardo/linux.git] / drivers / scsi / mpt2sas / mpt2sas_transport.c
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-2014  LSI Corporation
6  *  (mailto:DL-MPTFusionLinux@lsi.com)
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>
58 #include <scsi/scsi_transport_sas.h>
59 #include <scsi/scsi_dbg.h>
60
61 #include "mpt2sas_base.h"
62 /**
63  * _transport_sas_node_find_by_sas_address - sas node search
64  * @ioc: per adapter object
65  * @sas_address: sas address of expander or sas host
66  * Context: Calling function should acquire ioc->sas_node_lock.
67  *
68  * Search for either hba phys or expander device based on handle, then returns
69  * the sas_node object.
70  */
71 static 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  * _transport_convert_phy_link_rate -
84  * @link_rate: link rate returned from mpt firmware
85  *
86  * Convert link_rate from mpi fusion into sas_transport form.
87  */
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) {
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  * _transport_set_identify - set identify for phys and end devices
126  * @ioc: per adapter object
127  * @handle: device handle
128  * @identify: sas identify info
129  *
130  * Populates sas identify info.
131  *
132  * Returns 0 for success, non-zero for failure.
133  */
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;
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(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) {
177         case MPI2_SAS_DEVICE_INFO_NO_DEVICE:
178                 identify->device_type = SAS_PHY_UNUSED;
179                 break;
180         case MPI2_SAS_DEVICE_INFO_END_DEVICE:
181                 identify->device_type = SAS_END_DEVICE;
182                 break;
183         case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER:
184                 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
185                 break;
186         case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER:
187                 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
188                 break;
189         }
190
191         /* initiator_port_protocols */
192         if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR)
193                 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
194         if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR)
195                 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
196         if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR)
197                 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
198         if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST)
199                 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
200
201         /* target_port_protocols */
202         if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)
203                 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
204         if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET)
205                 identify->target_port_protocols |= SAS_PROTOCOL_STP;
206         if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET)
207                 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
208         if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)
209                 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
210
211         return 0;
212 }
213
214 /**
215  * mpt2sas_transport_done -  internal transport layer callback handler.
216  * @ioc: per adapter object
217  * @smid: system request message index
218  * @msix_index: MSIX table index supplied by the OS
219  * @reply: reply message frame(lower 32bit addr)
220  *
221  * Callback handler when sending internal generated transport cmds.
222  * The callback index passed is `ioc->transport_cb_idx`
223  *
224  * Return 1 meaning mf should be freed from _base_interrupt
225  *        0 means the mf is freed from this function.
226  */
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{
251         u8 smp_frame_type;
252         u8 function;
253         u8 reserved;
254         u8 request_length;
255 };
256
257 /* report manufacture reply structure */
258 struct rep_manu_reply{
259         u8 smp_frame_type; /* 0x41 */
260         u8 function; /* 0x01 */
261         u8 function_result;
262         u8 response_length;
263         u16 expander_change_count;
264         u8 reserved0[2];
265         u8 sas_format;
266         u8 reserved2[3];
267         u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
268         u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
269         u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
270         u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
271         u16 component_id;
272         u8 component_revision_id;
273         u8 reserved3;
274         u8 vendor_specific[8];
275 };
276
277 /**
278  * _transport_expander_report_manufacture - obtain SMP report_manufacture
279  * @ioc: per adapter object
280  * @sas_address: expander sas address
281  * @edev: the sas_expander_device object
282  *
283  * Fills in the sas_expander_device object when SMP port is created.
284  *
285  * Returns 0 for success, non-zero for failure.
286  */
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) {
327                         printk(MPT2SAS_ERR_FMT
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));
373         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
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 |
384             MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
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 |
394             MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
395             MPI2_SGE_FLAGS_END_OF_LIST);
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);
405         mpt2sas_base_put_smid_default(ioc, smid);
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
427                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
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,
437                      SAS_EXPANDER_VENDOR_ID_LEN);
438                 strncpy(edev->product_id, manufacture_reply->product_id,
439                      SAS_EXPANDER_PRODUCT_ID_LEN);
440                 strncpy(edev->product_rev, manufacture_reply->product_rev,
441                      SAS_EXPANDER_PRODUCT_REV_LEN);
442                 edev->level = manufacture_reply->sas_format & 1;
443                 if (edev->level) {
444                         strncpy(edev->component_vendor_id,
445                             manufacture_reply->component_vendor_id,
446                              SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
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
453                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
454                     "report_manufacture - no reply\n", ioc->name));
455
456  issue_host_reset:
457         if (issue_reset)
458                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
459                     FORCE_BIG_HAMMER);
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
469 /**
470  * _transport_delete_port - helper function to removing a port
471  * @ioc: per adapter object
472  * @mpt2sas_port: mpt2sas per port object
473  *
474  * Returns nothing.
475  */
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;
481         enum sas_device_type device_type =
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
488         ioc->logging_level |= MPT_DEBUG_TRANSPORT;
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);
494         ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
495 }
496
497 /**
498  * _transport_delete_phy - helper function to removing single phy from port
499  * @ioc: per adapter object
500  * @mpt2sas_port: mpt2sas per port object
501  * @mpt2sas_phy: mpt2sas per phy object
502  *
503  * Returns nothing.
504  */
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
521 /**
522  * _transport_add_phy - helper function to adding single phy to port
523  * @ioc: per adapter object
524  * @mpt2sas_port: mpt2sas per port object
525  * @mpt2sas_phy: mpt2sas per phy object
526  *
527  * Returns nothing.
528  */
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
545 /**
546  * _transport_add_phy_to_an_existing_port - adding new phy to existing port
547  * @ioc: per adapter object
548  * @sas_node: sas node object (either expander or sas host)
549  * @mpt2sas_phy: mpt2sas per phy object
550  * @sas_address: sas address of device/expander were phy needs to be added to
551  *
552  * Returns nothing.
553  */
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
580 /**
581  * _transport_del_phy_from_an_existing_port - delete phy from existing port
582  * @ioc: per adapter object
583  * @sas_node: sas node object (either expander or sas host)
584  * @mpt2sas_phy: mpt2sas per phy object
585  *
586  * Returns nothing.
587  */
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
614 /**
615  * _transport_sanity_check - sanity check when adding a new port
616  * @ioc: per adapter object
617  * @sas_node: sas node object (either expander or sas host)
618  * @sas_address: sas address of device being added
619  *
620  * See the explanation above from _transport_delete_duplicate_port
621  */
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
637 /**
638  * mpt2sas_transport_port_add - insert port to the list
639  * @ioc: per adapter object
640  * @handle: handle of attached device
641  * @sas_address: sas address of parent expander or sas host
642  * Context: This function will acquire ioc->sas_node_lock.
643  *
644  * Adding new port object to the sas_node->sas_port_list.
645  *
646  * Returns mpt2sas_port.
647  */
648 struct _sas_port *
649 mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle,
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 ==
755             MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
756             mpt2sas_port->remote_identify.device_type ==
757             MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
758                 _transport_expander_report_manufacture(ioc,
759                     mpt2sas_port->remote_identify.sas_address,
760                     rphy_to_expander_device(rphy));
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
772 /**
773  * mpt2sas_transport_port_remove - remove port from the list
774  * @ioc: per adapter object
775  * @sas_address: sas address of attached device
776  * @sas_address_parent: sas address of parent expander or sas host
777  * Context: This function will acquire ioc->sas_node_lock.
778  *
779  * Removing object and freeing associated memory from the
780  * ioc->sas_port_list.
781  *
782  * Return nothing.
783  */
784 void
785 mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
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
839 /**
840  * mpt2sas_transport_add_host_phy - report sas_host phy to transport
841  * @ioc: per adapter object
842  * @mpt2sas_phy: mpt2sas per phy object
843  * @phy_pg0: sas phy page 0
844  * @parent_dev: parent device class object
845  *
846  * Returns 0 for success, non-zero for failure.
847  */
848 int
849 mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
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(
876             phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
877         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
878             phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
879         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
880             phy_pg0.HwLinkRate >> 4);
881         phy->minimum_linkrate = _transport_convert_phy_link_rate(
882             phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
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
906 /**
907  * mpt2sas_transport_add_expander_phy - report expander phy to transport
908  * @ioc: per adapter object
909  * @mpt2sas_phy: mpt2sas per phy object
910  * @expander_pg1: expander page 1
911  * @parent_dev: parent device class object
912  *
913  * Returns 0 for success, non-zero for failure.
914  */
915 int
916 mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
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 &
944             MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
945         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
946             expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
947         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
948             expander_pg1.HwLinkRate >> 4);
949         phy->minimum_linkrate = _transport_convert_phy_link_rate(
950             expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
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
973 /**
974  * mpt2sas_transport_update_links - refreshing phy link changes
975  * @ioc: per adapter object
976  * @sas_address: sas address of parent expander or sas host
977  * @handle: attached device handle
978  * @phy_numberv: phy number
979  * @link_rate: new link rate
980  *
981  * Returns nothing.
982  */
983 void
984 mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
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 */
1043 struct phy_error_log_request{
1044         u8 smp_frame_type; /* 0x40 */
1045         u8 function; /* 0x11 */
1046         u8 allocated_response_length;
1047         u8 request_length; /* 02 */
1048         u8 reserved_1[5];
1049         u8 phy_identifier;
1050         u8 reserved_2[2];
1051 };
1052
1053 /* report phy error log reply structure */
1054 struct phy_error_log_reply{
1055         u8 smp_frame_type; /* 0x41 */
1056         u8 function; /* 0x11 */
1057         u8 function_result;
1058         u8 response_length;
1059         __be16 expander_change_count;
1060         u8 reserved_1[3];
1061         u8 phy_identifier;
1062         u8 reserved_2[2];
1063         __be32 invalid_dword;
1064         __be32 running_disparity_error;
1065         __be32 loss_of_dword_sync;
1066         __be32 phy_reset_problem;
1067 };
1068
1069 /**
1070  * _transport_get_expander_phy_error_log - return expander counters
1071  * @ioc: per adapter object
1072  * @phy: The sas phy object
1073  *
1074  * Returns 0 for success, non-zero for failure.
1075  *
1076  */
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;
1083         struct phy_error_log_request *phy_error_log_request;
1084         struct phy_error_log_reply *phy_error_log_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) {
1117                         printk(MPT2SAS_ERR_FMT
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 |
1176             MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
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 |
1186             MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1187             MPI2_SGE_FLAGS_END_OF_LIST);
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
1218                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
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
1229                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
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);
1235                 phy->running_disparity_error_count =
1236                     be32_to_cpu(phy_error_log_reply->running_disparity_error);
1237                 phy->loss_of_dword_sync_count =
1238                     be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1239                 phy->phy_reset_problem_count =
1240                     be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1241                 rc = 0;
1242         } else
1243                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1244                     "phy_error_log - no reply\n", ioc->name));
1245
1246  issue_host_reset:
1247         if (issue_reset)
1248                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1249                     FORCE_BIG_HAMMER);
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
1259 /**
1260  * _transport_get_linkerrors - return phy counters for both hba and expanders
1261  * @phy: The sas phy object
1262  *
1263  * Returns 0 for success, non-zero for failure.
1264  *
1265  */
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
1299         phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
1300         phy->running_disparity_error_count =
1301             le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
1302         phy->loss_of_dword_sync_count =
1303             le32_to_cpu(phy_pg1.LossDwordSynchCount);
1304         phy->phy_reset_problem_count =
1305             le32_to_cpu(phy_pg1.PhyResetProblemCount);
1306         return 0;
1307 }
1308
1309 /**
1310  * _transport_get_enclosure_identifier -
1311  * @phy: The sas phy object
1312  *
1313  * Obtain the enclosure logical id for an expander.
1314  * Returns 0 for success, non-zero for failure.
1315  */
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);
1325         sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
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
1338 /**
1339  * _transport_get_bay_identifier -
1340  * @phy: The sas phy object
1341  *
1342  * Returns the slot id for a device that resides inside an enclosure.
1343  */
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);
1353         sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
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 */
1364 struct phy_control_request{
1365         u8 smp_frame_type; /* 0x40 */
1366         u8 function; /* 0x91 */
1367         u8 allocated_response_length;
1368         u8 request_length; /* 0x09 */
1369         u16 expander_change_count;
1370         u8 reserved_1[3];
1371         u8 phy_identifier;
1372         u8 phy_operation;
1373         u8 reserved_2[13];
1374         u64 attached_device_name;
1375         u8 programmed_min_physical_link_rate;
1376         u8 programmed_max_physical_link_rate;
1377         u8 reserved_3[6];
1378 };
1379
1380 /* phy control reply structure */
1381 struct phy_control_reply{
1382         u8 smp_frame_type; /* 0x41 */
1383         u8 function; /* 0x11 */
1384         u8 function_result;
1385         u8 response_length;
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
1392 /**
1393  * _transport_expander_phy_control - expander phy control
1394  * @ioc: per adapter object
1395  * @phy: The sas phy object
1396  *
1397  * Returns 0 for success, non-zero for failure.
1398  *
1399  */
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;
1406         struct phy_control_request *phy_control_request;
1407         struct phy_control_reply *phy_control_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) {
1440                         printk(MPT2SAS_ERR_FMT
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 |
1504             MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
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 |
1514             MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1515             MPI2_SGE_FLAGS_END_OF_LIST);
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
1548                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
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
1559                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1560                     "phy_control - function_result(%d)\n",
1561                     ioc->name, phy_control_reply->function_result));
1562
1563                 rc = 0;
1564         } else
1565                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1566                     "phy_control - no reply\n", ioc->name));
1567
1568  issue_host_reset:
1569         if (issue_reset)
1570                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1571                     FORCE_BIG_HAMMER);
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
1581 /**
1582  * _transport_phy_reset -
1583  * @phy: The sas phy object
1584  * @hard_reset:
1585  *
1586  * Returns 0 for success, non-zero for failure.
1587  */
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 :
1608                     SMP_PHY_CONTROL_LINK_RESET);
1609
1610         /* handle hba phys */
1611         memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
1612         mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
1613         mpi_request.Operation = hard_reset ?
1614             MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_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
1632 /**
1633  * _transport_phy_enable - enable/disable phys
1634  * @phy: The sas phy object
1635  * @enable: enable phy when true
1636  *
1637  * Only support sas_host direct attached phys.
1638  * Returns 0 for success, non-zero for failure.
1639  */
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 :
1665                     SMP_PHY_CONTROL_DISABLE);
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) &
1687             MPI2_IOCSTATUS_MASK;
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 &
1698                     MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
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) &
1730             MPI2_IOCSTATUS_MASK;
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 &
1743                     MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
1744                 sas_iounit_pg1->PhyData[i].PhyFlags =
1745                     (sas_iounit_pg0->PhyData[i].PhyFlags &
1746                     (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
1747                     MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
1748         }
1749         if (enable)
1750                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1751                     &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1752         else
1753                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1754                     |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
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
1768 /**
1769  * _transport_phy_speed - set phy min/max link rates
1770  * @phy: The sas phy object
1771  * @rates: rates defined in sas_phy_linkrates
1772  *
1773  * Only support sas_host direct attached phys.
1774  * Returns 0 for success, non-zero for failure.
1775  */
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,
1812                     SMP_PHY_CONTROL_LINK_RESET);
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) &
1835             MPI2_IOCSTATUS_MASK;
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(
1870                     phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
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 &
1875                     MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1876         }
1877
1878  out:
1879         kfree(sas_iounit_pg1);
1880         return rc;
1881 }
1882
1883
1884 /**
1885  * _transport_smp_handler - transport portal for smp passthru
1886  * @shost: shost object
1887  * @rphy: sas transport rphy object
1888  * @req:
1889  *
1890  * This used primarily for smp_utils.
1891  * Example:
1892  *           smp_rep_general /sys/class/bsg/expander-5:0
1893  */
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;
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;
1917         struct bvec_iter iter;
1918
1919         if (!rsp) {
1920                 printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
1921                     "missing\n", ioc->name, __func__);
1922                 return -EINVAL;
1923         }
1924         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1925                 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1926                     __func__, ioc->name);
1927                 return -EFAULT;
1928         }
1929
1930         rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1931         if (rc)
1932                 return rc;
1933
1934         if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1935                 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
1936                     __func__);
1937                 rc = -EAGAIN;
1938                 goto out;
1939         }
1940         ioc->transport_cmds.status = MPT2_CMD_PENDING;
1941
1942         /* Check if the request is split across multiple segments */
1943         if (bio_multiple_segments(req->bio)) {
1944                 u32 offset = 0;
1945
1946                 /* Allocate memory and copy the request */
1947                 pci_addr_out = pci_alloc_consistent(ioc->pdev,
1948                     blk_rq_bytes(req), &pci_dma_out);
1949                 if (!pci_addr_out) {
1950                         printk(MPT2SAS_INFO_FMT "%s(): PCI Addr out = NULL\n",
1951                             ioc->name, __func__);
1952                         rc = -ENOMEM;
1953                         goto out;
1954                 }
1955
1956                 bio_for_each_segment(bvec, req->bio, iter) {
1957                         memcpy(pci_addr_out + offset,
1958                             page_address(bvec.bv_page) + bvec.bv_offset,
1959                             bvec.bv_len);
1960                         offset += bvec.bv_len;
1961                 }
1962         } else {
1963                 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1964                     blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
1965                 if (!dma_addr_out) {
1966                         printk(MPT2SAS_INFO_FMT "%s(): DMA Addr out = NULL\n",
1967                             ioc->name, __func__);
1968                         rc = -ENOMEM;
1969                         goto free_pci;
1970                 }
1971         }
1972
1973         /* Check if the response needs to be populated across
1974          * multiple segments */
1975         if (bio_multiple_segments(rsp->bio)) {
1976                 pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp),
1977                     &pci_dma_in);
1978                 if (!pci_addr_in) {
1979                         printk(MPT2SAS_INFO_FMT "%s(): PCI Addr in = NULL\n",
1980                             ioc->name, __func__);
1981                         rc = -ENOMEM;
1982                         goto unmap;
1983                 }
1984         } else {
1985                 dma_addr_in =  pci_map_single(ioc->pdev, bio_data(rsp->bio),
1986                     blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
1987                 if (!dma_addr_in) {
1988                         printk(MPT2SAS_INFO_FMT "%s(): DMA Addr in = NULL\n",
1989                             ioc->name, __func__);
1990                         rc = -ENOMEM;
1991                         goto unmap;
1992                 }
1993         }
1994
1995         wait_state_count = 0;
1996         ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1997         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1998                 if (wait_state_count++ == 10) {
1999                         printk(MPT2SAS_ERR_FMT
2000                             "%s: failed due to ioc not operational\n",
2001                             ioc->name, __func__);
2002                         rc = -EFAULT;
2003                         goto unmap;
2004                 }
2005                 ssleep(1);
2006                 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
2007                 printk(MPT2SAS_INFO_FMT "%s: waiting for "
2008                     "operational state(count=%d)\n", ioc->name,
2009                     __func__, wait_state_count);
2010         }
2011         if (wait_state_count)
2012                 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
2013                     ioc->name, __func__);
2014
2015         smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
2016         if (!smid) {
2017                 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2018                     ioc->name, __func__);
2019                 rc = -EAGAIN;
2020                 goto unmap;
2021         }
2022
2023         rc = 0;
2024         mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2025         ioc->transport_cmds.smid = smid;
2026
2027         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
2028         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
2029         mpi_request->PhysicalPort = 0xFF;
2030         mpi_request->VF_ID = 0; /* TODO */
2031         mpi_request->VP_ID = 0;
2032         mpi_request->SASAddress = (rphy) ?
2033             cpu_to_le64(rphy->identify.sas_address) :
2034             cpu_to_le64(ioc->sas_hba.sas_address);
2035         mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2036         psge = &mpi_request->SGL;
2037
2038         /* WRITE sgel first */
2039         sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2040             MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
2041         sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2042         if (bio_multiple_segments(req->bio)) {
2043                 ioc->base_add_sg_single(psge, sgl_flags |
2044                     (blk_rq_bytes(req) - 4), pci_dma_out);
2045         } else {
2046                 ioc->base_add_sg_single(psge, sgl_flags |
2047                     (blk_rq_bytes(req) - 4), dma_addr_out);
2048         }
2049
2050         /* incr sgel */
2051         psge += ioc->sge_size;
2052
2053         /* READ sgel last */
2054         sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2055             MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
2056             MPI2_SGE_FLAGS_END_OF_LIST);
2057         sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
2058         if (bio_multiple_segments(rsp->bio)) {
2059                 ioc->base_add_sg_single(psge, sgl_flags |
2060                     (blk_rq_bytes(rsp) + 4), pci_dma_in);
2061         } else {
2062                 ioc->base_add_sg_single(psge, sgl_flags |
2063                     (blk_rq_bytes(rsp) + 4), dma_addr_in);
2064         }
2065
2066         dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
2067             "sending smp request\n", ioc->name, __func__));
2068
2069         init_completion(&ioc->transport_cmds.done);
2070         mpt2sas_base_put_smid_default(ioc, smid);
2071         timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
2072             10*HZ);
2073
2074         if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
2075                 printk(MPT2SAS_ERR_FMT "%s : timeout\n",
2076                     __func__, ioc->name);
2077                 _debug_dump_mf(mpi_request,
2078                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
2079                 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
2080                         issue_reset = 1;
2081                 goto issue_host_reset;
2082         }
2083
2084         dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
2085             "complete\n", ioc->name, __func__));
2086
2087         if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
2088
2089                 mpi_reply = ioc->transport_cmds.reply;
2090
2091                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
2092                     "%s - reply data transfer size(%d)\n",
2093                     ioc->name, __func__,
2094                     le16_to_cpu(mpi_reply->ResponseDataLength)));
2095
2096                 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
2097                 req->sense_len = sizeof(*mpi_reply);
2098                 req->resid_len = 0;
2099                 rsp->resid_len -=
2100                     le16_to_cpu(mpi_reply->ResponseDataLength);
2101                 /* check if the resp needs to be copied from the allocated
2102                  * pci mem */
2103                 if (bio_multiple_segments(rsp->bio)) {
2104                         u32 offset = 0;
2105                         u32 bytes_to_copy =
2106                             le16_to_cpu(mpi_reply->ResponseDataLength);
2107                         bio_for_each_segment(bvec, rsp->bio, iter) {
2108                                 if (bytes_to_copy <= bvec.bv_len) {
2109                                         memcpy(page_address(bvec.bv_page) +
2110                                             bvec.bv_offset, pci_addr_in +
2111                                             offset, bytes_to_copy);
2112                                         break;
2113                                 } else {
2114                                         memcpy(page_address(bvec.bv_page) +
2115                                             bvec.bv_offset, pci_addr_in +
2116                                             offset, bvec.bv_len);
2117                                         bytes_to_copy -= bvec.bv_len;
2118                                 }
2119                                 offset += bvec.bv_len;
2120                         }
2121                 }
2122         } else {
2123                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
2124                     "%s - no reply\n", ioc->name, __func__));
2125                 rc = -ENXIO;
2126         }
2127
2128  issue_host_reset:
2129         if (issue_reset) {
2130                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
2131                     FORCE_BIG_HAMMER);
2132                 rc = -ETIMEDOUT;
2133         }
2134
2135  unmap:
2136         if (dma_addr_out)
2137                 pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
2138                     PCI_DMA_BIDIRECTIONAL);
2139         if (dma_addr_in)
2140                 pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
2141                     PCI_DMA_BIDIRECTIONAL);
2142
2143  free_pci:
2144         if (pci_addr_out)
2145                 pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out,
2146                     pci_dma_out);
2147
2148         if (pci_addr_in)
2149                 pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in,
2150                     pci_dma_in);
2151
2152  out:
2153         ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
2154         mutex_unlock(&ioc->transport_cmds.mutex);
2155         return rc;
2156 }
2157
2158 struct sas_function_template mpt2sas_transport_functions = {
2159         .get_linkerrors         = _transport_get_linkerrors,
2160         .get_enclosure_identifier = _transport_get_enclosure_identifier,
2161         .get_bay_identifier     = _transport_get_bay_identifier,
2162         .phy_reset              = _transport_phy_reset,
2163         .phy_enable             = _transport_phy_enable,
2164         .set_phy_speed          = _transport_phy_speed,
2165         .smp_handler            = _transport_smp_handler,
2166 };
2167
2168 struct scsi_transport_template *mpt2sas_transport_template;