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, int local)
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;
857 port->local_attached = 1;
859 error = sas_phy_add(port);
865 if (phy_info->attached.handle) {
866 struct sas_rphy *rphy;
868 rphy = sas_rphy_alloc(port);
870 return 0; /* non-fatal: an rphy can be added later */
872 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
873 error = sas_rphy_add(rphy);
879 phy_info->rphy = rphy;
886 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
888 struct mptsas_portinfo *port_info;
890 int error = -ENOMEM, i;
892 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
895 memset(port_info, 0, sizeof(*port_info));
897 error = mptsas_sas_io_unit_pg0(ioc, port_info);
899 goto out_free_port_info;
901 list_add_tail(&port_info->list, &ioc->sas_topology);
903 for (i = 0; i < port_info->num_phys; i++) {
904 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
905 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
906 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
908 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
909 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
910 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
911 port_info->phy_info[i].identify.phy_id =
912 port_info->phy_info[i].phy_id;
913 handle = port_info->phy_info[i].identify.handle;
915 if (port_info->phy_info[i].attached.handle) {
916 mptsas_sas_device_pg0(ioc,
917 &port_info->phy_info[i].attached,
918 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
919 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
920 port_info->phy_info[i].attached.handle);
923 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
924 &port_info->phy_info[i], *index, 1);
937 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
939 struct mptsas_portinfo *port_info, *p;
940 int error = -ENOMEM, i, j;
942 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
945 memset(port_info, 0, sizeof(*port_info));
947 error = mptsas_sas_expander_pg0(ioc, port_info,
948 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
949 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
951 goto out_free_port_info;
953 *handle = port_info->handle;
955 list_add_tail(&port_info->list, &ioc->sas_topology);
956 for (i = 0; i < port_info->num_phys; i++) {
957 struct device *parent;
959 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
960 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
961 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
963 if (port_info->phy_info[i].identify.handle) {
964 mptsas_sas_device_pg0(ioc,
965 &port_info->phy_info[i].identify,
966 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
967 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
968 port_info->phy_info[i].identify.handle);
969 port_info->phy_info[i].identify.phy_id =
970 port_info->phy_info[i].phy_id;
973 if (port_info->phy_info[i].attached.handle) {
974 mptsas_sas_device_pg0(ioc,
975 &port_info->phy_info[i].attached,
976 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
977 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
978 port_info->phy_info[i].attached.handle);
982 * If we find a parent port handle this expander is
983 * attached to another expander, else it hangs of the
986 parent = &ioc->sh->shost_gendev;
987 list_for_each_entry(p, &ioc->sas_topology, list) {
988 for (j = 0; j < p->num_phys; j++) {
989 if (port_info->phy_info[i].identify.handle ==
990 p->phy_info[j].attached.handle)
991 parent = &p->phy_info[j].rphy->dev;
995 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1009 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1011 u32 handle = 0xFFFF;
1014 mptsas_probe_hba_phys(ioc, &index);
1015 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1020 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1022 struct Scsi_Host *sh;
1025 unsigned long flags;
1034 r = mpt_attach(pdev,id);
1038 ioc = pci_get_drvdata(pdev);
1039 ioc->DoneCtx = mptsasDoneCtx;
1040 ioc->TaskCtx = mptsasTaskCtx;
1041 ioc->InternalCtx = mptsasInternalCtx;
1043 /* Added sanity check on readiness of the MPT adapter.
1045 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1046 printk(MYIOC_s_WARN_FMT
1047 "Skipping because it's not operational!\n",
1053 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1058 /* Sanity check - ensure at least 1 port is INITIATOR capable
1061 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1062 if (ioc->pfacts[ii].ProtocolFlags &
1063 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1068 printk(MYIOC_s_WARN_FMT
1069 "Skipping ioc=%p because SCSI Initiator mode "
1070 "is NOT enabled!\n", ioc->name, ioc);
1074 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1076 printk(MYIOC_s_WARN_FMT
1077 "Unable to register controller with SCSI subsystem\n",
1082 spin_lock_irqsave(&ioc->FreeQlock, flags);
1084 /* Attach the SCSI Host to the IOC structure
1092 /* set 16 byte cdb's */
1093 sh->max_cmd_len = 16;
1095 sh->max_id = ioc->pfacts->MaxDevices + 1;
1097 sh->transportt = mptsas_transport_template;
1099 sh->max_lun = MPT_LAST_LUN + 1;
1100 sh->max_channel = 0;
1101 sh->this_id = ioc->pfacts[0].PortSCSIID;
1105 sh->unique_id = ioc->id;
1107 INIT_LIST_HEAD(&ioc->sas_topology);
1109 /* Verify that we won't exceed the maximum
1110 * number of chain buffers
1111 * We can optimize: ZZ = req_sz/sizeof(SGE)
1113 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1114 * + (req_sz - 64)/sizeof(SGE)
1115 * A slightly different algorithm is required for
1118 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1119 if (sizeof(dma_addr_t) == sizeof(u64)) {
1120 numSGE = (scale - 1) *
1121 (ioc->facts.MaxChainDepth-1) + scale +
1122 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1125 numSGE = 1 + (scale - 1) *
1126 (ioc->facts.MaxChainDepth-1) + scale +
1127 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1131 if (numSGE < sh->sg_tablesize) {
1132 /* Reset this value */
1133 dprintk((MYIOC_s_INFO_FMT
1134 "Resetting sg_tablesize to %d from %d\n",
1135 ioc->name, numSGE, sh->sg_tablesize));
1136 sh->sg_tablesize = numSGE;
1139 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1141 hd = (MPT_SCSI_HOST *) sh->hostdata;
1144 /* SCSI needs scsi_cmnd lookup table!
1145 * (with size equal to req_depth*PtrSz!)
1147 sz = ioc->req_depth * sizeof(void *);
1148 mem = kmalloc(sz, GFP_ATOMIC);
1151 goto mptsas_probe_failed;
1155 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1157 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1158 ioc->name, hd->ScsiLookup, sz));
1160 /* Allocate memory for the device structures.
1161 * A non-Null pointer at an offset
1162 * indicates a device exists.
1163 * max_id = 1 + maximum id (hosts.h)
1165 sz = sh->max_id * sizeof(void *);
1166 mem = kmalloc(sz, GFP_ATOMIC);
1169 goto mptsas_probe_failed;
1173 hd->Targets = (VirtDevice **) mem;
1176 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1178 /* Clear the TM flags
1181 hd->tmState = TM_STATE_NONE;
1182 hd->resetPending = 0;
1183 hd->abortSCpnt = NULL;
1185 /* Clear the pointer used to store
1186 * single-threaded commands, i.e., those
1187 * issued during a bus scan, dv and
1188 * configuration pages.
1192 /* Initialize this SCSI Hosts' timers
1193 * To use, set the timer expires field
1196 init_timer(&hd->timer);
1197 hd->timer.data = (unsigned long) hd;
1198 hd->timer.function = mptscsih_timer_expired;
1200 hd->mpt_pq_filter = mpt_pq_filter;
1201 ioc->sas_data.ptClear = mpt_pt_clear;
1203 if (ioc->sas_data.ptClear==1) {
1204 mptbase_sas_persist_operation(
1205 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1208 ddvprintk((MYIOC_s_INFO_FMT
1209 "mpt_pq_filter %x mpt_pq_filter %x\n",
1214 init_waitqueue_head(&hd->scandv_waitq);
1215 hd->scandv_wait_done = 0;
1216 hd->last_queue_full = 0;
1218 error = scsi_add_host(sh, &ioc->pcidev->dev);
1220 dprintk((KERN_ERR MYNAM
1221 "scsi_add_host failed\n"));
1222 goto mptsas_probe_failed;
1225 mptsas_scan_sas_topology(ioc);
1229 mptsas_probe_failed:
1231 mptscsih_remove(pdev);
1235 static void __devexit mptsas_remove(struct pci_dev *pdev)
1237 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1238 struct mptsas_portinfo *p, *n;
1240 sas_remove_host(ioc->sh);
1242 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1247 mptscsih_remove(pdev);
1250 static struct pci_device_id mptsas_pci_table[] = {
1251 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1252 PCI_ANY_ID, PCI_ANY_ID },
1253 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1254 PCI_ANY_ID, PCI_ANY_ID },
1255 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1256 PCI_ANY_ID, PCI_ANY_ID },
1257 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1258 PCI_ANY_ID, PCI_ANY_ID },
1259 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1260 PCI_ANY_ID, PCI_ANY_ID },
1261 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1262 PCI_ANY_ID, PCI_ANY_ID },
1263 {0} /* Terminating entry */
1265 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1268 static struct pci_driver mptsas_driver = {
1270 .id_table = mptsas_pci_table,
1271 .probe = mptsas_probe,
1272 .remove = __devexit_p(mptsas_remove),
1273 .shutdown = mptscsih_shutdown,
1275 .suspend = mptscsih_suspend,
1276 .resume = mptscsih_resume,
1283 show_mptmod_ver(my_NAME, my_VERSION);
1285 mptsas_transport_template =
1286 sas_attach_transport(&mptsas_transport_functions);
1287 if (!mptsas_transport_template)
1290 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1291 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1293 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1295 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1296 devtprintk((KERN_INFO MYNAM
1297 ": Registered for IOC event notifications\n"));
1300 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1301 dprintk((KERN_INFO MYNAM
1302 ": Registered for IOC reset notifications\n"));
1305 return pci_register_driver(&mptsas_driver);
1311 pci_unregister_driver(&mptsas_driver);
1312 sas_release_transport(mptsas_transport_template);
1314 mpt_reset_deregister(mptsasDoneCtx);
1315 mpt_event_deregister(mptsasDoneCtx);
1317 mpt_deregister(mptsasInternalCtx);
1318 mpt_deregister(mptsasTaskCtx);
1319 mpt_deregister(mptsasDoneCtx);
1322 module_init(mptsas_init);
1323 module_exit(mptsas_exit);