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 Dell
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.
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>
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 "
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;
90 * SAS topology structures
92 * The MPT Fusion firmware interface spreads information about the
93 * SAS topology over many manufacture pages, thus we need some data
94 * structure to collect it and process it for the SAS transport class.
97 struct mptsas_devinfo {
98 u16 handle; /* unique id to address this device */
99 u8 phy_id; /* phy number of parent device */
100 u8 port_id; /* sas physical port this device
102 u8 target; /* logical target id of this device */
103 u8 bus; /* logical bus number of this device */
104 u64 sas_address; /* WWN of this device,
105 SATA is assigned by HBA,expander */
106 u32 device_info; /* bitfield detailed info about this device */
109 struct mptsas_phyinfo {
110 u8 phy_id; /* phy index */
111 u8 port_id; /* port number this phy is part of */
112 u8 negotiated_link_rate; /* nego'd link rate for this phy */
113 u8 hw_link_rate; /* hardware max/min phys link rate */
114 u8 programmed_link_rate; /* programmed max/min phy link rate */
115 struct mptsas_devinfo identify; /* point to phy device info */
116 struct mptsas_devinfo attached; /* point to attached device info */
117 struct sas_rphy *rphy;
120 struct mptsas_portinfo {
121 struct list_head list;
122 u16 handle; /* unique id to address this */
123 u8 num_phys; /* number of phys */
124 struct mptsas_phyinfo *phy_info;
129 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
131 printk("---- IO UNIT PAGE 0 ------------\n");
132 printk("Handle=0x%X\n",
133 le16_to_cpu(phy_data->AttachedDeviceHandle));
134 printk("Controller Handle=0x%X\n",
135 le16_to_cpu(phy_data->ControllerDevHandle));
136 printk("Port=0x%X\n", phy_data->Port);
137 printk("Port Flags=0x%X\n", phy_data->PortFlags);
138 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
139 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
140 printk("Controller PHY Device Info=0x%X\n",
141 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
142 printk("DiscoveryStatus=0x%X\n",
143 le32_to_cpu(phy_data->DiscoveryStatus));
147 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
151 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
153 printk("---- SAS PHY PAGE 0 ------------\n");
154 printk("Attached Device Handle=0x%X\n",
155 le16_to_cpu(pg0->AttachedDevHandle));
156 printk("SAS Address=0x%llX\n",
157 (unsigned long long)le64_to_cpu(sas_address));
158 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
159 printk("Attached Device Info=0x%X\n",
160 le32_to_cpu(pg0->AttachedDeviceInfo));
161 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
162 printk("Change Count=0x%X\n", pg0->ChangeCount);
163 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
167 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
169 printk("---- SAS PHY PAGE 1 ------------\n");
170 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
171 printk("Running Disparity Error Count=0x%x\n",
172 pg1->RunningDisparityErrorCount);
173 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
174 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
178 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
182 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
184 printk("---- SAS DEVICE PAGE 0 ---------\n");
185 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
186 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
187 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
188 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
189 printk("Target ID=0x%X\n", pg0->TargetID);
190 printk("Bus=0x%X\n", pg0->Bus);
191 /* The PhyNum field specifies the PHY number of the parent
192 * device this device is linked to
194 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
195 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
196 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
197 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
198 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
202 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
204 printk("---- SAS EXPANDER PAGE 1 ------------\n");
206 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
207 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
208 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
209 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
210 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
211 printk("Owner Device Handle=0x%X\n",
212 le16_to_cpu(pg1->OwnerDevHandle));
213 printk("Attached Device Handle=0x%X\n",
214 le16_to_cpu(pg1->AttachedDevHandle));
217 #define mptsas_print_phy_data(phy_data) do { } while (0)
218 #define mptsas_print_phy_pg0(pg0) do { } while (0)
219 #define mptsas_print_phy_pg1(pg1) do { } while (0)
220 #define mptsas_print_device_pg0(pg0) do { } while (0)
221 #define mptsas_print_expander_pg1(pg1) do { } while (0)
226 * This is pretty ugly. We will be able to seriously clean it up
227 * once the DV code in mptscsih goes away and we can properly
228 * implement ->target_alloc.
231 mptsas_slave_alloc(struct scsi_device *device)
233 struct Scsi_Host *host = device->host;
234 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
235 struct sas_rphy *rphy;
236 struct mptsas_portinfo *p;
238 uint target = device->id;
241 if ((vdev = hd->Targets[target]) != NULL)
244 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
246 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
247 hd->ioc->name, sizeof(VirtDevice));
251 memset(vdev, 0, sizeof(VirtDevice));
252 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
253 vdev->ioc_id = hd->ioc->id;
255 rphy = dev_to_rphy(device->sdev_target->dev.parent);
256 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
257 for (i = 0; i < p->num_phys; i++) {
258 if (p->phy_info[i].attached.sas_address ==
259 rphy->identify.sas_address) {
261 p->phy_info[i].attached.target;
262 vdev->bus_id = p->phy_info[i].attached.bus;
263 hd->Targets[device->id] = vdev;
269 printk("No matching SAS device found!!\n");
275 device->hostdata = vdev;
279 static struct scsi_host_template mptsas_driver_template = {
280 .proc_name = "mptsas",
281 .proc_info = mptscsih_proc_info,
282 .name = "MPT SPI Host",
283 .info = mptscsih_info,
284 .queuecommand = mptscsih_qcmd,
285 .slave_alloc = mptsas_slave_alloc,
286 .slave_configure = mptscsih_slave_configure,
287 .slave_destroy = mptscsih_slave_destroy,
288 .change_queue_depth = mptscsih_change_queue_depth,
289 .eh_abort_handler = mptscsih_abort,
290 .eh_device_reset_handler = mptscsih_dev_reset,
291 .eh_bus_reset_handler = mptscsih_bus_reset,
292 .eh_host_reset_handler = mptscsih_host_reset,
293 .bios_param = mptscsih_bios_param,
294 .can_queue = MPT_FC_CAN_QUEUE,
296 .sg_tablesize = MPT_SCSI_SG_DEPTH,
299 .use_clustering = ENABLE_CLUSTERING,
302 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
304 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
305 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
308 static int mptsas_get_linkerrors(struct sas_phy *phy)
310 MPT_ADAPTER *ioc = phy_to_ioc(phy);
311 ConfigExtendedPageHeader_t hdr;
313 SasPhyPage1_t *buffer;
314 dma_addr_t dma_handle;
317 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
318 hdr.ExtPageLength = 0;
319 hdr.PageNumber = 1 /* page number 1*/;
322 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
323 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
325 cfg.cfghdr.ehdr = &hdr;
327 cfg.pageAddr = phy->identify.phy_identifier;
328 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
329 cfg.dir = 0; /* read */
332 error = mpt_config(ioc, &cfg);
335 if (!hdr.ExtPageLength)
338 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
343 cfg.physAddr = dma_handle;
344 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
346 error = mpt_config(ioc, &cfg);
348 goto out_free_consistent;
350 mptsas_print_phy_pg1(buffer);
352 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
353 phy->running_disparity_error_count =
354 le32_to_cpu(buffer->RunningDisparityErrorCount);
355 phy->loss_of_dword_sync_count =
356 le32_to_cpu(buffer->LossDwordSynchCount);
357 phy->phy_reset_problem_count =
358 le32_to_cpu(buffer->PhyResetProblemCount);
361 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
366 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
367 MPT_FRAME_HDR *reply)
369 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
371 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
372 memcpy(ioc->sas_mgmt.reply, reply,
373 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
375 complete(&ioc->sas_mgmt.done);
379 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
381 MPT_ADAPTER *ioc = phy_to_ioc(phy);
382 SasIoUnitControlRequest_t *req;
383 SasIoUnitControlReply_t *reply;
386 unsigned long timeleft;
387 int error = -ERESTARTSYS;
389 /* not implemented for expanders */
390 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
393 if (down_interruptible(&ioc->sas_mgmt.mutex))
396 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
402 hdr = (MPIHeader_t *) mf;
403 req = (SasIoUnitControlRequest_t *)mf;
404 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
405 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
406 req->MsgContext = hdr->MsgContext;
407 req->Operation = hard_reset ?
408 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
409 req->PhyNum = phy->identify.phy_identifier;
411 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
413 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
416 /* On timeout reset the board */
417 mpt_free_msg_frame(ioc, mf);
418 mpt_HardResetHandler(ioc, CAN_SLEEP);
423 /* a reply frame is expected */
424 if ((ioc->sas_mgmt.status &
425 MPT_IOCTL_STATUS_RF_VALID) == 0) {
430 /* process the completed Reply Message Frame */
431 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
432 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
433 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
444 up(&ioc->sas_mgmt.mutex);
449 static struct sas_function_template mptsas_transport_functions = {
450 .get_linkerrors = mptsas_get_linkerrors,
451 .phy_reset = mptsas_phy_reset,
454 static struct scsi_transport_template *mptsas_transport_template;
457 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
459 ConfigExtendedPageHeader_t hdr;
461 SasIOUnitPage0_t *buffer;
462 dma_addr_t dma_handle;
465 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
466 hdr.ExtPageLength = 0;
470 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
471 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
473 cfg.cfghdr.ehdr = &hdr;
476 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
477 cfg.dir = 0; /* read */
480 error = mpt_config(ioc, &cfg);
483 if (!hdr.ExtPageLength) {
488 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
495 cfg.physAddr = dma_handle;
496 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
498 error = mpt_config(ioc, &cfg);
500 goto out_free_consistent;
502 port_info->num_phys = buffer->NumPhys;
503 port_info->phy_info = kcalloc(port_info->num_phys,
504 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
505 if (!port_info->phy_info) {
507 goto out_free_consistent;
510 for (i = 0; i < port_info->num_phys; i++) {
511 mptsas_print_phy_data(&buffer->PhyData[i]);
512 port_info->phy_info[i].phy_id = i;
513 port_info->phy_info[i].port_id =
514 buffer->PhyData[i].Port;
515 port_info->phy_info[i].negotiated_link_rate =
516 buffer->PhyData[i].NegotiatedLinkRate;
520 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
527 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
528 u32 form, u32 form_specific)
530 ConfigExtendedPageHeader_t hdr;
532 SasPhyPage0_t *buffer;
533 dma_addr_t dma_handle;
536 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
537 hdr.ExtPageLength = 0;
541 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
542 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
544 cfg.cfghdr.ehdr = &hdr;
545 cfg.dir = 0; /* read */
548 /* Get Phy Pg 0 for each Phy. */
550 cfg.pageAddr = form + form_specific;
551 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
553 error = mpt_config(ioc, &cfg);
557 if (!hdr.ExtPageLength) {
562 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
569 cfg.physAddr = dma_handle;
570 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
572 error = mpt_config(ioc, &cfg);
574 goto out_free_consistent;
576 mptsas_print_phy_pg0(buffer);
578 phy_info->hw_link_rate = buffer->HwLinkRate;
579 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
580 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
581 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
584 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
591 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
592 u32 form, u32 form_specific)
594 ConfigExtendedPageHeader_t hdr;
596 SasDevicePage0_t *buffer;
597 dma_addr_t dma_handle;
601 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
602 hdr.ExtPageLength = 0;
606 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
607 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
609 cfg.cfghdr.ehdr = &hdr;
610 cfg.pageAddr = form + form_specific;
612 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
613 cfg.dir = 0; /* read */
616 error = mpt_config(ioc, &cfg);
619 if (!hdr.ExtPageLength) {
624 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
631 cfg.physAddr = dma_handle;
632 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
634 error = mpt_config(ioc, &cfg);
636 goto out_free_consistent;
638 mptsas_print_device_pg0(buffer);
640 device_info->handle = le16_to_cpu(buffer->DevHandle);
641 device_info->phy_id = buffer->PhyNum;
642 device_info->port_id = buffer->PhysicalPort;
643 device_info->target = buffer->TargetID;
644 device_info->bus = buffer->Bus;
645 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
646 device_info->sas_address = le64_to_cpu(sas_address);
647 device_info->device_info =
648 le32_to_cpu(buffer->DeviceInfo);
651 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
658 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
659 u32 form, u32 form_specific)
661 ConfigExtendedPageHeader_t hdr;
663 SasExpanderPage0_t *buffer;
664 dma_addr_t dma_handle;
667 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
668 hdr.ExtPageLength = 0;
672 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
673 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
675 cfg.cfghdr.ehdr = &hdr;
677 cfg.pageAddr = form + form_specific;
678 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
679 cfg.dir = 0; /* read */
682 error = mpt_config(ioc, &cfg);
686 if (!hdr.ExtPageLength) {
691 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
698 cfg.physAddr = dma_handle;
699 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
701 error = mpt_config(ioc, &cfg);
703 goto out_free_consistent;
705 /* save config data */
706 port_info->num_phys = buffer->NumPhys;
707 port_info->handle = le16_to_cpu(buffer->DevHandle);
708 port_info->phy_info = kcalloc(port_info->num_phys,
709 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
710 if (!port_info->phy_info) {
712 goto out_free_consistent;
716 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
723 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
724 u32 form, u32 form_specific)
726 ConfigExtendedPageHeader_t hdr;
728 SasExpanderPage1_t *buffer;
729 dma_addr_t dma_handle;
732 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
733 hdr.ExtPageLength = 0;
737 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
738 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
740 cfg.cfghdr.ehdr = &hdr;
742 cfg.pageAddr = form + form_specific;
743 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
744 cfg.dir = 0; /* read */
747 error = mpt_config(ioc, &cfg);
751 if (!hdr.ExtPageLength) {
756 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
763 cfg.physAddr = dma_handle;
764 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
766 error = mpt_config(ioc, &cfg);
768 goto out_free_consistent;
771 mptsas_print_expander_pg1(buffer);
773 /* save config data */
774 phy_info->phy_id = buffer->PhyIdentifier;
775 phy_info->port_id = buffer->PhysicalPort;
776 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
777 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
778 phy_info->hw_link_rate = buffer->HwLinkRate;
779 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
780 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
784 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
791 mptsas_parse_device_info(struct sas_identify *identify,
792 struct mptsas_devinfo *device_info)
796 identify->sas_address = device_info->sas_address;
797 identify->phy_identifier = device_info->phy_id;
800 * Fill in Phy Initiator Port Protocol.
801 * Bits 6:3, more than one bit can be set, fall through cases.
803 protocols = device_info->device_info & 0x78;
804 identify->initiator_port_protocols = 0;
805 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
806 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
807 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
808 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
809 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
810 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
811 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
812 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
815 * Fill in Phy Target Port Protocol.
816 * Bits 10:7, more than one bit can be set, fall through cases.
818 protocols = device_info->device_info & 0x780;
819 identify->target_port_protocols = 0;
820 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
821 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
822 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
823 identify->target_port_protocols |= SAS_PROTOCOL_STP;
824 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
825 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
826 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
827 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
830 * Fill in Attached device type.
832 switch (device_info->device_info &
833 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
834 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
835 identify->device_type = SAS_PHY_UNUSED;
837 case MPI_SAS_DEVICE_INFO_END_DEVICE:
838 identify->device_type = SAS_END_DEVICE;
840 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
841 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
843 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
844 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
849 static int mptsas_probe_one_phy(struct device *dev,
850 struct mptsas_phyinfo *phy_info, int index, int local)
852 struct sas_phy *port;
855 port = sas_phy_alloc(dev, index);
859 port->port_identifier = phy_info->port_id;
860 mptsas_parse_device_info(&port->identify, &phy_info->identify);
863 * Set Negotiated link rate.
865 switch (phy_info->negotiated_link_rate) {
866 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
867 port->negotiated_linkrate = SAS_PHY_DISABLED;
869 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
870 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
872 case MPI_SAS_IOUNIT0_RATE_1_5:
873 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
875 case MPI_SAS_IOUNIT0_RATE_3_0:
876 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
878 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
879 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
881 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
886 * Set Max hardware link rate.
888 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
889 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
890 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
892 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
893 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
900 * Set Max programmed link rate.
902 switch (phy_info->programmed_link_rate &
903 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
904 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
905 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
907 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
908 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
915 * Set Min hardware link rate.
917 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
918 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
919 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
921 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
922 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
929 * Set Min programmed link rate.
931 switch (phy_info->programmed_link_rate &
932 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
933 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
934 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
936 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
937 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
944 port->local_attached = 1;
946 error = sas_phy_add(port);
952 if (phy_info->attached.handle) {
953 struct sas_rphy *rphy;
955 rphy = sas_rphy_alloc(port);
957 return 0; /* non-fatal: an rphy can be added later */
959 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
960 error = sas_rphy_add(rphy);
966 phy_info->rphy = rphy;
973 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
975 struct mptsas_portinfo *port_info;
977 int error = -ENOMEM, i;
979 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
982 memset(port_info, 0, sizeof(*port_info));
984 error = mptsas_sas_io_unit_pg0(ioc, port_info);
986 goto out_free_port_info;
988 list_add_tail(&port_info->list, &ioc->sas_topology);
990 for (i = 0; i < port_info->num_phys; i++) {
991 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
992 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
993 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
995 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
996 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
997 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
998 port_info->phy_info[i].identify.phy_id =
999 port_info->phy_info[i].phy_id;
1000 handle = port_info->phy_info[i].identify.handle;
1002 if (port_info->phy_info[i].attached.handle) {
1003 mptsas_sas_device_pg0(ioc,
1004 &port_info->phy_info[i].attached,
1005 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1006 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1007 port_info->phy_info[i].attached.handle);
1010 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1011 &port_info->phy_info[i], *index, 1);
1024 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1026 struct mptsas_portinfo *port_info, *p;
1027 int error = -ENOMEM, i, j;
1029 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
1032 memset(port_info, 0, sizeof(*port_info));
1034 error = mptsas_sas_expander_pg0(ioc, port_info,
1035 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1036 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1038 goto out_free_port_info;
1040 *handle = port_info->handle;
1042 list_add_tail(&port_info->list, &ioc->sas_topology);
1043 for (i = 0; i < port_info->num_phys; i++) {
1044 struct device *parent;
1046 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1047 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1048 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1050 if (port_info->phy_info[i].identify.handle) {
1051 mptsas_sas_device_pg0(ioc,
1052 &port_info->phy_info[i].identify,
1053 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1054 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1055 port_info->phy_info[i].identify.handle);
1056 port_info->phy_info[i].identify.phy_id =
1057 port_info->phy_info[i].phy_id;
1060 if (port_info->phy_info[i].attached.handle) {
1061 mptsas_sas_device_pg0(ioc,
1062 &port_info->phy_info[i].attached,
1063 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1064 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1065 port_info->phy_info[i].attached.handle);
1069 * If we find a parent port handle this expander is
1070 * attached to another expander, else it hangs of the
1073 parent = &ioc->sh->shost_gendev;
1074 list_for_each_entry(p, &ioc->sas_topology, list) {
1075 for (j = 0; j < p->num_phys; j++) {
1076 if (port_info->phy_info[i].identify.handle ==
1077 p->phy_info[j].attached.handle)
1078 parent = &p->phy_info[j].rphy->dev;
1082 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1096 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1098 u32 handle = 0xFFFF;
1101 mptsas_probe_hba_phys(ioc, &index);
1102 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1107 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1109 struct Scsi_Host *sh;
1112 unsigned long flags;
1121 r = mpt_attach(pdev,id);
1125 ioc = pci_get_drvdata(pdev);
1126 ioc->DoneCtx = mptsasDoneCtx;
1127 ioc->TaskCtx = mptsasTaskCtx;
1128 ioc->InternalCtx = mptsasInternalCtx;
1130 /* Added sanity check on readiness of the MPT adapter.
1132 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1133 printk(MYIOC_s_WARN_FMT
1134 "Skipping because it's not operational!\n",
1140 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1145 /* Sanity check - ensure at least 1 port is INITIATOR capable
1148 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1149 if (ioc->pfacts[ii].ProtocolFlags &
1150 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1155 printk(MYIOC_s_WARN_FMT
1156 "Skipping ioc=%p because SCSI Initiator mode "
1157 "is NOT enabled!\n", ioc->name, ioc);
1161 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1163 printk(MYIOC_s_WARN_FMT
1164 "Unable to register controller with SCSI subsystem\n",
1169 spin_lock_irqsave(&ioc->FreeQlock, flags);
1171 /* Attach the SCSI Host to the IOC structure
1179 /* set 16 byte cdb's */
1180 sh->max_cmd_len = 16;
1182 sh->max_id = ioc->pfacts->MaxDevices + 1;
1184 sh->transportt = mptsas_transport_template;
1186 sh->max_lun = MPT_LAST_LUN + 1;
1187 sh->max_channel = 0;
1188 sh->this_id = ioc->pfacts[0].PortSCSIID;
1192 sh->unique_id = ioc->id;
1194 INIT_LIST_HEAD(&ioc->sas_topology);
1195 init_MUTEX(&ioc->sas_mgmt.mutex);
1196 init_completion(&ioc->sas_mgmt.done);
1198 /* Verify that we won't exceed the maximum
1199 * number of chain buffers
1200 * We can optimize: ZZ = req_sz/sizeof(SGE)
1202 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1203 * + (req_sz - 64)/sizeof(SGE)
1204 * A slightly different algorithm is required for
1207 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1208 if (sizeof(dma_addr_t) == sizeof(u64)) {
1209 numSGE = (scale - 1) *
1210 (ioc->facts.MaxChainDepth-1) + scale +
1211 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1214 numSGE = 1 + (scale - 1) *
1215 (ioc->facts.MaxChainDepth-1) + scale +
1216 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1220 if (numSGE < sh->sg_tablesize) {
1221 /* Reset this value */
1222 dprintk((MYIOC_s_INFO_FMT
1223 "Resetting sg_tablesize to %d from %d\n",
1224 ioc->name, numSGE, sh->sg_tablesize));
1225 sh->sg_tablesize = numSGE;
1228 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1230 hd = (MPT_SCSI_HOST *) sh->hostdata;
1233 /* SCSI needs scsi_cmnd lookup table!
1234 * (with size equal to req_depth*PtrSz!)
1236 sz = ioc->req_depth * sizeof(void *);
1237 mem = kmalloc(sz, GFP_ATOMIC);
1240 goto mptsas_probe_failed;
1244 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1246 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1247 ioc->name, hd->ScsiLookup, sz));
1249 /* Allocate memory for the device structures.
1250 * A non-Null pointer at an offset
1251 * indicates a device exists.
1252 * max_id = 1 + maximum id (hosts.h)
1254 sz = sh->max_id * sizeof(void *);
1255 mem = kmalloc(sz, GFP_ATOMIC);
1258 goto mptsas_probe_failed;
1262 hd->Targets = (VirtDevice **) mem;
1265 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1267 /* Clear the TM flags
1270 hd->tmState = TM_STATE_NONE;
1271 hd->resetPending = 0;
1272 hd->abortSCpnt = NULL;
1274 /* Clear the pointer used to store
1275 * single-threaded commands, i.e., those
1276 * issued during a bus scan, dv and
1277 * configuration pages.
1281 /* Initialize this SCSI Hosts' timers
1282 * To use, set the timer expires field
1285 init_timer(&hd->timer);
1286 hd->timer.data = (unsigned long) hd;
1287 hd->timer.function = mptscsih_timer_expired;
1289 hd->mpt_pq_filter = mpt_pq_filter;
1290 ioc->sas_data.ptClear = mpt_pt_clear;
1292 if (ioc->sas_data.ptClear==1) {
1293 mptbase_sas_persist_operation(
1294 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1297 ddvprintk((MYIOC_s_INFO_FMT
1298 "mpt_pq_filter %x mpt_pq_filter %x\n",
1303 init_waitqueue_head(&hd->scandv_waitq);
1304 hd->scandv_wait_done = 0;
1305 hd->last_queue_full = 0;
1307 error = scsi_add_host(sh, &ioc->pcidev->dev);
1309 dprintk((KERN_ERR MYNAM
1310 "scsi_add_host failed\n"));
1311 goto mptsas_probe_failed;
1314 mptsas_scan_sas_topology(ioc);
1318 mptsas_probe_failed:
1320 mptscsih_remove(pdev);
1324 static void __devexit mptsas_remove(struct pci_dev *pdev)
1326 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1327 struct mptsas_portinfo *p, *n;
1329 sas_remove_host(ioc->sh);
1331 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1336 mptscsih_remove(pdev);
1339 static struct pci_device_id mptsas_pci_table[] = {
1340 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1341 PCI_ANY_ID, PCI_ANY_ID },
1342 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1343 PCI_ANY_ID, PCI_ANY_ID },
1344 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1345 PCI_ANY_ID, PCI_ANY_ID },
1346 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1347 PCI_ANY_ID, PCI_ANY_ID },
1348 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1349 PCI_ANY_ID, PCI_ANY_ID },
1350 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1351 PCI_ANY_ID, PCI_ANY_ID },
1352 {0} /* Terminating entry */
1354 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1357 static struct pci_driver mptsas_driver = {
1359 .id_table = mptsas_pci_table,
1360 .probe = mptsas_probe,
1361 .remove = __devexit_p(mptsas_remove),
1362 .shutdown = mptscsih_shutdown,
1364 .suspend = mptscsih_suspend,
1365 .resume = mptscsih_resume,
1372 show_mptmod_ver(my_NAME, my_VERSION);
1374 mptsas_transport_template =
1375 sas_attach_transport(&mptsas_transport_functions);
1376 if (!mptsas_transport_template)
1379 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1380 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1382 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1383 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1385 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1386 devtprintk((KERN_INFO MYNAM
1387 ": Registered for IOC event notifications\n"));
1390 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1391 dprintk((KERN_INFO MYNAM
1392 ": Registered for IOC reset notifications\n"));
1395 return pci_register_driver(&mptsas_driver);
1401 pci_unregister_driver(&mptsas_driver);
1402 sas_release_transport(mptsas_transport_template);
1404 mpt_reset_deregister(mptsasDoneCtx);
1405 mpt_event_deregister(mptsasDoneCtx);
1407 mpt_deregister(mptsasMgmtCtx);
1408 mpt_deregister(mptsasInternalCtx);
1409 mpt_deregister(mptsasTaskCtx);
1410 mpt_deregister(mptsasDoneCtx);
1413 module_init(mptsas_init);
1414 module_exit(mptsas_exit);