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 .module = THIS_MODULE,
281 .proc_name = "mptsas",
282 .proc_info = mptscsih_proc_info,
283 .name = "MPT SPI Host",
284 .info = mptscsih_info,
285 .queuecommand = mptscsih_qcmd,
286 .slave_alloc = mptsas_slave_alloc,
287 .slave_configure = mptscsih_slave_configure,
288 .slave_destroy = mptscsih_slave_destroy,
289 .change_queue_depth = mptscsih_change_queue_depth,
290 .eh_abort_handler = mptscsih_abort,
291 .eh_device_reset_handler = mptscsih_dev_reset,
292 .eh_bus_reset_handler = mptscsih_bus_reset,
293 .eh_host_reset_handler = mptscsih_host_reset,
294 .bios_param = mptscsih_bios_param,
295 .can_queue = MPT_FC_CAN_QUEUE,
297 .sg_tablesize = MPT_SCSI_SG_DEPTH,
300 .use_clustering = ENABLE_CLUSTERING,
303 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
305 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
306 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
309 static int mptsas_get_linkerrors(struct sas_phy *phy)
311 MPT_ADAPTER *ioc = phy_to_ioc(phy);
312 ConfigExtendedPageHeader_t hdr;
314 SasPhyPage1_t *buffer;
315 dma_addr_t dma_handle;
318 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
319 hdr.ExtPageLength = 0;
320 hdr.PageNumber = 1 /* page number 1*/;
323 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
324 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
326 cfg.cfghdr.ehdr = &hdr;
328 cfg.pageAddr = phy->identify.phy_identifier;
329 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
330 cfg.dir = 0; /* read */
333 error = mpt_config(ioc, &cfg);
336 if (!hdr.ExtPageLength)
339 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
344 cfg.physAddr = dma_handle;
345 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
347 error = mpt_config(ioc, &cfg);
349 goto out_free_consistent;
351 mptsas_print_phy_pg1(buffer);
353 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
354 phy->running_disparity_error_count =
355 le32_to_cpu(buffer->RunningDisparityErrorCount);
356 phy->loss_of_dword_sync_count =
357 le32_to_cpu(buffer->LossDwordSynchCount);
358 phy->phy_reset_problem_count =
359 le32_to_cpu(buffer->PhyResetProblemCount);
362 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
367 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
368 MPT_FRAME_HDR *reply)
370 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
372 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
373 memcpy(ioc->sas_mgmt.reply, reply,
374 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
376 complete(&ioc->sas_mgmt.done);
380 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
382 MPT_ADAPTER *ioc = phy_to_ioc(phy);
383 SasIoUnitControlRequest_t *req;
384 SasIoUnitControlReply_t *reply;
387 unsigned long timeleft;
388 int error = -ERESTARTSYS;
390 /* not implemented for expanders */
391 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
394 if (down_interruptible(&ioc->sas_mgmt.mutex))
397 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
403 hdr = (MPIHeader_t *) mf;
404 req = (SasIoUnitControlRequest_t *)mf;
405 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
406 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
407 req->MsgContext = hdr->MsgContext;
408 req->Operation = hard_reset ?
409 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
410 req->PhyNum = phy->identify.phy_identifier;
412 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
414 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
417 /* On timeout reset the board */
418 mpt_free_msg_frame(ioc, mf);
419 mpt_HardResetHandler(ioc, CAN_SLEEP);
424 /* a reply frame is expected */
425 if ((ioc->sas_mgmt.status &
426 MPT_IOCTL_STATUS_RF_VALID) == 0) {
431 /* process the completed Reply Message Frame */
432 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
433 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
434 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
445 up(&ioc->sas_mgmt.mutex);
450 static struct sas_function_template mptsas_transport_functions = {
451 .get_linkerrors = mptsas_get_linkerrors,
452 .phy_reset = mptsas_phy_reset,
455 static struct scsi_transport_template *mptsas_transport_template;
458 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
460 ConfigExtendedPageHeader_t hdr;
462 SasIOUnitPage0_t *buffer;
463 dma_addr_t dma_handle;
466 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
467 hdr.ExtPageLength = 0;
471 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
472 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
474 cfg.cfghdr.ehdr = &hdr;
477 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
478 cfg.dir = 0; /* read */
481 error = mpt_config(ioc, &cfg);
484 if (!hdr.ExtPageLength) {
489 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
496 cfg.physAddr = dma_handle;
497 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
499 error = mpt_config(ioc, &cfg);
501 goto out_free_consistent;
503 port_info->num_phys = buffer->NumPhys;
504 port_info->phy_info = kcalloc(port_info->num_phys,
505 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
506 if (!port_info->phy_info) {
508 goto out_free_consistent;
511 for (i = 0; i < port_info->num_phys; i++) {
512 mptsas_print_phy_data(&buffer->PhyData[i]);
513 port_info->phy_info[i].phy_id = i;
514 port_info->phy_info[i].port_id =
515 buffer->PhyData[i].Port;
516 port_info->phy_info[i].negotiated_link_rate =
517 buffer->PhyData[i].NegotiatedLinkRate;
521 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
528 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
529 u32 form, u32 form_specific)
531 ConfigExtendedPageHeader_t hdr;
533 SasPhyPage0_t *buffer;
534 dma_addr_t dma_handle;
537 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
538 hdr.ExtPageLength = 0;
542 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
543 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
545 cfg.cfghdr.ehdr = &hdr;
546 cfg.dir = 0; /* read */
549 /* Get Phy Pg 0 for each Phy. */
551 cfg.pageAddr = form + form_specific;
552 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
554 error = mpt_config(ioc, &cfg);
558 if (!hdr.ExtPageLength) {
563 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
570 cfg.physAddr = dma_handle;
571 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
573 error = mpt_config(ioc, &cfg);
575 goto out_free_consistent;
577 mptsas_print_phy_pg0(buffer);
579 phy_info->hw_link_rate = buffer->HwLinkRate;
580 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
581 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
582 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
585 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
592 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
593 u32 form, u32 form_specific)
595 ConfigExtendedPageHeader_t hdr;
597 SasDevicePage0_t *buffer;
598 dma_addr_t dma_handle;
602 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
603 hdr.ExtPageLength = 0;
607 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
608 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
610 cfg.cfghdr.ehdr = &hdr;
611 cfg.pageAddr = form + form_specific;
613 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
614 cfg.dir = 0; /* read */
617 error = mpt_config(ioc, &cfg);
620 if (!hdr.ExtPageLength) {
625 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
632 cfg.physAddr = dma_handle;
633 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
635 error = mpt_config(ioc, &cfg);
637 goto out_free_consistent;
639 mptsas_print_device_pg0(buffer);
641 device_info->handle = le16_to_cpu(buffer->DevHandle);
642 device_info->phy_id = buffer->PhyNum;
643 device_info->port_id = buffer->PhysicalPort;
644 device_info->target = buffer->TargetID;
645 device_info->bus = buffer->Bus;
646 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
647 device_info->sas_address = le64_to_cpu(sas_address);
648 device_info->device_info =
649 le32_to_cpu(buffer->DeviceInfo);
652 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
659 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
660 u32 form, u32 form_specific)
662 ConfigExtendedPageHeader_t hdr;
664 SasExpanderPage0_t *buffer;
665 dma_addr_t dma_handle;
668 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
669 hdr.ExtPageLength = 0;
673 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
674 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
676 cfg.cfghdr.ehdr = &hdr;
678 cfg.pageAddr = form + form_specific;
679 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
680 cfg.dir = 0; /* read */
683 error = mpt_config(ioc, &cfg);
687 if (!hdr.ExtPageLength) {
692 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
699 cfg.physAddr = dma_handle;
700 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
702 error = mpt_config(ioc, &cfg);
704 goto out_free_consistent;
706 /* save config data */
707 port_info->num_phys = buffer->NumPhys;
708 port_info->handle = le16_to_cpu(buffer->DevHandle);
709 port_info->phy_info = kcalloc(port_info->num_phys,
710 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
711 if (!port_info->phy_info) {
713 goto out_free_consistent;
717 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
724 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
725 u32 form, u32 form_specific)
727 ConfigExtendedPageHeader_t hdr;
729 SasExpanderPage1_t *buffer;
730 dma_addr_t dma_handle;
733 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
734 hdr.ExtPageLength = 0;
738 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
739 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
741 cfg.cfghdr.ehdr = &hdr;
743 cfg.pageAddr = form + form_specific;
744 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
745 cfg.dir = 0; /* read */
748 error = mpt_config(ioc, &cfg);
752 if (!hdr.ExtPageLength) {
757 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
764 cfg.physAddr = dma_handle;
765 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
767 error = mpt_config(ioc, &cfg);
769 goto out_free_consistent;
772 mptsas_print_expander_pg1(buffer);
774 /* save config data */
775 phy_info->phy_id = buffer->PhyIdentifier;
776 phy_info->port_id = buffer->PhysicalPort;
777 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
778 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
779 phy_info->hw_link_rate = buffer->HwLinkRate;
780 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
781 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
785 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
792 mptsas_parse_device_info(struct sas_identify *identify,
793 struct mptsas_devinfo *device_info)
797 identify->sas_address = device_info->sas_address;
798 identify->phy_identifier = device_info->phy_id;
801 * Fill in Phy Initiator Port Protocol.
802 * Bits 6:3, more than one bit can be set, fall through cases.
804 protocols = device_info->device_info & 0x78;
805 identify->initiator_port_protocols = 0;
806 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
807 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
808 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
809 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
810 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
811 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
812 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
813 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
816 * Fill in Phy Target Port Protocol.
817 * Bits 10:7, more than one bit can be set, fall through cases.
819 protocols = device_info->device_info & 0x780;
820 identify->target_port_protocols = 0;
821 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
822 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
823 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
824 identify->target_port_protocols |= SAS_PROTOCOL_STP;
825 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
826 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
827 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
828 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
831 * Fill in Attached device type.
833 switch (device_info->device_info &
834 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
835 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
836 identify->device_type = SAS_PHY_UNUSED;
838 case MPI_SAS_DEVICE_INFO_END_DEVICE:
839 identify->device_type = SAS_END_DEVICE;
841 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
842 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
844 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
845 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
850 static int mptsas_probe_one_phy(struct device *dev,
851 struct mptsas_phyinfo *phy_info, int index, int local)
853 struct sas_phy *port;
856 port = sas_phy_alloc(dev, index);
860 port->port_identifier = phy_info->port_id;
861 mptsas_parse_device_info(&port->identify, &phy_info->identify);
864 * Set Negotiated link rate.
866 switch (phy_info->negotiated_link_rate) {
867 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
868 port->negotiated_linkrate = SAS_PHY_DISABLED;
870 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
871 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
873 case MPI_SAS_IOUNIT0_RATE_1_5:
874 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
876 case MPI_SAS_IOUNIT0_RATE_3_0:
877 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
879 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
880 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
882 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
887 * Set Max hardware link rate.
889 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
890 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
891 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
893 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
894 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
901 * Set Max programmed link rate.
903 switch (phy_info->programmed_link_rate &
904 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
905 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
906 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
908 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
909 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
916 * Set Min hardware link rate.
918 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
919 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
920 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
922 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
923 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
930 * Set Min programmed link rate.
932 switch (phy_info->programmed_link_rate &
933 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
934 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
935 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
937 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
938 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
945 port->local_attached = 1;
947 error = sas_phy_add(port);
953 if (phy_info->attached.handle) {
954 struct sas_rphy *rphy;
956 rphy = sas_rphy_alloc(port);
958 return 0; /* non-fatal: an rphy can be added later */
960 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
961 error = sas_rphy_add(rphy);
967 phy_info->rphy = rphy;
974 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
976 struct mptsas_portinfo *port_info;
978 int error = -ENOMEM, i;
980 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
983 memset(port_info, 0, sizeof(*port_info));
985 error = mptsas_sas_io_unit_pg0(ioc, port_info);
987 goto out_free_port_info;
989 list_add_tail(&port_info->list, &ioc->sas_topology);
991 for (i = 0; i < port_info->num_phys; i++) {
992 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
993 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
994 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
996 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
997 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
998 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
999 port_info->phy_info[i].identify.phy_id =
1000 port_info->phy_info[i].phy_id;
1001 handle = port_info->phy_info[i].identify.handle;
1003 if (port_info->phy_info[i].attached.handle) {
1004 mptsas_sas_device_pg0(ioc,
1005 &port_info->phy_info[i].attached,
1006 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1007 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1008 port_info->phy_info[i].attached.handle);
1011 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1012 &port_info->phy_info[i], *index, 1);
1025 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1027 struct mptsas_portinfo *port_info, *p;
1028 int error = -ENOMEM, i, j;
1030 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
1033 memset(port_info, 0, sizeof(*port_info));
1035 error = mptsas_sas_expander_pg0(ioc, port_info,
1036 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1037 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1039 goto out_free_port_info;
1041 *handle = port_info->handle;
1043 list_add_tail(&port_info->list, &ioc->sas_topology);
1044 for (i = 0; i < port_info->num_phys; i++) {
1045 struct device *parent;
1047 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1048 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1049 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1051 if (port_info->phy_info[i].identify.handle) {
1052 mptsas_sas_device_pg0(ioc,
1053 &port_info->phy_info[i].identify,
1054 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1055 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1056 port_info->phy_info[i].identify.handle);
1057 port_info->phy_info[i].identify.phy_id =
1058 port_info->phy_info[i].phy_id;
1061 if (port_info->phy_info[i].attached.handle) {
1062 mptsas_sas_device_pg0(ioc,
1063 &port_info->phy_info[i].attached,
1064 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1065 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1066 port_info->phy_info[i].attached.handle);
1070 * If we find a parent port handle this expander is
1071 * attached to another expander, else it hangs of the
1074 parent = &ioc->sh->shost_gendev;
1075 list_for_each_entry(p, &ioc->sas_topology, list) {
1076 for (j = 0; j < p->num_phys; j++) {
1077 if (port_info->phy_info[i].identify.handle ==
1078 p->phy_info[j].attached.handle)
1079 parent = &p->phy_info[j].rphy->dev;
1083 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1097 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1099 u32 handle = 0xFFFF;
1102 mptsas_probe_hba_phys(ioc, &index);
1103 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1108 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1110 struct Scsi_Host *sh;
1113 unsigned long flags;
1122 r = mpt_attach(pdev,id);
1126 ioc = pci_get_drvdata(pdev);
1127 ioc->DoneCtx = mptsasDoneCtx;
1128 ioc->TaskCtx = mptsasTaskCtx;
1129 ioc->InternalCtx = mptsasInternalCtx;
1131 /* Added sanity check on readiness of the MPT adapter.
1133 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1134 printk(MYIOC_s_WARN_FMT
1135 "Skipping because it's not operational!\n",
1138 goto out_mptsas_probe;
1142 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1145 goto out_mptsas_probe;
1148 /* Sanity check - ensure at least 1 port is INITIATOR capable
1151 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1152 if (ioc->pfacts[ii].ProtocolFlags &
1153 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1158 printk(MYIOC_s_WARN_FMT
1159 "Skipping ioc=%p because SCSI Initiator mode "
1160 "is NOT enabled!\n", ioc->name, ioc);
1164 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1166 printk(MYIOC_s_WARN_FMT
1167 "Unable to register controller with SCSI subsystem\n",
1170 goto out_mptsas_probe;
1173 spin_lock_irqsave(&ioc->FreeQlock, flags);
1175 /* Attach the SCSI Host to the IOC structure
1183 /* set 16 byte cdb's */
1184 sh->max_cmd_len = 16;
1186 sh->max_id = ioc->pfacts->MaxDevices + 1;
1188 sh->transportt = mptsas_transport_template;
1190 sh->max_lun = MPT_LAST_LUN + 1;
1191 sh->max_channel = 0;
1192 sh->this_id = ioc->pfacts[0].PortSCSIID;
1196 sh->unique_id = ioc->id;
1198 INIT_LIST_HEAD(&ioc->sas_topology);
1199 init_MUTEX(&ioc->sas_mgmt.mutex);
1200 init_completion(&ioc->sas_mgmt.done);
1202 /* Verify that we won't exceed the maximum
1203 * number of chain buffers
1204 * We can optimize: ZZ = req_sz/sizeof(SGE)
1206 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1207 * + (req_sz - 64)/sizeof(SGE)
1208 * A slightly different algorithm is required for
1211 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1212 if (sizeof(dma_addr_t) == sizeof(u64)) {
1213 numSGE = (scale - 1) *
1214 (ioc->facts.MaxChainDepth-1) + scale +
1215 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1218 numSGE = 1 + (scale - 1) *
1219 (ioc->facts.MaxChainDepth-1) + scale +
1220 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1224 if (numSGE < sh->sg_tablesize) {
1225 /* Reset this value */
1226 dprintk((MYIOC_s_INFO_FMT
1227 "Resetting sg_tablesize to %d from %d\n",
1228 ioc->name, numSGE, sh->sg_tablesize));
1229 sh->sg_tablesize = numSGE;
1232 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1234 hd = (MPT_SCSI_HOST *) sh->hostdata;
1237 /* SCSI needs scsi_cmnd lookup table!
1238 * (with size equal to req_depth*PtrSz!)
1240 sz = ioc->req_depth * sizeof(void *);
1241 mem = kmalloc(sz, GFP_ATOMIC);
1244 goto out_mptsas_probe;
1248 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1250 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1251 ioc->name, hd->ScsiLookup, sz));
1253 /* Allocate memory for the device structures.
1254 * A non-Null pointer at an offset
1255 * indicates a device exists.
1256 * max_id = 1 + maximum id (hosts.h)
1258 sz = sh->max_id * sizeof(void *);
1259 mem = kmalloc(sz, GFP_ATOMIC);
1262 goto out_mptsas_probe;
1266 hd->Targets = (VirtDevice **) mem;
1269 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1271 /* Clear the TM flags
1274 hd->tmState = TM_STATE_NONE;
1275 hd->resetPending = 0;
1276 hd->abortSCpnt = NULL;
1278 /* Clear the pointer used to store
1279 * single-threaded commands, i.e., those
1280 * issued during a bus scan, dv and
1281 * configuration pages.
1285 /* Initialize this SCSI Hosts' timers
1286 * To use, set the timer expires field
1289 init_timer(&hd->timer);
1290 hd->timer.data = (unsigned long) hd;
1291 hd->timer.function = mptscsih_timer_expired;
1293 hd->mpt_pq_filter = mpt_pq_filter;
1294 ioc->sas_data.ptClear = mpt_pt_clear;
1296 if (ioc->sas_data.ptClear==1) {
1297 mptbase_sas_persist_operation(
1298 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1301 ddvprintk((MYIOC_s_INFO_FMT
1302 "mpt_pq_filter %x mpt_pq_filter %x\n",
1307 init_waitqueue_head(&hd->scandv_waitq);
1308 hd->scandv_wait_done = 0;
1309 hd->last_queue_full = 0;
1311 error = scsi_add_host(sh, &ioc->pcidev->dev);
1313 dprintk((KERN_ERR MYNAM
1314 "scsi_add_host failed\n"));
1315 goto out_mptsas_probe;
1318 mptsas_scan_sas_topology(ioc);
1324 mptscsih_remove(pdev);
1328 static void __devexit mptsas_remove(struct pci_dev *pdev)
1330 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1331 struct mptsas_portinfo *p, *n;
1333 sas_remove_host(ioc->sh);
1335 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1340 mptscsih_remove(pdev);
1343 static struct pci_device_id mptsas_pci_table[] = {
1344 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1345 PCI_ANY_ID, PCI_ANY_ID },
1346 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1347 PCI_ANY_ID, PCI_ANY_ID },
1348 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1349 PCI_ANY_ID, PCI_ANY_ID },
1350 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1351 PCI_ANY_ID, PCI_ANY_ID },
1352 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1353 PCI_ANY_ID, PCI_ANY_ID },
1354 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1355 PCI_ANY_ID, PCI_ANY_ID },
1356 {0} /* Terminating entry */
1358 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1361 static struct pci_driver mptsas_driver = {
1363 .id_table = mptsas_pci_table,
1364 .probe = mptsas_probe,
1365 .remove = __devexit_p(mptsas_remove),
1366 .shutdown = mptscsih_shutdown,
1368 .suspend = mptscsih_suspend,
1369 .resume = mptscsih_resume,
1376 show_mptmod_ver(my_NAME, my_VERSION);
1378 mptsas_transport_template =
1379 sas_attach_transport(&mptsas_transport_functions);
1380 if (!mptsas_transport_template)
1383 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1384 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1386 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1387 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1389 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1390 devtprintk((KERN_INFO MYNAM
1391 ": Registered for IOC event notifications\n"));
1394 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1395 dprintk((KERN_INFO MYNAM
1396 ": Registered for IOC reset notifications\n"));
1399 return pci_register_driver(&mptsas_driver);
1405 pci_unregister_driver(&mptsas_driver);
1406 sas_release_transport(mptsas_transport_template);
1408 mpt_reset_deregister(mptsasDoneCtx);
1409 mpt_event_deregister(mptsasDoneCtx);
1411 mpt_deregister(mptsasMgmtCtx);
1412 mpt_deregister(mptsasInternalCtx);
1413 mpt_deregister(mptsasTaskCtx);
1414 mpt_deregister(mptsasDoneCtx);
1417 module_init(mptsas_init);
1418 module_exit(mptsas_exit);