[SCSI] fusion: move sas persistent event handling over to the mptsas module
[linux-2.6/cjktty.git] / drivers / message / fusion / mptsas.c
blob90660bfa148cff0696eebc00ffec8dc549c62f68
1 /*
2 * linux/drivers/message/fusion/mptsas.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
8 * Copyright (c) 2005-2006 Dell
9 */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 NO WARRANTY
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/sched.h>
52 #include <linux/workqueue.h>
54 #include <scsi/scsi_cmnd.h>
55 #include <scsi/scsi_device.h>
56 #include <scsi/scsi_host.h>
57 #include <scsi/scsi_transport_sas.h>
59 #include "mptbase.h"
60 #include "mptscsih.h"
63 #define my_NAME "Fusion MPT SAS Host driver"
64 #define my_VERSION MPT_LINUX_VERSION_COMMON
65 #define MYNAM "mptsas"
67 MODULE_AUTHOR(MODULEAUTHOR);
68 MODULE_DESCRIPTION(my_NAME);
69 MODULE_LICENSE("GPL");
71 static int mpt_pq_filter;
72 module_param(mpt_pq_filter, int, 0);
73 MODULE_PARM_DESC(mpt_pq_filter,
74 "Enable peripheral qualifier filter: enable=1 "
75 "(default=0)");
77 static int mpt_pt_clear;
78 module_param(mpt_pt_clear, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear,
80 "Clear persistency table: enable=1 "
81 "(default=MPTSCSIH_PT_CLEAR=0)");
83 static int mptsasDoneCtx = -1;
84 static int mptsasTaskCtx = -1;
85 static int mptsasInternalCtx = -1; /* Used only for internal commands */
86 static int mptsasMgmtCtx = -1;
89 enum mptsas_hotplug_action {
90 MPTSAS_ADD_DEVICE,
91 MPTSAS_DEL_DEVICE,
92 MPTSAS_ADD_RAID,
93 MPTSAS_DEL_RAID,
96 struct mptsas_hotplug_event {
97 struct work_struct work;
98 MPT_ADAPTER *ioc;
99 enum mptsas_hotplug_action event_type;
100 u64 sas_address;
101 u32 channel;
102 u32 id;
103 u32 device_info;
104 u16 handle;
105 u16 parent_handle;
106 u8 phy_id;
110 * SAS topology structures
112 * The MPT Fusion firmware interface spreads information about the
113 * SAS topology over many manufacture pages, thus we need some data
114 * structure to collect it and process it for the SAS transport class.
117 struct mptsas_devinfo {
118 u16 handle; /* unique id to address this device */
119 u16 handle_parent; /* unique id to address parent device */
120 u8 phy_id; /* phy number of parent device */
121 u8 port_id; /* sas physical port this device
122 is assoc'd with */
123 u8 id; /* logical target id of this device */
124 u8 channel; /* logical bus number of this device */
125 u64 sas_address; /* WWN of this device,
126 SATA is assigned by HBA,expander */
127 u32 device_info; /* bitfield detailed info about this device */
130 struct mptsas_phyinfo {
131 u8 phy_id; /* phy index */
132 u8 port_id; /* port number this phy is part of */
133 u8 negotiated_link_rate; /* nego'd link rate for this phy */
134 u8 hw_link_rate; /* hardware max/min phys link rate */
135 u8 programmed_link_rate; /* programmed max/min phy link rate */
136 struct mptsas_devinfo identify; /* point to phy device info */
137 struct mptsas_devinfo attached; /* point to attached device info */
138 struct sas_phy *phy;
139 struct sas_rphy *rphy;
142 struct mptsas_portinfo {
143 struct list_head list;
144 u16 handle; /* unique id to address this */
145 u8 num_phys; /* number of phys */
146 struct mptsas_phyinfo *phy_info;
150 #ifdef SASDEBUG
151 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
153 printk("---- IO UNIT PAGE 0 ------------\n");
154 printk("Handle=0x%X\n",
155 le16_to_cpu(phy_data->AttachedDeviceHandle));
156 printk("Controller Handle=0x%X\n",
157 le16_to_cpu(phy_data->ControllerDevHandle));
158 printk("Port=0x%X\n", phy_data->Port);
159 printk("Port Flags=0x%X\n", phy_data->PortFlags);
160 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
161 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
162 printk("Controller PHY Device Info=0x%X\n",
163 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
164 printk("DiscoveryStatus=0x%X\n",
165 le32_to_cpu(phy_data->DiscoveryStatus));
166 printk("\n");
169 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
171 __le64 sas_address;
173 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
175 printk("---- SAS PHY PAGE 0 ------------\n");
176 printk("Attached Device Handle=0x%X\n",
177 le16_to_cpu(pg0->AttachedDevHandle));
178 printk("SAS Address=0x%llX\n",
179 (unsigned long long)le64_to_cpu(sas_address));
180 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
181 printk("Attached Device Info=0x%X\n",
182 le32_to_cpu(pg0->AttachedDeviceInfo));
183 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
184 printk("Change Count=0x%X\n", pg0->ChangeCount);
185 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
186 printk("\n");
189 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
191 printk("---- SAS PHY PAGE 1 ------------\n");
192 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
193 printk("Running Disparity Error Count=0x%x\n",
194 pg1->RunningDisparityErrorCount);
195 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
196 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
197 printk("\n");
200 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
202 __le64 sas_address;
204 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
206 printk("---- SAS DEVICE PAGE 0 ---------\n");
207 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
208 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
209 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
210 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
211 printk("Target ID=0x%X\n", pg0->TargetID);
212 printk("Bus=0x%X\n", pg0->Bus);
213 /* The PhyNum field specifies the PHY number of the parent
214 * device this device is linked to
216 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
217 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
218 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
219 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
220 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
221 printk("\n");
224 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
226 printk("---- SAS EXPANDER PAGE 1 ------------\n");
228 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
229 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
230 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
231 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
232 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
233 printk("Owner Device Handle=0x%X\n",
234 le16_to_cpu(pg1->OwnerDevHandle));
235 printk("Attached Device Handle=0x%X\n",
236 le16_to_cpu(pg1->AttachedDevHandle));
238 #else
239 #define mptsas_print_phy_data(phy_data) do { } while (0)
240 #define mptsas_print_phy_pg0(pg0) do { } while (0)
241 #define mptsas_print_phy_pg1(pg1) do { } while (0)
242 #define mptsas_print_device_pg0(pg0) do { } while (0)
243 #define mptsas_print_expander_pg1(pg1) do { } while (0)
244 #endif
248 * This is pretty ugly. We will be able to seriously clean it up
249 * once the DV code in mptscsih goes away and we can properly
250 * implement ->target_alloc.
252 static int
253 mptsas_slave_alloc(struct scsi_device *sdev)
255 struct Scsi_Host *host = sdev->host;
256 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
257 struct sas_rphy *rphy;
258 struct mptsas_portinfo *p;
259 VirtTarget *vtarget;
260 VirtDevice *vdev;
261 struct scsi_target *starget;
262 int i;
264 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
265 if (!vdev) {
266 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
267 hd->ioc->name, sizeof(VirtDevice));
268 return -ENOMEM;
270 vdev->ioc_id = hd->ioc->id;
271 sdev->hostdata = vdev;
272 starget = scsi_target(sdev);
273 vtarget = starget->hostdata;
274 vdev->vtarget = vtarget;
275 if (vtarget->num_luns == 0) {
276 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
277 hd->Targets[sdev->id] = vtarget;
281 RAID volumes placed beyond the last expected port.
283 if (sdev->channel == hd->ioc->num_ports) {
284 vdev->target_id = sdev->id;
285 vdev->bus_id = 0;
286 vdev->lun = 0;
287 goto out;
290 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
291 mutex_lock(&hd->ioc->sas_topology_mutex);
292 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
293 for (i = 0; i < p->num_phys; i++) {
294 if (p->phy_info[i].attached.sas_address ==
295 rphy->identify.sas_address) {
296 vdev->target_id =
297 p->phy_info[i].attached.id;
298 vdev->bus_id = p->phy_info[i].attached.channel;
299 vdev->lun = sdev->lun;
300 mutex_unlock(&hd->ioc->sas_topology_mutex);
301 goto out;
305 mutex_unlock(&hd->ioc->sas_topology_mutex);
307 printk("No matching SAS device found!!\n");
308 kfree(vdev);
309 return -ENODEV;
311 out:
312 vtarget->ioc_id = vdev->ioc_id;
313 vtarget->target_id = vdev->target_id;
314 vtarget->bus_id = vdev->bus_id;
315 vtarget->num_luns++;
316 return 0;
319 static void
320 mptsas_slave_destroy(struct scsi_device *sdev)
322 struct Scsi_Host *host = sdev->host;
323 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
324 struct sas_rphy *rphy;
325 struct mptsas_portinfo *p;
326 int i;
327 VirtDevice *vdev;
330 * Handle hotplug removal case.
331 * We need to clear out attached data structure.
333 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
335 mutex_lock(&hd->ioc->sas_topology_mutex);
336 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
337 for (i = 0; i < p->num_phys; i++) {
338 if (p->phy_info[i].attached.sas_address ==
339 rphy->identify.sas_address) {
340 memset(&p->phy_info[i].attached, 0,
341 sizeof(struct mptsas_devinfo));
342 p->phy_info[i].rphy = NULL;
343 goto out;
348 out:
349 mutex_unlock(&hd->ioc->sas_topology_mutex);
351 * Issue target reset to flush firmware outstanding commands.
353 vdev = sdev->hostdata;
354 if (vdev->configured_lun){
355 if (mptscsih_TMHandler(hd,
356 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
357 vdev->bus_id,
358 vdev->target_id,
359 0, 0, 5 /* 5 second timeout */)
360 < 0){
362 /* The TM request failed!
363 * Fatal error case.
365 printk(MYIOC_s_WARN_FMT
366 "Error processing TaskMgmt id=%d TARGET_RESET\n",
367 hd->ioc->name,
368 vdev->target_id);
370 hd->tmPending = 0;
371 hd->tmState = TM_STATE_NONE;
374 mptscsih_slave_destroy(sdev);
377 static struct scsi_host_template mptsas_driver_template = {
378 .module = THIS_MODULE,
379 .proc_name = "mptsas",
380 .proc_info = mptscsih_proc_info,
381 .name = "MPT SPI Host",
382 .info = mptscsih_info,
383 .queuecommand = mptscsih_qcmd,
384 .target_alloc = mptscsih_target_alloc,
385 .slave_alloc = mptsas_slave_alloc,
386 .slave_configure = mptscsih_slave_configure,
387 .target_destroy = mptscsih_target_destroy,
388 .slave_destroy = mptsas_slave_destroy,
389 .change_queue_depth = mptscsih_change_queue_depth,
390 .eh_abort_handler = mptscsih_abort,
391 .eh_device_reset_handler = mptscsih_dev_reset,
392 .eh_bus_reset_handler = mptscsih_bus_reset,
393 .eh_host_reset_handler = mptscsih_host_reset,
394 .bios_param = mptscsih_bios_param,
395 .can_queue = MPT_FC_CAN_QUEUE,
396 .this_id = -1,
397 .sg_tablesize = MPT_SCSI_SG_DEPTH,
398 .max_sectors = 8192,
399 .cmd_per_lun = 7,
400 .use_clustering = ENABLE_CLUSTERING,
403 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
405 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
406 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
409 static int mptsas_get_linkerrors(struct sas_phy *phy)
411 MPT_ADAPTER *ioc = phy_to_ioc(phy);
412 ConfigExtendedPageHeader_t hdr;
413 CONFIGPARMS cfg;
414 SasPhyPage1_t *buffer;
415 dma_addr_t dma_handle;
416 int error;
418 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
419 hdr.ExtPageLength = 0;
420 hdr.PageNumber = 1 /* page number 1*/;
421 hdr.Reserved1 = 0;
422 hdr.Reserved2 = 0;
423 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
424 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
426 cfg.cfghdr.ehdr = &hdr;
427 cfg.physAddr = -1;
428 cfg.pageAddr = phy->identify.phy_identifier;
429 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
430 cfg.dir = 0; /* read */
431 cfg.timeout = 10;
433 error = mpt_config(ioc, &cfg);
434 if (error)
435 return error;
436 if (!hdr.ExtPageLength)
437 return -ENXIO;
439 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
440 &dma_handle);
441 if (!buffer)
442 return -ENOMEM;
444 cfg.physAddr = dma_handle;
445 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
447 error = mpt_config(ioc, &cfg);
448 if (error)
449 goto out_free_consistent;
451 mptsas_print_phy_pg1(buffer);
453 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
454 phy->running_disparity_error_count =
455 le32_to_cpu(buffer->RunningDisparityErrorCount);
456 phy->loss_of_dword_sync_count =
457 le32_to_cpu(buffer->LossDwordSynchCount);
458 phy->phy_reset_problem_count =
459 le32_to_cpu(buffer->PhyResetProblemCount);
461 out_free_consistent:
462 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
463 buffer, dma_handle);
464 return error;
467 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
468 MPT_FRAME_HDR *reply)
470 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
471 if (reply != NULL) {
472 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
473 memcpy(ioc->sas_mgmt.reply, reply,
474 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
476 complete(&ioc->sas_mgmt.done);
477 return 1;
480 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
482 MPT_ADAPTER *ioc = phy_to_ioc(phy);
483 SasIoUnitControlRequest_t *req;
484 SasIoUnitControlReply_t *reply;
485 MPT_FRAME_HDR *mf;
486 MPIHeader_t *hdr;
487 unsigned long timeleft;
488 int error = -ERESTARTSYS;
490 /* not implemented for expanders */
491 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
492 return -ENXIO;
494 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
495 goto out;
497 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
498 if (!mf) {
499 error = -ENOMEM;
500 goto out_unlock;
503 hdr = (MPIHeader_t *) mf;
504 req = (SasIoUnitControlRequest_t *)mf;
505 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
506 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
507 req->MsgContext = hdr->MsgContext;
508 req->Operation = hard_reset ?
509 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
510 req->PhyNum = phy->identify.phy_identifier;
512 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
514 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
515 10 * HZ);
516 if (!timeleft) {
517 /* On timeout reset the board */
518 mpt_free_msg_frame(ioc, mf);
519 mpt_HardResetHandler(ioc, CAN_SLEEP);
520 error = -ETIMEDOUT;
521 goto out_unlock;
524 /* a reply frame is expected */
525 if ((ioc->sas_mgmt.status &
526 MPT_IOCTL_STATUS_RF_VALID) == 0) {
527 error = -ENXIO;
528 goto out_unlock;
531 /* process the completed Reply Message Frame */
532 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
533 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
534 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
535 __FUNCTION__,
536 reply->IOCStatus,
537 reply->IOCLogInfo);
538 error = -ENXIO;
539 goto out_unlock;
542 error = 0;
544 out_unlock:
545 mutex_unlock(&ioc->sas_mgmt.mutex);
546 out:
547 return error;
550 static struct sas_function_template mptsas_transport_functions = {
551 .get_linkerrors = mptsas_get_linkerrors,
552 .phy_reset = mptsas_phy_reset,
555 static struct scsi_transport_template *mptsas_transport_template;
557 static int
558 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
560 ConfigExtendedPageHeader_t hdr;
561 CONFIGPARMS cfg;
562 SasIOUnitPage0_t *buffer;
563 dma_addr_t dma_handle;
564 int error, i;
566 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
567 hdr.ExtPageLength = 0;
568 hdr.PageNumber = 0;
569 hdr.Reserved1 = 0;
570 hdr.Reserved2 = 0;
571 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
572 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
574 cfg.cfghdr.ehdr = &hdr;
575 cfg.physAddr = -1;
576 cfg.pageAddr = 0;
577 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
578 cfg.dir = 0; /* read */
579 cfg.timeout = 10;
581 error = mpt_config(ioc, &cfg);
582 if (error)
583 goto out;
584 if (!hdr.ExtPageLength) {
585 error = -ENXIO;
586 goto out;
589 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
590 &dma_handle);
591 if (!buffer) {
592 error = -ENOMEM;
593 goto out;
596 cfg.physAddr = dma_handle;
597 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
599 error = mpt_config(ioc, &cfg);
600 if (error)
601 goto out_free_consistent;
603 port_info->num_phys = buffer->NumPhys;
604 port_info->phy_info = kcalloc(port_info->num_phys,
605 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
606 if (!port_info->phy_info) {
607 error = -ENOMEM;
608 goto out_free_consistent;
611 for (i = 0; i < port_info->num_phys; i++) {
612 mptsas_print_phy_data(&buffer->PhyData[i]);
613 port_info->phy_info[i].phy_id = i;
614 port_info->phy_info[i].port_id =
615 buffer->PhyData[i].Port;
616 port_info->phy_info[i].negotiated_link_rate =
617 buffer->PhyData[i].NegotiatedLinkRate;
620 out_free_consistent:
621 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
622 buffer, dma_handle);
623 out:
624 return error;
627 static int
628 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
629 u32 form, u32 form_specific)
631 ConfigExtendedPageHeader_t hdr;
632 CONFIGPARMS cfg;
633 SasPhyPage0_t *buffer;
634 dma_addr_t dma_handle;
635 int error;
637 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
638 hdr.ExtPageLength = 0;
639 hdr.PageNumber = 0;
640 hdr.Reserved1 = 0;
641 hdr.Reserved2 = 0;
642 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
643 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
645 cfg.cfghdr.ehdr = &hdr;
646 cfg.dir = 0; /* read */
647 cfg.timeout = 10;
649 /* Get Phy Pg 0 for each Phy. */
650 cfg.physAddr = -1;
651 cfg.pageAddr = form + form_specific;
652 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
654 error = mpt_config(ioc, &cfg);
655 if (error)
656 goto out;
658 if (!hdr.ExtPageLength) {
659 error = -ENXIO;
660 goto out;
663 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
664 &dma_handle);
665 if (!buffer) {
666 error = -ENOMEM;
667 goto out;
670 cfg.physAddr = dma_handle;
671 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
673 error = mpt_config(ioc, &cfg);
674 if (error)
675 goto out_free_consistent;
677 mptsas_print_phy_pg0(buffer);
679 phy_info->hw_link_rate = buffer->HwLinkRate;
680 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
681 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
682 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
684 out_free_consistent:
685 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
686 buffer, dma_handle);
687 out:
688 return error;
691 static int
692 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
693 u32 form, u32 form_specific)
695 ConfigExtendedPageHeader_t hdr;
696 CONFIGPARMS cfg;
697 SasDevicePage0_t *buffer;
698 dma_addr_t dma_handle;
699 __le64 sas_address;
700 int error;
702 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
703 hdr.ExtPageLength = 0;
704 hdr.PageNumber = 0;
705 hdr.Reserved1 = 0;
706 hdr.Reserved2 = 0;
707 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
708 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
710 cfg.cfghdr.ehdr = &hdr;
711 cfg.pageAddr = form + form_specific;
712 cfg.physAddr = -1;
713 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
714 cfg.dir = 0; /* read */
715 cfg.timeout = 10;
717 error = mpt_config(ioc, &cfg);
718 if (error)
719 goto out;
720 if (!hdr.ExtPageLength) {
721 error = -ENXIO;
722 goto out;
725 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
726 &dma_handle);
727 if (!buffer) {
728 error = -ENOMEM;
729 goto out;
732 cfg.physAddr = dma_handle;
733 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
735 error = mpt_config(ioc, &cfg);
736 if (error)
737 goto out_free_consistent;
739 mptsas_print_device_pg0(buffer);
741 device_info->handle = le16_to_cpu(buffer->DevHandle);
742 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
743 device_info->phy_id = buffer->PhyNum;
744 device_info->port_id = buffer->PhysicalPort;
745 device_info->id = buffer->TargetID;
746 device_info->channel = buffer->Bus;
747 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
748 device_info->sas_address = le64_to_cpu(sas_address);
749 device_info->device_info =
750 le32_to_cpu(buffer->DeviceInfo);
752 out_free_consistent:
753 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
754 buffer, dma_handle);
755 out:
756 return error;
759 static int
760 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
761 u32 form, u32 form_specific)
763 ConfigExtendedPageHeader_t hdr;
764 CONFIGPARMS cfg;
765 SasExpanderPage0_t *buffer;
766 dma_addr_t dma_handle;
767 int error;
769 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
770 hdr.ExtPageLength = 0;
771 hdr.PageNumber = 0;
772 hdr.Reserved1 = 0;
773 hdr.Reserved2 = 0;
774 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
775 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
777 cfg.cfghdr.ehdr = &hdr;
778 cfg.physAddr = -1;
779 cfg.pageAddr = form + form_specific;
780 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
781 cfg.dir = 0; /* read */
782 cfg.timeout = 10;
784 error = mpt_config(ioc, &cfg);
785 if (error)
786 goto out;
788 if (!hdr.ExtPageLength) {
789 error = -ENXIO;
790 goto out;
793 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
794 &dma_handle);
795 if (!buffer) {
796 error = -ENOMEM;
797 goto out;
800 cfg.physAddr = dma_handle;
801 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
803 error = mpt_config(ioc, &cfg);
804 if (error)
805 goto out_free_consistent;
807 /* save config data */
808 port_info->num_phys = buffer->NumPhys;
809 port_info->handle = le16_to_cpu(buffer->DevHandle);
810 port_info->phy_info = kcalloc(port_info->num_phys,
811 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
812 if (!port_info->phy_info) {
813 error = -ENOMEM;
814 goto out_free_consistent;
817 out_free_consistent:
818 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
819 buffer, dma_handle);
820 out:
821 return error;
824 static int
825 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
826 u32 form, u32 form_specific)
828 ConfigExtendedPageHeader_t hdr;
829 CONFIGPARMS cfg;
830 SasExpanderPage1_t *buffer;
831 dma_addr_t dma_handle;
832 int error;
834 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
835 hdr.ExtPageLength = 0;
836 hdr.PageNumber = 1;
837 hdr.Reserved1 = 0;
838 hdr.Reserved2 = 0;
839 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
840 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
842 cfg.cfghdr.ehdr = &hdr;
843 cfg.physAddr = -1;
844 cfg.pageAddr = form + form_specific;
845 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
846 cfg.dir = 0; /* read */
847 cfg.timeout = 10;
849 error = mpt_config(ioc, &cfg);
850 if (error)
851 goto out;
853 if (!hdr.ExtPageLength) {
854 error = -ENXIO;
855 goto out;
858 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
859 &dma_handle);
860 if (!buffer) {
861 error = -ENOMEM;
862 goto out;
865 cfg.physAddr = dma_handle;
866 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
868 error = mpt_config(ioc, &cfg);
869 if (error)
870 goto out_free_consistent;
873 mptsas_print_expander_pg1(buffer);
875 /* save config data */
876 phy_info->phy_id = buffer->PhyIdentifier;
877 phy_info->port_id = buffer->PhysicalPort;
878 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
879 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
880 phy_info->hw_link_rate = buffer->HwLinkRate;
881 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
882 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
885 out_free_consistent:
886 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
887 buffer, dma_handle);
888 out:
889 return error;
893 * Returns true if there is a scsi end device
895 static inline int
896 mptsas_is_end_device(struct mptsas_devinfo * attached)
898 if ((attached->handle) &&
899 (attached->device_info &
900 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
901 ((attached->device_info &
902 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
903 (attached->device_info &
904 MPI_SAS_DEVICE_INFO_STP_TARGET) |
905 (attached->device_info &
906 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
907 return 1;
908 else
909 return 0;
912 static void
913 mptsas_parse_device_info(struct sas_identify *identify,
914 struct mptsas_devinfo *device_info)
916 u16 protocols;
918 identify->sas_address = device_info->sas_address;
919 identify->phy_identifier = device_info->phy_id;
922 * Fill in Phy Initiator Port Protocol.
923 * Bits 6:3, more than one bit can be set, fall through cases.
925 protocols = device_info->device_info & 0x78;
926 identify->initiator_port_protocols = 0;
927 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
928 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
929 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
930 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
931 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
932 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
933 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
934 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
937 * Fill in Phy Target Port Protocol.
938 * Bits 10:7, more than one bit can be set, fall through cases.
940 protocols = device_info->device_info & 0x780;
941 identify->target_port_protocols = 0;
942 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
943 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
944 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
945 identify->target_port_protocols |= SAS_PROTOCOL_STP;
946 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
947 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
948 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
949 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
952 * Fill in Attached device type.
954 switch (device_info->device_info &
955 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
956 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
957 identify->device_type = SAS_PHY_UNUSED;
958 break;
959 case MPI_SAS_DEVICE_INFO_END_DEVICE:
960 identify->device_type = SAS_END_DEVICE;
961 break;
962 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
963 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
964 break;
965 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
966 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
967 break;
971 static int mptsas_probe_one_phy(struct device *dev,
972 struct mptsas_phyinfo *phy_info, int index, int local)
974 struct sas_phy *phy;
975 int error;
977 phy = sas_phy_alloc(dev, index);
978 if (!phy)
979 return -ENOMEM;
981 phy->port_identifier = phy_info->port_id;
982 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
985 * Set Negotiated link rate.
987 switch (phy_info->negotiated_link_rate) {
988 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
989 phy->negotiated_linkrate = SAS_PHY_DISABLED;
990 break;
991 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
992 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
993 break;
994 case MPI_SAS_IOUNIT0_RATE_1_5:
995 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
996 break;
997 case MPI_SAS_IOUNIT0_RATE_3_0:
998 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
999 break;
1000 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1001 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1002 default:
1003 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1004 break;
1008 * Set Max hardware link rate.
1010 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1011 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1012 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1013 break;
1014 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1015 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1016 break;
1017 default:
1018 break;
1022 * Set Max programmed link rate.
1024 switch (phy_info->programmed_link_rate &
1025 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1026 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1027 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1028 break;
1029 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1030 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1031 break;
1032 default:
1033 break;
1037 * Set Min hardware link rate.
1039 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1040 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1041 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1042 break;
1043 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1044 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1045 break;
1046 default:
1047 break;
1051 * Set Min programmed link rate.
1053 switch (phy_info->programmed_link_rate &
1054 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1055 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1056 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1057 break;
1058 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1059 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1060 break;
1061 default:
1062 break;
1065 if (local)
1066 phy->local_attached = 1;
1068 error = sas_phy_add(phy);
1069 if (error) {
1070 sas_phy_free(phy);
1071 return error;
1073 phy_info->phy = phy;
1075 if (phy_info->attached.handle) {
1076 struct sas_rphy *rphy;
1078 rphy = sas_rphy_alloc(phy);
1079 if (!rphy)
1080 return 0; /* non-fatal: an rphy can be added later */
1082 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1083 error = sas_rphy_add(rphy);
1084 if (error) {
1085 sas_rphy_free(rphy);
1086 return error;
1089 phy_info->rphy = rphy;
1092 return 0;
1095 static int
1096 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1098 struct mptsas_portinfo *port_info;
1099 u32 handle = 0xFFFF;
1100 int error = -ENOMEM, i;
1102 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1103 if (!port_info)
1104 goto out;
1106 error = mptsas_sas_io_unit_pg0(ioc, port_info);
1107 if (error)
1108 goto out_free_port_info;
1110 ioc->num_ports = port_info->num_phys;
1111 mutex_lock(&ioc->sas_topology_mutex);
1112 list_add_tail(&port_info->list, &ioc->sas_topology);
1113 mutex_unlock(&ioc->sas_topology_mutex);
1115 for (i = 0; i < port_info->num_phys; i++) {
1116 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1117 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1118 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1120 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1121 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1122 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1123 port_info->phy_info[i].identify.phy_id =
1124 port_info->phy_info[i].phy_id;
1125 handle = port_info->phy_info[i].identify.handle;
1127 if (port_info->phy_info[i].attached.handle) {
1128 mptsas_sas_device_pg0(ioc,
1129 &port_info->phy_info[i].attached,
1130 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1131 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1132 port_info->phy_info[i].attached.handle);
1135 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1136 &port_info->phy_info[i], *index, 1);
1137 (*index)++;
1140 return 0;
1142 out_free_port_info:
1143 kfree(port_info);
1144 out:
1145 return error;
1148 static int
1149 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1151 struct mptsas_portinfo *port_info, *p;
1152 int error = -ENOMEM, i, j;
1154 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1155 if (!port_info)
1156 goto out;
1158 error = mptsas_sas_expander_pg0(ioc, port_info,
1159 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1160 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1161 if (error)
1162 goto out_free_port_info;
1164 *handle = port_info->handle;
1166 mutex_lock(&ioc->sas_topology_mutex);
1167 list_add_tail(&port_info->list, &ioc->sas_topology);
1168 mutex_unlock(&ioc->sas_topology_mutex);
1170 for (i = 0; i < port_info->num_phys; i++) {
1171 struct device *parent;
1173 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1174 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1175 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1177 if (port_info->phy_info[i].identify.handle) {
1178 mptsas_sas_device_pg0(ioc,
1179 &port_info->phy_info[i].identify,
1180 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1181 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1182 port_info->phy_info[i].identify.handle);
1183 port_info->phy_info[i].identify.phy_id =
1184 port_info->phy_info[i].phy_id;
1187 if (port_info->phy_info[i].attached.handle) {
1188 mptsas_sas_device_pg0(ioc,
1189 &port_info->phy_info[i].attached,
1190 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1191 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1192 port_info->phy_info[i].attached.handle);
1196 * If we find a parent port handle this expander is
1197 * attached to another expander, else it hangs of the
1198 * HBA phys.
1200 parent = &ioc->sh->shost_gendev;
1201 mutex_lock(&ioc->sas_topology_mutex);
1202 list_for_each_entry(p, &ioc->sas_topology, list) {
1203 for (j = 0; j < p->num_phys; j++) {
1204 if (port_info->phy_info[i].identify.handle ==
1205 p->phy_info[j].attached.handle)
1206 parent = &p->phy_info[j].rphy->dev;
1209 mutex_unlock(&ioc->sas_topology_mutex);
1211 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1212 *index, 0);
1213 (*index)++;
1216 return 0;
1218 out_free_port_info:
1219 kfree(port_info);
1220 out:
1221 return error;
1224 static void
1225 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1227 u32 handle = 0xFFFF;
1228 int index = 0;
1230 mptsas_probe_hba_phys(ioc, &index);
1231 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1235 static struct mptsas_phyinfo *
1236 mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1238 struct mptsas_portinfo *port_info;
1239 struct mptsas_devinfo device_info;
1240 struct mptsas_phyinfo *phy_info = NULL;
1241 int i, error;
1244 * Retrieve the parent sas_address
1246 error = mptsas_sas_device_pg0(ioc, &device_info,
1247 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1248 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1249 parent_handle);
1250 if (error) {
1251 printk("mptsas: failed to retrieve device page\n");
1252 return NULL;
1256 * The phy_info structures are never deallocated during lifetime of
1257 * a host, so the code below is safe without additional refcounting.
1259 mutex_lock(&ioc->sas_topology_mutex);
1260 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1261 for (i = 0; i < port_info->num_phys; i++) {
1262 if (port_info->phy_info[i].identify.sas_address ==
1263 device_info.sas_address &&
1264 port_info->phy_info[i].phy_id == phy_id) {
1265 phy_info = &port_info->phy_info[i];
1266 break;
1270 mutex_unlock(&ioc->sas_topology_mutex);
1272 return phy_info;
1275 static struct mptsas_phyinfo *
1276 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1278 struct mptsas_portinfo *port_info;
1279 struct mptsas_phyinfo *phy_info = NULL;
1280 int i;
1283 * The phy_info structures are never deallocated during lifetime of
1284 * a host, so the code below is safe without additional refcounting.
1286 mutex_lock(&ioc->sas_topology_mutex);
1287 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1288 for (i = 0; i < port_info->num_phys; i++)
1289 if (mptsas_is_end_device(&port_info->phy_info[i].attached))
1290 if (port_info->phy_info[i].attached.id == id) {
1291 phy_info = &port_info->phy_info[i];
1292 break;
1295 mutex_unlock(&ioc->sas_topology_mutex);
1297 return phy_info;
1300 static void
1301 mptsas_hotplug_work(void *arg)
1303 struct mptsas_hotplug_event *ev = arg;
1304 MPT_ADAPTER *ioc = ev->ioc;
1305 struct mptsas_phyinfo *phy_info;
1306 struct sas_rphy *rphy;
1307 struct scsi_device *sdev;
1308 char *ds = NULL;
1309 struct mptsas_devinfo sas_device;
1311 switch (ev->event_type) {
1312 case MPTSAS_DEL_DEVICE:
1314 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1315 if (!phy_info) {
1316 printk("mptsas: remove event for non-existant PHY.\n");
1317 break;
1320 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1321 ds = "ssp";
1322 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1323 ds = "stp";
1324 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1325 ds = "sata";
1327 printk(MYIOC_s_INFO_FMT
1328 "removing %s device, channel %d, id %d, phy %d\n",
1329 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1331 if (phy_info->rphy) {
1332 sas_rphy_delete(phy_info->rphy);
1333 phy_info->rphy = NULL;
1335 break;
1336 case MPTSAS_ADD_DEVICE:
1339 * When there is no sas address,
1340 * RAID volumes are being deleted,
1341 * and hidden phy disk are being added.
1342 * We don't know the SAS data yet,
1343 * so lookup sas device page to get
1344 * pertaining info
1346 if (!ev->sas_address) {
1347 if (mptsas_sas_device_pg0(ioc,
1348 &sas_device, ev->id,
1349 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1350 MPI_SAS_DEVICE_PGAD_FORM_SHIFT)))
1351 break;
1352 ev->handle = sas_device.handle;
1353 ev->parent_handle = sas_device.handle_parent;
1354 ev->channel = sas_device.channel;
1355 ev->phy_id = sas_device.phy_id;
1356 ev->sas_address = sas_device.sas_address;
1357 ev->device_info = sas_device.device_info;
1360 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1361 ev->parent_handle, ev->phy_id);
1362 if (!phy_info) {
1363 printk("mptsas: add event for non-existant PHY.\n");
1364 break;
1367 if (phy_info->rphy) {
1368 printk("mptsas: trying to add existing device.\n");
1369 break;
1372 /* fill attached info */
1373 phy_info->attached.handle = ev->handle;
1374 phy_info->attached.phy_id = ev->phy_id;
1375 phy_info->attached.port_id = phy_info->identify.port_id;
1376 phy_info->attached.id = ev->id;
1377 phy_info->attached.channel = ev->channel;
1378 phy_info->attached.sas_address = ev->sas_address;
1379 phy_info->attached.device_info = ev->device_info;
1381 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1382 ds = "ssp";
1383 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1384 ds = "stp";
1385 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1386 ds = "sata";
1388 printk(MYIOC_s_INFO_FMT
1389 "attaching %s device, channel %d, id %d, phy %d\n",
1390 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1393 rphy = sas_rphy_alloc(phy_info->phy);
1394 if (!rphy)
1395 break; /* non-fatal: an rphy can be added later */
1397 rphy->scsi_target_id = phy_info->attached.id;
1398 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1399 if (sas_rphy_add(rphy)) {
1400 sas_rphy_free(rphy);
1401 break;
1404 phy_info->rphy = rphy;
1405 break;
1406 case MPTSAS_ADD_RAID:
1407 sdev = scsi_device_lookup(
1408 ioc->sh,
1409 ioc->num_ports,
1410 ev->id,
1412 if (sdev) {
1413 scsi_device_put(sdev);
1414 break;
1416 printk(MYIOC_s_INFO_FMT
1417 "attaching device, channel %d, id %d\n",
1418 ioc->name, ioc->num_ports, ev->id);
1419 scsi_add_device(ioc->sh,
1420 ioc->num_ports,
1421 ev->id,
1423 mpt_findImVolumes(ioc);
1424 break;
1425 case MPTSAS_DEL_RAID:
1426 sdev = scsi_device_lookup(
1427 ioc->sh,
1428 ioc->num_ports,
1429 ev->id,
1431 if (!sdev)
1432 break;
1433 printk(MYIOC_s_INFO_FMT
1434 "removing device, channel %d, id %d\n",
1435 ioc->name, ioc->num_ports, ev->id);
1436 scsi_remove_device(sdev);
1437 scsi_device_put(sdev);
1438 mpt_findImVolumes(ioc);
1439 break;
1442 kfree(ev);
1445 static void
1446 mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1447 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1449 struct mptsas_hotplug_event *ev;
1450 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1451 __le64 sas_address;
1453 if ((device_info &
1454 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1455 MPI_SAS_DEVICE_INFO_STP_TARGET |
1456 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1457 return;
1459 if ((sas_event_data->ReasonCode &
1460 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
1461 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
1462 return;
1464 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1465 if (!ev) {
1466 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1467 return;
1471 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1472 ev->ioc = ioc;
1473 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1474 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1475 ev->channel = sas_event_data->Bus;
1476 ev->id = sas_event_data->TargetID;
1477 ev->phy_id = sas_event_data->PhyNum;
1478 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1479 ev->sas_address = le64_to_cpu(sas_address);
1480 ev->device_info = device_info;
1482 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1483 ev->event_type = MPTSAS_ADD_DEVICE;
1484 else
1485 ev->event_type = MPTSAS_DEL_DEVICE;
1487 schedule_work(&ev->work);
1490 static void
1491 mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1492 EVENT_DATA_RAID *raid_event_data)
1494 struct mptsas_hotplug_event *ev;
1495 RAID_VOL0_STATUS * volumeStatus;
1497 if (ioc->bus_type != SAS)
1498 return;
1500 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1501 if (!ev) {
1502 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1503 return;
1506 memset(ev,0,sizeof(struct mptsas_hotplug_event));
1507 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1508 ev->ioc = ioc;
1509 ev->id = raid_event_data->VolumeID;
1511 switch (raid_event_data->ReasonCode) {
1512 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
1513 ev->event_type = MPTSAS_ADD_DEVICE;
1514 break;
1515 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1516 ev->event_type = MPTSAS_DEL_DEVICE;
1517 break;
1518 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
1519 ev->event_type = MPTSAS_DEL_RAID;
1520 break;
1521 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
1522 ev->event_type = MPTSAS_ADD_RAID;
1523 break;
1524 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
1525 volumeStatus = (RAID_VOL0_STATUS *) &
1526 raid_event_data->SettingsStatus;
1527 ev->event_type = (volumeStatus->State ==
1528 MPI_RAIDVOL0_STATUS_STATE_FAILED) ?
1529 MPTSAS_DEL_RAID : MPTSAS_ADD_RAID;
1530 break;
1531 default:
1532 break;
1534 schedule_work(&ev->work);
1537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1538 /* work queue thread to clear the persitency table */
1539 static void
1540 mptscsih_sas_persist_clear_table(void * arg)
1542 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1544 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1547 static int
1548 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1550 int rc=1;
1551 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1553 if (!ioc->sh)
1554 goto out;
1556 switch (event) {
1557 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1558 mptscsih_send_sas_event(ioc,
1559 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1560 break;
1561 case MPI_EVENT_INTEGRATED_RAID:
1562 mptscsih_send_raid_event(ioc,
1563 (EVENT_DATA_RAID *)reply->Data);
1564 break;
1565 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1566 INIT_WORK(&ioc->mptscsih_persistTask,
1567 mptscsih_sas_persist_clear_table,
1568 (void *)ioc);
1569 schedule_work(&ioc->mptscsih_persistTask);
1570 break;
1571 default:
1572 rc = mptscsih_event_process(ioc, reply);
1573 break;
1575 out:
1577 return rc;
1580 static int
1581 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1583 struct Scsi_Host *sh;
1584 MPT_SCSI_HOST *hd;
1585 MPT_ADAPTER *ioc;
1586 unsigned long flags;
1587 int ii;
1588 int numSGE = 0;
1589 int scale;
1590 int ioc_cap;
1591 int error=0;
1592 int r;
1594 r = mpt_attach(pdev,id);
1595 if (r)
1596 return r;
1598 ioc = pci_get_drvdata(pdev);
1599 ioc->DoneCtx = mptsasDoneCtx;
1600 ioc->TaskCtx = mptsasTaskCtx;
1601 ioc->InternalCtx = mptsasInternalCtx;
1603 /* Added sanity check on readiness of the MPT adapter.
1605 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1606 printk(MYIOC_s_WARN_FMT
1607 "Skipping because it's not operational!\n",
1608 ioc->name);
1609 error = -ENODEV;
1610 goto out_mptsas_probe;
1613 if (!ioc->active) {
1614 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1615 ioc->name);
1616 error = -ENODEV;
1617 goto out_mptsas_probe;
1620 /* Sanity check - ensure at least 1 port is INITIATOR capable
1622 ioc_cap = 0;
1623 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1624 if (ioc->pfacts[ii].ProtocolFlags &
1625 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1626 ioc_cap++;
1629 if (!ioc_cap) {
1630 printk(MYIOC_s_WARN_FMT
1631 "Skipping ioc=%p because SCSI Initiator mode "
1632 "is NOT enabled!\n", ioc->name, ioc);
1633 return 0;
1636 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1637 if (!sh) {
1638 printk(MYIOC_s_WARN_FMT
1639 "Unable to register controller with SCSI subsystem\n",
1640 ioc->name);
1641 error = -1;
1642 goto out_mptsas_probe;
1645 spin_lock_irqsave(&ioc->FreeQlock, flags);
1647 /* Attach the SCSI Host to the IOC structure
1649 ioc->sh = sh;
1651 sh->io_port = 0;
1652 sh->n_io_port = 0;
1653 sh->irq = 0;
1655 /* set 16 byte cdb's */
1656 sh->max_cmd_len = 16;
1658 sh->max_id = ioc->pfacts->MaxDevices + 1;
1660 sh->transportt = mptsas_transport_template;
1662 sh->max_lun = MPT_LAST_LUN + 1;
1663 sh->max_channel = 0;
1664 sh->this_id = ioc->pfacts[0].PortSCSIID;
1666 /* Required entry.
1668 sh->unique_id = ioc->id;
1670 INIT_LIST_HEAD(&ioc->sas_topology);
1671 mutex_init(&ioc->sas_topology_mutex);
1673 mutex_init(&ioc->sas_mgmt.mutex);
1674 init_completion(&ioc->sas_mgmt.done);
1676 /* Verify that we won't exceed the maximum
1677 * number of chain buffers
1678 * We can optimize: ZZ = req_sz/sizeof(SGE)
1679 * For 32bit SGE's:
1680 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1681 * + (req_sz - 64)/sizeof(SGE)
1682 * A slightly different algorithm is required for
1683 * 64bit SGEs.
1685 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1686 if (sizeof(dma_addr_t) == sizeof(u64)) {
1687 numSGE = (scale - 1) *
1688 (ioc->facts.MaxChainDepth-1) + scale +
1689 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1690 sizeof(u32));
1691 } else {
1692 numSGE = 1 + (scale - 1) *
1693 (ioc->facts.MaxChainDepth-1) + scale +
1694 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1695 sizeof(u32));
1698 if (numSGE < sh->sg_tablesize) {
1699 /* Reset this value */
1700 dprintk((MYIOC_s_INFO_FMT
1701 "Resetting sg_tablesize to %d from %d\n",
1702 ioc->name, numSGE, sh->sg_tablesize));
1703 sh->sg_tablesize = numSGE;
1706 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1708 hd = (MPT_SCSI_HOST *) sh->hostdata;
1709 hd->ioc = ioc;
1711 /* SCSI needs scsi_cmnd lookup table!
1712 * (with size equal to req_depth*PtrSz!)
1714 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1715 if (!hd->ScsiLookup) {
1716 error = -ENOMEM;
1717 goto out_mptsas_probe;
1720 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1721 ioc->name, hd->ScsiLookup));
1723 /* Allocate memory for the device structures.
1724 * A non-Null pointer at an offset
1725 * indicates a device exists.
1726 * max_id = 1 + maximum id (hosts.h)
1728 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1729 if (!hd->Targets) {
1730 error = -ENOMEM;
1731 goto out_mptsas_probe;
1734 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
1736 /* Clear the TM flags
1738 hd->tmPending = 0;
1739 hd->tmState = TM_STATE_NONE;
1740 hd->resetPending = 0;
1741 hd->abortSCpnt = NULL;
1743 /* Clear the pointer used to store
1744 * single-threaded commands, i.e., those
1745 * issued during a bus scan, dv and
1746 * configuration pages.
1748 hd->cmdPtr = NULL;
1750 /* Initialize this SCSI Hosts' timers
1751 * To use, set the timer expires field
1752 * and add_timer
1754 init_timer(&hd->timer);
1755 hd->timer.data = (unsigned long) hd;
1756 hd->timer.function = mptscsih_timer_expired;
1758 hd->mpt_pq_filter = mpt_pq_filter;
1759 ioc->sas_data.ptClear = mpt_pt_clear;
1761 if (ioc->sas_data.ptClear==1) {
1762 mptbase_sas_persist_operation(
1763 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1766 ddvprintk((MYIOC_s_INFO_FMT
1767 "mpt_pq_filter %x mpt_pq_filter %x\n",
1768 ioc->name,
1769 mpt_pq_filter,
1770 mpt_pq_filter));
1772 init_waitqueue_head(&hd->scandv_waitq);
1773 hd->scandv_wait_done = 0;
1774 hd->last_queue_full = 0;
1776 error = scsi_add_host(sh, &ioc->pcidev->dev);
1777 if (error) {
1778 dprintk((KERN_ERR MYNAM
1779 "scsi_add_host failed\n"));
1780 goto out_mptsas_probe;
1783 mptsas_scan_sas_topology(ioc);
1786 Reporting RAID volumes.
1788 if (!ioc->raid_data.pIocPg2)
1789 return 0;
1790 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1791 return 0;
1792 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1793 scsi_add_device(sh,
1794 ioc->num_ports,
1795 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1799 return 0;
1801 out_mptsas_probe:
1803 mptscsih_remove(pdev);
1804 return error;
1807 static void __devexit mptsas_remove(struct pci_dev *pdev)
1809 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1810 struct mptsas_portinfo *p, *n;
1812 sas_remove_host(ioc->sh);
1814 mutex_lock(&ioc->sas_topology_mutex);
1815 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1816 list_del(&p->list);
1817 kfree(p);
1819 mutex_unlock(&ioc->sas_topology_mutex);
1821 mptscsih_remove(pdev);
1824 static struct pci_device_id mptsas_pci_table[] = {
1825 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1826 PCI_ANY_ID, PCI_ANY_ID },
1827 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1828 PCI_ANY_ID, PCI_ANY_ID },
1829 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1830 PCI_ANY_ID, PCI_ANY_ID },
1831 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1832 PCI_ANY_ID, PCI_ANY_ID },
1833 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1834 PCI_ANY_ID, PCI_ANY_ID },
1835 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1836 PCI_ANY_ID, PCI_ANY_ID },
1837 {0} /* Terminating entry */
1839 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1842 static struct pci_driver mptsas_driver = {
1843 .name = "mptsas",
1844 .id_table = mptsas_pci_table,
1845 .probe = mptsas_probe,
1846 .remove = __devexit_p(mptsas_remove),
1847 .shutdown = mptscsih_shutdown,
1848 #ifdef CONFIG_PM
1849 .suspend = mptscsih_suspend,
1850 .resume = mptscsih_resume,
1851 #endif
1854 static int __init
1855 mptsas_init(void)
1857 show_mptmod_ver(my_NAME, my_VERSION);
1859 mptsas_transport_template =
1860 sas_attach_transport(&mptsas_transport_functions);
1861 if (!mptsas_transport_template)
1862 return -ENODEV;
1864 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1865 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1866 mptsasInternalCtx =
1867 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1868 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1870 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1871 devtprintk((KERN_INFO MYNAM
1872 ": Registered for IOC event notifications\n"));
1875 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1876 dprintk((KERN_INFO MYNAM
1877 ": Registered for IOC reset notifications\n"));
1880 return pci_register_driver(&mptsas_driver);
1883 static void __exit
1884 mptsas_exit(void)
1886 pci_unregister_driver(&mptsas_driver);
1887 sas_release_transport(mptsas_transport_template);
1889 mpt_reset_deregister(mptsasDoneCtx);
1890 mpt_event_deregister(mptsasDoneCtx);
1892 mpt_deregister(mptsasMgmtCtx);
1893 mpt_deregister(mptsasInternalCtx);
1894 mpt_deregister(mptsasTaskCtx);
1895 mpt_deregister(mptsasDoneCtx);
1898 module_init(mptsas_init);
1899 module_exit(mptsas_exit);