GNU Linux-libre 4.14.266-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  * Returns 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  * Returns 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         ioc->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  * Returns nothing.
465  */
466 static void
467 _transport_delete_port(struct MPT3SAS_ADAPTER *ioc,
468         struct _sas_port *mpt3sas_port)
469 {
470         u64 sas_address = mpt3sas_port->remote_identify.sas_address;
471         enum sas_device_type device_type =
472             mpt3sas_port->remote_identify.device_type;
473
474         dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
475             "remove: sas_addr(0x%016llx)\n",
476             (unsigned long long) sas_address);
477
478         ioc->logging_level |= MPT_DEBUG_TRANSPORT;
479         if (device_type == SAS_END_DEVICE)
480                 mpt3sas_device_remove_by_sas_address(ioc, sas_address);
481         else if (device_type == SAS_EDGE_EXPANDER_DEVICE ||
482             device_type == SAS_FANOUT_EXPANDER_DEVICE)
483                 mpt3sas_expander_remove(ioc, sas_address);
484         ioc->logging_level &= ~MPT_DEBUG_TRANSPORT;
485 }
486
487 /**
488  * _transport_delete_phy - helper function to removing single phy from port
489  * @ioc: per adapter object
490  * @mpt3sas_port: mpt3sas per port object
491  * @mpt3sas_phy: mpt3sas per phy object
492  *
493  * Returns nothing.
494  */
495 static void
496 _transport_delete_phy(struct MPT3SAS_ADAPTER *ioc,
497         struct _sas_port *mpt3sas_port, struct _sas_phy *mpt3sas_phy)
498 {
499         u64 sas_address = mpt3sas_port->remote_identify.sas_address;
500
501         dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
502             "remove: sas_addr(0x%016llx), phy(%d)\n",
503             (unsigned long long) sas_address, mpt3sas_phy->phy_id);
504
505         list_del(&mpt3sas_phy->port_siblings);
506         mpt3sas_port->num_phys--;
507         sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
508         mpt3sas_phy->phy_belongs_to_port = 0;
509 }
510
511 /**
512  * _transport_add_phy - helper function to adding single phy to port
513  * @ioc: per adapter object
514  * @mpt3sas_port: mpt3sas per port object
515  * @mpt3sas_phy: mpt3sas per phy object
516  *
517  * Returns nothing.
518  */
519 static void
520 _transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt3sas_port,
521         struct _sas_phy *mpt3sas_phy)
522 {
523         u64 sas_address = mpt3sas_port->remote_identify.sas_address;
524
525         dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
526             "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long)
527             sas_address, mpt3sas_phy->phy_id);
528
529         list_add_tail(&mpt3sas_phy->port_siblings, &mpt3sas_port->phy_list);
530         mpt3sas_port->num_phys++;
531         sas_port_add_phy(mpt3sas_port->port, mpt3sas_phy->phy);
532         mpt3sas_phy->phy_belongs_to_port = 1;
533 }
534
535 /**
536  * _transport_add_phy_to_an_existing_port - adding new phy to existing port
537  * @ioc: per adapter object
538  * @sas_node: sas node object (either expander or sas host)
539  * @mpt3sas_phy: mpt3sas per phy object
540  * @sas_address: sas address of device/expander were phy needs to be added to
541  *
542  * Returns nothing.
543  */
544 static void
545 _transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
546         struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy,
547         u64 sas_address)
548 {
549         struct _sas_port *mpt3sas_port;
550         struct _sas_phy *phy_srch;
551
552         if (mpt3sas_phy->phy_belongs_to_port == 1)
553                 return;
554
555         list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list,
556             port_list) {
557                 if (mpt3sas_port->remote_identify.sas_address !=
558                     sas_address)
559                         continue;
560                 list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
561                     port_siblings) {
562                         if (phy_srch == mpt3sas_phy)
563                                 return;
564                 }
565                 _transport_add_phy(ioc, mpt3sas_port, mpt3sas_phy);
566                         return;
567         }
568
569 }
570
571 /**
572  * _transport_del_phy_from_an_existing_port - delete phy from existing port
573  * @ioc: per adapter object
574  * @sas_node: sas node object (either expander or sas host)
575  * @mpt3sas_phy: mpt3sas per phy object
576  *
577  * Returns nothing.
578  */
579 static void
580 _transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc,
581         struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy)
582 {
583         struct _sas_port *mpt3sas_port, *next;
584         struct _sas_phy *phy_srch;
585
586         if (mpt3sas_phy->phy_belongs_to_port == 0)
587                 return;
588
589         list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
590             port_list) {
591                 list_for_each_entry(phy_srch, &mpt3sas_port->phy_list,
592                     port_siblings) {
593                         if (phy_srch != mpt3sas_phy)
594                                 continue;
595
596                         if (mpt3sas_port->num_phys == 1)
597                                 _transport_delete_port(ioc, mpt3sas_port);
598                         else
599                                 _transport_delete_phy(ioc, mpt3sas_port,
600                                     mpt3sas_phy);
601                         return;
602                 }
603         }
604 }
605
606 /**
607  * _transport_sanity_check - sanity check when adding a new port
608  * @ioc: per adapter object
609  * @sas_node: sas node object (either expander or sas host)
610  * @sas_address: sas address of device being added
611  *
612  * See the explanation above from _transport_delete_duplicate_port
613  */
614 static void
615 _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node,
616         u64 sas_address)
617 {
618         int i;
619
620         for (i = 0; i < sas_node->num_phys; i++) {
621                 if (sas_node->phy[i].remote_identify.sas_address != sas_address)
622                         continue;
623                 if (sas_node->phy[i].phy_belongs_to_port == 1)
624                         _transport_del_phy_from_an_existing_port(ioc, sas_node,
625                             &sas_node->phy[i]);
626         }
627 }
628
629 /**
630  * mpt3sas_transport_port_add - insert port to the list
631  * @ioc: per adapter object
632  * @handle: handle of attached device
633  * @sas_address: sas address of parent expander or sas host
634  * Context: This function will acquire ioc->sas_node_lock.
635  *
636  * Adding new port object to the sas_node->sas_port_list.
637  *
638  * Returns mpt3sas_port.
639  */
640 struct _sas_port *
641 mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
642         u64 sas_address)
643 {
644         struct _sas_phy *mpt3sas_phy, *next;
645         struct _sas_port *mpt3sas_port;
646         unsigned long flags;
647         struct _sas_node *sas_node;
648         struct sas_rphy *rphy;
649         struct _sas_device *sas_device = NULL;
650         int i;
651         struct sas_port *port;
652
653         mpt3sas_port = kzalloc(sizeof(struct _sas_port),
654             GFP_KERNEL);
655         if (!mpt3sas_port) {
656                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
657                     ioc->name, __FILE__, __LINE__, __func__);
658                 return NULL;
659         }
660
661         INIT_LIST_HEAD(&mpt3sas_port->port_list);
662         INIT_LIST_HEAD(&mpt3sas_port->phy_list);
663         spin_lock_irqsave(&ioc->sas_node_lock, flags);
664         sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
665         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
666
667         if (!sas_node) {
668                 pr_err(MPT3SAS_FMT
669                         "%s: Could not find parent sas_address(0x%016llx)!\n",
670                         ioc->name, __func__, (unsigned long long)sas_address);
671                 goto out_fail;
672         }
673
674         if ((_transport_set_identify(ioc, handle,
675             &mpt3sas_port->remote_identify))) {
676                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
677                     ioc->name, __FILE__, __LINE__, __func__);
678                 goto out_fail;
679         }
680
681         if (mpt3sas_port->remote_identify.device_type == SAS_PHY_UNUSED) {
682                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
683                     ioc->name, __FILE__, __LINE__, __func__);
684                 goto out_fail;
685         }
686
687         _transport_sanity_check(ioc, sas_node,
688             mpt3sas_port->remote_identify.sas_address);
689
690         for (i = 0; i < sas_node->num_phys; i++) {
691                 if (sas_node->phy[i].remote_identify.sas_address !=
692                     mpt3sas_port->remote_identify.sas_address)
693                         continue;
694                 list_add_tail(&sas_node->phy[i].port_siblings,
695                     &mpt3sas_port->phy_list);
696                 mpt3sas_port->num_phys++;
697         }
698
699         if (!mpt3sas_port->num_phys) {
700                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
701                     ioc->name, __FILE__, __LINE__, __func__);
702                 goto out_fail;
703         }
704
705         if (!sas_node->parent_dev) {
706                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
707                     ioc->name, __FILE__, __LINE__, __func__);
708                 goto out_fail;
709         }
710         port = sas_port_alloc_num(sas_node->parent_dev);
711         if ((sas_port_add(port))) {
712                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
713                     ioc->name, __FILE__, __LINE__, __func__);
714                 goto out_fail;
715         }
716
717         list_for_each_entry(mpt3sas_phy, &mpt3sas_port->phy_list,
718             port_siblings) {
719                 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
720                         dev_printk(KERN_INFO, &port->dev,
721                                 "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n",
722                                 handle, (unsigned long long)
723                             mpt3sas_port->remote_identify.sas_address,
724                             mpt3sas_phy->phy_id);
725                 sas_port_add_phy(port, mpt3sas_phy->phy);
726                 mpt3sas_phy->phy_belongs_to_port = 1;
727         }
728
729         mpt3sas_port->port = port;
730         if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE)
731                 rphy = sas_end_device_alloc(port);
732         else
733                 rphy = sas_expander_alloc(port,
734                     mpt3sas_port->remote_identify.device_type);
735
736         rphy->identify = mpt3sas_port->remote_identify;
737
738         if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
739                 sas_device = mpt3sas_get_sdev_by_addr(ioc,
740                                     mpt3sas_port->remote_identify.sas_address);
741                 if (!sas_device) {
742                         dfailprintk(ioc, printk(MPT3SAS_FMT
743                                 "failure at %s:%d/%s()!\n",
744                                 ioc->name, __FILE__, __LINE__, __func__));
745                         goto out_fail;
746                 }
747                 sas_device->pend_sas_rphy_add = 1;
748         }
749
750         if ((sas_rphy_add(rphy))) {
751                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
752                     ioc->name, __FILE__, __LINE__, __func__);
753         }
754
755         if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
756                 sas_device->pend_sas_rphy_add = 0;
757                 sas_device_put(sas_device);
758         }
759
760         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
761                 dev_printk(KERN_INFO, &rphy->dev,
762                         "add: handle(0x%04x), sas_addr(0x%016llx)\n",
763                         handle, (unsigned long long)
764                     mpt3sas_port->remote_identify.sas_address);
765         mpt3sas_port->rphy = rphy;
766         spin_lock_irqsave(&ioc->sas_node_lock, flags);
767         list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list);
768         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
769
770         /* fill in report manufacture */
771         if (mpt3sas_port->remote_identify.device_type ==
772             MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER ||
773             mpt3sas_port->remote_identify.device_type ==
774             MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
775                 _transport_expander_report_manufacture(ioc,
776                     mpt3sas_port->remote_identify.sas_address,
777                     rphy_to_expander_device(rphy));
778         return mpt3sas_port;
779
780  out_fail:
781         list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list,
782             port_siblings)
783                 list_del(&mpt3sas_phy->port_siblings);
784         kfree(mpt3sas_port);
785         return NULL;
786 }
787
788 /**
789  * mpt3sas_transport_port_remove - remove port from the list
790  * @ioc: per adapter object
791  * @sas_address: sas address of attached device
792  * @sas_address_parent: sas address of parent expander or sas host
793  * Context: This function will acquire ioc->sas_node_lock.
794  *
795  * Removing object and freeing associated memory from the
796  * ioc->sas_port_list.
797  *
798  * Return nothing.
799  */
800 void
801 mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
802         u64 sas_address_parent)
803 {
804         int i;
805         unsigned long flags;
806         struct _sas_port *mpt3sas_port, *next;
807         struct _sas_node *sas_node;
808         u8 found = 0;
809         struct _sas_phy *mpt3sas_phy, *next_phy;
810
811         spin_lock_irqsave(&ioc->sas_node_lock, flags);
812         sas_node = _transport_sas_node_find_by_sas_address(ioc,
813             sas_address_parent);
814         if (!sas_node) {
815                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
816                 return;
817         }
818         list_for_each_entry_safe(mpt3sas_port, next, &sas_node->sas_port_list,
819             port_list) {
820                 if (mpt3sas_port->remote_identify.sas_address != sas_address)
821                         continue;
822                 found = 1;
823                 list_del(&mpt3sas_port->port_list);
824                 goto out;
825         }
826  out:
827         if (!found) {
828                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
829                 return;
830         }
831
832         for (i = 0; i < sas_node->num_phys; i++) {
833                 if (sas_node->phy[i].remote_identify.sas_address == sas_address)
834                         memset(&sas_node->phy[i].remote_identify, 0 ,
835                             sizeof(struct sas_identify));
836         }
837
838         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
839
840         list_for_each_entry_safe(mpt3sas_phy, next_phy,
841             &mpt3sas_port->phy_list, port_siblings) {
842                 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
843                         dev_printk(KERN_INFO, &mpt3sas_port->port->dev,
844                             "remove: sas_addr(0x%016llx), phy(%d)\n",
845                             (unsigned long long)
846                             mpt3sas_port->remote_identify.sas_address,
847                             mpt3sas_phy->phy_id);
848                 mpt3sas_phy->phy_belongs_to_port = 0;
849                 if (!ioc->remove_host)
850                         sas_port_delete_phy(mpt3sas_port->port,
851                                                 mpt3sas_phy->phy);
852                 list_del(&mpt3sas_phy->port_siblings);
853         }
854         if (!ioc->remove_host)
855                 sas_port_delete(mpt3sas_port->port);
856         kfree(mpt3sas_port);
857 }
858
859 /**
860  * mpt3sas_transport_add_host_phy - report sas_host phy to transport
861  * @ioc: per adapter object
862  * @mpt3sas_phy: mpt3sas per phy object
863  * @phy_pg0: sas phy page 0
864  * @parent_dev: parent device class object
865  *
866  * Returns 0 for success, non-zero for failure.
867  */
868 int
869 mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
870         *mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
871 {
872         struct sas_phy *phy;
873         int phy_index = mpt3sas_phy->phy_id;
874
875
876         INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
877         phy = sas_phy_alloc(parent_dev, phy_index);
878         if (!phy) {
879                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
880                     ioc->name, __FILE__, __LINE__, __func__);
881                 return -1;
882         }
883         if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
884             &mpt3sas_phy->identify))) {
885                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
886                     ioc->name, __FILE__, __LINE__, __func__);
887                 sas_phy_free(phy);
888                 return -1;
889         }
890         phy->identify = mpt3sas_phy->identify;
891         mpt3sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
892         if (mpt3sas_phy->attached_handle)
893                 _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
894                     &mpt3sas_phy->remote_identify);
895         phy->identify.phy_identifier = mpt3sas_phy->phy_id;
896         phy->negotiated_linkrate = _transport_convert_phy_link_rate(
897             phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
898         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
899             phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
900         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
901             phy_pg0.HwLinkRate >> 4);
902         phy->minimum_linkrate = _transport_convert_phy_link_rate(
903             phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
904         phy->maximum_linkrate = _transport_convert_phy_link_rate(
905             phy_pg0.ProgrammedLinkRate >> 4);
906
907         if ((sas_phy_add(phy))) {
908                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
909                     ioc->name, __FILE__, __LINE__, __func__);
910                 sas_phy_free(phy);
911                 return -1;
912         }
913         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
914                 dev_printk(KERN_INFO, &phy->dev,
915                     "add: handle(0x%04x), sas_addr(0x%016llx)\n"
916                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
917                     mpt3sas_phy->handle, (unsigned long long)
918                     mpt3sas_phy->identify.sas_address,
919                     mpt3sas_phy->attached_handle,
920                     (unsigned long long)
921                     mpt3sas_phy->remote_identify.sas_address);
922         mpt3sas_phy->phy = phy;
923         return 0;
924 }
925
926
927 /**
928  * mpt3sas_transport_add_expander_phy - report expander phy to transport
929  * @ioc: per adapter object
930  * @mpt3sas_phy: mpt3sas per phy object
931  * @expander_pg1: expander page 1
932  * @parent_dev: parent device class object
933  *
934  * Returns 0 for success, non-zero for failure.
935  */
936 int
937 mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
938         *mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1,
939         struct device *parent_dev)
940 {
941         struct sas_phy *phy;
942         int phy_index = mpt3sas_phy->phy_id;
943
944         INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
945         phy = sas_phy_alloc(parent_dev, phy_index);
946         if (!phy) {
947                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
948                     ioc->name, __FILE__, __LINE__, __func__);
949                 return -1;
950         }
951         if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
952             &mpt3sas_phy->identify))) {
953                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
954                     ioc->name, __FILE__, __LINE__, __func__);
955                 sas_phy_free(phy);
956                 return -1;
957         }
958         phy->identify = mpt3sas_phy->identify;
959         mpt3sas_phy->attached_handle =
960             le16_to_cpu(expander_pg1.AttachedDevHandle);
961         if (mpt3sas_phy->attached_handle)
962                 _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
963                     &mpt3sas_phy->remote_identify);
964         phy->identify.phy_identifier = mpt3sas_phy->phy_id;
965         phy->negotiated_linkrate = _transport_convert_phy_link_rate(
966             expander_pg1.NegotiatedLinkRate &
967             MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
968         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
969             expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
970         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
971             expander_pg1.HwLinkRate >> 4);
972         phy->minimum_linkrate = _transport_convert_phy_link_rate(
973             expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
974         phy->maximum_linkrate = _transport_convert_phy_link_rate(
975             expander_pg1.ProgrammedLinkRate >> 4);
976
977         if ((sas_phy_add(phy))) {
978                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
979                     ioc->name, __FILE__, __LINE__, __func__);
980                 sas_phy_free(phy);
981                 return -1;
982         }
983         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
984                 dev_printk(KERN_INFO, &phy->dev,
985                     "add: handle(0x%04x), sas_addr(0x%016llx)\n"
986                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
987                     mpt3sas_phy->handle, (unsigned long long)
988                     mpt3sas_phy->identify.sas_address,
989                     mpt3sas_phy->attached_handle,
990                     (unsigned long long)
991                     mpt3sas_phy->remote_identify.sas_address);
992         mpt3sas_phy->phy = phy;
993         return 0;
994 }
995
996 /**
997  * mpt3sas_transport_update_links - refreshing phy link changes
998  * @ioc: per adapter object
999  * @sas_address: sas address of parent expander or sas host
1000  * @handle: attached device handle
1001  * @phy_numberv: phy number
1002  * @link_rate: new link rate
1003  *
1004  * Returns nothing.
1005  */
1006 void
1007 mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc,
1008         u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
1009 {
1010         unsigned long flags;
1011         struct _sas_node *sas_node;
1012         struct _sas_phy *mpt3sas_phy;
1013
1014         if (ioc->shost_recovery || ioc->pci_error_recovery)
1015                 return;
1016
1017         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1018         sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
1019         if (!sas_node) {
1020                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1021                 return;
1022         }
1023
1024         mpt3sas_phy = &sas_node->phy[phy_number];
1025         mpt3sas_phy->attached_handle = handle;
1026         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1027         if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
1028                 _transport_set_identify(ioc, handle,
1029                     &mpt3sas_phy->remote_identify);
1030                 _transport_add_phy_to_an_existing_port(ioc, sas_node,
1031                     mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address);
1032         } else
1033                 memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct
1034                     sas_identify));
1035
1036         if (mpt3sas_phy->phy)
1037                 mpt3sas_phy->phy->negotiated_linkrate =
1038                     _transport_convert_phy_link_rate(link_rate);
1039
1040         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
1041                 dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
1042                     "refresh: parent sas_addr(0x%016llx),\n"
1043                     "\tlink_rate(0x%02x), phy(%d)\n"
1044                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1045                     (unsigned long long)sas_address,
1046                     link_rate, phy_number, handle, (unsigned long long)
1047                     mpt3sas_phy->remote_identify.sas_address);
1048 }
1049
1050 static inline void *
1051 phy_to_ioc(struct sas_phy *phy)
1052 {
1053         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1054         return shost_priv(shost);
1055 }
1056
1057 static inline void *
1058 rphy_to_ioc(struct sas_rphy *rphy)
1059 {
1060         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
1061         return shost_priv(shost);
1062 }
1063
1064 /* report phy error log structure */
1065 struct phy_error_log_request {
1066         u8 smp_frame_type; /* 0x40 */
1067         u8 function; /* 0x11 */
1068         u8 allocated_response_length;
1069         u8 request_length; /* 02 */
1070         u8 reserved_1[5];
1071         u8 phy_identifier;
1072         u8 reserved_2[2];
1073 };
1074
1075 /* report phy error log reply structure */
1076 struct phy_error_log_reply {
1077         u8 smp_frame_type; /* 0x41 */
1078         u8 function; /* 0x11 */
1079         u8 function_result;
1080         u8 response_length;
1081         __be16 expander_change_count;
1082         u8 reserved_1[3];
1083         u8 phy_identifier;
1084         u8 reserved_2[2];
1085         __be32 invalid_dword;
1086         __be32 running_disparity_error;
1087         __be32 loss_of_dword_sync;
1088         __be32 phy_reset_problem;
1089 };
1090
1091 /**
1092  * _transport_get_expander_phy_error_log - return expander counters
1093  * @ioc: per adapter object
1094  * @phy: The sas phy object
1095  *
1096  * Returns 0 for success, non-zero for failure.
1097  *
1098  */
1099 static int
1100 _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
1101         struct sas_phy *phy)
1102 {
1103         Mpi2SmpPassthroughRequest_t *mpi_request;
1104         Mpi2SmpPassthroughReply_t *mpi_reply;
1105         struct phy_error_log_request *phy_error_log_request;
1106         struct phy_error_log_reply *phy_error_log_reply;
1107         int rc;
1108         u16 smid;
1109         u32 ioc_state;
1110         void *psge;
1111         u8 issue_reset = 0;
1112         void *data_out = NULL;
1113         dma_addr_t data_out_dma;
1114         u32 sz;
1115         u16 wait_state_count;
1116
1117         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1118                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1119                     __func__, ioc->name);
1120                 return -EFAULT;
1121         }
1122
1123         mutex_lock(&ioc->transport_cmds.mutex);
1124
1125         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1126                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n",
1127                     ioc->name, __func__);
1128                 rc = -EAGAIN;
1129                 goto out;
1130         }
1131         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1132
1133         wait_state_count = 0;
1134         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1135         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1136                 if (wait_state_count++ == 10) {
1137                         pr_err(MPT3SAS_FMT
1138                             "%s: failed due to ioc not operational\n",
1139                             ioc->name, __func__);
1140                         rc = -EFAULT;
1141                         goto out;
1142                 }
1143                 ssleep(1);
1144                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1145                 pr_info(MPT3SAS_FMT
1146                         "%s: waiting for operational state(count=%d)\n",
1147                         ioc->name, __func__, wait_state_count);
1148         }
1149         if (wait_state_count)
1150                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1151                     ioc->name, __func__);
1152
1153         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1154         if (!smid) {
1155                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1156                     ioc->name, __func__);
1157                 rc = -EAGAIN;
1158                 goto out;
1159         }
1160
1161         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1162         ioc->transport_cmds.smid = smid;
1163
1164         sz = sizeof(struct phy_error_log_request) +
1165             sizeof(struct phy_error_log_reply);
1166         data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1167         if (!data_out) {
1168                 pr_err("failure at %s:%d/%s()!\n", __FILE__,
1169                     __LINE__, __func__);
1170                 rc = -ENOMEM;
1171                 mpt3sas_base_free_smid(ioc, smid);
1172                 goto out;
1173         }
1174
1175         rc = -EINVAL;
1176         memset(data_out, 0, sz);
1177         phy_error_log_request = data_out;
1178         phy_error_log_request->smp_frame_type = 0x40;
1179         phy_error_log_request->function = 0x11;
1180         phy_error_log_request->request_length = 2;
1181         phy_error_log_request->allocated_response_length = 0;
1182         phy_error_log_request->phy_identifier = phy->number;
1183
1184         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1185         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1186         mpi_request->PhysicalPort = 0xFF;
1187         mpi_request->VF_ID = 0; /* TODO */
1188         mpi_request->VP_ID = 0;
1189         mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1190         mpi_request->RequestDataLength =
1191             cpu_to_le16(sizeof(struct phy_error_log_request));
1192         psge = &mpi_request->SGL;
1193
1194         ioc->build_sg(ioc, psge, data_out_dma,
1195                 sizeof(struct phy_error_log_request),
1196             data_out_dma + sizeof(struct phy_error_log_request),
1197             sizeof(struct phy_error_log_reply));
1198
1199         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1200                 "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n",
1201                 ioc->name, (unsigned long long)phy->identify.sas_address,
1202                 phy->number));
1203         init_completion(&ioc->transport_cmds.done);
1204         ioc->put_smid_default(ioc, smid);
1205         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
1206
1207         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
1208                 pr_err(MPT3SAS_FMT "%s: timeout\n",
1209                     ioc->name, __func__);
1210                 _debug_dump_mf(mpi_request,
1211                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1212                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
1213                         issue_reset = 1;
1214                 goto issue_host_reset;
1215         }
1216
1217         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1218                 "phy_error_log - complete\n", ioc->name));
1219
1220         if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
1221
1222                 mpi_reply = ioc->transport_cmds.reply;
1223
1224                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1225                     "phy_error_log - reply data transfer size(%d)\n",
1226                     ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1227
1228                 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1229                     sizeof(struct phy_error_log_reply))
1230                         goto out;
1231
1232                 phy_error_log_reply = data_out +
1233                     sizeof(struct phy_error_log_request);
1234
1235                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1236                     "phy_error_log - function_result(%d)\n",
1237                     ioc->name, phy_error_log_reply->function_result));
1238
1239                 phy->invalid_dword_count =
1240                     be32_to_cpu(phy_error_log_reply->invalid_dword);
1241                 phy->running_disparity_error_count =
1242                     be32_to_cpu(phy_error_log_reply->running_disparity_error);
1243                 phy->loss_of_dword_sync_count =
1244                     be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1245                 phy->phy_reset_problem_count =
1246                     be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1247                 rc = 0;
1248         } else
1249                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1250                     "phy_error_log - no reply\n", ioc->name));
1251
1252  issue_host_reset:
1253         if (issue_reset)
1254                 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
1255  out:
1256         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
1257         if (data_out)
1258                 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1259
1260         mutex_unlock(&ioc->transport_cmds.mutex);
1261         return rc;
1262 }
1263
1264 /**
1265  * _transport_get_linkerrors - return phy counters for both hba and expanders
1266  * @phy: The sas phy object
1267  *
1268  * Returns 0 for success, non-zero for failure.
1269  *
1270  */
1271 static int
1272 _transport_get_linkerrors(struct sas_phy *phy)
1273 {
1274         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1275         unsigned long flags;
1276         Mpi2ConfigReply_t mpi_reply;
1277         Mpi2SasPhyPage1_t phy_pg1;
1278
1279         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1280         if (_transport_sas_node_find_by_sas_address(ioc,
1281             phy->identify.sas_address) == NULL) {
1282                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1283                 return -EINVAL;
1284         }
1285         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1286
1287         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1288                 return _transport_get_expander_phy_error_log(ioc, phy);
1289
1290         /* get hba phy error logs */
1291         if ((mpt3sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
1292                     phy->number))) {
1293                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1294                     ioc->name, __FILE__, __LINE__, __func__);
1295                 return -ENXIO;
1296         }
1297
1298         if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1299                 pr_info(MPT3SAS_FMT
1300                         "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n",
1301                         ioc->name, phy->number,
1302                         le16_to_cpu(mpi_reply.IOCStatus),
1303                     le32_to_cpu(mpi_reply.IOCLogInfo));
1304
1305         phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
1306         phy->running_disparity_error_count =
1307             le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
1308         phy->loss_of_dword_sync_count =
1309             le32_to_cpu(phy_pg1.LossDwordSynchCount);
1310         phy->phy_reset_problem_count =
1311             le32_to_cpu(phy_pg1.PhyResetProblemCount);
1312         return 0;
1313 }
1314
1315 /**
1316  * _transport_get_enclosure_identifier -
1317  * @phy: The sas phy object
1318  *
1319  * Obtain the enclosure logical id for an expander.
1320  * Returns 0 for success, non-zero for failure.
1321  */
1322 static int
1323 _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1324 {
1325         struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1326         struct _sas_device *sas_device;
1327         unsigned long flags;
1328         int rc;
1329
1330         spin_lock_irqsave(&ioc->sas_device_lock, flags);
1331         sas_device = __mpt3sas_get_sdev_by_addr(ioc,
1332             rphy->identify.sas_address);
1333         if (sas_device) {
1334                 *identifier = sas_device->enclosure_logical_id;
1335                 rc = 0;
1336                 sas_device_put(sas_device);
1337         } else {
1338                 *identifier = 0;
1339                 rc = -ENXIO;
1340         }
1341
1342         spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1343         return rc;
1344 }
1345
1346 /**
1347  * _transport_get_bay_identifier -
1348  * @phy: The sas phy object
1349  *
1350  * Returns the slot id for a device that resides inside an enclosure.
1351  */
1352 static int
1353 _transport_get_bay_identifier(struct sas_rphy *rphy)
1354 {
1355         struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1356         struct _sas_device *sas_device;
1357         unsigned long flags;
1358         int rc;
1359
1360         spin_lock_irqsave(&ioc->sas_device_lock, flags);
1361         sas_device = __mpt3sas_get_sdev_by_addr(ioc,
1362             rphy->identify.sas_address);
1363         if (sas_device) {
1364                 rc = sas_device->slot;
1365                 sas_device_put(sas_device);
1366         } else {
1367                 rc = -ENXIO;
1368         }
1369         spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1370         return rc;
1371 }
1372
1373 /* phy control request structure */
1374 struct phy_control_request {
1375         u8 smp_frame_type; /* 0x40 */
1376         u8 function; /* 0x91 */
1377         u8 allocated_response_length;
1378         u8 request_length; /* 0x09 */
1379         u16 expander_change_count;
1380         u8 reserved_1[3];
1381         u8 phy_identifier;
1382         u8 phy_operation;
1383         u8 reserved_2[13];
1384         u64 attached_device_name;
1385         u8 programmed_min_physical_link_rate;
1386         u8 programmed_max_physical_link_rate;
1387         u8 reserved_3[6];
1388 };
1389
1390 /* phy control reply structure */
1391 struct phy_control_reply {
1392         u8 smp_frame_type; /* 0x41 */
1393         u8 function; /* 0x11 */
1394         u8 function_result;
1395         u8 response_length;
1396 };
1397
1398 #define SMP_PHY_CONTROL_LINK_RESET      (0x01)
1399 #define SMP_PHY_CONTROL_HARD_RESET      (0x02)
1400 #define SMP_PHY_CONTROL_DISABLE         (0x03)
1401
1402 /**
1403  * _transport_expander_phy_control - expander phy control
1404  * @ioc: per adapter object
1405  * @phy: The sas phy object
1406  *
1407  * Returns 0 for success, non-zero for failure.
1408  *
1409  */
1410 static int
1411 _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
1412         struct sas_phy *phy, u8 phy_operation)
1413 {
1414         Mpi2SmpPassthroughRequest_t *mpi_request;
1415         Mpi2SmpPassthroughReply_t *mpi_reply;
1416         struct phy_control_request *phy_control_request;
1417         struct phy_control_reply *phy_control_reply;
1418         int rc;
1419         u16 smid;
1420         u32 ioc_state;
1421         void *psge;
1422         u8 issue_reset = 0;
1423         void *data_out = NULL;
1424         dma_addr_t data_out_dma;
1425         u32 sz;
1426         u16 wait_state_count;
1427
1428         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1429                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1430                     __func__, ioc->name);
1431                 return -EFAULT;
1432         }
1433
1434         mutex_lock(&ioc->transport_cmds.mutex);
1435
1436         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1437                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n",
1438                     ioc->name, __func__);
1439                 rc = -EAGAIN;
1440                 goto out;
1441         }
1442         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1443
1444         wait_state_count = 0;
1445         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1446         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1447                 if (wait_state_count++ == 10) {
1448                         pr_err(MPT3SAS_FMT
1449                             "%s: failed due to ioc not operational\n",
1450                             ioc->name, __func__);
1451                         rc = -EFAULT;
1452                         goto out;
1453                 }
1454                 ssleep(1);
1455                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1456                 pr_info(MPT3SAS_FMT
1457                         "%s: waiting for operational state(count=%d)\n",
1458                         ioc->name, __func__, wait_state_count);
1459         }
1460         if (wait_state_count)
1461                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1462                     ioc->name, __func__);
1463
1464         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1465         if (!smid) {
1466                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1467                     ioc->name, __func__);
1468                 rc = -EAGAIN;
1469                 goto out;
1470         }
1471
1472         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1473         ioc->transport_cmds.smid = smid;
1474
1475         sz = sizeof(struct phy_control_request) +
1476             sizeof(struct phy_control_reply);
1477         data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1478         if (!data_out) {
1479                 pr_err("failure at %s:%d/%s()!\n", __FILE__,
1480                     __LINE__, __func__);
1481                 rc = -ENOMEM;
1482                 mpt3sas_base_free_smid(ioc, smid);
1483                 goto out;
1484         }
1485
1486         rc = -EINVAL;
1487         memset(data_out, 0, sz);
1488         phy_control_request = data_out;
1489         phy_control_request->smp_frame_type = 0x40;
1490         phy_control_request->function = 0x91;
1491         phy_control_request->request_length = 9;
1492         phy_control_request->allocated_response_length = 0;
1493         phy_control_request->phy_identifier = phy->number;
1494         phy_control_request->phy_operation = phy_operation;
1495         phy_control_request->programmed_min_physical_link_rate =
1496             phy->minimum_linkrate << 4;
1497         phy_control_request->programmed_max_physical_link_rate =
1498             phy->maximum_linkrate << 4;
1499
1500         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1501         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1502         mpi_request->PhysicalPort = 0xFF;
1503         mpi_request->VF_ID = 0; /* TODO */
1504         mpi_request->VP_ID = 0;
1505         mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1506         mpi_request->RequestDataLength =
1507             cpu_to_le16(sizeof(struct phy_error_log_request));
1508         psge = &mpi_request->SGL;
1509
1510         ioc->build_sg(ioc, psge, data_out_dma,
1511                             sizeof(struct phy_control_request),
1512             data_out_dma + sizeof(struct phy_control_request),
1513             sizeof(struct phy_control_reply));
1514
1515         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1516                 "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
1517                 ioc->name, (unsigned long long)phy->identify.sas_address,
1518                 phy->number, phy_operation));
1519         init_completion(&ioc->transport_cmds.done);
1520         ioc->put_smid_default(ioc, smid);
1521         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
1522
1523         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
1524                 pr_err(MPT3SAS_FMT "%s: timeout\n",
1525                     ioc->name, __func__);
1526                 _debug_dump_mf(mpi_request,
1527                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1528                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
1529                         issue_reset = 1;
1530                 goto issue_host_reset;
1531         }
1532
1533         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1534                 "phy_control - complete\n", ioc->name));
1535
1536         if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
1537
1538                 mpi_reply = ioc->transport_cmds.reply;
1539
1540                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1541                     "phy_control - reply data transfer size(%d)\n",
1542                     ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1543
1544                 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1545                     sizeof(struct phy_control_reply))
1546                         goto out;
1547
1548                 phy_control_reply = data_out +
1549                     sizeof(struct phy_control_request);
1550
1551                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1552                     "phy_control - function_result(%d)\n",
1553                     ioc->name, phy_control_reply->function_result));
1554
1555                 rc = 0;
1556         } else
1557                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1558                     "phy_control - no reply\n", ioc->name));
1559
1560  issue_host_reset:
1561         if (issue_reset)
1562                 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
1563  out:
1564         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
1565         if (data_out)
1566                 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1567
1568         mutex_unlock(&ioc->transport_cmds.mutex);
1569         return rc;
1570 }
1571
1572 /**
1573  * _transport_phy_reset -
1574  * @phy: The sas phy object
1575  * @hard_reset:
1576  *
1577  * Returns 0 for success, non-zero for failure.
1578  */
1579 static int
1580 _transport_phy_reset(struct sas_phy *phy, int hard_reset)
1581 {
1582         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1583         Mpi2SasIoUnitControlReply_t mpi_reply;
1584         Mpi2SasIoUnitControlRequest_t mpi_request;
1585         unsigned long flags;
1586
1587         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1588         if (_transport_sas_node_find_by_sas_address(ioc,
1589             phy->identify.sas_address) == NULL) {
1590                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1591                 return -EINVAL;
1592         }
1593         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1594
1595         /* handle expander phys */
1596         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1597                 return _transport_expander_phy_control(ioc, phy,
1598                     (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1599                     SMP_PHY_CONTROL_LINK_RESET);
1600
1601         /* handle hba phys */
1602         memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
1603         mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
1604         mpi_request.Operation = hard_reset ?
1605             MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
1606         mpi_request.PhyNum = phy->number;
1607
1608         if ((mpt3sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
1609                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1610                     ioc->name, __FILE__, __LINE__, __func__);
1611                 return -ENXIO;
1612         }
1613
1614         if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1615                 pr_info(MPT3SAS_FMT
1616                 "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
1617                 ioc->name, phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1618                     le32_to_cpu(mpi_reply.IOCLogInfo));
1619
1620         return 0;
1621 }
1622
1623 /**
1624  * _transport_phy_enable - enable/disable phys
1625  * @phy: The sas phy object
1626  * @enable: enable phy when true
1627  *
1628  * Only support sas_host direct attached phys.
1629  * Returns 0 for success, non-zero for failure.
1630  */
1631 static int
1632 _transport_phy_enable(struct sas_phy *phy, int enable)
1633 {
1634         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1635         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1636         Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
1637         Mpi2ConfigReply_t mpi_reply;
1638         u16 ioc_status;
1639         u16 sz;
1640         int rc = 0;
1641         unsigned long flags;
1642         int i, discovery_active;
1643
1644         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1645         if (_transport_sas_node_find_by_sas_address(ioc,
1646             phy->identify.sas_address) == NULL) {
1647                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1648                 return -EINVAL;
1649         }
1650         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1651
1652         /* handle expander phys */
1653         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1654                 return _transport_expander_phy_control(ioc, phy,
1655                     (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1656                     SMP_PHY_CONTROL_DISABLE);
1657
1658         /* handle hba phys */
1659
1660         /* read sas_iounit page 0 */
1661         sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
1662             sizeof(Mpi2SasIOUnit0PhyData_t));
1663         sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
1664         if (!sas_iounit_pg0) {
1665                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1666                     ioc->name, __FILE__, __LINE__, __func__);
1667                 rc = -ENOMEM;
1668                 goto out;
1669         }
1670         if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
1671             sas_iounit_pg0, sz))) {
1672                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1673                     ioc->name, __FILE__, __LINE__, __func__);
1674                 rc = -ENXIO;
1675                 goto out;
1676         }
1677         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1678             MPI2_IOCSTATUS_MASK;
1679         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1680                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1681                     ioc->name, __FILE__, __LINE__, __func__);
1682                 rc = -EIO;
1683                 goto out;
1684         }
1685
1686         /* unable to enable/disable phys when when discovery is active */
1687         for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
1688                 if (sas_iounit_pg0->PhyData[i].PortFlags &
1689                     MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
1690                         pr_err(MPT3SAS_FMT "discovery is active on " \
1691                             "port = %d, phy = %d: unable to enable/disable "
1692                             "phys, try again later!\n", ioc->name,
1693                             sas_iounit_pg0->PhyData[i].Port, i);
1694                         discovery_active = 1;
1695                 }
1696         }
1697
1698         if (discovery_active) {
1699                 rc = -EAGAIN;
1700                 goto out;
1701         }
1702
1703         /* read sas_iounit page 1 */
1704         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1705             sizeof(Mpi2SasIOUnit1PhyData_t));
1706         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1707         if (!sas_iounit_pg1) {
1708                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1709                     ioc->name, __FILE__, __LINE__, __func__);
1710                 rc = -ENOMEM;
1711                 goto out;
1712         }
1713         if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1714             sas_iounit_pg1, sz))) {
1715                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1716                     ioc->name, __FILE__, __LINE__, __func__);
1717                 rc = -ENXIO;
1718                 goto out;
1719         }
1720         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1721             MPI2_IOCSTATUS_MASK;
1722         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1723                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1724                     ioc->name, __FILE__, __LINE__, __func__);
1725                 rc = -EIO;
1726                 goto out;
1727         }
1728
1729         /* copy Port/PortFlags/PhyFlags from page 0 */
1730         for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
1731                 sas_iounit_pg1->PhyData[i].Port =
1732                     sas_iounit_pg0->PhyData[i].Port;
1733                 sas_iounit_pg1->PhyData[i].PortFlags =
1734                     (sas_iounit_pg0->PhyData[i].PortFlags &
1735                     MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
1736                 sas_iounit_pg1->PhyData[i].PhyFlags =
1737                     (sas_iounit_pg0->PhyData[i].PhyFlags &
1738                     (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
1739                     MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
1740         }
1741
1742         if (enable)
1743                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1744                     &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1745         else
1746                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1747                     |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1748
1749         mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1750
1751         /* link reset */
1752         if (enable)
1753                 _transport_phy_reset(phy, 0);
1754
1755  out:
1756         kfree(sas_iounit_pg1);
1757         kfree(sas_iounit_pg0);
1758         return rc;
1759 }
1760
1761 /**
1762  * _transport_phy_speed - set phy min/max link rates
1763  * @phy: The sas phy object
1764  * @rates: rates defined in sas_phy_linkrates
1765  *
1766  * Only support sas_host direct attached phys.
1767  * Returns 0 for success, non-zero for failure.
1768  */
1769 static int
1770 _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1771 {
1772         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1773         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1774         Mpi2SasPhyPage0_t phy_pg0;
1775         Mpi2ConfigReply_t mpi_reply;
1776         u16 ioc_status;
1777         u16 sz;
1778         int i;
1779         int rc = 0;
1780         unsigned long flags;
1781
1782         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1783         if (_transport_sas_node_find_by_sas_address(ioc,
1784             phy->identify.sas_address) == NULL) {
1785                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1786                 return -EINVAL;
1787         }
1788         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1789
1790         if (!rates->minimum_linkrate)
1791                 rates->minimum_linkrate = phy->minimum_linkrate;
1792         else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1793                 rates->minimum_linkrate = phy->minimum_linkrate_hw;
1794
1795         if (!rates->maximum_linkrate)
1796                 rates->maximum_linkrate = phy->maximum_linkrate;
1797         else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1798                 rates->maximum_linkrate = phy->maximum_linkrate_hw;
1799
1800         /* handle expander phys */
1801         if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1802                 phy->minimum_linkrate = rates->minimum_linkrate;
1803                 phy->maximum_linkrate = rates->maximum_linkrate;
1804                 return _transport_expander_phy_control(ioc, phy,
1805                     SMP_PHY_CONTROL_LINK_RESET);
1806         }
1807
1808         /* handle hba phys */
1809
1810         /* sas_iounit page 1 */
1811         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1812             sizeof(Mpi2SasIOUnit1PhyData_t));
1813         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1814         if (!sas_iounit_pg1) {
1815                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1816                     ioc->name, __FILE__, __LINE__, __func__);
1817                 rc = -ENOMEM;
1818                 goto out;
1819         }
1820         if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1821             sas_iounit_pg1, sz))) {
1822                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1823                     ioc->name, __FILE__, __LINE__, __func__);
1824                 rc = -ENXIO;
1825                 goto out;
1826         }
1827         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1828             MPI2_IOCSTATUS_MASK;
1829         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1830                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1831                     ioc->name, __FILE__, __LINE__, __func__);
1832                 rc = -EIO;
1833                 goto out;
1834         }
1835
1836         for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1837                 if (phy->number != i) {
1838                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1839                             (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1840                             (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1841                 } else {
1842                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1843                             (rates->minimum_linkrate +
1844                             (rates->maximum_linkrate << 4));
1845                 }
1846         }
1847
1848         if (mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1849             sz)) {
1850                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1851                     ioc->name, __FILE__, __LINE__, __func__);
1852                 rc = -ENXIO;
1853                 goto out;
1854         }
1855
1856         /* link reset */
1857         _transport_phy_reset(phy, 0);
1858
1859         /* read phy page 0, then update the rates in the sas transport phy */
1860         if (!mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1861             phy->number)) {
1862                 phy->minimum_linkrate = _transport_convert_phy_link_rate(
1863                     phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
1864                 phy->maximum_linkrate = _transport_convert_phy_link_rate(
1865                     phy_pg0.ProgrammedLinkRate >> 4);
1866                 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1867                     phy_pg0.NegotiatedLinkRate &
1868                     MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1869         }
1870
1871  out:
1872         kfree(sas_iounit_pg1);
1873         return rc;
1874 }
1875
1876 static int
1877 _transport_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
1878                 dma_addr_t *dma_addr, size_t *dma_len, void **p)
1879 {
1880         /* Check if the request is split across multiple segments */
1881         if (buf->sg_cnt > 1) {
1882                 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr,
1883                                 GFP_KERNEL);
1884                 if (!*p)
1885                         return -ENOMEM;
1886                 *dma_len = buf->payload_len;
1887         } else {
1888                 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL))
1889                         return -ENOMEM;
1890                 *dma_addr = sg_dma_address(buf->sg_list);
1891                 *dma_len = sg_dma_len(buf->sg_list);
1892                 *p = NULL;
1893         }
1894
1895         return 0;
1896 }
1897
1898 static void
1899 _transport_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
1900                 dma_addr_t dma_addr, void *p)
1901 {
1902         if (p)
1903                 dma_free_coherent(dev, buf->payload_len, p, dma_addr);
1904         else
1905                 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL);
1906 }
1907
1908 /**
1909  * _transport_smp_handler - transport portal for smp passthru
1910  * @shost: shost object
1911  * @rphy: sas transport rphy object
1912  * @req:
1913  *
1914  * This used primarily for smp_utils.
1915  * Example:
1916  *           smp_rep_general /sys/class/bsg/expander-5:0
1917  */
1918 static void
1919 _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
1920                 struct sas_rphy *rphy)
1921 {
1922         struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1923         Mpi2SmpPassthroughRequest_t *mpi_request;
1924         Mpi2SmpPassthroughReply_t *mpi_reply;
1925         int rc;
1926         u16 smid;
1927         u32 ioc_state;
1928         void *psge;
1929         dma_addr_t dma_addr_in;
1930         dma_addr_t dma_addr_out;
1931         void *addr_in = NULL;
1932         void *addr_out = NULL;
1933         size_t dma_len_in;
1934         size_t dma_len_out;
1935         u16 wait_state_count;
1936         unsigned int reslen = 0;
1937
1938         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1939                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1940                     __func__, ioc->name);
1941                 rc = -EFAULT;
1942                 goto job_done;
1943         }
1944
1945         rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1946         if (rc)
1947                 goto job_done;
1948
1949         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1950                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ioc->name,
1951                     __func__);
1952                 rc = -EAGAIN;
1953                 goto out;
1954         }
1955         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1956
1957         rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->request_payload,
1958                         &dma_addr_out, &dma_len_out, &addr_out);
1959         if (rc)
1960                 goto out;
1961         if (addr_out) {
1962                 sg_copy_to_buffer(job->request_payload.sg_list,
1963                                 job->request_payload.sg_cnt, addr_out,
1964                                 job->request_payload.payload_len);
1965         }
1966
1967         rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
1968                         &dma_addr_in, &dma_len_in, &addr_in);
1969         if (rc)
1970                 goto unmap_out;
1971
1972         wait_state_count = 0;
1973         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1974         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1975                 if (wait_state_count++ == 10) {
1976                         pr_err(MPT3SAS_FMT
1977                             "%s: failed due to ioc not operational\n",
1978                             ioc->name, __func__);
1979                         rc = -EFAULT;
1980                         goto unmap_in;
1981                 }
1982                 ssleep(1);
1983                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1984                 pr_info(MPT3SAS_FMT
1985                         "%s: waiting for operational state(count=%d)\n",
1986                         ioc->name, __func__, wait_state_count);
1987         }
1988         if (wait_state_count)
1989                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1990                     ioc->name, __func__);
1991
1992         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1993         if (!smid) {
1994                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1995                     ioc->name, __func__);
1996                 rc = -EAGAIN;
1997                 goto unmap_in;
1998         }
1999
2000         rc = 0;
2001         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
2002         ioc->transport_cmds.smid = smid;
2003
2004         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
2005         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
2006         mpi_request->PhysicalPort = 0xFF;
2007         mpi_request->SASAddress = (rphy) ?
2008             cpu_to_le64(rphy->identify.sas_address) :
2009             cpu_to_le64(ioc->sas_hba.sas_address);
2010         mpi_request->RequestDataLength = cpu_to_le16(dma_len_out - 4);
2011         psge = &mpi_request->SGL;
2012
2013         ioc->build_sg(ioc, psge, dma_addr_out, dma_len_out - 4, dma_addr_in,
2014                         dma_len_in - 4);
2015
2016         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2017                 "%s - sending smp request\n", ioc->name, __func__));
2018
2019         init_completion(&ioc->transport_cmds.done);
2020         ioc->put_smid_default(ioc, smid);
2021         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
2022
2023         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
2024                 pr_err(MPT3SAS_FMT "%s : timeout\n",
2025                     __func__, ioc->name);
2026                 _debug_dump_mf(mpi_request,
2027                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
2028                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) {
2029                         mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
2030                         rc = -ETIMEDOUT;
2031                         goto unmap_in;
2032                 }
2033         }
2034
2035         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2036                 "%s - complete\n", ioc->name, __func__));
2037
2038         if (!(ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID)) {
2039                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2040                     "%s - no reply\n", ioc->name, __func__));
2041                 rc = -ENXIO;
2042                 goto unmap_in;
2043         }
2044
2045         mpi_reply = ioc->transport_cmds.reply;
2046
2047         dtransportprintk(ioc,
2048                 pr_info(MPT3SAS_FMT "%s - reply data transfer size(%d)\n",
2049                         ioc->name, __func__,
2050                         le16_to_cpu(mpi_reply->ResponseDataLength)));
2051
2052         memcpy(job->reply, mpi_reply, sizeof(*mpi_reply));
2053         job->reply_len = sizeof(*mpi_reply);
2054         reslen = le16_to_cpu(mpi_reply->ResponseDataLength);
2055
2056         if (addr_in) {
2057                 sg_copy_to_buffer(job->reply_payload.sg_list,
2058                                 job->reply_payload.sg_cnt, addr_in,
2059                                 job->reply_payload.payload_len);
2060         }
2061
2062         rc = 0;
2063  unmap_in:
2064         _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
2065                         dma_addr_in, addr_in);
2066  unmap_out:
2067         _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->request_payload,
2068                         dma_addr_out, addr_out);
2069  out:
2070         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
2071         mutex_unlock(&ioc->transport_cmds.mutex);
2072 job_done:
2073         bsg_job_done(job, rc, reslen);
2074 }
2075
2076 struct sas_function_template mpt3sas_transport_functions = {
2077         .get_linkerrors         = _transport_get_linkerrors,
2078         .get_enclosure_identifier = _transport_get_enclosure_identifier,
2079         .get_bay_identifier     = _transport_get_bay_identifier,
2080         .phy_reset              = _transport_phy_reset,
2081         .phy_enable             = _transport_phy_enable,
2082         .set_phy_speed          = _transport_phy_speed,
2083         .smp_handler            = _transport_smp_handler,
2084 };
2085
2086 struct scsi_transport_template *mpt3sas_transport_template;