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