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 *sdev)
233 struct Scsi_Host *host = sdev->host;
234 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
235 struct sas_rphy *rphy;
236 struct mptsas_portinfo *p;
239 struct scsi_target *starget;
242 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
244 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
245 hd->ioc->name, sizeof(VirtDevice));
248 memset(vdev, 0, sizeof(VirtDevice));
249 vdev->ioc_id = hd->ioc->id;
250 sdev->hostdata = vdev;
251 starget = scsi_target(sdev);
252 vtarget = starget->hostdata;
253 vdev->vtarget = vtarget;
254 if (vtarget->num_luns == 0) {
255 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
256 hd->Targets[sdev->id] = vtarget;
259 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
260 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
261 for (i = 0; i < p->num_phys; i++) {
262 if (p->phy_info[i].attached.sas_address ==
263 rphy->identify.sas_address) {
265 p->phy_info[i].attached.target;
266 vdev->bus_id = p->phy_info[i].attached.bus;
267 vdev->lun = sdev->lun;
273 printk("No matching SAS device found!!\n");
278 vtarget->ioc_id = vdev->ioc_id;
279 vtarget->target_id = vdev->target_id;
280 vtarget->bus_id = vdev->bus_id;
285 static struct scsi_host_template mptsas_driver_template = {
286 .module = THIS_MODULE,
287 .proc_name = "mptsas",
288 .proc_info = mptscsih_proc_info,
289 .name = "MPT SPI Host",
290 .info = mptscsih_info,
291 .queuecommand = mptscsih_qcmd,
292 .target_alloc = mptscsih_target_alloc,
293 .slave_alloc = mptsas_slave_alloc,
294 .slave_configure = mptscsih_slave_configure,
295 .target_destroy = mptscsih_target_destroy,
296 .slave_destroy = mptscsih_slave_destroy,
297 .change_queue_depth = mptscsih_change_queue_depth,
298 .eh_abort_handler = mptscsih_abort,
299 .eh_device_reset_handler = mptscsih_dev_reset,
300 .eh_bus_reset_handler = mptscsih_bus_reset,
301 .eh_host_reset_handler = mptscsih_host_reset,
302 .bios_param = mptscsih_bios_param,
303 .can_queue = MPT_FC_CAN_QUEUE,
305 .sg_tablesize = MPT_SCSI_SG_DEPTH,
308 .use_clustering = ENABLE_CLUSTERING,
311 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
313 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
314 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
317 static int mptsas_get_linkerrors(struct sas_phy *phy)
319 MPT_ADAPTER *ioc = phy_to_ioc(phy);
320 ConfigExtendedPageHeader_t hdr;
322 SasPhyPage1_t *buffer;
323 dma_addr_t dma_handle;
326 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
327 hdr.ExtPageLength = 0;
328 hdr.PageNumber = 1 /* page number 1*/;
331 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
332 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
334 cfg.cfghdr.ehdr = &hdr;
336 cfg.pageAddr = phy->identify.phy_identifier;
337 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
338 cfg.dir = 0; /* read */
341 error = mpt_config(ioc, &cfg);
344 if (!hdr.ExtPageLength)
347 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
352 cfg.physAddr = dma_handle;
353 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
355 error = mpt_config(ioc, &cfg);
357 goto out_free_consistent;
359 mptsas_print_phy_pg1(buffer);
361 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
362 phy->running_disparity_error_count =
363 le32_to_cpu(buffer->RunningDisparityErrorCount);
364 phy->loss_of_dword_sync_count =
365 le32_to_cpu(buffer->LossDwordSynchCount);
366 phy->phy_reset_problem_count =
367 le32_to_cpu(buffer->PhyResetProblemCount);
370 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
375 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
376 MPT_FRAME_HDR *reply)
378 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
380 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
381 memcpy(ioc->sas_mgmt.reply, reply,
382 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
384 complete(&ioc->sas_mgmt.done);
388 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
390 MPT_ADAPTER *ioc = phy_to_ioc(phy);
391 SasIoUnitControlRequest_t *req;
392 SasIoUnitControlReply_t *reply;
395 unsigned long timeleft;
396 int error = -ERESTARTSYS;
398 /* not implemented for expanders */
399 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
402 if (down_interruptible(&ioc->sas_mgmt.mutex))
405 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
411 hdr = (MPIHeader_t *) mf;
412 req = (SasIoUnitControlRequest_t *)mf;
413 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
414 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
415 req->MsgContext = hdr->MsgContext;
416 req->Operation = hard_reset ?
417 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
418 req->PhyNum = phy->identify.phy_identifier;
420 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
422 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
425 /* On timeout reset the board */
426 mpt_free_msg_frame(ioc, mf);
427 mpt_HardResetHandler(ioc, CAN_SLEEP);
432 /* a reply frame is expected */
433 if ((ioc->sas_mgmt.status &
434 MPT_IOCTL_STATUS_RF_VALID) == 0) {
439 /* process the completed Reply Message Frame */
440 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
441 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
442 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
453 up(&ioc->sas_mgmt.mutex);
458 static struct sas_function_template mptsas_transport_functions = {
459 .get_linkerrors = mptsas_get_linkerrors,
460 .phy_reset = mptsas_phy_reset,
463 static struct scsi_transport_template *mptsas_transport_template;
466 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
468 ConfigExtendedPageHeader_t hdr;
470 SasIOUnitPage0_t *buffer;
471 dma_addr_t dma_handle;
474 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
475 hdr.ExtPageLength = 0;
479 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
480 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
482 cfg.cfghdr.ehdr = &hdr;
485 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
486 cfg.dir = 0; /* read */
489 error = mpt_config(ioc, &cfg);
492 if (!hdr.ExtPageLength) {
497 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
504 cfg.physAddr = dma_handle;
505 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
507 error = mpt_config(ioc, &cfg);
509 goto out_free_consistent;
511 port_info->num_phys = buffer->NumPhys;
512 port_info->phy_info = kcalloc(port_info->num_phys,
513 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
514 if (!port_info->phy_info) {
516 goto out_free_consistent;
519 for (i = 0; i < port_info->num_phys; i++) {
520 mptsas_print_phy_data(&buffer->PhyData[i]);
521 port_info->phy_info[i].phy_id = i;
522 port_info->phy_info[i].port_id =
523 buffer->PhyData[i].Port;
524 port_info->phy_info[i].negotiated_link_rate =
525 buffer->PhyData[i].NegotiatedLinkRate;
529 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
536 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
537 u32 form, u32 form_specific)
539 ConfigExtendedPageHeader_t hdr;
541 SasPhyPage0_t *buffer;
542 dma_addr_t dma_handle;
545 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
546 hdr.ExtPageLength = 0;
550 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
551 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
553 cfg.cfghdr.ehdr = &hdr;
554 cfg.dir = 0; /* read */
557 /* Get Phy Pg 0 for each Phy. */
559 cfg.pageAddr = form + form_specific;
560 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
562 error = mpt_config(ioc, &cfg);
566 if (!hdr.ExtPageLength) {
571 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
578 cfg.physAddr = dma_handle;
579 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
581 error = mpt_config(ioc, &cfg);
583 goto out_free_consistent;
585 mptsas_print_phy_pg0(buffer);
587 phy_info->hw_link_rate = buffer->HwLinkRate;
588 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
589 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
590 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
593 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
600 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
601 u32 form, u32 form_specific)
603 ConfigExtendedPageHeader_t hdr;
605 SasDevicePage0_t *buffer;
606 dma_addr_t dma_handle;
610 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
611 hdr.ExtPageLength = 0;
615 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
616 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
618 cfg.cfghdr.ehdr = &hdr;
619 cfg.pageAddr = form + form_specific;
621 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
622 cfg.dir = 0; /* read */
625 error = mpt_config(ioc, &cfg);
628 if (!hdr.ExtPageLength) {
633 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
640 cfg.physAddr = dma_handle;
641 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
643 error = mpt_config(ioc, &cfg);
645 goto out_free_consistent;
647 mptsas_print_device_pg0(buffer);
649 device_info->handle = le16_to_cpu(buffer->DevHandle);
650 device_info->phy_id = buffer->PhyNum;
651 device_info->port_id = buffer->PhysicalPort;
652 device_info->target = buffer->TargetID;
653 device_info->bus = buffer->Bus;
654 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
655 device_info->sas_address = le64_to_cpu(sas_address);
656 device_info->device_info =
657 le32_to_cpu(buffer->DeviceInfo);
660 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
667 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
668 u32 form, u32 form_specific)
670 ConfigExtendedPageHeader_t hdr;
672 SasExpanderPage0_t *buffer;
673 dma_addr_t dma_handle;
676 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
677 hdr.ExtPageLength = 0;
681 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
682 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
684 cfg.cfghdr.ehdr = &hdr;
686 cfg.pageAddr = form + form_specific;
687 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
688 cfg.dir = 0; /* read */
691 error = mpt_config(ioc, &cfg);
695 if (!hdr.ExtPageLength) {
700 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
707 cfg.physAddr = dma_handle;
708 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
710 error = mpt_config(ioc, &cfg);
712 goto out_free_consistent;
714 /* save config data */
715 port_info->num_phys = buffer->NumPhys;
716 port_info->handle = le16_to_cpu(buffer->DevHandle);
717 port_info->phy_info = kcalloc(port_info->num_phys,
718 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
719 if (!port_info->phy_info) {
721 goto out_free_consistent;
725 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
732 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
733 u32 form, u32 form_specific)
735 ConfigExtendedPageHeader_t hdr;
737 SasExpanderPage1_t *buffer;
738 dma_addr_t dma_handle;
741 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
742 hdr.ExtPageLength = 0;
746 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
747 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
749 cfg.cfghdr.ehdr = &hdr;
751 cfg.pageAddr = form + form_specific;
752 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
753 cfg.dir = 0; /* read */
756 error = mpt_config(ioc, &cfg);
760 if (!hdr.ExtPageLength) {
765 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
772 cfg.physAddr = dma_handle;
773 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
775 error = mpt_config(ioc, &cfg);
777 goto out_free_consistent;
780 mptsas_print_expander_pg1(buffer);
782 /* save config data */
783 phy_info->phy_id = buffer->PhyIdentifier;
784 phy_info->port_id = buffer->PhysicalPort;
785 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
786 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
787 phy_info->hw_link_rate = buffer->HwLinkRate;
788 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
789 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
793 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
800 mptsas_parse_device_info(struct sas_identify *identify,
801 struct mptsas_devinfo *device_info)
805 identify->sas_address = device_info->sas_address;
806 identify->phy_identifier = device_info->phy_id;
809 * Fill in Phy Initiator Port Protocol.
810 * Bits 6:3, more than one bit can be set, fall through cases.
812 protocols = device_info->device_info & 0x78;
813 identify->initiator_port_protocols = 0;
814 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
815 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
816 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
817 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
818 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
819 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
820 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
821 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
824 * Fill in Phy Target Port Protocol.
825 * Bits 10:7, more than one bit can be set, fall through cases.
827 protocols = device_info->device_info & 0x780;
828 identify->target_port_protocols = 0;
829 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
830 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
831 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
832 identify->target_port_protocols |= SAS_PROTOCOL_STP;
833 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
834 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
835 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
836 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
839 * Fill in Attached device type.
841 switch (device_info->device_info &
842 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
843 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
844 identify->device_type = SAS_PHY_UNUSED;
846 case MPI_SAS_DEVICE_INFO_END_DEVICE:
847 identify->device_type = SAS_END_DEVICE;
849 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
850 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
852 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
853 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
858 static int mptsas_probe_one_phy(struct device *dev,
859 struct mptsas_phyinfo *phy_info, int index, int local)
861 struct sas_phy *port;
864 port = sas_phy_alloc(dev, index);
868 port->port_identifier = phy_info->port_id;
869 mptsas_parse_device_info(&port->identify, &phy_info->identify);
872 * Set Negotiated link rate.
874 switch (phy_info->negotiated_link_rate) {
875 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
876 port->negotiated_linkrate = SAS_PHY_DISABLED;
878 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
879 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
881 case MPI_SAS_IOUNIT0_RATE_1_5:
882 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
884 case MPI_SAS_IOUNIT0_RATE_3_0:
885 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
887 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
888 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
890 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
895 * Set Max hardware link rate.
897 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
898 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
899 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
901 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
902 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
909 * Set Max programmed link rate.
911 switch (phy_info->programmed_link_rate &
912 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
913 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
914 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
916 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
917 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
924 * Set Min hardware link rate.
926 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
927 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
928 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
930 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
931 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
938 * Set Min programmed link rate.
940 switch (phy_info->programmed_link_rate &
941 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
942 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
943 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
945 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
946 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
953 port->local_attached = 1;
955 error = sas_phy_add(port);
961 if (phy_info->attached.handle) {
962 struct sas_rphy *rphy;
964 rphy = sas_rphy_alloc(port);
966 return 0; /* non-fatal: an rphy can be added later */
968 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
969 error = sas_rphy_add(rphy);
975 phy_info->rphy = rphy;
982 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
984 struct mptsas_portinfo *port_info;
986 int error = -ENOMEM, i;
988 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
991 memset(port_info, 0, sizeof(*port_info));
993 error = mptsas_sas_io_unit_pg0(ioc, port_info);
995 goto out_free_port_info;
997 list_add_tail(&port_info->list, &ioc->sas_topology);
998 for (i = 0; i < port_info->num_phys; i++) {
999 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1000 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1001 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1003 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1004 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1005 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1006 port_info->phy_info[i].identify.phy_id =
1007 port_info->phy_info[i].phy_id;
1008 handle = port_info->phy_info[i].identify.handle;
1010 if (port_info->phy_info[i].attached.handle) {
1011 mptsas_sas_device_pg0(ioc,
1012 &port_info->phy_info[i].attached,
1013 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1014 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1015 port_info->phy_info[i].attached.handle);
1018 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1019 &port_info->phy_info[i], *index, 1);
1032 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1034 struct mptsas_portinfo *port_info, *p;
1035 int error = -ENOMEM, i, j;
1037 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
1040 memset(port_info, 0, sizeof(*port_info));
1042 error = mptsas_sas_expander_pg0(ioc, port_info,
1043 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1044 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1046 goto out_free_port_info;
1048 *handle = port_info->handle;
1050 list_add_tail(&port_info->list, &ioc->sas_topology);
1051 for (i = 0; i < port_info->num_phys; i++) {
1052 struct device *parent;
1054 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1055 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1056 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1058 if (port_info->phy_info[i].identify.handle) {
1059 mptsas_sas_device_pg0(ioc,
1060 &port_info->phy_info[i].identify,
1061 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1062 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1063 port_info->phy_info[i].identify.handle);
1064 port_info->phy_info[i].identify.phy_id =
1065 port_info->phy_info[i].phy_id;
1068 if (port_info->phy_info[i].attached.handle) {
1069 mptsas_sas_device_pg0(ioc,
1070 &port_info->phy_info[i].attached,
1071 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1072 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1073 port_info->phy_info[i].attached.handle);
1077 * If we find a parent port handle this expander is
1078 * attached to another expander, else it hangs of the
1081 parent = &ioc->sh->shost_gendev;
1082 list_for_each_entry(p, &ioc->sas_topology, list) {
1083 for (j = 0; j < p->num_phys; j++) {
1084 if (port_info->phy_info[i].identify.handle ==
1085 p->phy_info[j].attached.handle)
1086 parent = &p->phy_info[j].rphy->dev;
1090 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1104 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1106 u32 handle = 0xFFFF;
1109 mptsas_probe_hba_phys(ioc, &index);
1110 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1115 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1117 struct Scsi_Host *sh;
1120 unsigned long flags;
1129 r = mpt_attach(pdev,id);
1133 ioc = pci_get_drvdata(pdev);
1134 ioc->DoneCtx = mptsasDoneCtx;
1135 ioc->TaskCtx = mptsasTaskCtx;
1136 ioc->InternalCtx = mptsasInternalCtx;
1138 /* Added sanity check on readiness of the MPT adapter.
1140 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1141 printk(MYIOC_s_WARN_FMT
1142 "Skipping because it's not operational!\n",
1145 goto out_mptsas_probe;
1149 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1152 goto out_mptsas_probe;
1155 /* Sanity check - ensure at least 1 port is INITIATOR capable
1158 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1159 if (ioc->pfacts[ii].ProtocolFlags &
1160 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1165 printk(MYIOC_s_WARN_FMT
1166 "Skipping ioc=%p because SCSI Initiator mode "
1167 "is NOT enabled!\n", ioc->name, ioc);
1171 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1173 printk(MYIOC_s_WARN_FMT
1174 "Unable to register controller with SCSI subsystem\n",
1177 goto out_mptsas_probe;
1180 spin_lock_irqsave(&ioc->FreeQlock, flags);
1182 /* Attach the SCSI Host to the IOC structure
1190 /* set 16 byte cdb's */
1191 sh->max_cmd_len = 16;
1193 sh->max_id = ioc->pfacts->MaxDevices + 1;
1195 sh->transportt = mptsas_transport_template;
1197 sh->max_lun = MPT_LAST_LUN + 1;
1198 sh->max_channel = 0;
1199 sh->this_id = ioc->pfacts[0].PortSCSIID;
1203 sh->unique_id = ioc->id;
1205 INIT_LIST_HEAD(&ioc->sas_topology);
1206 init_MUTEX(&ioc->sas_mgmt.mutex);
1207 init_completion(&ioc->sas_mgmt.done);
1209 /* Verify that we won't exceed the maximum
1210 * number of chain buffers
1211 * We can optimize: ZZ = req_sz/sizeof(SGE)
1213 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1214 * + (req_sz - 64)/sizeof(SGE)
1215 * A slightly different algorithm is required for
1218 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1219 if (sizeof(dma_addr_t) == sizeof(u64)) {
1220 numSGE = (scale - 1) *
1221 (ioc->facts.MaxChainDepth-1) + scale +
1222 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1225 numSGE = 1 + (scale - 1) *
1226 (ioc->facts.MaxChainDepth-1) + scale +
1227 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1231 if (numSGE < sh->sg_tablesize) {
1232 /* Reset this value */
1233 dprintk((MYIOC_s_INFO_FMT
1234 "Resetting sg_tablesize to %d from %d\n",
1235 ioc->name, numSGE, sh->sg_tablesize));
1236 sh->sg_tablesize = numSGE;
1239 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1241 hd = (MPT_SCSI_HOST *) sh->hostdata;
1244 /* SCSI needs scsi_cmnd lookup table!
1245 * (with size equal to req_depth*PtrSz!)
1247 sz = ioc->req_depth * sizeof(void *);
1248 mem = kmalloc(sz, GFP_ATOMIC);
1251 goto out_mptsas_probe;
1255 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1257 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1258 ioc->name, hd->ScsiLookup, sz));
1260 /* Allocate memory for the device structures.
1261 * A non-Null pointer at an offset
1262 * indicates a device exists.
1263 * max_id = 1 + maximum id (hosts.h)
1265 sz = sh->max_id * sizeof(void *);
1266 mem = kmalloc(sz, GFP_ATOMIC);
1269 goto out_mptsas_probe;
1273 hd->Targets = (VirtTarget **) mem;
1276 " vtarget @ %p, sz=%d\n", hd->Targets, sz));
1278 /* Clear the TM flags
1281 hd->tmState = TM_STATE_NONE;
1282 hd->resetPending = 0;
1283 hd->abortSCpnt = NULL;
1285 /* Clear the pointer used to store
1286 * single-threaded commands, i.e., those
1287 * issued during a bus scan, dv and
1288 * configuration pages.
1292 /* Initialize this SCSI Hosts' timers
1293 * To use, set the timer expires field
1296 init_timer(&hd->timer);
1297 hd->timer.data = (unsigned long) hd;
1298 hd->timer.function = mptscsih_timer_expired;
1300 hd->mpt_pq_filter = mpt_pq_filter;
1301 ioc->sas_data.ptClear = mpt_pt_clear;
1303 if (ioc->sas_data.ptClear==1) {
1304 mptbase_sas_persist_operation(
1305 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1308 ddvprintk((MYIOC_s_INFO_FMT
1309 "mpt_pq_filter %x mpt_pq_filter %x\n",
1314 init_waitqueue_head(&hd->scandv_waitq);
1315 hd->scandv_wait_done = 0;
1316 hd->last_queue_full = 0;
1318 error = scsi_add_host(sh, &ioc->pcidev->dev);
1320 dprintk((KERN_ERR MYNAM
1321 "scsi_add_host failed\n"));
1322 goto out_mptsas_probe;
1325 mptsas_scan_sas_topology(ioc);
1331 mptscsih_remove(pdev);
1335 static void __devexit mptsas_remove(struct pci_dev *pdev)
1337 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1338 struct mptsas_portinfo *p, *n;
1340 sas_remove_host(ioc->sh);
1342 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1347 mptscsih_remove(pdev);
1350 static struct pci_device_id mptsas_pci_table[] = {
1351 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1352 PCI_ANY_ID, PCI_ANY_ID },
1353 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1354 PCI_ANY_ID, PCI_ANY_ID },
1355 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1356 PCI_ANY_ID, PCI_ANY_ID },
1357 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1358 PCI_ANY_ID, PCI_ANY_ID },
1359 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1360 PCI_ANY_ID, PCI_ANY_ID },
1361 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1362 PCI_ANY_ID, PCI_ANY_ID },
1363 {0} /* Terminating entry */
1365 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1368 static struct pci_driver mptsas_driver = {
1370 .id_table = mptsas_pci_table,
1371 .probe = mptsas_probe,
1372 .remove = __devexit_p(mptsas_remove),
1373 .shutdown = mptscsih_shutdown,
1375 .suspend = mptscsih_suspend,
1376 .resume = mptscsih_resume,
1383 show_mptmod_ver(my_NAME, my_VERSION);
1385 mptsas_transport_template =
1386 sas_attach_transport(&mptsas_transport_functions);
1387 if (!mptsas_transport_template)
1390 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1391 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1393 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1394 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1396 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1397 devtprintk((KERN_INFO MYNAM
1398 ": Registered for IOC event notifications\n"));
1401 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1402 dprintk((KERN_INFO MYNAM
1403 ": Registered for IOC reset notifications\n"));
1406 return pci_register_driver(&mptsas_driver);
1412 pci_unregister_driver(&mptsas_driver);
1413 sas_release_transport(mptsas_transport_template);
1415 mpt_reset_deregister(mptsasDoneCtx);
1416 mpt_event_deregister(mptsasDoneCtx);
1418 mpt_deregister(mptsasMgmtCtx);
1419 mpt_deregister(mptsasInternalCtx);
1420 mpt_deregister(mptsasTaskCtx);
1421 mpt_deregister(mptsasDoneCtx);
1424 module_init(mptsas_init);
1425 module_exit(mptsas_exit);