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 printk("PhyNum=0x%X\n", pg0->PhyNum);
192 printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus));
193 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
194 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
195 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
199 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
201 printk("---- SAS EXPANDER PAGE 1 ------------\n");
203 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
204 printk("PHY Identifier=0x%X\n", pg1->Phy);
205 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
206 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
207 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
208 printk("Owner Device Handle=0x%X\n",
209 le16_to_cpu(pg1->OwnerDevHandle));
210 printk("Attached Device Handle=0x%X\n",
211 le16_to_cpu(pg1->AttachedDevHandle));
214 #define mptsas_print_phy_data(phy_data) do { } while (0)
215 #define mptsas_print_phy_pg0(pg0) do { } while (0)
216 #define mptsas_print_phy_pg1(pg1) do { } while (0)
217 #define mptsas_print_device_pg0(pg0) do { } while (0)
218 #define mptsas_print_expander_pg1(pg1) do { } while (0)
223 * This is pretty ugly. We will be able to seriously clean it up
224 * once the DV code in mptscsih goes away and we can properly
225 * implement ->target_alloc.
228 mptsas_slave_alloc(struct scsi_device *device)
230 struct Scsi_Host *host = device->host;
231 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
232 struct sas_rphy *rphy;
233 struct mptsas_portinfo *p;
235 uint target = device->id;
238 if ((vdev = hd->Targets[target]) != NULL)
241 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
243 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
244 hd->ioc->name, sizeof(VirtDevice));
248 memset(vdev, 0, sizeof(VirtDevice));
249 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
250 vdev->ioc_id = hd->ioc->id;
252 rphy = dev_to_rphy(device->sdev_target->dev.parent);
253 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
254 for (i = 0; i < p->num_phys; i++) {
255 if (p->phy_info[i].attached.sas_address ==
256 rphy->identify.sas_address) {
258 p->phy_info[i].attached.target;
259 vdev->bus_id = p->phy_info[i].attached.bus;
260 hd->Targets[device->id] = vdev;
266 printk("No matching SAS device found!!\n");
272 device->hostdata = vdev;
276 static struct scsi_host_template mptsas_driver_template = {
277 .proc_name = "mptsas",
278 .proc_info = mptscsih_proc_info,
279 .name = "MPT SPI Host",
280 .info = mptscsih_info,
281 .queuecommand = mptscsih_qcmd,
282 .slave_alloc = mptsas_slave_alloc,
283 .slave_configure = mptscsih_slave_configure,
284 .slave_destroy = mptscsih_slave_destroy,
285 .change_queue_depth = mptscsih_change_queue_depth,
286 .eh_abort_handler = mptscsih_abort,
287 .eh_device_reset_handler = mptscsih_dev_reset,
288 .eh_bus_reset_handler = mptscsih_bus_reset,
289 .eh_host_reset_handler = mptscsih_host_reset,
290 .bios_param = mptscsih_bios_param,
291 .can_queue = MPT_FC_CAN_QUEUE,
293 .sg_tablesize = MPT_SCSI_SG_DEPTH,
296 .use_clustering = ENABLE_CLUSTERING,
299 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
301 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
302 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
305 static int mptsas_get_linkerrors(struct sas_phy *phy)
307 MPT_ADAPTER *ioc = phy_to_ioc(phy);
308 ConfigExtendedPageHeader_t hdr;
310 SasPhyPage1_t *buffer;
311 dma_addr_t dma_handle;
314 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
315 hdr.ExtPageLength = 0;
316 hdr.PageNumber = 1 /* page number 1*/;
319 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
320 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
322 cfg.cfghdr.ehdr = &hdr;
324 cfg.pageAddr = phy->identify.phy_identifier;
325 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
326 cfg.dir = 0; /* read */
329 error = mpt_config(ioc, &cfg);
332 if (!hdr.ExtPageLength)
335 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
340 cfg.physAddr = dma_handle;
341 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
343 error = mpt_config(ioc, &cfg);
345 goto out_free_consistent;
347 mptsas_print_phy_pg1(buffer);
349 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
350 phy->running_disparity_error_count =
351 le32_to_cpu(buffer->RunningDisparityErrorCount);
352 phy->loss_of_dword_sync_count =
353 le32_to_cpu(buffer->LossDwordSynchCount);
354 phy->phy_reset_problem_count =
355 le32_to_cpu(buffer->PhyResetProblemCount);
358 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
363 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
364 MPT_FRAME_HDR *reply)
366 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
368 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
369 memcpy(ioc->sas_mgmt.reply, reply,
370 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
372 complete(&ioc->sas_mgmt.done);
376 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
378 MPT_ADAPTER *ioc = phy_to_ioc(phy);
379 SasIoUnitControlRequest_t *req;
380 SasIoUnitControlReply_t *reply;
383 unsigned long timeleft;
384 int error = -ERESTARTSYS;
386 /* not implemented for expanders */
387 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
390 if (down_interruptible(&ioc->sas_mgmt.mutex))
393 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
399 hdr = (MPIHeader_t *) mf;
400 req = (SasIoUnitControlRequest_t *)mf;
401 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
402 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
403 req->MsgContext = hdr->MsgContext;
404 req->Operation = hard_reset ?
405 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
406 req->PhyNum = phy->identify.phy_identifier;
408 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
410 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
413 /* On timeout reset the board */
414 mpt_free_msg_frame(ioc, mf);
415 mpt_HardResetHandler(ioc, CAN_SLEEP);
420 /* a reply frame is expected */
421 if ((ioc->sas_mgmt.status &
422 MPT_IOCTL_STATUS_RF_VALID) == 0) {
427 /* process the completed Reply Message Frame */
428 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
429 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
430 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
441 up(&ioc->sas_mgmt.mutex);
446 static struct sas_function_template mptsas_transport_functions = {
447 .get_linkerrors = mptsas_get_linkerrors,
448 .phy_reset = mptsas_phy_reset,
451 static struct scsi_transport_template *mptsas_transport_template;
454 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
456 ConfigExtendedPageHeader_t hdr;
458 SasIOUnitPage0_t *buffer;
459 dma_addr_t dma_handle;
462 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
463 hdr.ExtPageLength = 0;
467 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
468 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
470 cfg.cfghdr.ehdr = &hdr;
473 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
474 cfg.dir = 0; /* read */
477 error = mpt_config(ioc, &cfg);
480 if (!hdr.ExtPageLength) {
485 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
492 cfg.physAddr = dma_handle;
493 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
495 error = mpt_config(ioc, &cfg);
497 goto out_free_consistent;
499 port_info->num_phys = buffer->NumPhys;
500 port_info->phy_info = kcalloc(port_info->num_phys,
501 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
502 if (!port_info->phy_info) {
504 goto out_free_consistent;
507 for (i = 0; i < port_info->num_phys; i++) {
508 mptsas_print_phy_data(&buffer->PhyData[i]);
509 port_info->phy_info[i].phy_id = i;
510 port_info->phy_info[i].port_id =
511 buffer->PhyData[i].Port;
512 port_info->phy_info[i].negotiated_link_rate =
513 buffer->PhyData[i].NegotiatedLinkRate;
517 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
524 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
525 u32 form, u32 form_specific)
527 ConfigExtendedPageHeader_t hdr;
529 SasPhyPage0_t *buffer;
530 dma_addr_t dma_handle;
533 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
534 hdr.ExtPageLength = 0;
538 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
539 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
541 cfg.cfghdr.ehdr = &hdr;
542 cfg.dir = 0; /* read */
545 /* Get Phy Pg 0 for each Phy. */
547 cfg.pageAddr = form + form_specific;
548 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
550 error = mpt_config(ioc, &cfg);
554 if (!hdr.ExtPageLength) {
559 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
566 cfg.physAddr = dma_handle;
567 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
569 error = mpt_config(ioc, &cfg);
571 goto out_free_consistent;
573 mptsas_print_phy_pg0(buffer);
575 phy_info->hw_link_rate = buffer->HwLinkRate;
576 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
577 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
578 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
581 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
588 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
589 u32 form, u32 form_specific)
591 ConfigExtendedPageHeader_t hdr;
593 SasDevicePage0_t *buffer;
594 dma_addr_t dma_handle;
598 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
599 hdr.ExtPageLength = 0;
603 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
604 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
606 cfg.cfghdr.ehdr = &hdr;
607 cfg.pageAddr = form + form_specific;
609 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
610 cfg.dir = 0; /* read */
613 error = mpt_config(ioc, &cfg);
616 if (!hdr.ExtPageLength) {
621 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
628 cfg.physAddr = dma_handle;
629 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
631 error = mpt_config(ioc, &cfg);
633 goto out_free_consistent;
635 mptsas_print_device_pg0(buffer);
637 device_info->handle = le16_to_cpu(buffer->DevHandle);
638 device_info->phy_id = buffer->PhyNum;
639 device_info->port_id = buffer->PhysicalPort;
640 device_info->target = buffer->TargetID;
641 device_info->bus = buffer->Bus;
642 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
643 device_info->sas_address = le64_to_cpu(sas_address);
644 device_info->device_info =
645 le32_to_cpu(buffer->DeviceInfo);
648 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
655 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
656 u32 form, u32 form_specific)
658 ConfigExtendedPageHeader_t hdr;
660 SasExpanderPage0_t *buffer;
661 dma_addr_t dma_handle;
664 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
665 hdr.ExtPageLength = 0;
669 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
670 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
672 cfg.cfghdr.ehdr = &hdr;
674 cfg.pageAddr = form + form_specific;
675 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
676 cfg.dir = 0; /* read */
679 error = mpt_config(ioc, &cfg);
683 if (!hdr.ExtPageLength) {
688 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
695 cfg.physAddr = dma_handle;
696 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
698 error = mpt_config(ioc, &cfg);
700 goto out_free_consistent;
702 /* save config data */
703 port_info->num_phys = buffer->NumPhys;
704 port_info->handle = le16_to_cpu(buffer->DevHandle);
705 port_info->phy_info = kcalloc(port_info->num_phys,
706 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
707 if (!port_info->phy_info) {
709 goto out_free_consistent;
713 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
720 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
721 u32 form, u32 form_specific)
723 ConfigExtendedPageHeader_t hdr;
725 SasExpanderPage1_t *buffer;
726 dma_addr_t dma_handle;
729 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
730 hdr.ExtPageLength = 0;
734 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
735 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
737 cfg.cfghdr.ehdr = &hdr;
739 cfg.pageAddr = form + form_specific;
740 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
741 cfg.dir = 0; /* read */
744 error = mpt_config(ioc, &cfg);
748 if (!hdr.ExtPageLength) {
753 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
760 cfg.physAddr = dma_handle;
761 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
763 error = mpt_config(ioc, &cfg);
765 goto out_free_consistent;
768 mptsas_print_expander_pg1(buffer);
770 /* save config data */
771 phy_info->phy_id = buffer->PhyIdentifier;
772 phy_info->port_id = buffer->PhysicalPort;
773 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
774 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
775 phy_info->hw_link_rate = buffer->HwLinkRate;
776 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
777 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
781 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
788 mptsas_parse_device_info(struct sas_identify *identify,
789 struct mptsas_devinfo *device_info)
793 identify->sas_address = device_info->sas_address;
794 identify->phy_identifier = device_info->phy_id;
797 * Fill in Phy Initiator Port Protocol.
798 * Bits 6:3, more than one bit can be set, fall through cases.
800 protocols = device_info->device_info & 0x78;
801 identify->initiator_port_protocols = 0;
802 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
803 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
804 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
805 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
806 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
807 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
808 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
809 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
812 * Fill in Phy Target Port Protocol.
813 * Bits 10:7, more than one bit can be set, fall through cases.
815 protocols = device_info->device_info & 0x780;
816 identify->target_port_protocols = 0;
817 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
818 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
819 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
820 identify->target_port_protocols |= SAS_PROTOCOL_STP;
821 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
822 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
823 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
824 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
827 * Fill in Attached device type.
829 switch (device_info->device_info &
830 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
831 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
832 identify->device_type = SAS_PHY_UNUSED;
834 case MPI_SAS_DEVICE_INFO_END_DEVICE:
835 identify->device_type = SAS_END_DEVICE;
837 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
838 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
840 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
841 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
846 static int mptsas_probe_one_phy(struct device *dev,
847 struct mptsas_phyinfo *phy_info, int index, int local)
849 struct sas_phy *port;
852 port = sas_phy_alloc(dev, index);
856 port->port_identifier = phy_info->port_id;
857 mptsas_parse_device_info(&port->identify, &phy_info->identify);
860 * Set Negotiated link rate.
862 switch (phy_info->negotiated_link_rate) {
863 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
864 port->negotiated_linkrate = SAS_PHY_DISABLED;
866 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
867 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
869 case MPI_SAS_IOUNIT0_RATE_1_5:
870 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
872 case MPI_SAS_IOUNIT0_RATE_3_0:
873 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
875 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
876 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
878 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
883 * Set Max hardware link rate.
885 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
886 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
887 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
889 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
890 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
897 * Set Max programmed link rate.
899 switch (phy_info->programmed_link_rate &
900 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
901 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
902 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
904 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
905 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
912 * Set Min hardware link rate.
914 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
915 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
916 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
918 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
919 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
926 * Set Min programmed link rate.
928 switch (phy_info->programmed_link_rate &
929 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
930 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
931 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
933 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
934 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
941 port->local_attached = 1;
943 error = sas_phy_add(port);
949 if (phy_info->attached.handle) {
950 struct sas_rphy *rphy;
952 rphy = sas_rphy_alloc(port);
954 return 0; /* non-fatal: an rphy can be added later */
956 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
957 error = sas_rphy_add(rphy);
963 phy_info->rphy = rphy;
970 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
972 struct mptsas_portinfo *port_info;
974 int error = -ENOMEM, i;
976 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
979 memset(port_info, 0, sizeof(*port_info));
981 error = mptsas_sas_io_unit_pg0(ioc, port_info);
983 goto out_free_port_info;
985 list_add_tail(&port_info->list, &ioc->sas_topology);
987 for (i = 0; i < port_info->num_phys; i++) {
988 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
989 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
990 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
992 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
993 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
994 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
995 port_info->phy_info[i].identify.phy_id =
996 port_info->phy_info[i].phy_id;
997 handle = port_info->phy_info[i].identify.handle;
999 if (port_info->phy_info[i].attached.handle) {
1000 mptsas_sas_device_pg0(ioc,
1001 &port_info->phy_info[i].attached,
1002 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1003 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1004 port_info->phy_info[i].attached.handle);
1007 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1008 &port_info->phy_info[i], *index, 1);
1021 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1023 struct mptsas_portinfo *port_info, *p;
1024 int error = -ENOMEM, i, j;
1026 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
1029 memset(port_info, 0, sizeof(*port_info));
1031 error = mptsas_sas_expander_pg0(ioc, port_info,
1032 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1033 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1035 goto out_free_port_info;
1037 *handle = port_info->handle;
1039 list_add_tail(&port_info->list, &ioc->sas_topology);
1040 for (i = 0; i < port_info->num_phys; i++) {
1041 struct device *parent;
1043 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1044 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1045 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1047 if (port_info->phy_info[i].identify.handle) {
1048 mptsas_sas_device_pg0(ioc,
1049 &port_info->phy_info[i].identify,
1050 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1051 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1052 port_info->phy_info[i].identify.handle);
1053 port_info->phy_info[i].identify.phy_id =
1054 port_info->phy_info[i].phy_id;
1057 if (port_info->phy_info[i].attached.handle) {
1058 mptsas_sas_device_pg0(ioc,
1059 &port_info->phy_info[i].attached,
1060 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1061 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1062 port_info->phy_info[i].attached.handle);
1066 * If we find a parent port handle this expander is
1067 * attached to another expander, else it hangs of the
1070 parent = &ioc->sh->shost_gendev;
1071 list_for_each_entry(p, &ioc->sas_topology, list) {
1072 for (j = 0; j < p->num_phys; j++) {
1073 if (port_info->phy_info[i].identify.handle ==
1074 p->phy_info[j].attached.handle)
1075 parent = &p->phy_info[j].rphy->dev;
1079 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1093 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1095 u32 handle = 0xFFFF;
1098 mptsas_probe_hba_phys(ioc, &index);
1099 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1104 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1106 struct Scsi_Host *sh;
1109 unsigned long flags;
1118 r = mpt_attach(pdev,id);
1122 ioc = pci_get_drvdata(pdev);
1123 ioc->DoneCtx = mptsasDoneCtx;
1124 ioc->TaskCtx = mptsasTaskCtx;
1125 ioc->InternalCtx = mptsasInternalCtx;
1127 /* Added sanity check on readiness of the MPT adapter.
1129 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1130 printk(MYIOC_s_WARN_FMT
1131 "Skipping because it's not operational!\n",
1137 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1142 /* Sanity check - ensure at least 1 port is INITIATOR capable
1145 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1146 if (ioc->pfacts[ii].ProtocolFlags &
1147 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1152 printk(MYIOC_s_WARN_FMT
1153 "Skipping ioc=%p because SCSI Initiator mode "
1154 "is NOT enabled!\n", ioc->name, ioc);
1158 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1160 printk(MYIOC_s_WARN_FMT
1161 "Unable to register controller with SCSI subsystem\n",
1166 spin_lock_irqsave(&ioc->FreeQlock, flags);
1168 /* Attach the SCSI Host to the IOC structure
1176 /* set 16 byte cdb's */
1177 sh->max_cmd_len = 16;
1179 sh->max_id = ioc->pfacts->MaxDevices + 1;
1181 sh->transportt = mptsas_transport_template;
1183 sh->max_lun = MPT_LAST_LUN + 1;
1184 sh->max_channel = 0;
1185 sh->this_id = ioc->pfacts[0].PortSCSIID;
1189 sh->unique_id = ioc->id;
1191 INIT_LIST_HEAD(&ioc->sas_topology);
1192 init_MUTEX(&ioc->sas_mgmt.mutex);
1193 init_completion(&ioc->sas_mgmt.done);
1195 /* Verify that we won't exceed the maximum
1196 * number of chain buffers
1197 * We can optimize: ZZ = req_sz/sizeof(SGE)
1199 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1200 * + (req_sz - 64)/sizeof(SGE)
1201 * A slightly different algorithm is required for
1204 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1205 if (sizeof(dma_addr_t) == sizeof(u64)) {
1206 numSGE = (scale - 1) *
1207 (ioc->facts.MaxChainDepth-1) + scale +
1208 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1211 numSGE = 1 + (scale - 1) *
1212 (ioc->facts.MaxChainDepth-1) + scale +
1213 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1217 if (numSGE < sh->sg_tablesize) {
1218 /* Reset this value */
1219 dprintk((MYIOC_s_INFO_FMT
1220 "Resetting sg_tablesize to %d from %d\n",
1221 ioc->name, numSGE, sh->sg_tablesize));
1222 sh->sg_tablesize = numSGE;
1225 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1227 hd = (MPT_SCSI_HOST *) sh->hostdata;
1230 /* SCSI needs scsi_cmnd lookup table!
1231 * (with size equal to req_depth*PtrSz!)
1233 sz = ioc->req_depth * sizeof(void *);
1234 mem = kmalloc(sz, GFP_ATOMIC);
1237 goto mptsas_probe_failed;
1241 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1243 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1244 ioc->name, hd->ScsiLookup, sz));
1246 /* Allocate memory for the device structures.
1247 * A non-Null pointer at an offset
1248 * indicates a device exists.
1249 * max_id = 1 + maximum id (hosts.h)
1251 sz = sh->max_id * sizeof(void *);
1252 mem = kmalloc(sz, GFP_ATOMIC);
1255 goto mptsas_probe_failed;
1259 hd->Targets = (VirtDevice **) mem;
1262 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1264 /* Clear the TM flags
1267 hd->tmState = TM_STATE_NONE;
1268 hd->resetPending = 0;
1269 hd->abortSCpnt = NULL;
1271 /* Clear the pointer used to store
1272 * single-threaded commands, i.e., those
1273 * issued during a bus scan, dv and
1274 * configuration pages.
1278 /* Initialize this SCSI Hosts' timers
1279 * To use, set the timer expires field
1282 init_timer(&hd->timer);
1283 hd->timer.data = (unsigned long) hd;
1284 hd->timer.function = mptscsih_timer_expired;
1286 hd->mpt_pq_filter = mpt_pq_filter;
1287 ioc->sas_data.ptClear = mpt_pt_clear;
1289 if (ioc->sas_data.ptClear==1) {
1290 mptbase_sas_persist_operation(
1291 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1294 ddvprintk((MYIOC_s_INFO_FMT
1295 "mpt_pq_filter %x mpt_pq_filter %x\n",
1300 init_waitqueue_head(&hd->scandv_waitq);
1301 hd->scandv_wait_done = 0;
1302 hd->last_queue_full = 0;
1304 error = scsi_add_host(sh, &ioc->pcidev->dev);
1306 dprintk((KERN_ERR MYNAM
1307 "scsi_add_host failed\n"));
1308 goto mptsas_probe_failed;
1311 mptsas_scan_sas_topology(ioc);
1315 mptsas_probe_failed:
1317 mptscsih_remove(pdev);
1321 static void __devexit mptsas_remove(struct pci_dev *pdev)
1323 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1324 struct mptsas_portinfo *p, *n;
1326 sas_remove_host(ioc->sh);
1328 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1333 mptscsih_remove(pdev);
1336 static struct pci_device_id mptsas_pci_table[] = {
1337 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1338 PCI_ANY_ID, PCI_ANY_ID },
1339 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1340 PCI_ANY_ID, PCI_ANY_ID },
1341 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1342 PCI_ANY_ID, PCI_ANY_ID },
1343 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1344 PCI_ANY_ID, PCI_ANY_ID },
1345 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1346 PCI_ANY_ID, PCI_ANY_ID },
1347 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1348 PCI_ANY_ID, PCI_ANY_ID },
1349 {0} /* Terminating entry */
1351 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1354 static struct pci_driver mptsas_driver = {
1356 .id_table = mptsas_pci_table,
1357 .probe = mptsas_probe,
1358 .remove = __devexit_p(mptsas_remove),
1359 .shutdown = mptscsih_shutdown,
1361 .suspend = mptscsih_suspend,
1362 .resume = mptscsih_resume,
1369 show_mptmod_ver(my_NAME, my_VERSION);
1371 mptsas_transport_template =
1372 sas_attach_transport(&mptsas_transport_functions);
1373 if (!mptsas_transport_template)
1376 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1377 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1379 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1380 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1382 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1383 devtprintk((KERN_INFO MYNAM
1384 ": Registered for IOC event notifications\n"));
1387 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1388 dprintk((KERN_INFO MYNAM
1389 ": Registered for IOC reset notifications\n"));
1392 return pci_register_driver(&mptsas_driver);
1398 pci_unregister_driver(&mptsas_driver);
1399 sas_release_transport(mptsas_transport_template);
1401 mpt_reset_deregister(mptsasDoneCtx);
1402 mpt_event_deregister(mptsasDoneCtx);
1404 mpt_deregister(mptsasMgmtCtx);
1405 mpt_deregister(mptsasInternalCtx);
1406 mpt_deregister(mptsasTaskCtx);
1407 mpt_deregister(mptsasDoneCtx);
1410 module_init(mptsas_init);
1411 module_exit(mptsas_exit);