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