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