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-2006 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;
89 enum mptsas_hotplug_action {
94 struct mptsas_hotplug_event {
95 struct work_struct work;
97 enum mptsas_hotplug_action event_type;
108 * SAS topology structures
110 * The MPT Fusion firmware interface spreads information about the
111 * SAS topology over many manufacture pages, thus we need some data
112 * structure to collect it and process it for the SAS transport class.
115 struct mptsas_devinfo {
116 u16 handle; /* unique id to address this device */
117 u8 phy_id; /* phy number of parent device */
118 u8 port_id; /* sas physical port this device
120 u8 id; /* logical target id of this device */
121 u8 channel; /* logical bus number of this device */
122 u64 sas_address; /* WWN of this device,
123 SATA is assigned by HBA,expander */
124 u32 device_info; /* bitfield detailed info about this device */
127 struct mptsas_phyinfo {
128 u8 phy_id; /* phy index */
129 u8 port_id; /* port number this phy is part of */
130 u8 negotiated_link_rate; /* nego'd link rate for this phy */
131 u8 hw_link_rate; /* hardware max/min phys link rate */
132 u8 programmed_link_rate; /* programmed max/min phy link rate */
133 struct mptsas_devinfo identify; /* point to phy device info */
134 struct mptsas_devinfo attached; /* point to attached device info */
136 struct sas_rphy *rphy;
139 struct mptsas_portinfo {
140 struct list_head list;
141 u16 handle; /* unique id to address this */
142 u8 num_phys; /* number of phys */
143 struct mptsas_phyinfo *phy_info;
148 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
150 printk("---- IO UNIT PAGE 0 ------------\n");
151 printk("Handle=0x%X\n",
152 le16_to_cpu(phy_data->AttachedDeviceHandle));
153 printk("Controller Handle=0x%X\n",
154 le16_to_cpu(phy_data->ControllerDevHandle));
155 printk("Port=0x%X\n", phy_data->Port);
156 printk("Port Flags=0x%X\n", phy_data->PortFlags);
157 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
158 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
159 printk("Controller PHY Device Info=0x%X\n",
160 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
161 printk("DiscoveryStatus=0x%X\n",
162 le32_to_cpu(phy_data->DiscoveryStatus));
166 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
170 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
172 printk("---- SAS PHY PAGE 0 ------------\n");
173 printk("Attached Device Handle=0x%X\n",
174 le16_to_cpu(pg0->AttachedDevHandle));
175 printk("SAS Address=0x%llX\n",
176 (unsigned long long)le64_to_cpu(sas_address));
177 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
178 printk("Attached Device Info=0x%X\n",
179 le32_to_cpu(pg0->AttachedDeviceInfo));
180 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
181 printk("Change Count=0x%X\n", pg0->ChangeCount);
182 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
186 static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
188 printk("---- SAS PHY PAGE 1 ------------\n");
189 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
190 printk("Running Disparity Error Count=0x%x\n",
191 pg1->RunningDisparityErrorCount);
192 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
193 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
197 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
201 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
203 printk("---- SAS DEVICE PAGE 0 ---------\n");
204 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
205 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
206 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
207 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
208 printk("Target ID=0x%X\n", pg0->TargetID);
209 printk("Bus=0x%X\n", pg0->Bus);
210 /* The PhyNum field specifies the PHY number of the parent
211 * device this device is linked to
213 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
214 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
215 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
216 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
217 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
221 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
223 printk("---- SAS EXPANDER PAGE 1 ------------\n");
225 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
226 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
227 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
228 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
229 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
230 printk("Owner Device Handle=0x%X\n",
231 le16_to_cpu(pg1->OwnerDevHandle));
232 printk("Attached Device Handle=0x%X\n",
233 le16_to_cpu(pg1->AttachedDevHandle));
236 #define mptsas_print_phy_data(phy_data) do { } while (0)
237 #define mptsas_print_phy_pg0(pg0) do { } while (0)
238 #define mptsas_print_phy_pg1(pg1) do { } while (0)
239 #define mptsas_print_device_pg0(pg0) do { } while (0)
240 #define mptsas_print_expander_pg1(pg1) do { } while (0)
245 * This is pretty ugly. We will be able to seriously clean it up
246 * once the DV code in mptscsih goes away and we can properly
247 * implement ->target_alloc.
250 mptsas_slave_alloc(struct scsi_device *sdev)
252 struct Scsi_Host *host = sdev->host;
253 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
254 struct sas_rphy *rphy;
255 struct mptsas_portinfo *p;
258 struct scsi_target *starget;
261 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
263 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
264 hd->ioc->name, sizeof(VirtDevice));
267 vdev->ioc_id = hd->ioc->id;
268 sdev->hostdata = vdev;
269 starget = scsi_target(sdev);
270 vtarget = starget->hostdata;
271 vdev->vtarget = vtarget;
272 if (vtarget->num_luns == 0) {
273 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
274 hd->Targets[sdev->id] = vtarget;
277 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
278 mutex_lock(&hd->ioc->sas_topology_mutex);
279 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
280 for (i = 0; i < p->num_phys; i++) {
281 if (p->phy_info[i].attached.sas_address ==
282 rphy->identify.sas_address) {
284 p->phy_info[i].attached.id;
285 vdev->bus_id = p->phy_info[i].attached.channel;
286 vdev->lun = sdev->lun;
291 mutex_unlock(&hd->ioc->sas_topology_mutex);
293 printk("No matching SAS device found!!\n");
298 mutex_unlock(&hd->ioc->sas_topology_mutex);
299 vtarget->ioc_id = vdev->ioc_id;
300 vtarget->target_id = vdev->target_id;
301 vtarget->bus_id = vdev->bus_id;
307 mptsas_slave_destroy(struct scsi_device *sdev)
309 struct Scsi_Host *host = sdev->host;
310 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
311 struct sas_rphy *rphy;
312 struct mptsas_portinfo *p;
316 * Handle hotplug removal case.
317 * We need to clear out attached data structure.
319 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
321 mutex_lock(&hd->ioc->sas_topology_mutex);
322 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
323 for (i = 0; i < p->num_phys; i++) {
324 if (p->phy_info[i].attached.sas_address ==
325 rphy->identify.sas_address) {
326 memset(&p->phy_info[i].attached, 0,
327 sizeof(struct mptsas_devinfo));
328 p->phy_info[i].rphy = NULL;
335 mutex_unlock(&hd->ioc->sas_topology_mutex);
337 * TODO: Issue target reset to flush firmware outstanding commands.
339 mptscsih_slave_destroy(sdev);
342 static struct scsi_host_template mptsas_driver_template = {
343 .module = THIS_MODULE,
344 .proc_name = "mptsas",
345 .proc_info = mptscsih_proc_info,
346 .name = "MPT SPI Host",
347 .info = mptscsih_info,
348 .queuecommand = mptscsih_qcmd,
349 .target_alloc = mptscsih_target_alloc,
350 .slave_alloc = mptsas_slave_alloc,
351 .slave_configure = mptscsih_slave_configure,
352 .target_destroy = mptscsih_target_destroy,
353 .slave_destroy = mptsas_slave_destroy,
354 .change_queue_depth = mptscsih_change_queue_depth,
355 .eh_abort_handler = mptscsih_abort,
356 .eh_device_reset_handler = mptscsih_dev_reset,
357 .eh_bus_reset_handler = mptscsih_bus_reset,
358 .eh_host_reset_handler = mptscsih_host_reset,
359 .bios_param = mptscsih_bios_param,
360 .can_queue = MPT_FC_CAN_QUEUE,
362 .sg_tablesize = MPT_SCSI_SG_DEPTH,
365 .use_clustering = ENABLE_CLUSTERING,
368 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
370 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
371 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
374 static int mptsas_get_linkerrors(struct sas_phy *phy)
376 MPT_ADAPTER *ioc = phy_to_ioc(phy);
377 ConfigExtendedPageHeader_t hdr;
379 SasPhyPage1_t *buffer;
380 dma_addr_t dma_handle;
383 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
384 hdr.ExtPageLength = 0;
385 hdr.PageNumber = 1 /* page number 1*/;
388 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
389 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
391 cfg.cfghdr.ehdr = &hdr;
393 cfg.pageAddr = phy->identify.phy_identifier;
394 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
395 cfg.dir = 0; /* read */
398 error = mpt_config(ioc, &cfg);
401 if (!hdr.ExtPageLength)
404 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
409 cfg.physAddr = dma_handle;
410 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
412 error = mpt_config(ioc, &cfg);
414 goto out_free_consistent;
416 mptsas_print_phy_pg1(buffer);
418 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
419 phy->running_disparity_error_count =
420 le32_to_cpu(buffer->RunningDisparityErrorCount);
421 phy->loss_of_dword_sync_count =
422 le32_to_cpu(buffer->LossDwordSynchCount);
423 phy->phy_reset_problem_count =
424 le32_to_cpu(buffer->PhyResetProblemCount);
427 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
432 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
433 MPT_FRAME_HDR *reply)
435 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
437 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
438 memcpy(ioc->sas_mgmt.reply, reply,
439 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
441 complete(&ioc->sas_mgmt.done);
445 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
447 MPT_ADAPTER *ioc = phy_to_ioc(phy);
448 SasIoUnitControlRequest_t *req;
449 SasIoUnitControlReply_t *reply;
452 unsigned long timeleft;
453 int error = -ERESTARTSYS;
455 /* not implemented for expanders */
456 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
459 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
462 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
468 hdr = (MPIHeader_t *) mf;
469 req = (SasIoUnitControlRequest_t *)mf;
470 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
471 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
472 req->MsgContext = hdr->MsgContext;
473 req->Operation = hard_reset ?
474 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
475 req->PhyNum = phy->identify.phy_identifier;
477 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
479 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
482 /* On timeout reset the board */
483 mpt_free_msg_frame(ioc, mf);
484 mpt_HardResetHandler(ioc, CAN_SLEEP);
489 /* a reply frame is expected */
490 if ((ioc->sas_mgmt.status &
491 MPT_IOCTL_STATUS_RF_VALID) == 0) {
496 /* process the completed Reply Message Frame */
497 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
498 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
499 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
510 mutex_unlock(&ioc->sas_mgmt.mutex);
515 static struct sas_function_template mptsas_transport_functions = {
516 .get_linkerrors = mptsas_get_linkerrors,
517 .phy_reset = mptsas_phy_reset,
520 static struct scsi_transport_template *mptsas_transport_template;
523 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
525 ConfigExtendedPageHeader_t hdr;
527 SasIOUnitPage0_t *buffer;
528 dma_addr_t dma_handle;
531 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
532 hdr.ExtPageLength = 0;
536 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
537 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
539 cfg.cfghdr.ehdr = &hdr;
542 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
543 cfg.dir = 0; /* read */
546 error = mpt_config(ioc, &cfg);
549 if (!hdr.ExtPageLength) {
554 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
561 cfg.physAddr = dma_handle;
562 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
564 error = mpt_config(ioc, &cfg);
566 goto out_free_consistent;
568 port_info->num_phys = buffer->NumPhys;
569 port_info->phy_info = kcalloc(port_info->num_phys,
570 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
571 if (!port_info->phy_info) {
573 goto out_free_consistent;
576 for (i = 0; i < port_info->num_phys; i++) {
577 mptsas_print_phy_data(&buffer->PhyData[i]);
578 port_info->phy_info[i].phy_id = i;
579 port_info->phy_info[i].port_id =
580 buffer->PhyData[i].Port;
581 port_info->phy_info[i].negotiated_link_rate =
582 buffer->PhyData[i].NegotiatedLinkRate;
586 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
593 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
594 u32 form, u32 form_specific)
596 ConfigExtendedPageHeader_t hdr;
598 SasPhyPage0_t *buffer;
599 dma_addr_t dma_handle;
602 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
603 hdr.ExtPageLength = 0;
607 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
608 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
610 cfg.cfghdr.ehdr = &hdr;
611 cfg.dir = 0; /* read */
614 /* Get Phy Pg 0 for each Phy. */
616 cfg.pageAddr = form + form_specific;
617 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
619 error = mpt_config(ioc, &cfg);
623 if (!hdr.ExtPageLength) {
628 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
635 cfg.physAddr = dma_handle;
636 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
638 error = mpt_config(ioc, &cfg);
640 goto out_free_consistent;
642 mptsas_print_phy_pg0(buffer);
644 phy_info->hw_link_rate = buffer->HwLinkRate;
645 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
646 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
647 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
650 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
657 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
658 u32 form, u32 form_specific)
660 ConfigExtendedPageHeader_t hdr;
662 SasDevicePage0_t *buffer;
663 dma_addr_t dma_handle;
667 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
668 hdr.ExtPageLength = 0;
672 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
673 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
675 cfg.cfghdr.ehdr = &hdr;
676 cfg.pageAddr = form + form_specific;
678 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
679 cfg.dir = 0; /* read */
682 error = mpt_config(ioc, &cfg);
685 if (!hdr.ExtPageLength) {
690 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
697 cfg.physAddr = dma_handle;
698 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
700 error = mpt_config(ioc, &cfg);
702 goto out_free_consistent;
704 mptsas_print_device_pg0(buffer);
706 device_info->handle = le16_to_cpu(buffer->DevHandle);
707 device_info->phy_id = buffer->PhyNum;
708 device_info->port_id = buffer->PhysicalPort;
709 device_info->id = buffer->TargetID;
710 device_info->channel = buffer->Bus;
711 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
712 device_info->sas_address = le64_to_cpu(sas_address);
713 device_info->device_info =
714 le32_to_cpu(buffer->DeviceInfo);
717 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
724 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
725 u32 form, u32 form_specific)
727 ConfigExtendedPageHeader_t hdr;
729 SasExpanderPage0_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;
771 /* save config data */
772 port_info->num_phys = buffer->NumPhys;
773 port_info->handle = le16_to_cpu(buffer->DevHandle);
774 port_info->phy_info = kcalloc(port_info->num_phys,
775 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
776 if (!port_info->phy_info) {
778 goto out_free_consistent;
782 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
789 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
790 u32 form, u32 form_specific)
792 ConfigExtendedPageHeader_t hdr;
794 SasExpanderPage1_t *buffer;
795 dma_addr_t dma_handle;
798 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
799 hdr.ExtPageLength = 0;
803 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
804 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
806 cfg.cfghdr.ehdr = &hdr;
808 cfg.pageAddr = form + form_specific;
809 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
810 cfg.dir = 0; /* read */
813 error = mpt_config(ioc, &cfg);
817 if (!hdr.ExtPageLength) {
822 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
829 cfg.physAddr = dma_handle;
830 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
832 error = mpt_config(ioc, &cfg);
834 goto out_free_consistent;
837 mptsas_print_expander_pg1(buffer);
839 /* save config data */
840 phy_info->phy_id = buffer->PhyIdentifier;
841 phy_info->port_id = buffer->PhysicalPort;
842 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
843 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
844 phy_info->hw_link_rate = buffer->HwLinkRate;
845 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
846 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
850 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
857 mptsas_parse_device_info(struct sas_identify *identify,
858 struct mptsas_devinfo *device_info)
862 identify->sas_address = device_info->sas_address;
863 identify->phy_identifier = device_info->phy_id;
866 * Fill in Phy Initiator Port Protocol.
867 * Bits 6:3, more than one bit can be set, fall through cases.
869 protocols = device_info->device_info & 0x78;
870 identify->initiator_port_protocols = 0;
871 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
872 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
873 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
874 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
875 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
876 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
877 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
878 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
881 * Fill in Phy Target Port Protocol.
882 * Bits 10:7, more than one bit can be set, fall through cases.
884 protocols = device_info->device_info & 0x780;
885 identify->target_port_protocols = 0;
886 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
887 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
888 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
889 identify->target_port_protocols |= SAS_PROTOCOL_STP;
890 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
891 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
892 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
893 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
896 * Fill in Attached device type.
898 switch (device_info->device_info &
899 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
900 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
901 identify->device_type = SAS_PHY_UNUSED;
903 case MPI_SAS_DEVICE_INFO_END_DEVICE:
904 identify->device_type = SAS_END_DEVICE;
906 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
907 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
909 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
910 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
915 static int mptsas_probe_one_phy(struct device *dev,
916 struct mptsas_phyinfo *phy_info, int index, int local)
921 phy = sas_phy_alloc(dev, index);
925 phy->port_identifier = phy_info->port_id;
926 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
929 * Set Negotiated link rate.
931 switch (phy_info->negotiated_link_rate) {
932 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
933 phy->negotiated_linkrate = SAS_PHY_DISABLED;
935 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
936 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
938 case MPI_SAS_IOUNIT0_RATE_1_5:
939 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
941 case MPI_SAS_IOUNIT0_RATE_3_0:
942 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
944 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
945 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
947 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
952 * Set Max hardware link rate.
954 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
955 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
956 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
958 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
959 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
966 * Set Max programmed link rate.
968 switch (phy_info->programmed_link_rate &
969 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
970 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
971 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
973 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
974 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
981 * Set Min hardware link rate.
983 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
984 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
985 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
987 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
988 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
995 * Set Min programmed link rate.
997 switch (phy_info->programmed_link_rate &
998 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
999 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1000 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1002 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1003 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1010 phy->local_attached = 1;
1012 error = sas_phy_add(phy);
1017 phy_info->phy = phy;
1019 if (phy_info->attached.handle) {
1020 struct sas_rphy *rphy;
1022 rphy = sas_rphy_alloc(phy);
1024 return 0; /* non-fatal: an rphy can be added later */
1026 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1027 error = sas_rphy_add(rphy);
1029 sas_rphy_free(rphy);
1033 phy_info->rphy = rphy;
1040 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1042 struct mptsas_portinfo *port_info;
1043 u32 handle = 0xFFFF;
1044 int error = -ENOMEM, i;
1046 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1050 error = mptsas_sas_io_unit_pg0(ioc, port_info);
1052 goto out_free_port_info;
1054 mutex_lock(&ioc->sas_topology_mutex);
1055 list_add_tail(&port_info->list, &ioc->sas_topology);
1056 mutex_unlock(&ioc->sas_topology_mutex);
1058 for (i = 0; i < port_info->num_phys; i++) {
1059 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1060 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1061 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1063 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1064 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
1065 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
1066 port_info->phy_info[i].identify.phy_id =
1067 port_info->phy_info[i].phy_id;
1068 handle = port_info->phy_info[i].identify.handle;
1070 if (port_info->phy_info[i].attached.handle) {
1071 mptsas_sas_device_pg0(ioc,
1072 &port_info->phy_info[i].attached,
1073 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1074 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1075 port_info->phy_info[i].attached.handle);
1078 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1079 &port_info->phy_info[i], *index, 1);
1092 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1094 struct mptsas_portinfo *port_info, *p;
1095 int error = -ENOMEM, i, j;
1097 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1101 error = mptsas_sas_expander_pg0(ioc, port_info,
1102 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1103 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1105 goto out_free_port_info;
1107 *handle = port_info->handle;
1109 mutex_lock(&ioc->sas_topology_mutex);
1110 list_add_tail(&port_info->list, &ioc->sas_topology);
1111 mutex_unlock(&ioc->sas_topology_mutex);
1113 for (i = 0; i < port_info->num_phys; i++) {
1114 struct device *parent;
1116 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
1117 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
1118 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
1120 if (port_info->phy_info[i].identify.handle) {
1121 mptsas_sas_device_pg0(ioc,
1122 &port_info->phy_info[i].identify,
1123 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1124 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1125 port_info->phy_info[i].identify.handle);
1126 port_info->phy_info[i].identify.phy_id =
1127 port_info->phy_info[i].phy_id;
1130 if (port_info->phy_info[i].attached.handle) {
1131 mptsas_sas_device_pg0(ioc,
1132 &port_info->phy_info[i].attached,
1133 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1134 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1135 port_info->phy_info[i].attached.handle);
1139 * If we find a parent port handle this expander is
1140 * attached to another expander, else it hangs of the
1143 parent = &ioc->sh->shost_gendev;
1144 mutex_lock(&ioc->sas_topology_mutex);
1145 list_for_each_entry(p, &ioc->sas_topology, list) {
1146 for (j = 0; j < p->num_phys; j++) {
1147 if (port_info->phy_info[i].identify.handle ==
1148 p->phy_info[j].attached.handle)
1149 parent = &p->phy_info[j].rphy->dev;
1152 mutex_unlock(&ioc->sas_topology_mutex);
1154 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1168 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1170 u32 handle = 0xFFFF;
1173 mptsas_probe_hba_phys(ioc, &index);
1174 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1178 static struct mptsas_phyinfo *
1179 mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1181 struct mptsas_portinfo *port_info;
1182 struct mptsas_devinfo device_info;
1183 struct mptsas_phyinfo *phy_info = NULL;
1187 * Retrieve the parent sas_address
1189 error = mptsas_sas_device_pg0(ioc, &device_info,
1190 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1191 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1194 printk("mptsas: failed to retrieve device page\n");
1199 * The phy_info structures are never deallocated during lifetime of
1200 * a host, so the code below is safe without additional refcounting.
1202 mutex_lock(&ioc->sas_topology_mutex);
1203 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1204 for (i = 0; i < port_info->num_phys; i++) {
1205 if (port_info->phy_info[i].identify.sas_address ==
1206 device_info.sas_address &&
1207 port_info->phy_info[i].phy_id == phy_id) {
1208 phy_info = &port_info->phy_info[i];
1213 mutex_unlock(&ioc->sas_topology_mutex);
1218 static struct mptsas_phyinfo *
1219 mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
1221 struct mptsas_portinfo *port_info;
1222 struct mptsas_phyinfo *phy_info = NULL;
1226 * The phy_info structures are never deallocated during lifetime of
1227 * a host, so the code below is safe without additional refcounting.
1229 mutex_lock(&ioc->sas_topology_mutex);
1230 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1231 for (i = 0; i < port_info->num_phys; i++) {
1232 if (port_info->phy_info[i].attached.handle == handle) {
1233 phy_info = &port_info->phy_info[i];
1238 mutex_unlock(&ioc->sas_topology_mutex);
1244 mptsas_hotplug_work(void *arg)
1246 struct mptsas_hotplug_event *ev = arg;
1247 MPT_ADAPTER *ioc = ev->ioc;
1248 struct mptsas_phyinfo *phy_info;
1249 struct sas_rphy *rphy;
1252 if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1254 if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1256 if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1259 switch (ev->event_type) {
1260 case MPTSAS_DEL_DEVICE:
1261 printk(MYIOC_s_INFO_FMT
1262 "removing %s device, channel %d, id %d, phy %d\n",
1263 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1265 phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
1267 printk("mptsas: remove event for non-existant PHY.\n");
1271 if (phy_info->rphy) {
1272 sas_rphy_delete(phy_info->rphy);
1273 phy_info->rphy = NULL;
1276 case MPTSAS_ADD_DEVICE:
1277 printk(MYIOC_s_INFO_FMT
1278 "attaching %s device, channel %d, id %d, phy %d\n",
1279 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1281 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1282 ev->parent_handle, ev->phy_id);
1284 printk("mptsas: add event for non-existant PHY.\n");
1288 if (phy_info->rphy) {
1289 printk("mptsas: trying to add existing device.\n");
1293 /* fill attached info */
1294 phy_info->attached.handle = ev->handle;
1295 phy_info->attached.phy_id = ev->phy_id;
1296 phy_info->attached.port_id = phy_info->identify.port_id;
1297 phy_info->attached.id = ev->id;
1298 phy_info->attached.channel = ev->channel;
1299 phy_info->attached.sas_address = ev->sas_address;
1300 phy_info->attached.device_info = ev->device_info;
1302 rphy = sas_rphy_alloc(phy_info->phy);
1304 break; /* non-fatal: an rphy can be added later */
1306 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1307 if (sas_rphy_add(rphy)) {
1308 sas_rphy_free(rphy);
1312 phy_info->rphy = rphy;
1320 mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1321 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1323 struct mptsas_hotplug_event *ev;
1324 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1328 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1329 MPI_SAS_DEVICE_INFO_STP_TARGET |
1330 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1333 if ((sas_event_data->ReasonCode &
1334 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
1335 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
1338 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1340 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1345 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1347 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1348 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1349 ev->channel = sas_event_data->Bus;
1350 ev->id = sas_event_data->TargetID;
1351 ev->phy_id = sas_event_data->PhyNum;
1352 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1353 ev->sas_address = le64_to_cpu(sas_address);
1354 ev->device_info = device_info;
1356 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1357 ev->event_type = MPTSAS_ADD_DEVICE;
1359 ev->event_type = MPTSAS_DEL_DEVICE;
1361 schedule_work(&ev->work);
1365 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1367 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1373 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1374 mptscsih_send_sas_event(ioc,
1375 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1376 return 1; /* currently means nothing really */
1379 return mptscsih_event_process(ioc, reply);
1384 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1386 struct Scsi_Host *sh;
1389 unsigned long flags;
1397 r = mpt_attach(pdev,id);
1401 ioc = pci_get_drvdata(pdev);
1402 ioc->DoneCtx = mptsasDoneCtx;
1403 ioc->TaskCtx = mptsasTaskCtx;
1404 ioc->InternalCtx = mptsasInternalCtx;
1406 /* Added sanity check on readiness of the MPT adapter.
1408 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1409 printk(MYIOC_s_WARN_FMT
1410 "Skipping because it's not operational!\n",
1413 goto out_mptsas_probe;
1417 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1420 goto out_mptsas_probe;
1423 /* Sanity check - ensure at least 1 port is INITIATOR capable
1426 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1427 if (ioc->pfacts[ii].ProtocolFlags &
1428 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1433 printk(MYIOC_s_WARN_FMT
1434 "Skipping ioc=%p because SCSI Initiator mode "
1435 "is NOT enabled!\n", ioc->name, ioc);
1439 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1441 printk(MYIOC_s_WARN_FMT
1442 "Unable to register controller with SCSI subsystem\n",
1445 goto out_mptsas_probe;
1448 spin_lock_irqsave(&ioc->FreeQlock, flags);
1450 /* Attach the SCSI Host to the IOC structure
1458 /* set 16 byte cdb's */
1459 sh->max_cmd_len = 16;
1461 sh->max_id = ioc->pfacts->MaxDevices + 1;
1463 sh->transportt = mptsas_transport_template;
1465 sh->max_lun = MPT_LAST_LUN + 1;
1466 sh->max_channel = 0;
1467 sh->this_id = ioc->pfacts[0].PortSCSIID;
1471 sh->unique_id = ioc->id;
1473 INIT_LIST_HEAD(&ioc->sas_topology);
1474 mutex_init(&ioc->sas_topology_mutex);
1476 mutex_init(&ioc->sas_mgmt.mutex);
1477 init_completion(&ioc->sas_mgmt.done);
1479 /* Verify that we won't exceed the maximum
1480 * number of chain buffers
1481 * We can optimize: ZZ = req_sz/sizeof(SGE)
1483 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1484 * + (req_sz - 64)/sizeof(SGE)
1485 * A slightly different algorithm is required for
1488 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1489 if (sizeof(dma_addr_t) == sizeof(u64)) {
1490 numSGE = (scale - 1) *
1491 (ioc->facts.MaxChainDepth-1) + scale +
1492 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1495 numSGE = 1 + (scale - 1) *
1496 (ioc->facts.MaxChainDepth-1) + scale +
1497 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1501 if (numSGE < sh->sg_tablesize) {
1502 /* Reset this value */
1503 dprintk((MYIOC_s_INFO_FMT
1504 "Resetting sg_tablesize to %d from %d\n",
1505 ioc->name, numSGE, sh->sg_tablesize));
1506 sh->sg_tablesize = numSGE;
1509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1511 hd = (MPT_SCSI_HOST *) sh->hostdata;
1514 /* SCSI needs scsi_cmnd lookup table!
1515 * (with size equal to req_depth*PtrSz!)
1517 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1518 if (!hd->ScsiLookup) {
1520 goto out_mptsas_probe;
1523 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1524 ioc->name, hd->ScsiLookup));
1526 /* Allocate memory for the device structures.
1527 * A non-Null pointer at an offset
1528 * indicates a device exists.
1529 * max_id = 1 + maximum id (hosts.h)
1531 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1534 goto out_mptsas_probe;
1537 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
1539 /* Clear the TM flags
1542 hd->tmState = TM_STATE_NONE;
1543 hd->resetPending = 0;
1544 hd->abortSCpnt = NULL;
1546 /* Clear the pointer used to store
1547 * single-threaded commands, i.e., those
1548 * issued during a bus scan, dv and
1549 * configuration pages.
1553 /* Initialize this SCSI Hosts' timers
1554 * To use, set the timer expires field
1557 init_timer(&hd->timer);
1558 hd->timer.data = (unsigned long) hd;
1559 hd->timer.function = mptscsih_timer_expired;
1561 hd->mpt_pq_filter = mpt_pq_filter;
1562 ioc->sas_data.ptClear = mpt_pt_clear;
1564 if (ioc->sas_data.ptClear==1) {
1565 mptbase_sas_persist_operation(
1566 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1569 ddvprintk((MYIOC_s_INFO_FMT
1570 "mpt_pq_filter %x mpt_pq_filter %x\n",
1575 init_waitqueue_head(&hd->scandv_waitq);
1576 hd->scandv_wait_done = 0;
1577 hd->last_queue_full = 0;
1579 error = scsi_add_host(sh, &ioc->pcidev->dev);
1581 dprintk((KERN_ERR MYNAM
1582 "scsi_add_host failed\n"));
1583 goto out_mptsas_probe;
1586 mptsas_scan_sas_topology(ioc);
1592 mptscsih_remove(pdev);
1596 static void __devexit mptsas_remove(struct pci_dev *pdev)
1598 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1599 struct mptsas_portinfo *p, *n;
1601 sas_remove_host(ioc->sh);
1603 mutex_lock(&ioc->sas_topology_mutex);
1604 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1608 mutex_unlock(&ioc->sas_topology_mutex);
1610 mptscsih_remove(pdev);
1613 static struct pci_device_id mptsas_pci_table[] = {
1614 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1615 PCI_ANY_ID, PCI_ANY_ID },
1616 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1617 PCI_ANY_ID, PCI_ANY_ID },
1618 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1619 PCI_ANY_ID, PCI_ANY_ID },
1620 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1621 PCI_ANY_ID, PCI_ANY_ID },
1622 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1623 PCI_ANY_ID, PCI_ANY_ID },
1624 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1625 PCI_ANY_ID, PCI_ANY_ID },
1626 {0} /* Terminating entry */
1628 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1631 static struct pci_driver mptsas_driver = {
1633 .id_table = mptsas_pci_table,
1634 .probe = mptsas_probe,
1635 .remove = __devexit_p(mptsas_remove),
1636 .shutdown = mptscsih_shutdown,
1638 .suspend = mptscsih_suspend,
1639 .resume = mptscsih_resume,
1646 show_mptmod_ver(my_NAME, my_VERSION);
1648 mptsas_transport_template =
1649 sas_attach_transport(&mptsas_transport_functions);
1650 if (!mptsas_transport_template)
1653 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1654 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1656 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1657 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1659 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1660 devtprintk((KERN_INFO MYNAM
1661 ": Registered for IOC event notifications\n"));
1664 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1665 dprintk((KERN_INFO MYNAM
1666 ": Registered for IOC reset notifications\n"));
1669 return pci_register_driver(&mptsas_driver);
1675 pci_unregister_driver(&mptsas_driver);
1676 sas_release_transport(mptsas_transport_template);
1678 mpt_reset_deregister(mptsasDoneCtx);
1679 mpt_event_deregister(mptsasDoneCtx);
1681 mpt_deregister(mptsasMgmtCtx);
1682 mpt_deregister(mptsasInternalCtx);
1683 mpt_deregister(mptsasTaskCtx);
1684 mpt_deregister(mptsasDoneCtx);
1687 module_init(mptsas_init);
1688 module_exit(mptsas_exit);