IB/mthca: Return an error on ib_copy_to_udata() failure
[pandora-kernel.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         mpt2sas_base_put_smid_default(ioc, smid);
402         init_completion(&ioc->transport_cmds.done);
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         mpt2sas_base_put_smid_default(ioc, smid);
1188         init_completion(&ioc->transport_cmds.done);
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         mpt2sas_base_put_smid_default(ioc, smid);
1513         init_completion(&ioc->transport_cmds.done);
1514         timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1515             10*HZ);
1516
1517         if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1518                 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
1519                     ioc->name, __func__);
1520                 _debug_dump_mf(mpi_request,
1521                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1522                 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1523                         issue_reset = 1;
1524                 goto issue_host_reset;
1525         }
1526
1527         dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - "
1528             "complete\n", ioc->name));
1529
1530         if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1531
1532                 mpi_reply = ioc->transport_cmds.reply;
1533
1534                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1535                     "phy_control - reply data transfer size(%d)\n",
1536                     ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength)));
1537
1538                 if (le16_to_cpu(mpi_reply->ResponseDataLength) !=
1539                     sizeof(struct phy_control_reply))
1540                         goto out;
1541
1542                 phy_control_reply = data_out +
1543                     sizeof(struct phy_control_request);
1544
1545                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1546                     "phy_control - function_result(%d)\n",
1547                     ioc->name, phy_control_reply->function_result));
1548
1549                 rc = 0;
1550         } else
1551                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1552                     "phy_control - no reply\n", ioc->name));
1553
1554  issue_host_reset:
1555         if (issue_reset)
1556                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1557                     FORCE_BIG_HAMMER);
1558  out:
1559         ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
1560         if (data_out)
1561                 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma);
1562
1563         mutex_unlock(&ioc->transport_cmds.mutex);
1564         return rc;
1565 }
1566
1567 /**
1568  * _transport_phy_reset -
1569  * @phy: The sas phy object
1570  * @hard_reset:
1571  *
1572  * Returns 0 for success, non-zero for failure.
1573  */
1574 static int
1575 _transport_phy_reset(struct sas_phy *phy, int hard_reset)
1576 {
1577         struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1578         Mpi2SasIoUnitControlReply_t mpi_reply;
1579         Mpi2SasIoUnitControlRequest_t mpi_request;
1580         unsigned long flags;
1581
1582         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1583         if (_transport_sas_node_find_by_sas_address(ioc,
1584             phy->identify.sas_address) == NULL) {
1585                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1586                 return -EINVAL;
1587         }
1588         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1589
1590         /* handle expander phys */
1591         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1592                 return _transport_expander_phy_control(ioc, phy,
1593                     (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET :
1594                     SMP_PHY_CONTROL_LINK_RESET);
1595
1596         /* handle hba phys */
1597         memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t));
1598         mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
1599         mpi_request.Operation = hard_reset ?
1600             MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET;
1601         mpi_request.PhyNum = phy->number;
1602
1603         if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) {
1604                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1605                     ioc->name, __FILE__, __LINE__, __func__);
1606                 return -ENXIO;
1607         }
1608
1609         if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo)
1610                 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status"
1611                     "(0x%04x), loginfo(0x%08x)\n", ioc->name,
1612                     phy->number, le16_to_cpu(mpi_reply.IOCStatus),
1613                     le32_to_cpu(mpi_reply.IOCLogInfo));
1614
1615         return 0;
1616 }
1617
1618 /**
1619  * _transport_phy_enable - enable/disable phys
1620  * @phy: The sas phy object
1621  * @enable: enable phy when true
1622  *
1623  * Only support sas_host direct attached phys.
1624  * Returns 0 for success, non-zero for failure.
1625  */
1626 static int
1627 _transport_phy_enable(struct sas_phy *phy, int enable)
1628 {
1629         struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1630         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1631         Mpi2ConfigReply_t mpi_reply;
1632         u16 ioc_status;
1633         u16 sz;
1634         int rc = 0;
1635         unsigned long flags;
1636
1637         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1638         if (_transport_sas_node_find_by_sas_address(ioc,
1639             phy->identify.sas_address) == NULL) {
1640                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1641                 return -EINVAL;
1642         }
1643         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1644
1645         /* handle expander phys */
1646         if (phy->identify.sas_address != ioc->sas_hba.sas_address)
1647                 return _transport_expander_phy_control(ioc, phy,
1648                     (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET :
1649                     SMP_PHY_CONTROL_DISABLE);
1650
1651         /* handle hba phys */
1652
1653         /* sas_iounit page 1 */
1654         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1655             sizeof(Mpi2SasIOUnit1PhyData_t));
1656         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1657         if (!sas_iounit_pg1) {
1658                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1659                     ioc->name, __FILE__, __LINE__, __func__);
1660                 rc = -ENOMEM;
1661                 goto out;
1662         }
1663         if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1664             sas_iounit_pg1, sz))) {
1665                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1666                     ioc->name, __FILE__, __LINE__, __func__);
1667                 rc = -ENXIO;
1668                 goto out;
1669         }
1670         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1671             MPI2_IOCSTATUS_MASK;
1672         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1673                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1674                     ioc->name, __FILE__, __LINE__, __func__);
1675                 rc = -EIO;
1676                 goto out;
1677         }
1678
1679         if (enable)
1680                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1681                     &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1682         else
1683                 sas_iounit_pg1->PhyData[phy->number].PhyFlags
1684                     |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE;
1685
1686         mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz);
1687
1688         /* link reset */
1689         if (enable)
1690                 _transport_phy_reset(phy, 0);
1691
1692  out:
1693         kfree(sas_iounit_pg1);
1694         return rc;
1695 }
1696
1697 /**
1698  * _transport_phy_speed - set phy min/max link rates
1699  * @phy: The sas phy object
1700  * @rates: rates defined in sas_phy_linkrates
1701  *
1702  * Only support sas_host direct attached phys.
1703  * Returns 0 for success, non-zero for failure.
1704  */
1705 static int
1706 _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
1707 {
1708         struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy);
1709         Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL;
1710         Mpi2SasPhyPage0_t phy_pg0;
1711         Mpi2ConfigReply_t mpi_reply;
1712         u16 ioc_status;
1713         u16 sz;
1714         int i;
1715         int rc = 0;
1716         unsigned long flags;
1717
1718         spin_lock_irqsave(&ioc->sas_node_lock, flags);
1719         if (_transport_sas_node_find_by_sas_address(ioc,
1720             phy->identify.sas_address) == NULL) {
1721                 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1722                 return -EINVAL;
1723         }
1724         spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
1725
1726         if (!rates->minimum_linkrate)
1727                 rates->minimum_linkrate = phy->minimum_linkrate;
1728         else if (rates->minimum_linkrate < phy->minimum_linkrate_hw)
1729                 rates->minimum_linkrate = phy->minimum_linkrate_hw;
1730
1731         if (!rates->maximum_linkrate)
1732                 rates->maximum_linkrate = phy->maximum_linkrate;
1733         else if (rates->maximum_linkrate > phy->maximum_linkrate_hw)
1734                 rates->maximum_linkrate = phy->maximum_linkrate_hw;
1735
1736         /* handle expander phys */
1737         if (phy->identify.sas_address != ioc->sas_hba.sas_address) {
1738                 phy->minimum_linkrate = rates->minimum_linkrate;
1739                 phy->maximum_linkrate = rates->maximum_linkrate;
1740                 return _transport_expander_phy_control(ioc, phy,
1741                     SMP_PHY_CONTROL_LINK_RESET);
1742         }
1743
1744         /* handle hba phys */
1745
1746         /* sas_iounit page 1 */
1747         sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys *
1748             sizeof(Mpi2SasIOUnit1PhyData_t));
1749         sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL);
1750         if (!sas_iounit_pg1) {
1751                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1752                     ioc->name, __FILE__, __LINE__, __func__);
1753                 rc = -ENOMEM;
1754                 goto out;
1755         }
1756         if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply,
1757             sas_iounit_pg1, sz))) {
1758                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1759                     ioc->name, __FILE__, __LINE__, __func__);
1760                 rc = -ENXIO;
1761                 goto out;
1762         }
1763         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1764             MPI2_IOCSTATUS_MASK;
1765         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1766                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1767                     ioc->name, __FILE__, __LINE__, __func__);
1768                 rc = -EIO;
1769                 goto out;
1770         }
1771
1772         for (i = 0; i < ioc->sas_hba.num_phys; i++) {
1773                 if (phy->number != i) {
1774                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1775                             (ioc->sas_hba.phy[i].phy->minimum_linkrate +
1776                             (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4));
1777                 } else {
1778                         sas_iounit_pg1->PhyData[i].MaxMinLinkRate =
1779                             (rates->minimum_linkrate +
1780                             (rates->maximum_linkrate << 4));
1781                 }
1782         }
1783
1784         if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1,
1785             sz)) {
1786                 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
1787                     ioc->name, __FILE__, __LINE__, __func__);
1788                 rc = -ENXIO;
1789                 goto out;
1790         }
1791
1792         /* link reset */
1793         _transport_phy_reset(phy, 0);
1794
1795         /* read phy page 0, then update the rates in the sas transport phy */
1796         if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0,
1797             phy->number)) {
1798                 phy->minimum_linkrate = _transport_convert_phy_link_rate(
1799                     phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK);
1800                 phy->maximum_linkrate = _transport_convert_phy_link_rate(
1801                     phy_pg0.ProgrammedLinkRate >> 4);
1802                 phy->negotiated_linkrate = _transport_convert_phy_link_rate(
1803                     phy_pg0.NegotiatedLinkRate &
1804                     MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL);
1805         }
1806
1807  out:
1808         kfree(sas_iounit_pg1);
1809         return rc;
1810 }
1811
1812
1813 /**
1814  * _transport_smp_handler - transport portal for smp passthru
1815  * @shost: shost object
1816  * @rphy: sas transport rphy object
1817  * @req:
1818  *
1819  * This used primarily for smp_utils.
1820  * Example:
1821  *           smp_rep_general /sys/class/bsg/expander-5:0
1822  */
1823 static int
1824 _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1825     struct request *req)
1826 {
1827         struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
1828         Mpi2SmpPassthroughRequest_t *mpi_request;
1829         Mpi2SmpPassthroughReply_t *mpi_reply;
1830         int rc;
1831         u16 smid;
1832         u32 ioc_state;
1833         unsigned long timeleft;
1834         void *psge;
1835         u32 sgl_flags;
1836         u8 issue_reset = 0;
1837         dma_addr_t dma_addr_in = 0;
1838         dma_addr_t dma_addr_out = 0;
1839         u16 wait_state_count;
1840         struct request *rsp = req->next_rq;
1841
1842         if (!rsp) {
1843                 printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
1844                     "missing\n", ioc->name, __func__);
1845                 return -EINVAL;
1846         }
1847
1848         /* do we need to support multiple segments? */
1849         if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1850                 printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, "
1851                     "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt,
1852                     blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
1853                 return -EINVAL;
1854         }
1855
1856         if (ioc->shost_recovery) {
1857                 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
1858                     __func__, ioc->name);
1859                 return -EFAULT;
1860         }
1861
1862         rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
1863         if (rc)
1864                 return rc;
1865
1866         if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) {
1867                 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name,
1868                     __func__);
1869                 rc = -EAGAIN;
1870                 goto out;
1871         }
1872         ioc->transport_cmds.status = MPT2_CMD_PENDING;
1873
1874         wait_state_count = 0;
1875         ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1876         while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1877                 if (wait_state_count++ == 10) {
1878                         printk(MPT2SAS_ERR_FMT
1879                             "%s: failed due to ioc not operational\n",
1880                             ioc->name, __func__);
1881                         rc = -EFAULT;
1882                         goto out;
1883                 }
1884                 ssleep(1);
1885                 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1886                 printk(MPT2SAS_INFO_FMT "%s: waiting for "
1887                     "operational state(count=%d)\n", ioc->name,
1888                     __func__, wait_state_count);
1889         }
1890         if (wait_state_count)
1891                 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
1892                     ioc->name, __func__);
1893
1894         smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx);
1895         if (!smid) {
1896                 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1897                     ioc->name, __func__);
1898                 rc = -EAGAIN;
1899                 goto out;
1900         }
1901
1902         rc = 0;
1903         mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1904         ioc->transport_cmds.smid = smid;
1905
1906         memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1907         mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1908         mpi_request->PhysicalPort = 0xFF;
1909         mpi_request->VF_ID = 0; /* TODO */
1910         mpi_request->VP_ID = 0;
1911         mpi_request->SASAddress = (rphy) ?
1912             cpu_to_le64(rphy->identify.sas_address) :
1913             cpu_to_le64(ioc->sas_hba.sas_address);
1914         mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
1915         psge = &mpi_request->SGL;
1916
1917         /* WRITE sgel first */
1918         sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1919             MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC);
1920         sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1921         dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
1922                 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
1923         if (!dma_addr_out) {
1924                 mpt2sas_base_free_smid(ioc, smid);
1925                 goto unmap;
1926         }
1927
1928         ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4),
1929             dma_addr_out);
1930
1931         /* incr sgel */
1932         psge += ioc->sge_size;
1933
1934         /* READ sgel last */
1935         sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1936             MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER |
1937             MPI2_SGE_FLAGS_END_OF_LIST);
1938         sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
1939         dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio),
1940                                      blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
1941         if (!dma_addr_in) {
1942                 mpt2sas_base_free_smid(ioc, smid);
1943                 goto unmap;
1944         }
1945
1946         ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4),
1947             dma_addr_in);
1948
1949         dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1950             "sending smp request\n", ioc->name, __func__));
1951
1952         mpt2sas_base_put_smid_default(ioc, smid);
1953         init_completion(&ioc->transport_cmds.done);
1954         timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1955             10*HZ);
1956
1957         if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) {
1958                 printk(MPT2SAS_ERR_FMT "%s : timeout\n",
1959                     __func__, ioc->name);
1960                 _debug_dump_mf(mpi_request,
1961                     sizeof(Mpi2SmpPassthroughRequest_t)/4);
1962                 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET))
1963                         issue_reset = 1;
1964                 goto issue_host_reset;
1965         }
1966
1967         dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - "
1968             "complete\n", ioc->name, __func__));
1969
1970         if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) {
1971
1972                 mpi_reply = ioc->transport_cmds.reply;
1973
1974                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1975                     "%s - reply data transfer size(%d)\n",
1976                     ioc->name, __func__,
1977                     le16_to_cpu(mpi_reply->ResponseDataLength)));
1978
1979                 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply));
1980                 req->sense_len = sizeof(*mpi_reply);
1981                 req->resid_len = 0;
1982                 rsp->resid_len -=
1983                     le16_to_cpu(mpi_reply->ResponseDataLength);
1984         } else {
1985                 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT
1986                     "%s - no reply\n", ioc->name, __func__));
1987                 rc = -ENXIO;
1988         }
1989
1990  issue_host_reset:
1991         if (issue_reset) {
1992                 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
1993                     FORCE_BIG_HAMMER);
1994                 rc = -ETIMEDOUT;
1995         }
1996
1997  unmap:
1998         if (dma_addr_out)
1999                 pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req),
2000                     PCI_DMA_BIDIRECTIONAL);
2001         if (dma_addr_in)
2002                 pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp),
2003                     PCI_DMA_BIDIRECTIONAL);
2004
2005  out:
2006         ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
2007         mutex_unlock(&ioc->transport_cmds.mutex);
2008         return rc;
2009 }
2010
2011 struct sas_function_template mpt2sas_transport_functions = {
2012         .get_linkerrors         = _transport_get_linkerrors,
2013         .get_enclosure_identifier = _transport_get_enclosure_identifier,
2014         .get_bay_identifier     = _transport_get_bay_identifier,
2015         .phy_reset              = _transport_phy_reset,
2016         .phy_enable             = _transport_phy_enable,
2017         .set_phy_speed          = _transport_phy_speed,
2018         .smp_handler            = _transport_smp_handler,
2019 };
2020
2021 struct scsi_transport_template *mpt2sas_transport_template;