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 */
89 * SAS topology structures
91 * The MPT Fusion firmware interface spreads information about the
92 * SAS topology over many manufacture pages, thus we need some data
93 * structure to collect it and process it for the SAS transport class.
96 struct mptsas_devinfo {
97 u16 handle; /* unique id to address this device */
98 u8 phy_id; /* phy number of parent device */
99 u8 port_id; /* sas physical port this device
101 u8 target; /* logical target id of this device */
102 u8 bus; /* logical bus number of this device */
103 u64 sas_address; /* WWN of this device,
104 SATA is assigned by HBA,expander */
105 u32 device_info; /* bitfield detailed info about this device */
108 struct mptsas_phyinfo {
109 u8 phy_id; /* phy index */
110 u8 port_id; /* port number this phy is part of */
111 u8 negotiated_link_rate; /* nego'd link rate for this phy */
112 u8 hw_link_rate; /* hardware max/min phys link rate */
113 u8 programmed_link_rate; /* programmed max/min phy link rate */
114 struct mptsas_devinfo identify; /* point to phy device info */
115 struct mptsas_devinfo attached; /* point to attached device info */
116 struct sas_rphy *rphy;
119 struct mptsas_portinfo {
120 struct list_head list;
121 u16 handle; /* unique id to address this */
122 u8 num_phys; /* number of phys */
123 struct mptsas_phyinfo *phy_info;
128 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
130 printk("---- IO UNIT PAGE 0 ------------\n");
131 printk("Handle=0x%X\n",
132 le16_to_cpu(phy_data->AttachedDeviceHandle));
133 printk("Controller Handle=0x%X\n",
134 le16_to_cpu(phy_data->ControllerDevHandle));
135 printk("Port=0x%X\n", phy_data->Port);
136 printk("Port Flags=0x%X\n", phy_data->PortFlags);
137 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
138 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
139 printk("Controller PHY Device Info=0x%X\n",
140 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
141 printk("DiscoveryStatus=0x%X\n",
142 le32_to_cpu(phy_data->DiscoveryStatus));
146 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
150 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
152 printk("---- SAS PHY PAGE 0 ------------\n");
153 printk("Attached Device Handle=0x%X\n",
154 le16_to_cpu(pg0->AttachedDevHandle));
155 printk("SAS Address=0x%llX\n",
156 (unsigned long long)le64_to_cpu(sas_address));
157 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
158 printk("Attached Device Info=0x%X\n",
159 le32_to_cpu(pg0->AttachedDeviceInfo));
160 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
161 printk("Change Count=0x%X\n", pg0->ChangeCount);
162 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
166 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
168 printk("---- SAS PHY PAGE 1 ------------\n");
169 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
170 printk("Running Disparity Error Count=0x%x\n",
171 pg1->RunningDisparityErrorCount);
172 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
173 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
177 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
181 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
183 printk("---- SAS DEVICE PAGE 0 ---------\n");
184 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
185 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
186 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
187 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
188 printk("Target ID=0x%X\n", pg0->TargetID);
189 printk("Bus=0x%X\n", pg0->Bus);
190 printk("PhyNum=0x%X\n", pg0->PhyNum);
191 printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus));
192 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
193 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
194 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
198 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
200 printk("---- SAS EXPANDER PAGE 1 ------------\n");
202 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
203 printk("PHY Identifier=0x%X\n", pg1->Phy);
204 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
205 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
206 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
207 printk("Owner Device Handle=0x%X\n",
208 le16_to_cpu(pg1->OwnerDevHandle));
209 printk("Attached Device Handle=0x%X\n",
210 le16_to_cpu(pg1->AttachedDevHandle));
213 #define mptsas_print_phy_data(phy_data) do { } while (0)
214 #define mptsas_print_phy_pg0(pg0) do { } while (0)
215 #define mptsas_print_phy_pg1(pg1) do { } while (0)
216 #define mptsas_print_device_pg0(pg0) do { } while (0)
217 #define mptsas_print_expander_pg1(pg1) do { } while (0)
222 * This is pretty ugly. We will be able to seriously clean it up
223 * once the DV code in mptscsih goes away and we can properly
224 * implement ->target_alloc.
227 mptsas_slave_alloc(struct scsi_device *device)
229 struct Scsi_Host *host = device->host;
230 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
231 struct sas_rphy *rphy;
232 struct mptsas_portinfo *p;
234 uint target = device->id;
237 if ((vdev = hd->Targets[target]) != NULL)
240 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
242 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
243 hd->ioc->name, sizeof(VirtDevice));
247 memset(vdev, 0, sizeof(VirtDevice));
248 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
249 vdev->ioc_id = hd->ioc->id;
251 rphy = dev_to_rphy(device->sdev_target->dev.parent);
252 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
253 for (i = 0; i < p->num_phys; i++) {
254 if (p->phy_info[i].attached.sas_address ==
255 rphy->identify.sas_address) {
257 p->phy_info[i].attached.target;
258 vdev->bus_id = p->phy_info[i].attached.bus;
259 hd->Targets[device->id] = vdev;
265 printk("No matching SAS device found!!\n");
271 device->hostdata = vdev;
275 static struct scsi_host_template mptsas_driver_template = {
276 .proc_name = "mptsas",
277 .proc_info = mptscsih_proc_info,
278 .name = "MPT SPI Host",
279 .info = mptscsih_info,
280 .queuecommand = mptscsih_qcmd,
281 .slave_alloc = mptsas_slave_alloc,
282 .slave_configure = mptscsih_slave_configure,
283 .slave_destroy = mptscsih_slave_destroy,
284 .change_queue_depth = mptscsih_change_queue_depth,
285 .eh_abort_handler = mptscsih_abort,
286 .eh_device_reset_handler = mptscsih_dev_reset,
287 .eh_bus_reset_handler = mptscsih_bus_reset,
288 .eh_host_reset_handler = mptscsih_host_reset,
289 .bios_param = mptscsih_bios_param,
290 .can_queue = MPT_FC_CAN_QUEUE,
292 .sg_tablesize = MPT_SCSI_SG_DEPTH,
295 .use_clustering = ENABLE_CLUSTERING,
298 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
300 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
301 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
304 static int mptsas_get_linkerrors(struct sas_phy *phy)
306 MPT_ADAPTER *ioc = phy_to_ioc(phy);
307 ConfigExtendedPageHeader_t hdr;
309 SasPhyPage1_t *buffer;
310 dma_addr_t dma_handle;
313 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
314 hdr.ExtPageLength = 0;
315 hdr.PageNumber = 1 /* page number 1*/;
318 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
319 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
321 cfg.cfghdr.ehdr = &hdr;
323 cfg.pageAddr = phy->identify.phy_identifier;
324 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
325 cfg.dir = 0; /* read */
328 error = mpt_config(ioc, &cfg);
331 if (!hdr.ExtPageLength)
334 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
339 cfg.physAddr = dma_handle;
340 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
342 error = mpt_config(ioc, &cfg);
344 goto out_free_consistent;
346 mptsas_print_phy_pg1(buffer);
348 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
349 phy->running_disparity_error_count =
350 le32_to_cpu(buffer->RunningDisparityErrorCount);
351 phy->loss_of_dword_sync_count =
352 le32_to_cpu(buffer->LossDwordSynchCount);
353 phy->phy_reset_problem_count =
354 le32_to_cpu(buffer->PhyResetProblemCount);
357 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
363 static struct sas_function_template mptsas_transport_functions = {
364 .get_linkerrors = mptsas_get_linkerrors,
367 static struct scsi_transport_template *mptsas_transport_template;
370 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
372 ConfigExtendedPageHeader_t hdr;
374 SasIOUnitPage0_t *buffer;
375 dma_addr_t dma_handle;
378 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
379 hdr.ExtPageLength = 0;
383 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
384 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
386 cfg.cfghdr.ehdr = &hdr;
389 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
390 cfg.dir = 0; /* read */
393 error = mpt_config(ioc, &cfg);
396 if (!hdr.ExtPageLength) {
401 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
408 cfg.physAddr = dma_handle;
409 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
411 error = mpt_config(ioc, &cfg);
413 goto out_free_consistent;
415 port_info->num_phys = buffer->NumPhys;
416 port_info->phy_info = kcalloc(port_info->num_phys,
417 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
418 if (!port_info->phy_info) {
420 goto out_free_consistent;
423 for (i = 0; i < port_info->num_phys; i++) {
424 mptsas_print_phy_data(&buffer->PhyData[i]);
425 port_info->phy_info[i].phy_id = i;
426 port_info->phy_info[i].port_id =
427 buffer->PhyData[i].Port;
428 port_info->phy_info[i].negotiated_link_rate =
429 buffer->PhyData[i].NegotiatedLinkRate;
433 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
440 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
441 u32 form, u32 form_specific)
443 ConfigExtendedPageHeader_t hdr;
445 SasPhyPage0_t *buffer;
446 dma_addr_t dma_handle;
449 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
450 hdr.ExtPageLength = 0;
454 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
455 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
457 cfg.cfghdr.ehdr = &hdr;
458 cfg.dir = 0; /* read */
461 /* Get Phy Pg 0 for each Phy. */
463 cfg.pageAddr = form + form_specific;
464 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
466 error = mpt_config(ioc, &cfg);
470 if (!hdr.ExtPageLength) {
475 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
482 cfg.physAddr = dma_handle;
483 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
485 error = mpt_config(ioc, &cfg);
487 goto out_free_consistent;
489 mptsas_print_phy_pg0(buffer);
491 phy_info->hw_link_rate = buffer->HwLinkRate;
492 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
493 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
494 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
497 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
504 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
505 u32 form, u32 form_specific)
507 ConfigExtendedPageHeader_t hdr;
509 SasDevicePage0_t *buffer;
510 dma_addr_t dma_handle;
514 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
515 hdr.ExtPageLength = 0;
519 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
520 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
522 cfg.cfghdr.ehdr = &hdr;
523 cfg.pageAddr = form + form_specific;
525 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
526 cfg.dir = 0; /* read */
529 error = mpt_config(ioc, &cfg);
532 if (!hdr.ExtPageLength) {
537 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
544 cfg.physAddr = dma_handle;
545 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
547 error = mpt_config(ioc, &cfg);
549 goto out_free_consistent;
551 mptsas_print_device_pg0(buffer);
553 device_info->handle = le16_to_cpu(buffer->DevHandle);
554 device_info->phy_id = buffer->PhyNum;
555 device_info->port_id = buffer->PhysicalPort;
556 device_info->target = buffer->TargetID;
557 device_info->bus = buffer->Bus;
558 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
559 device_info->sas_address = le64_to_cpu(sas_address);
560 device_info->device_info =
561 le32_to_cpu(buffer->DeviceInfo);
564 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
571 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
572 u32 form, u32 form_specific)
574 ConfigExtendedPageHeader_t hdr;
576 SasExpanderPage0_t *buffer;
577 dma_addr_t dma_handle;
580 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
581 hdr.ExtPageLength = 0;
585 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
586 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
588 cfg.cfghdr.ehdr = &hdr;
590 cfg.pageAddr = form + form_specific;
591 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
592 cfg.dir = 0; /* read */
595 error = mpt_config(ioc, &cfg);
599 if (!hdr.ExtPageLength) {
604 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
611 cfg.physAddr = dma_handle;
612 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
614 error = mpt_config(ioc, &cfg);
616 goto out_free_consistent;
618 /* save config data */
619 port_info->num_phys = buffer->NumPhys;
620 port_info->handle = le16_to_cpu(buffer->DevHandle);
621 port_info->phy_info = kcalloc(port_info->num_phys,
622 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
623 if (!port_info->phy_info) {
625 goto out_free_consistent;
629 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
636 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
637 u32 form, u32 form_specific)
639 ConfigExtendedPageHeader_t hdr;
641 SasExpanderPage1_t *buffer;
642 dma_addr_t dma_handle;
645 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
646 hdr.ExtPageLength = 0;
650 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
651 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
653 cfg.cfghdr.ehdr = &hdr;
655 cfg.pageAddr = form + form_specific;
656 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
657 cfg.dir = 0; /* read */
660 error = mpt_config(ioc, &cfg);
664 if (!hdr.ExtPageLength) {
669 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
676 cfg.physAddr = dma_handle;
677 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
679 error = mpt_config(ioc, &cfg);
681 goto out_free_consistent;
684 mptsas_print_expander_pg1(buffer);
686 /* save config data */
687 phy_info->phy_id = buffer->PhyIdentifier;
688 phy_info->port_id = buffer->PhysicalPort;
689 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
690 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
691 phy_info->hw_link_rate = buffer->HwLinkRate;
692 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
693 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
697 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
704 mptsas_parse_device_info(struct sas_identify *identify,
705 struct mptsas_devinfo *device_info)
709 identify->sas_address = device_info->sas_address;
710 identify->phy_identifier = device_info->phy_id;
713 * Fill in Phy Initiator Port Protocol.
714 * Bits 6:3, more than one bit can be set, fall through cases.
716 protocols = device_info->device_info & 0x78;
717 identify->initiator_port_protocols = 0;
718 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
719 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
720 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
721 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
722 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
723 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
724 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
725 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
728 * Fill in Phy Target Port Protocol.
729 * Bits 10:7, more than one bit can be set, fall through cases.
731 protocols = device_info->device_info & 0x780;
732 identify->target_port_protocols = 0;
733 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
734 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
735 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
736 identify->target_port_protocols |= SAS_PROTOCOL_STP;
737 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
738 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
739 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
740 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
743 * Fill in Attached device type.
745 switch (device_info->device_info &
746 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
747 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
748 identify->device_type = SAS_PHY_UNUSED;
750 case MPI_SAS_DEVICE_INFO_END_DEVICE:
751 identify->device_type = SAS_END_DEVICE;
753 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
754 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
756 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
757 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
762 static int mptsas_probe_one_phy(struct device *dev,
763 struct mptsas_phyinfo *phy_info, int index)
765 struct sas_phy *port;
768 port = sas_phy_alloc(dev, index);
772 port->port_identifier = phy_info->port_id;
773 mptsas_parse_device_info(&port->identify, &phy_info->identify);
776 * Set Negotiated link rate.
778 switch (phy_info->negotiated_link_rate) {
779 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
780 port->negotiated_linkrate = SAS_PHY_DISABLED;
782 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
783 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
785 case MPI_SAS_IOUNIT0_RATE_1_5:
786 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
788 case MPI_SAS_IOUNIT0_RATE_3_0:
789 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
791 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
792 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
794 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
799 * Set Max hardware link rate.
801 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
802 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
803 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
805 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
806 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
813 * Set Max programmed link rate.
815 switch (phy_info->programmed_link_rate &
816 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
817 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
818 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
820 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
821 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
828 * Set Min hardware link rate.
830 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
831 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
832 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
834 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
835 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
842 * Set Min programmed link rate.
844 switch (phy_info->programmed_link_rate &
845 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
846 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
847 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
849 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
850 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
856 error = sas_phy_add(port);
862 if (phy_info->attached.handle) {
863 struct sas_rphy *rphy;
865 rphy = sas_rphy_alloc(port);
867 return 0; /* non-fatal: an rphy can be added later */
869 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
870 error = sas_rphy_add(rphy);
876 phy_info->rphy = rphy;
883 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
885 struct mptsas_portinfo *port_info;
887 int error = -ENOMEM, i;
889 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
892 memset(port_info, 0, sizeof(*port_info));
894 error = mptsas_sas_io_unit_pg0(ioc, port_info);
896 goto out_free_port_info;
898 list_add_tail(&port_info->list, &ioc->sas_topology);
900 for (i = 0; i < port_info->num_phys; i++) {
901 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
902 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
903 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
905 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
906 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
907 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
908 port_info->phy_info[i].identify.phy_id =
909 port_info->phy_info[i].phy_id;
910 handle = port_info->phy_info[i].identify.handle;
912 if (port_info->phy_info[i].attached.handle) {
913 mptsas_sas_device_pg0(ioc,
914 &port_info->phy_info[i].attached,
915 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
916 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
917 port_info->phy_info[i].attached.handle);
920 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
921 &port_info->phy_info[i], *index);
934 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
936 struct mptsas_portinfo *port_info, *p;
937 int error = -ENOMEM, i, j;
939 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
942 memset(port_info, 0, sizeof(*port_info));
944 error = mptsas_sas_expander_pg0(ioc, port_info,
945 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
946 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
948 goto out_free_port_info;
950 *handle = port_info->handle;
952 list_add_tail(&port_info->list, &ioc->sas_topology);
953 for (i = 0; i < port_info->num_phys; i++) {
954 struct device *parent;
956 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
957 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
958 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
960 if (port_info->phy_info[i].identify.handle) {
961 mptsas_sas_device_pg0(ioc,
962 &port_info->phy_info[i].identify,
963 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
964 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
965 port_info->phy_info[i].identify.handle);
966 port_info->phy_info[i].identify.phy_id =
967 port_info->phy_info[i].phy_id;
970 if (port_info->phy_info[i].attached.handle) {
971 mptsas_sas_device_pg0(ioc,
972 &port_info->phy_info[i].attached,
973 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
974 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
975 port_info->phy_info[i].attached.handle);
979 * If we find a parent port handle this expander is
980 * attached to another expander, else it hangs of the
983 parent = &ioc->sh->shost_gendev;
984 list_for_each_entry(p, &ioc->sas_topology, list) {
985 for (j = 0; j < p->num_phys; j++) {
986 if (port_info->phy_info[i].identify.handle ==
987 p->phy_info[j].attached.handle)
988 parent = &p->phy_info[j].rphy->dev;
992 mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
1005 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1007 u32 handle = 0xFFFF;
1010 mptsas_probe_hba_phys(ioc, &index);
1011 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1016 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1018 struct Scsi_Host *sh;
1021 unsigned long flags;
1030 r = mpt_attach(pdev,id);
1034 ioc = pci_get_drvdata(pdev);
1035 ioc->DoneCtx = mptsasDoneCtx;
1036 ioc->TaskCtx = mptsasTaskCtx;
1037 ioc->InternalCtx = mptsasInternalCtx;
1039 /* Added sanity check on readiness of the MPT adapter.
1041 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1042 printk(MYIOC_s_WARN_FMT
1043 "Skipping because it's not operational!\n",
1049 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1054 /* Sanity check - ensure at least 1 port is INITIATOR capable
1057 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1058 if (ioc->pfacts[ii].ProtocolFlags &
1059 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1064 printk(MYIOC_s_WARN_FMT
1065 "Skipping ioc=%p because SCSI Initiator mode "
1066 "is NOT enabled!\n", ioc->name, ioc);
1070 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1072 printk(MYIOC_s_WARN_FMT
1073 "Unable to register controller with SCSI subsystem\n",
1078 spin_lock_irqsave(&ioc->FreeQlock, flags);
1080 /* Attach the SCSI Host to the IOC structure
1088 /* set 16 byte cdb's */
1089 sh->max_cmd_len = 16;
1091 sh->max_id = ioc->pfacts->MaxDevices + 1;
1093 sh->transportt = mptsas_transport_template;
1095 sh->max_lun = MPT_LAST_LUN + 1;
1096 sh->max_channel = 0;
1097 sh->this_id = ioc->pfacts[0].PortSCSIID;
1101 sh->unique_id = ioc->id;
1103 INIT_LIST_HEAD(&ioc->sas_topology);
1105 /* Verify that we won't exceed the maximum
1106 * number of chain buffers
1107 * We can optimize: ZZ = req_sz/sizeof(SGE)
1109 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1110 * + (req_sz - 64)/sizeof(SGE)
1111 * A slightly different algorithm is required for
1114 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1115 if (sizeof(dma_addr_t) == sizeof(u64)) {
1116 numSGE = (scale - 1) *
1117 (ioc->facts.MaxChainDepth-1) + scale +
1118 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1121 numSGE = 1 + (scale - 1) *
1122 (ioc->facts.MaxChainDepth-1) + scale +
1123 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1127 if (numSGE < sh->sg_tablesize) {
1128 /* Reset this value */
1129 dprintk((MYIOC_s_INFO_FMT
1130 "Resetting sg_tablesize to %d from %d\n",
1131 ioc->name, numSGE, sh->sg_tablesize));
1132 sh->sg_tablesize = numSGE;
1135 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1137 hd = (MPT_SCSI_HOST *) sh->hostdata;
1140 /* SCSI needs scsi_cmnd lookup table!
1141 * (with size equal to req_depth*PtrSz!)
1143 sz = ioc->req_depth * sizeof(void *);
1144 mem = kmalloc(sz, GFP_ATOMIC);
1147 goto mptsas_probe_failed;
1151 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1153 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1154 ioc->name, hd->ScsiLookup, sz));
1156 /* Allocate memory for the device structures.
1157 * A non-Null pointer at an offset
1158 * indicates a device exists.
1159 * max_id = 1 + maximum id (hosts.h)
1161 sz = sh->max_id * sizeof(void *);
1162 mem = kmalloc(sz, GFP_ATOMIC);
1165 goto mptsas_probe_failed;
1169 hd->Targets = (VirtDevice **) mem;
1172 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1174 /* Clear the TM flags
1177 hd->tmState = TM_STATE_NONE;
1178 hd->resetPending = 0;
1179 hd->abortSCpnt = NULL;
1181 /* Clear the pointer used to store
1182 * single-threaded commands, i.e., those
1183 * issued during a bus scan, dv and
1184 * configuration pages.
1188 /* Initialize this SCSI Hosts' timers
1189 * To use, set the timer expires field
1192 init_timer(&hd->timer);
1193 hd->timer.data = (unsigned long) hd;
1194 hd->timer.function = mptscsih_timer_expired;
1196 hd->mpt_pq_filter = mpt_pq_filter;
1197 ioc->sas_data.ptClear = mpt_pt_clear;
1199 if (ioc->sas_data.ptClear==1) {
1200 mptbase_sas_persist_operation(
1201 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1204 ddvprintk((MYIOC_s_INFO_FMT
1205 "mpt_pq_filter %x mpt_pq_filter %x\n",
1210 init_waitqueue_head(&hd->scandv_waitq);
1211 hd->scandv_wait_done = 0;
1212 hd->last_queue_full = 0;
1214 error = scsi_add_host(sh, &ioc->pcidev->dev);
1216 dprintk((KERN_ERR MYNAM
1217 "scsi_add_host failed\n"));
1218 goto mptsas_probe_failed;
1221 mptsas_scan_sas_topology(ioc);
1225 mptsas_probe_failed:
1227 mptscsih_remove(pdev);
1231 static void __devexit mptsas_remove(struct pci_dev *pdev)
1233 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1234 struct mptsas_portinfo *p, *n;
1236 sas_remove_host(ioc->sh);
1238 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1243 mptscsih_remove(pdev);
1246 static struct pci_device_id mptsas_pci_table[] = {
1247 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1248 PCI_ANY_ID, PCI_ANY_ID },
1249 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1250 PCI_ANY_ID, PCI_ANY_ID },
1251 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1252 PCI_ANY_ID, PCI_ANY_ID },
1253 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1254 PCI_ANY_ID, PCI_ANY_ID },
1255 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1256 PCI_ANY_ID, PCI_ANY_ID },
1257 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1258 PCI_ANY_ID, PCI_ANY_ID },
1259 {0} /* Terminating entry */
1261 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1264 static struct pci_driver mptsas_driver = {
1266 .id_table = mptsas_pci_table,
1267 .probe = mptsas_probe,
1268 .remove = __devexit_p(mptsas_remove),
1269 .shutdown = mptscsih_shutdown,
1271 .suspend = mptscsih_suspend,
1272 .resume = mptscsih_resume,
1279 show_mptmod_ver(my_NAME, my_VERSION);
1281 mptsas_transport_template =
1282 sas_attach_transport(&mptsas_transport_functions);
1283 if (!mptsas_transport_template)
1286 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1287 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1289 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1291 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1292 devtprintk((KERN_INFO MYNAM
1293 ": Registered for IOC event notifications\n"));
1296 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1297 dprintk((KERN_INFO MYNAM
1298 ": Registered for IOC reset notifications\n"));
1301 return pci_register_driver(&mptsas_driver);
1307 pci_unregister_driver(&mptsas_driver);
1308 sas_release_transport(mptsas_transport_template);
1310 mpt_reset_deregister(mptsasDoneCtx);
1311 mpt_event_deregister(mptsasDoneCtx);
1313 mpt_deregister(mptsasInternalCtx);
1314 mpt_deregister(mptsasTaskCtx);
1315 mpt_deregister(mptsasDoneCtx);
1318 module_init(mptsas_init);
1319 module_exit(mptsas_exit);