Linux-libre 4.14.12-gnu
[librecmc/linux-libre.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                 sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
850                 list_del(&mpt3sas_phy->port_siblings);
851         }
852         sas_port_delete(mpt3sas_port->port);
853         kfree(mpt3sas_port);
854 }
855
856 /**
857  * mpt3sas_transport_add_host_phy - report sas_host phy to transport
858  * @ioc: per adapter object
859  * @mpt3sas_phy: mpt3sas per phy object
860  * @phy_pg0: sas phy page 0
861  * @parent_dev: parent device class object
862  *
863  * Returns 0 for success, non-zero for failure.
864  */
865 int
866 mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
867         *mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev)
868 {
869         struct sas_phy *phy;
870         int phy_index = mpt3sas_phy->phy_id;
871
872
873         INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
874         phy = sas_phy_alloc(parent_dev, phy_index);
875         if (!phy) {
876                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
877                     ioc->name, __FILE__, __LINE__, __func__);
878                 return -1;
879         }
880         if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
881             &mpt3sas_phy->identify))) {
882                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
883                     ioc->name, __FILE__, __LINE__, __func__);
884                 sas_phy_free(phy);
885                 return -1;
886         }
887         phy->identify = mpt3sas_phy->identify;
888         mpt3sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle);
889         if (mpt3sas_phy->attached_handle)
890                 _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
891                     &mpt3sas_phy->remote_identify);
892         phy->identify.phy_identifier = mpt3sas_phy->phy_id;
893         phy->negotiated_linkrate = _transport_convert_phy_link_rate(
894             phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
895         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
896             phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
897         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
898             phy_pg0.HwLinkRate >> 4);
899         phy->minimum_linkrate = _transport_convert_phy_link_rate(
900             phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
901         phy->maximum_linkrate = _transport_convert_phy_link_rate(
902             phy_pg0.ProgrammedLinkRate >> 4);
903
904         if ((sas_phy_add(phy))) {
905                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
906                     ioc->name, __FILE__, __LINE__, __func__);
907                 sas_phy_free(phy);
908                 return -1;
909         }
910         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
911                 dev_printk(KERN_INFO, &phy->dev,
912                     "add: handle(0x%04x), sas_addr(0x%016llx)\n"
913                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
914                     mpt3sas_phy->handle, (unsigned long long)
915                     mpt3sas_phy->identify.sas_address,
916                     mpt3sas_phy->attached_handle,
917                     (unsigned long long)
918                     mpt3sas_phy->remote_identify.sas_address);
919         mpt3sas_phy->phy = phy;
920         return 0;
921 }
922
923
924 /**
925  * mpt3sas_transport_add_expander_phy - report expander phy to transport
926  * @ioc: per adapter object
927  * @mpt3sas_phy: mpt3sas per phy object
928  * @expander_pg1: expander page 1
929  * @parent_dev: parent device class object
930  *
931  * Returns 0 for success, non-zero for failure.
932  */
933 int
934 mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy
935         *mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1,
936         struct device *parent_dev)
937 {
938         struct sas_phy *phy;
939         int phy_index = mpt3sas_phy->phy_id;
940
941         INIT_LIST_HEAD(&mpt3sas_phy->port_siblings);
942         phy = sas_phy_alloc(parent_dev, phy_index);
943         if (!phy) {
944                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
945                     ioc->name, __FILE__, __LINE__, __func__);
946                 return -1;
947         }
948         if ((_transport_set_identify(ioc, mpt3sas_phy->handle,
949             &mpt3sas_phy->identify))) {
950                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
951                     ioc->name, __FILE__, __LINE__, __func__);
952                 sas_phy_free(phy);
953                 return -1;
954         }
955         phy->identify = mpt3sas_phy->identify;
956         mpt3sas_phy->attached_handle =
957             le16_to_cpu(expander_pg1.AttachedDevHandle);
958         if (mpt3sas_phy->attached_handle)
959                 _transport_set_identify(ioc, mpt3sas_phy->attached_handle,
960                     &mpt3sas_phy->remote_identify);
961         phy->identify.phy_identifier = mpt3sas_phy->phy_id;
962         phy->negotiated_linkrate = _transport_convert_phy_link_rate(
963             expander_pg1.NegotiatedLinkRate &
964             MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
965         phy->minimum_linkrate_hw = _transport_convert_phy_link_rate(
966             expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK);
967         phy->maximum_linkrate_hw = _transport_convert_phy_link_rate(
968             expander_pg1.HwLinkRate >> 4);
969         phy->minimum_linkrate = _transport_convert_phy_link_rate(
970             expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
971         phy->maximum_linkrate = _transport_convert_phy_link_rate(
972             expander_pg1.ProgrammedLinkRate >> 4);
973
974         if ((sas_phy_add(phy))) {
975                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
976                     ioc->name, __FILE__, __LINE__, __func__);
977                 sas_phy_free(phy);
978                 return -1;
979         }
980         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
981                 dev_printk(KERN_INFO, &phy->dev,
982                     "add: handle(0x%04x), sas_addr(0x%016llx)\n"
983                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
984                     mpt3sas_phy->handle, (unsigned long long)
985                     mpt3sas_phy->identify.sas_address,
986                     mpt3sas_phy->attached_handle,
987                     (unsigned long long)
988                     mpt3sas_phy->remote_identify.sas_address);
989         mpt3sas_phy->phy = phy;
990         return 0;
991 }
992
993 /**
994  * mpt3sas_transport_update_links - refreshing phy link changes
995  * @ioc: per adapter object
996  * @sas_address: sas address of parent expander or sas host
997  * @handle: attached device handle
998  * @phy_numberv: phy number
999  * @link_rate: new link rate
1000  *
1001  * Returns nothing.
1002  */
1003 void
1004 mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc,
1005         u64 sas_address, u16 handle, u8 phy_number, u8 link_rate)
1006 {
1007         unsigned long flags;
1008         struct _sas_node *sas_node;
1009         struct _sas_phy *mpt3sas_phy;
1010
1011         if (ioc->shost_recovery || ioc->pci_error_recovery)
1012                 return;
1013
1014         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1015         sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address);
1016         if (!sas_node) {
1017                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1018                 return;
1019         }
1020
1021         mpt3sas_phy = &sas_node->phy[phy_number];
1022         mpt3sas_phy->attached_handle = handle;
1023         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1024         if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
1025                 _transport_set_identify(ioc, handle,
1026                     &mpt3sas_phy->remote_identify);
1027                 _transport_add_phy_to_an_existing_port(ioc, sas_node,
1028                     mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address);
1029         } else
1030                 memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct
1031                     sas_identify));
1032
1033         if (mpt3sas_phy->phy)
1034                 mpt3sas_phy->phy->negotiated_linkrate =
1035                     _transport_convert_phy_link_rate(link_rate);
1036
1037         if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
1038                 dev_printk(KERN_INFO, &mpt3sas_phy->phy->dev,
1039                     "refresh: parent sas_addr(0x%016llx),\n"
1040                     "\tlink_rate(0x%02x), phy(%d)\n"
1041                     "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n",
1042                     (unsigned long long)sas_address,
1043                     link_rate, phy_number, handle, (unsigned long long)
1044                     mpt3sas_phy->remote_identify.sas_address);
1045 }
1046
1047 static inline void *
1048 phy_to_ioc(struct sas_phy *phy)
1049 {
1050         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1051         return shost_priv(shost);
1052 }
1053
1054 static inline void *
1055 rphy_to_ioc(struct sas_rphy *rphy)
1056 {
1057         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
1058         return shost_priv(shost);
1059 }
1060
1061 /* report phy error log structure */
1062 struct phy_error_log_request {
1063         u8 smp_frame_type; /* 0x40 */
1064         u8 function; /* 0x11 */
1065         u8 allocated_response_length;
1066         u8 request_length; /* 02 */
1067         u8 reserved_1[5];
1068         u8 phy_identifier;
1069         u8 reserved_2[2];
1070 };
1071
1072 /* report phy error log reply structure */
1073 struct phy_error_log_reply {
1074         u8 smp_frame_type; /* 0x41 */
1075         u8 function; /* 0x11 */
1076         u8 function_result;
1077         u8 response_length;
1078         __be16 expander_change_count;
1079         u8 reserved_1[3];
1080         u8 phy_identifier;
1081         u8 reserved_2[2];
1082         __be32 invalid_dword;
1083         __be32 running_disparity_error;
1084         __be32 loss_of_dword_sync;
1085         __be32 phy_reset_problem;
1086 };
1087
1088 /**
1089  * _transport_get_expander_phy_error_log - return expander counters
1090  * @ioc: per adapter object
1091  * @phy: The sas phy object
1092  *
1093  * Returns 0 for success, non-zero for failure.
1094  *
1095  */
1096 static int
1097 _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
1098         struct sas_phy *phy)
1099 {
1100         Mpi2SmpPassthroughRequest_t *mpi_request;
1101         Mpi2SmpPassthroughReply_t *mpi_reply;
1102         struct phy_error_log_request *phy_error_log_request;
1103         struct phy_error_log_reply *phy_error_log_reply;
1104         int rc;
1105         u16 smid;
1106         u32 ioc_state;
1107         void *psge;
1108         u8 issue_reset = 0;
1109         void *data_out = NULL;
1110         dma_addr_t data_out_dma;
1111         u32 sz;
1112         u16 wait_state_count;
1113
1114         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1115                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1116                     __func__, ioc->name);
1117                 return -EFAULT;
1118         }
1119
1120         mutex_lock(&ioc->transport_cmds.mutex);
1121
1122         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1123                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n",
1124                     ioc->name, __func__);
1125                 rc = -EAGAIN;
1126                 goto out;
1127         }
1128         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1129
1130         wait_state_count = 0;
1131         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1132         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1133                 if (wait_state_count++ == 10) {
1134                         pr_err(MPT3SAS_FMT
1135                             "%s: failed due to ioc not operational\n",
1136                             ioc->name, __func__);
1137                         rc = -EFAULT;
1138                         goto out;
1139                 }
1140                 ssleep(1);
1141                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1142                 pr_info(MPT3SAS_FMT
1143                         "%s: waiting for operational state(count=%d)\n",
1144                         ioc->name, __func__, wait_state_count);
1145         }
1146         if (wait_state_count)
1147                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1148                     ioc->name, __func__);
1149
1150         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1151         if (!smid) {
1152                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1153                     ioc->name, __func__);
1154                 rc = -EAGAIN;
1155                 goto out;
1156         }
1157
1158         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1159         ioc->transport_cmds.smid = smid;
1160
1161         sz = sizeof(struct phy_error_log_request) +
1162             sizeof(struct phy_error_log_reply);
1163         data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1164         if (!data_out) {
1165                 pr_err("failure at %s:%d/%s()!\n", __FILE__,
1166                     __LINE__, __func__);
1167                 rc = -ENOMEM;
1168                 mpt3sas_base_free_smid(ioc, smid);
1169                 goto out;
1170         }
1171
1172         rc = -EINVAL;
1173         memset(data_out, 0, sz);
1174         phy_error_log_request = data_out;
1175         phy_error_log_request->smp_frame_type = 0x40;
1176         phy_error_log_request->function = 0x11;
1177         phy_error_log_request->request_length = 2;
1178         phy_error_log_request->allocated_response_length = 0;
1179         phy_error_log_request->phy_identifier = phy->number;
1180
1181         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1182         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1183         mpi_request->PhysicalPort = 0xFF;
1184         mpi_request->VF_ID = 0; /* TODO */
1185         mpi_request->VP_ID = 0;
1186         mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1187         mpi_request->RequestDataLength =
1188             cpu_to_le16(sizeof(struct phy_error_log_request));
1189         psge = &mpi_request->SGL;
1190
1191         ioc->build_sg(ioc, psge, data_out_dma,
1192                 sizeof(struct phy_error_log_request),
1193             data_out_dma + sizeof(struct phy_error_log_request),
1194             sizeof(struct phy_error_log_reply));
1195
1196         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1197                 "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n",
1198                 ioc->name, (unsigned long long)phy->identify.sas_address,
1199                 phy->number));
1200         init_completion(&ioc->transport_cmds.done);
1201         ioc->put_smid_default(ioc, smid);
1202         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
1203
1204         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
1205                 pr_err(MPT3SAS_FMT "%s: timeout\n",
1206                     ioc->name, __func__);
1207                 _debug_dump_mf(mpi_request,
1208                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1209                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
1210                         issue_reset = 1;
1211                 goto issue_host_reset;
1212         }
1213
1214         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1215                 "phy_error_log - complete\n", ioc->name));
1216
1217         if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
1218
1219                 mpi_reply = ioc->transport_cmds.reply;
1220
1221                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1222                     "phy_error_log - reply data transfer size(%d)\n",
1223                     ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1224
1225                 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1226                     sizeof(struct phy_error_log_reply))
1227                         goto out;
1228
1229                 phy_error_log_reply = data_out +
1230                     sizeof(struct phy_error_log_request);
1231
1232                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1233                     "phy_error_log - function_result(%d)\n",
1234                     ioc->name, phy_error_log_reply->function_result));
1235
1236                 phy->invalid_dword_count =
1237                     be32_to_cpu(phy_error_log_reply->invalid_dword);
1238                 phy->running_disparity_error_count =
1239                     be32_to_cpu(phy_error_log_reply->running_disparity_error);
1240                 phy->loss_of_dword_sync_count =
1241                     be32_to_cpu(phy_error_log_reply->loss_of_dword_sync);
1242                 phy->phy_reset_problem_count =
1243                     be32_to_cpu(phy_error_log_reply->phy_reset_problem);
1244                 rc = 0;
1245         } else
1246                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1247                     "phy_error_log - no reply\n", ioc->name));
1248
1249  issue_host_reset:
1250         if (issue_reset)
1251                 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
1252  out:
1253         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
1254         if (data_out)
1255                 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1256
1257         mutex_unlock(&ioc->transport_cmds.mutex);
1258         return rc;
1259 }
1260
1261 /**
1262  * _transport_get_linkerrors - return phy counters for both hba and expanders
1263  * @phy: The sas phy object
1264  *
1265  * Returns 0 for success, non-zero for failure.
1266  *
1267  */
1268 static int
1269 _transport_get_linkerrors(struct sas_phy *phy)
1270 {
1271         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1272         unsigned long flags;
1273         Mpi2ConfigReply_t mpi_reply;
1274         Mpi2SasPhyPage1_t phy_pg1;
1275
1276         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1277         if (_transport_sas_node_find_by_sas_address(ioc,
1278             phy->identify.sas_address) == NULL) {
1279                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1280                 return -EINVAL;
1281         }
1282         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1283
1284         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1285                 return _transport_get_expander_phy_error_log(ioc, phy);
1286
1287         /* get hba phy error logs */
1288         if ((mpt3sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1,
1289                     phy->number))) {
1290                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1291                     ioc->name, __FILE__, __LINE__, __func__);
1292                 return -ENXIO;
1293         }
1294
1295         if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1296                 pr_info(MPT3SAS_FMT
1297                         "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n",
1298                         ioc->name, phy->number,
1299                         le16_to_cpu(mpi_reply.IOCStatus),
1300                     le32_to_cpu(mpi_reply.IOCLogInfo));
1301
1302         phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount);
1303         phy->running_disparity_error_count =
1304             le32_to_cpu(phy_pg1.RunningDisparityErrorCount);
1305         phy->loss_of_dword_sync_count =
1306             le32_to_cpu(phy_pg1.LossDwordSynchCount);
1307         phy->phy_reset_problem_count =
1308             le32_to_cpu(phy_pg1.PhyResetProblemCount);
1309         return 0;
1310 }
1311
1312 /**
1313  * _transport_get_enclosure_identifier -
1314  * @phy: The sas phy object
1315  *
1316  * Obtain the enclosure logical id for an expander.
1317  * Returns 0 for success, non-zero for failure.
1318  */
1319 static int
1320 _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1321 {
1322         struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1323         struct _sas_device *sas_device;
1324         unsigned long flags;
1325         int rc;
1326
1327         spin_lock_irqsave(&ioc->sas_device_lock, flags);
1328         sas_device = __mpt3sas_get_sdev_by_addr(ioc,
1329             rphy->identify.sas_address);
1330         if (sas_device) {
1331                 *identifier = sas_device->enclosure_logical_id;
1332                 rc = 0;
1333                 sas_device_put(sas_device);
1334         } else {
1335                 *identifier = 0;
1336                 rc = -ENXIO;
1337         }
1338
1339         spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1340         return rc;
1341 }
1342
1343 /**
1344  * _transport_get_bay_identifier -
1345  * @phy: The sas phy object
1346  *
1347  * Returns the slot id for a device that resides inside an enclosure.
1348  */
1349 static int
1350 _transport_get_bay_identifier(struct sas_rphy *rphy)
1351 {
1352         struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy);
1353         struct _sas_device *sas_device;
1354         unsigned long flags;
1355         int rc;
1356
1357         spin_lock_irqsave(&ioc->sas_device_lock, flags);
1358         sas_device = __mpt3sas_get_sdev_by_addr(ioc,
1359             rphy->identify.sas_address);
1360         if (sas_device) {
1361                 rc = sas_device->slot;
1362                 sas_device_put(sas_device);
1363         } else {
1364                 rc = -ENXIO;
1365         }
1366         spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1367         return rc;
1368 }
1369
1370 /* phy control request structure */
1371 struct phy_control_request {
1372         u8 smp_frame_type; /* 0x40 */
1373         u8 function; /* 0x91 */
1374         u8 allocated_response_length;
1375         u8 request_length; /* 0x09 */
1376         u16 expander_change_count;
1377         u8 reserved_1[3];
1378         u8 phy_identifier;
1379         u8 phy_operation;
1380         u8 reserved_2[13];
1381         u64 attached_device_name;
1382         u8 programmed_min_physical_link_rate;
1383         u8 programmed_max_physical_link_rate;
1384         u8 reserved_3[6];
1385 };
1386
1387 /* phy control reply structure */
1388 struct phy_control_reply {
1389         u8 smp_frame_type; /* 0x41 */
1390         u8 function; /* 0x11 */
1391         u8 function_result;
1392         u8 response_length;
1393 };
1394
1395 #define SMP_PHY_CONTROL_LINK_RESET      (0x01)
1396 #define SMP_PHY_CONTROL_HARD_RESET      (0x02)
1397 #define SMP_PHY_CONTROL_DISABLE         (0x03)
1398
1399 /**
1400  * _transport_expander_phy_control - expander phy control
1401  * @ioc: per adapter object
1402  * @phy: The sas phy object
1403  *
1404  * Returns 0 for success, non-zero for failure.
1405  *
1406  */
1407 static int
1408 _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
1409         struct sas_phy *phy, u8 phy_operation)
1410 {
1411         Mpi2SmpPassthroughRequest_t *mpi_request;
1412         Mpi2SmpPassthroughReply_t *mpi_reply;
1413         struct phy_control_request *phy_control_request;
1414         struct phy_control_reply *phy_control_reply;
1415         int rc;
1416         u16 smid;
1417         u32 ioc_state;
1418         void *psge;
1419         u8 issue_reset = 0;
1420         void *data_out = NULL;
1421         dma_addr_t data_out_dma;
1422         u32 sz;
1423         u16 wait_state_count;
1424
1425         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1426                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1427                     __func__, ioc->name);
1428                 return -EFAULT;
1429         }
1430
1431         mutex_lock(&ioc->transport_cmds.mutex);
1432
1433         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1434                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n",
1435                     ioc->name, __func__);
1436                 rc = -EAGAIN;
1437                 goto out;
1438         }
1439         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1440
1441         wait_state_count = 0;
1442         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1443         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1444                 if (wait_state_count++ == 10) {
1445                         pr_err(MPT3SAS_FMT
1446                             "%s: failed due to ioc not operational\n",
1447                             ioc->name, __func__);
1448                         rc = -EFAULT;
1449                         goto out;
1450                 }
1451                 ssleep(1);
1452                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1453                 pr_info(MPT3SAS_FMT
1454                         "%s: waiting for operational state(count=%d)\n",
1455                         ioc->name, __func__, wait_state_count);
1456         }
1457         if (wait_state_count)
1458                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1459                     ioc->name, __func__);
1460
1461         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1462         if (!smid) {
1463                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1464                     ioc->name, __func__);
1465                 rc = -EAGAIN;
1466                 goto out;
1467         }
1468
1469         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1470         ioc->transport_cmds.smid = smid;
1471
1472         sz = sizeof(struct phy_control_request) +
1473             sizeof(struct phy_control_reply);
1474         data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma);
1475         if (!data_out) {
1476                 pr_err("failure at %s:%d/%s()!\n", __FILE__,
1477                     __LINE__, __func__);
1478                 rc = -ENOMEM;
1479                 mpt3sas_base_free_smid(ioc, smid);
1480                 goto out;
1481         }
1482
1483         rc = -EINVAL;
1484         memset(data_out, 0, sz);
1485         phy_control_request = data_out;
1486         phy_control_request->smp_frame_type = 0x40;
1487         phy_control_request->function = 0x91;
1488         phy_control_request->request_length = 9;
1489         phy_control_request->allocated_response_length = 0;
1490         phy_control_request->phy_identifier = phy->number;
1491         phy_control_request->phy_operation = phy_operation;
1492         phy_control_request->programmed_min_physical_link_rate =
1493             phy->minimum_linkrate << 4;
1494         phy_control_request->programmed_max_physical_link_rate =
1495             phy->maximum_linkrate << 4;
1496
1497         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1498         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1499         mpi_request->PhysicalPort = 0xFF;
1500         mpi_request->VF_ID = 0; /* TODO */
1501         mpi_request->VP_ID = 0;
1502         mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
1503         mpi_request->RequestDataLength =
1504             cpu_to_le16(sizeof(struct phy_error_log_request));
1505         psge = &mpi_request->SGL;
1506
1507         ioc->build_sg(ioc, psge, data_out_dma,
1508                             sizeof(struct phy_control_request),
1509             data_out_dma + sizeof(struct phy_control_request),
1510             sizeof(struct phy_control_reply));
1511
1512         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1513                 "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n",
1514                 ioc->name, (unsigned long long)phy->identify.sas_address,
1515                 phy->number, phy_operation));
1516         init_completion(&ioc->transport_cmds.done);
1517         ioc->put_smid_default(ioc, smid);
1518         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
1519
1520         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
1521                 pr_err(MPT3SAS_FMT "%s: timeout\n",
1522                     ioc->name, __func__);
1523                 _debug_dump_mf(mpi_request,
1524                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1525                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET))
1526                         issue_reset = 1;
1527                 goto issue_host_reset;
1528         }
1529
1530         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1531                 "phy_control - complete\n", ioc->name));
1532
1533         if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) {
1534
1535                 mpi_reply = ioc->transport_cmds.reply;
1536
1537                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1538                     "phy_control - reply data transfer size(%d)\n",
1539                     ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1540
1541                 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1542                     sizeof(struct phy_control_reply))
1543                         goto out;
1544
1545                 phy_control_reply = data_out +
1546                     sizeof(struct phy_control_request);
1547
1548                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1549                     "phy_control - function_result(%d)\n",
1550                     ioc->name, phy_control_reply->function_result));
1551
1552                 rc = 0;
1553         } else
1554                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
1555                     "phy_control - no reply\n", ioc->name));
1556
1557  issue_host_reset:
1558         if (issue_reset)
1559                 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
1560  out:
1561         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
1562         if (data_out)
1563                 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1564
1565         mutex_unlock(&ioc->transport_cmds.mutex);
1566         return rc;
1567 }
1568
1569 /**
1570  * _transport_phy_reset -
1571  * @phy: The sas phy object
1572  * @hard_reset:
1573  *
1574  * Returns 0 for success, non-zero for failure.
1575  */
1576 static int
1577 _transport_phy_reset(struct sas_phy *phy, int hard_reset)
1578 {
1579         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1580         Mpi2SasIoUnitControlReply_t mpi_reply;
1581         Mpi2SasIoUnitControlRequest_t mpi_request;
1582         unsigned long flags;
1583
1584         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1585         if (_transport_sas_node_find_by_sas_address(ioc,
1586             phy->identify.sas_address) == NULL) {
1587                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1588                 return -EINVAL;
1589         }
1590         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1591
1592         /* handle expander phys */
1593         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1594                 return _transport_expander_phy_control(ioc, phy,
1595                     (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1596                     SMP_PHY_CONTROL_LINK_RESET);
1597
1598         /* handle hba phys */
1599         memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
1600         mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
1601         mpi_request.Operation = hard_reset ?
1602             MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
1603         mpi_request.PhyNum = phy->number;
1604
1605         if ((mpt3sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
1606                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1607                     ioc->name, __FILE__, __LINE__, __func__);
1608                 return -ENXIO;
1609         }
1610
1611         if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1612                 pr_info(MPT3SAS_FMT
1613                 "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n",
1614                 ioc->name, phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1615                     le32_to_cpu(mpi_reply.IOCLogInfo));
1616
1617         return 0;
1618 }
1619
1620 /**
1621  * _transport_phy_enable - enable/disable phys
1622  * @phy: The sas phy object
1623  * @enable: enable phy when true
1624  *
1625  * Only support sas_host direct attached phys.
1626  * Returns 0 for success, non-zero for failure.
1627  */
1628 static int
1629 _transport_phy_enable(struct sas_phy *phy, int enable)
1630 {
1631         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1632         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1633         Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL;
1634         Mpi2ConfigReply_t mpi_reply;
1635         u16 ioc_status;
1636         u16 sz;
1637         int rc = 0;
1638         unsigned long flags;
1639         int i, discovery_active;
1640
1641         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1642         if (_transport_sas_node_find_by_sas_address(ioc,
1643             phy->identify.sas_address) == NULL) {
1644                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1645                 return -EINVAL;
1646         }
1647         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1648
1649         /* handle expander phys */
1650         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1651                 return _transport_expander_phy_control(ioc, phy,
1652                     (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1653                     SMP_PHY_CONTROL_DISABLE);
1654
1655         /* handle hba phys */
1656
1657         /* read sas_iounit page 0 */
1658         sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys *
1659             sizeof(Mpi2SasIOUnit0PhyData_t));
1660         sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL);
1661         if (!sas_iounit_pg0) {
1662                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1663                     ioc->name, __FILE__, __LINE__, __func__);
1664                 rc = -ENOMEM;
1665                 goto out;
1666         }
1667         if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply,
1668             sas_iounit_pg0, sz))) {
1669                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1670                     ioc->name, __FILE__, __LINE__, __func__);
1671                 rc = -ENXIO;
1672                 goto out;
1673         }
1674         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1675             MPI2_IOCSTATUS_MASK;
1676         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1677                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1678                     ioc->name, __FILE__, __LINE__, __func__);
1679                 rc = -EIO;
1680                 goto out;
1681         }
1682
1683         /* unable to enable/disable phys when when discovery is active */
1684         for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) {
1685                 if (sas_iounit_pg0->PhyData[i].PortFlags &
1686                     MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
1687                         pr_err(MPT3SAS_FMT "discovery is active on " \
1688                             "port = %d, phy = %d: unable to enable/disable "
1689                             "phys, try again later!\n", ioc->name,
1690                             sas_iounit_pg0->PhyData[i].Port, i);
1691                         discovery_active = 1;
1692                 }
1693         }
1694
1695         if (discovery_active) {
1696                 rc = -EAGAIN;
1697                 goto out;
1698         }
1699
1700         /* read sas_iounit page 1 */
1701         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1702             sizeof(Mpi2SasIOUnit1PhyData_t));
1703         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1704         if (!sas_iounit_pg1) {
1705                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1706                     ioc->name, __FILE__, __LINE__, __func__);
1707                 rc = -ENOMEM;
1708                 goto out;
1709         }
1710         if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1711             sas_iounit_pg1, sz))) {
1712                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1713                     ioc->name, __FILE__, __LINE__, __func__);
1714                 rc = -ENXIO;
1715                 goto out;
1716         }
1717         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1718             MPI2_IOCSTATUS_MASK;
1719         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1720                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1721                     ioc->name, __FILE__, __LINE__, __func__);
1722                 rc = -EIO;
1723                 goto out;
1724         }
1725
1726         /* copy Port/PortFlags/PhyFlags from page 0 */
1727         for (i = 0; i < ioc->sas_hba.num_phys ; i++) {
1728                 sas_iounit_pg1->PhyData[i].Port =
1729                     sas_iounit_pg0->PhyData[i].Port;
1730                 sas_iounit_pg1->PhyData[i].PortFlags =
1731                     (sas_iounit_pg0->PhyData[i].PortFlags &
1732                     MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG);
1733                 sas_iounit_pg1->PhyData[i].PhyFlags =
1734                     (sas_iounit_pg0->PhyData[i].PhyFlags &
1735                     (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED +
1736                     MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED));
1737         }
1738
1739         if (enable)
1740                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1741                     &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1742         else
1743                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1744                     |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1745
1746         mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1747
1748         /* link reset */
1749         if (enable)
1750                 _transport_phy_reset(phy, 0);
1751
1752  out:
1753         kfree(sas_iounit_pg1);
1754         kfree(sas_iounit_pg0);
1755         return rc;
1756 }
1757
1758 /**
1759  * _transport_phy_speed - set phy min/max link rates
1760  * @phy: The sas phy object
1761  * @rates: rates defined in sas_phy_linkrates
1762  *
1763  * Only support sas_host direct attached phys.
1764  * Returns 0 for success, non-zero for failure.
1765  */
1766 static int
1767 _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1768 {
1769         struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy);
1770         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1771         Mpi2SasPhyPage0_t phy_pg0;
1772         Mpi2ConfigReply_t mpi_reply;
1773         u16 ioc_status;
1774         u16 sz;
1775         int i;
1776         int rc = 0;
1777         unsigned long flags;
1778
1779         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1780         if (_transport_sas_node_find_by_sas_address(ioc,
1781             phy->identify.sas_address) == NULL) {
1782                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1783                 return -EINVAL;
1784         }
1785         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1786
1787         if (!rates->minimum_linkrate)
1788                 rates->minimum_linkrate = phy->minimum_linkrate;
1789         else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1790                 rates->minimum_linkrate = phy->minimum_linkrate_hw;
1791
1792         if (!rates->maximum_linkrate)
1793                 rates->maximum_linkrate = phy->maximum_linkrate;
1794         else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1795                 rates->maximum_linkrate = phy->maximum_linkrate_hw;
1796
1797         /* handle expander phys */
1798         if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1799                 phy->minimum_linkrate = rates->minimum_linkrate;
1800                 phy->maximum_linkrate = rates->maximum_linkrate;
1801                 return _transport_expander_phy_control(ioc, phy,
1802                     SMP_PHY_CONTROL_LINK_RESET);
1803         }
1804
1805         /* handle hba phys */
1806
1807         /* sas_iounit page 1 */
1808         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1809             sizeof(Mpi2SasIOUnit1PhyData_t));
1810         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1811         if (!sas_iounit_pg1) {
1812                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1813                     ioc->name, __FILE__, __LINE__, __func__);
1814                 rc = -ENOMEM;
1815                 goto out;
1816         }
1817         if ((mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1818             sas_iounit_pg1, sz))) {
1819                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1820                     ioc->name, __FILE__, __LINE__, __func__);
1821                 rc = -ENXIO;
1822                 goto out;
1823         }
1824         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1825             MPI2_IOCSTATUS_MASK;
1826         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1827                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1828                     ioc->name, __FILE__, __LINE__, __func__);
1829                 rc = -EIO;
1830                 goto out;
1831         }
1832
1833         for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1834                 if (phy->number != i) {
1835                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1836                             (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1837                             (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1838                 } else {
1839                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1840                             (rates->minimum_linkrate +
1841                             (rates->maximum_linkrate << 4));
1842                 }
1843         }
1844
1845         if (mpt3sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1846             sz)) {
1847                 pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
1848                     ioc->name, __FILE__, __LINE__, __func__);
1849                 rc = -ENXIO;
1850                 goto out;
1851         }
1852
1853         /* link reset */
1854         _transport_phy_reset(phy, 0);
1855
1856         /* read phy page 0, then update the rates in the sas transport phy */
1857         if (!mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1858             phy->number)) {
1859                 phy->minimum_linkrate = _transport_convert_phy_link_rate(
1860                     phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
1861                 phy->maximum_linkrate = _transport_convert_phy_link_rate(
1862                     phy_pg0.ProgrammedLinkRate >> 4);
1863                 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1864                     phy_pg0.NegotiatedLinkRate &
1865                     MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1866         }
1867
1868  out:
1869         kfree(sas_iounit_pg1);
1870         return rc;
1871 }
1872
1873 static int
1874 _transport_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
1875                 dma_addr_t *dma_addr, size_t *dma_len, void **p)
1876 {
1877         /* Check if the request is split across multiple segments */
1878         if (buf->sg_cnt > 1) {
1879                 *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr,
1880                                 GFP_KERNEL);
1881                 if (!*p)
1882                         return -ENOMEM;
1883                 *dma_len = buf->payload_len;
1884         } else {
1885                 if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL))
1886                         return -ENOMEM;
1887                 *dma_addr = sg_dma_address(buf->sg_list);
1888                 *dma_len = sg_dma_len(buf->sg_list);
1889                 *p = NULL;
1890         }
1891
1892         return 0;
1893 }
1894
1895 static void
1896 _transport_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
1897                 dma_addr_t dma_addr, void *p)
1898 {
1899         if (p)
1900                 dma_free_coherent(dev, buf->payload_len, p, dma_addr);
1901         else
1902                 dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL);
1903 }
1904
1905 /**
1906  * _transport_smp_handler - transport portal for smp passthru
1907  * @shost: shost object
1908  * @rphy: sas transport rphy object
1909  * @req:
1910  *
1911  * This used primarily for smp_utils.
1912  * Example:
1913  *           smp_rep_general /sys/class/bsg/expander-5:0
1914  */
1915 static void
1916 _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
1917                 struct sas_rphy *rphy)
1918 {
1919         struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
1920         Mpi2SmpPassthroughRequest_t *mpi_request;
1921         Mpi2SmpPassthroughReply_t *mpi_reply;
1922         int rc;
1923         u16 smid;
1924         u32 ioc_state;
1925         void *psge;
1926         dma_addr_t dma_addr_in;
1927         dma_addr_t dma_addr_out;
1928         void *addr_in = NULL;
1929         void *addr_out = NULL;
1930         size_t dma_len_in;
1931         size_t dma_len_out;
1932         u16 wait_state_count;
1933         unsigned int reslen = 0;
1934
1935         if (ioc->shost_recovery || ioc->pci_error_recovery) {
1936                 pr_info(MPT3SAS_FMT "%s: host reset in progress!\n",
1937                     __func__, ioc->name);
1938                 rc = -EFAULT;
1939                 goto out;
1940         }
1941
1942         rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1943         if (rc)
1944                 goto out;
1945
1946         if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) {
1947                 pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ioc->name,
1948                     __func__);
1949                 rc = -EAGAIN;
1950                 goto out;
1951         }
1952         ioc->transport_cmds.status = MPT3_CMD_PENDING;
1953
1954         rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->request_payload,
1955                         &dma_addr_out, &dma_len_out, &addr_out);
1956         if (rc)
1957                 goto out;
1958         if (addr_out) {
1959                 sg_copy_to_buffer(job->request_payload.sg_list,
1960                                 job->request_payload.sg_cnt, addr_out,
1961                                 job->request_payload.payload_len);
1962         }
1963
1964         rc = _transport_map_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
1965                         &dma_addr_in, &dma_len_in, &addr_in);
1966         if (rc)
1967                 goto unmap_out;
1968
1969         wait_state_count = 0;
1970         ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1971         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1972                 if (wait_state_count++ == 10) {
1973                         pr_err(MPT3SAS_FMT
1974                             "%s: failed due to ioc not operational\n",
1975                             ioc->name, __func__);
1976                         rc = -EFAULT;
1977                         goto unmap_in;
1978                 }
1979                 ssleep(1);
1980                 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
1981                 pr_info(MPT3SAS_FMT
1982                         "%s: waiting for operational state(count=%d)\n",
1983                         ioc->name, __func__, wait_state_count);
1984         }
1985         if (wait_state_count)
1986                 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
1987                     ioc->name, __func__);
1988
1989         smid = mpt3sas_base_get_smid(ioc, ioc->transport_cb_idx);
1990         if (!smid) {
1991                 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
1992                     ioc->name, __func__);
1993                 rc = -EAGAIN;
1994                 goto unmap_in;
1995         }
1996
1997         rc = 0;
1998         mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1999         ioc->transport_cmds.smid = smid;
2000
2001         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
2002         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
2003         mpi_request->PhysicalPort = 0xFF;
2004         mpi_request->SASAddress = (rphy) ?
2005             cpu_to_le64(rphy->identify.sas_address) :
2006             cpu_to_le64(ioc->sas_hba.sas_address);
2007         mpi_request->RequestDataLength = cpu_to_le16(dma_len_out - 4);
2008         psge = &mpi_request->SGL;
2009
2010         ioc->build_sg(ioc, psge, dma_addr_out, dma_len_out - 4, dma_addr_in,
2011                         dma_len_in - 4);
2012
2013         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2014                 "%s - sending smp request\n", ioc->name, __func__));
2015
2016         init_completion(&ioc->transport_cmds.done);
2017         ioc->put_smid_default(ioc, smid);
2018         wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ);
2019
2020         if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) {
2021                 pr_err(MPT3SAS_FMT "%s : timeout\n",
2022                     __func__, ioc->name);
2023                 _debug_dump_mf(mpi_request,
2024                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
2025                 if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) {
2026                         mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
2027                         rc = -ETIMEDOUT;
2028                         goto unmap_in;
2029                 }
2030         }
2031
2032         dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2033                 "%s - complete\n", ioc->name, __func__));
2034
2035         if (!(ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID)) {
2036                 dtransportprintk(ioc, pr_info(MPT3SAS_FMT
2037                     "%s - no reply\n", ioc->name, __func__));
2038                 rc = -ENXIO;
2039                 goto unmap_in;
2040         }
2041
2042         mpi_reply = ioc->transport_cmds.reply;
2043
2044         dtransportprintk(ioc,
2045                 pr_info(MPT3SAS_FMT "%s - reply data transfer size(%d)\n",
2046                         ioc->name, __func__,
2047                         le16_to_cpu(mpi_reply->ResponseDataLength)));
2048
2049         memcpy(job->reply, mpi_reply, sizeof(*mpi_reply));
2050         job->reply_len = sizeof(*mpi_reply);
2051         reslen = le16_to_cpu(mpi_reply->ResponseDataLength);
2052
2053         if (addr_in) {
2054                 sg_copy_to_buffer(job->reply_payload.sg_list,
2055                                 job->reply_payload.sg_cnt, addr_in,
2056                                 job->reply_payload.payload_len);
2057         }
2058
2059         rc = 0;
2060  unmap_in:
2061         _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->reply_payload,
2062                         dma_addr_in, addr_in);
2063  unmap_out:
2064         _transport_unmap_smp_buffer(&ioc->pdev->dev, &job->request_payload,
2065                         dma_addr_out, addr_out);
2066  out:
2067         ioc->transport_cmds.status = MPT3_CMD_NOT_USED;
2068         mutex_unlock(&ioc->transport_cmds.mutex);
2069         bsg_job_done(job, rc, reslen);
2070 }
2071
2072 struct sas_function_template mpt3sas_transport_functions = {
2073         .get_linkerrors         = _transport_get_linkerrors,
2074         .get_enclosure_identifier = _transport_get_enclosure_identifier,
2075         .get_bay_identifier     = _transport_get_bay_identifier,
2076         .phy_reset              = _transport_phy_reset,
2077         .phy_enable             = _transport_phy_enable,
2078         .set_phy_speed          = _transport_phy_speed,
2079         .smp_handler            = _transport_smp_handler,
2080 };
2081
2082 struct scsi_transport_template *mpt3sas_transport_template;