[PATCH] usbcore: Improve endpoint sysfs file handling
[linux/fpc-iii.git] / drivers / message / fusion / mptsas.c
blob7de19a84dc745dd2ea4199ffef4f17f79397d65a
1 /*
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
9 */
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.
21 NO WARRANTY
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>
59 #include "mptbase.h"
60 #include "mptscsih.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 "
75 "(default=0)");
77 static int mpt_pt_clear;
78 module_param(mpt_pt_clear, int, 0);
79 MODULE_PARM_DESC(mpt_pt_clear,
80 "Clear persistency table: enable=1 "
81 "(default=MPTSCSIH_PT_CLEAR=0)");
83 static int mptsasDoneCtx = -1;
84 static int mptsasTaskCtx = -1;
85 static int mptsasInternalCtx = -1; /* Used only for internal commands */
89 * SAS topology structures
91 * The MPT Fusion firmware interface spreads information about the
92 * SAS topology over many manufacture pages, thus we need some data
93 * structure to collect it and process it for the SAS transport class.
96 struct mptsas_devinfo {
97 u16 handle; /* unique id to address this device */
98 u8 phy_id; /* phy number of parent device */
99 u8 port_id; /* sas physical port this device
100 is assoc'd with */
101 u8 target; /* logical target id of this device */
102 u8 bus; /* logical bus number of this device */
103 u64 sas_address; /* WWN of this device,
104 SATA is assigned by HBA,expander */
105 u32 device_info; /* bitfield detailed info about this device */
108 struct mptsas_phyinfo {
109 u8 phy_id; /* phy index */
110 u8 port_id; /* port number this phy is part of */
111 u8 negotiated_link_rate; /* nego'd link rate for this phy */
112 u8 hw_link_rate; /* hardware max/min phys link rate */
113 u8 programmed_link_rate; /* programmed max/min phy link rate */
114 struct mptsas_devinfo identify; /* point to phy device info */
115 struct mptsas_devinfo attached; /* point to attached device info */
116 struct sas_rphy *rphy;
119 struct mptsas_portinfo {
120 struct list_head list;
121 u16 handle; /* unique id to address this */
122 u8 num_phys; /* number of phys */
123 struct mptsas_phyinfo *phy_info;
127 * This is pretty ugly. We will be able to seriously clean it up
128 * once the DV code in mptscsih goes away and we can properly
129 * implement ->target_alloc.
131 static int
132 mptsas_slave_alloc(struct scsi_device *device)
134 struct Scsi_Host *host = device->host;
135 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
136 struct sas_rphy *rphy;
137 struct mptsas_portinfo *p;
138 VirtDevice *vdev;
139 uint target = device->id;
140 int i;
142 if ((vdev = hd->Targets[target]) != NULL)
143 goto out;
145 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
146 if (!vdev) {
147 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
148 hd->ioc->name, sizeof(VirtDevice));
149 return -ENOMEM;
152 memset(vdev, 0, sizeof(VirtDevice));
153 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
154 vdev->ioc_id = hd->ioc->id;
156 rphy = dev_to_rphy(device->sdev_target->dev.parent);
157 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
158 for (i = 0; i < p->num_phys; i++) {
159 if (p->phy_info[i].attached.sas_address ==
160 rphy->identify.sas_address) {
161 vdev->target_id =
162 p->phy_info[i].attached.target;
163 vdev->bus_id = p->phy_info[i].attached.bus;
164 hd->Targets[device->id] = vdev;
165 goto out;
170 printk("No matching SAS device found!!\n");
171 kfree(vdev);
172 return -ENODEV;
174 out:
175 vdev->num_luns++;
176 device->hostdata = vdev;
177 return 0;
180 static struct scsi_host_template mptsas_driver_template = {
181 .proc_name = "mptsas",
182 .proc_info = mptscsih_proc_info,
183 .name = "MPT SPI Host",
184 .info = mptscsih_info,
185 .queuecommand = mptscsih_qcmd,
186 .slave_alloc = mptsas_slave_alloc,
187 .slave_configure = mptscsih_slave_configure,
188 .slave_destroy = mptscsih_slave_destroy,
189 .change_queue_depth = mptscsih_change_queue_depth,
190 .eh_abort_handler = mptscsih_abort,
191 .eh_device_reset_handler = mptscsih_dev_reset,
192 .eh_bus_reset_handler = mptscsih_bus_reset,
193 .eh_host_reset_handler = mptscsih_host_reset,
194 .bios_param = mptscsih_bios_param,
195 .can_queue = MPT_FC_CAN_QUEUE,
196 .this_id = -1,
197 .sg_tablesize = MPT_SCSI_SG_DEPTH,
198 .max_sectors = 8192,
199 .cmd_per_lun = 7,
200 .use_clustering = ENABLE_CLUSTERING,
203 static struct sas_function_template mptsas_transport_functions = {
206 static struct scsi_transport_template *mptsas_transport_template;
208 #ifdef SASDEBUG
209 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
211 printk("---- IO UNIT PAGE 0 ------------\n");
212 printk("Handle=0x%X\n",
213 le16_to_cpu(phy_data->AttachedDeviceHandle));
214 printk("Controller Handle=0x%X\n",
215 le16_to_cpu(phy_data->ControllerDevHandle));
216 printk("Port=0x%X\n", phy_data->Port);
217 printk("Port Flags=0x%X\n", phy_data->PortFlags);
218 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
219 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
220 printk("Controller PHY Device Info=0x%X\n",
221 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
222 printk("DiscoveryStatus=0x%X\n",
223 le32_to_cpu(phy_data->DiscoveryStatus));
224 printk("\n");
227 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
229 __le64 sas_address;
231 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
233 printk("---- SAS PHY PAGE 0 ------------\n");
234 printk("Attached Device Handle=0x%X\n",
235 le16_to_cpu(pg0->AttachedDevHandle));
236 printk("SAS Address=0x%llX\n",
237 (unsigned long long)le64_to_cpu(sas_address));
238 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
239 printk("Attached Device Info=0x%X\n",
240 le32_to_cpu(pg0->AttachedDeviceInfo));
241 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
242 printk("Change Count=0x%X\n", pg0->ChangeCount);
243 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
244 printk("\n");
247 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
249 __le64 sas_address;
251 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
253 printk("---- SAS DEVICE PAGE 0 ---------\n");
254 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
255 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
256 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
257 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
258 printk("Target ID=0x%X\n", pg0->TargetID);
259 printk("Bus=0x%X\n", pg0->Bus);
260 printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
261 printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
262 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
263 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
264 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
265 printk("\n");
268 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
270 printk("---- SAS EXPANDER PAGE 1 ------------\n");
272 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
273 printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
274 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
275 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
276 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
277 printk("Owner Device Handle=0x%X\n",
278 le16_to_cpu(pg1->OwnerDevHandle));
279 printk("Attached Device Handle=0x%X\n",
280 le16_to_cpu(pg1->AttachedDevHandle));
282 #else
283 #define mptsas_print_phy_data(phy_data) do { } while (0)
284 #define mptsas_print_phy_pg0(pg0) do { } while (0)
285 #define mptsas_print_device_pg0(pg0) do { } while (0)
286 #define mptsas_print_expander_pg1(pg1) do { } while (0)
287 #endif
289 static int
290 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
292 ConfigExtendedPageHeader_t hdr;
293 CONFIGPARMS cfg;
294 SasIOUnitPage0_t *buffer;
295 dma_addr_t dma_handle;
296 int error, i;
298 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
299 hdr.ExtPageLength = 0;
300 hdr.PageNumber = 0;
301 hdr.Reserved1 = 0;
302 hdr.Reserved2 = 0;
303 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
304 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
306 cfg.cfghdr.ehdr = &hdr;
307 cfg.physAddr = -1;
308 cfg.pageAddr = 0;
309 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
310 cfg.dir = 0; /* read */
311 cfg.timeout = 10;
313 error = mpt_config(ioc, &cfg);
314 if (error)
315 goto out;
316 if (!hdr.ExtPageLength) {
317 error = -ENXIO;
318 goto out;
321 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
322 &dma_handle);
323 if (!buffer) {
324 error = -ENOMEM;
325 goto out;
328 cfg.physAddr = dma_handle;
329 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
331 error = mpt_config(ioc, &cfg);
332 if (error)
333 goto out_free_consistent;
335 port_info->num_phys = buffer->NumPhys;
336 port_info->phy_info = kcalloc(port_info->num_phys,
337 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
338 if (!port_info->phy_info) {
339 error = -ENOMEM;
340 goto out_free_consistent;
343 for (i = 0; i < port_info->num_phys; i++) {
344 mptsas_print_phy_data(&buffer->PhyData[i]);
345 port_info->phy_info[i].phy_id = i;
346 port_info->phy_info[i].port_id =
347 buffer->PhyData[i].Port;
348 port_info->phy_info[i].negotiated_link_rate =
349 buffer->PhyData[i].NegotiatedLinkRate;
352 out_free_consistent:
353 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
354 buffer, dma_handle);
355 out:
356 return error;
359 static int
360 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
361 u32 form, u32 form_specific)
363 ConfigExtendedPageHeader_t hdr;
364 CONFIGPARMS cfg;
365 SasPhyPage0_t *buffer;
366 dma_addr_t dma_handle;
367 int error;
369 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
370 hdr.ExtPageLength = 0;
371 hdr.PageNumber = 0;
372 hdr.Reserved1 = 0;
373 hdr.Reserved2 = 0;
374 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
375 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
377 cfg.cfghdr.ehdr = &hdr;
378 cfg.dir = 0; /* read */
379 cfg.timeout = 10;
381 /* Get Phy Pg 0 for each Phy. */
382 cfg.physAddr = -1;
383 cfg.pageAddr = form + form_specific;
384 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
386 error = mpt_config(ioc, &cfg);
387 if (error)
388 goto out;
390 if (!hdr.ExtPageLength) {
391 error = -ENXIO;
392 goto out;
395 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
396 &dma_handle);
397 if (!buffer) {
398 error = -ENOMEM;
399 goto out;
402 cfg.physAddr = dma_handle;
403 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
405 error = mpt_config(ioc, &cfg);
406 if (error)
407 goto out_free_consistent;
409 mptsas_print_phy_pg0(buffer);
411 phy_info->hw_link_rate = buffer->HwLinkRate;
412 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
413 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
414 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
416 out_free_consistent:
417 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
418 buffer, dma_handle);
419 out:
420 return error;
423 static int
424 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
425 u32 form, u32 form_specific)
427 ConfigExtendedPageHeader_t hdr;
428 CONFIGPARMS cfg;
429 SasDevicePage0_t *buffer;
430 dma_addr_t dma_handle;
431 __le64 sas_address;
432 int error;
434 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
435 hdr.ExtPageLength = 0;
436 hdr.PageNumber = 0;
437 hdr.Reserved1 = 0;
438 hdr.Reserved2 = 0;
439 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
440 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
442 cfg.cfghdr.ehdr = &hdr;
443 cfg.pageAddr = form + form_specific;
444 cfg.physAddr = -1;
445 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
446 cfg.dir = 0; /* read */
447 cfg.timeout = 10;
449 error = mpt_config(ioc, &cfg);
450 if (error)
451 goto out;
452 if (!hdr.ExtPageLength) {
453 error = -ENXIO;
454 goto out;
457 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
458 &dma_handle);
459 if (!buffer) {
460 error = -ENOMEM;
461 goto out;
464 cfg.physAddr = dma_handle;
465 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
467 error = mpt_config(ioc, &cfg);
468 if (error)
469 goto out_free_consistent;
471 mptsas_print_device_pg0(buffer);
473 device_info->handle = le16_to_cpu(buffer->DevHandle);
474 device_info->phy_id = buffer->PhyNum;
475 device_info->port_id = buffer->PhysicalPort;
476 device_info->target = buffer->TargetID;
477 device_info->bus = buffer->Bus;
478 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
479 device_info->sas_address = le64_to_cpu(sas_address);
480 device_info->device_info =
481 le32_to_cpu(buffer->DeviceInfo);
483 out_free_consistent:
484 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
485 buffer, dma_handle);
486 out:
487 return error;
490 static int
491 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
492 u32 form, u32 form_specific)
494 ConfigExtendedPageHeader_t hdr;
495 CONFIGPARMS cfg;
496 SasExpanderPage0_t *buffer;
497 dma_addr_t dma_handle;
498 int error;
500 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
501 hdr.ExtPageLength = 0;
502 hdr.PageNumber = 0;
503 hdr.Reserved1 = 0;
504 hdr.Reserved2 = 0;
505 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
506 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
508 cfg.cfghdr.ehdr = &hdr;
509 cfg.physAddr = -1;
510 cfg.pageAddr = form + form_specific;
511 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
512 cfg.dir = 0; /* read */
513 cfg.timeout = 10;
515 error = mpt_config(ioc, &cfg);
516 if (error)
517 goto out;
519 if (!hdr.ExtPageLength) {
520 error = -ENXIO;
521 goto out;
524 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
525 &dma_handle);
526 if (!buffer) {
527 error = -ENOMEM;
528 goto out;
531 cfg.physAddr = dma_handle;
532 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
534 error = mpt_config(ioc, &cfg);
535 if (error)
536 goto out_free_consistent;
538 /* save config data */
539 port_info->num_phys = buffer->NumPhys;
540 port_info->handle = le16_to_cpu(buffer->DevHandle);
541 port_info->phy_info = kcalloc(port_info->num_phys,
542 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
543 if (!port_info->phy_info) {
544 error = -ENOMEM;
545 goto out_free_consistent;
548 out_free_consistent:
549 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
550 buffer, dma_handle);
551 out:
552 return error;
555 static int
556 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
557 u32 form, u32 form_specific)
559 ConfigExtendedPageHeader_t hdr;
560 CONFIGPARMS cfg;
561 SasExpanderPage1_t *buffer;
562 dma_addr_t dma_handle;
563 int error;
565 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
566 hdr.ExtPageLength = 0;
567 hdr.PageNumber = 1;
568 hdr.Reserved1 = 0;
569 hdr.Reserved2 = 0;
570 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
571 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
573 cfg.cfghdr.ehdr = &hdr;
574 cfg.physAddr = -1;
575 cfg.pageAddr = form + form_specific;
576 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
577 cfg.dir = 0; /* read */
578 cfg.timeout = 10;
580 error = mpt_config(ioc, &cfg);
581 if (error)
582 goto out;
584 if (!hdr.ExtPageLength) {
585 error = -ENXIO;
586 goto out;
589 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
590 &dma_handle);
591 if (!buffer) {
592 error = -ENOMEM;
593 goto out;
596 cfg.physAddr = dma_handle;
597 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
599 error = mpt_config(ioc, &cfg);
600 if (error)
601 goto out_free_consistent;
604 mptsas_print_expander_pg1(buffer);
606 /* save config data */
607 phy_info->phy_id = buffer->PhyIdentifier;
608 phy_info->port_id = buffer->PhysicalPort;
609 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
610 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
611 phy_info->hw_link_rate = buffer->HwLinkRate;
612 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
613 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
616 out_free_consistent:
617 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
618 buffer, dma_handle);
619 out:
620 return error;
623 static void
624 mptsas_parse_device_info(struct sas_identify *identify,
625 struct mptsas_devinfo *device_info)
627 u16 protocols;
629 identify->sas_address = device_info->sas_address;
630 identify->phy_identifier = device_info->phy_id;
633 * Fill in Phy Initiator Port Protocol.
634 * Bits 6:3, more than one bit can be set, fall through cases.
636 protocols = device_info->device_info & 0x78;
637 identify->initiator_port_protocols = 0;
638 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
639 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
640 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
641 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
642 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
643 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
644 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
645 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
648 * Fill in Phy Target Port Protocol.
649 * Bits 10:7, more than one bit can be set, fall through cases.
651 protocols = device_info->device_info & 0x780;
652 identify->target_port_protocols = 0;
653 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
654 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
655 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
656 identify->target_port_protocols |= SAS_PROTOCOL_STP;
657 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
658 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
659 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
660 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
663 * Fill in Attached device type.
665 switch (device_info->device_info &
666 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
667 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
668 identify->device_type = SAS_PHY_UNUSED;
669 break;
670 case MPI_SAS_DEVICE_INFO_END_DEVICE:
671 identify->device_type = SAS_END_DEVICE;
672 break;
673 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
674 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
675 break;
676 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
677 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
678 break;
682 static int mptsas_probe_one_phy(struct device *dev,
683 struct mptsas_phyinfo *phy_info, int index)
685 struct sas_phy *port;
686 int error;
688 port = sas_phy_alloc(dev, index);
689 if (!port)
690 return -ENOMEM;
692 port->port_identifier = phy_info->port_id;
693 mptsas_parse_device_info(&port->identify, &phy_info->identify);
696 * Set Negotiated link rate.
698 switch (phy_info->negotiated_link_rate) {
699 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
700 port->negotiated_linkrate = SAS_PHY_DISABLED;
701 break;
702 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
703 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
704 break;
705 case MPI_SAS_IOUNIT0_RATE_1_5:
706 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
707 break;
708 case MPI_SAS_IOUNIT0_RATE_3_0:
709 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
710 break;
711 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
712 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
713 default:
714 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
715 break;
719 * Set Max hardware link rate.
721 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
722 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
723 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
724 break;
725 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
726 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
727 break;
728 default:
729 break;
733 * Set Max programmed link rate.
735 switch (phy_info->programmed_link_rate &
736 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
737 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
738 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
739 break;
740 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
741 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
742 break;
743 default:
744 break;
748 * Set Min hardware link rate.
750 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
751 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
752 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
753 break;
754 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
755 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
756 break;
757 default:
758 break;
762 * Set Min programmed link rate.
764 switch (phy_info->programmed_link_rate &
765 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
766 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
767 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
768 break;
769 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
770 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
771 break;
772 default:
773 break;
776 error = sas_phy_add(port);
777 if (error) {
778 sas_phy_free(port);
779 return error;
782 if (phy_info->attached.handle) {
783 struct sas_rphy *rphy;
785 rphy = sas_rphy_alloc(port);
786 if (!rphy)
787 return 0; /* non-fatal: an rphy can be added later */
789 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
790 error = sas_rphy_add(rphy);
791 if (error) {
792 sas_rphy_free(rphy);
793 return error;
796 phy_info->rphy = rphy;
799 return 0;
802 static int
803 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
805 struct mptsas_portinfo *port_info;
806 u32 handle = 0xFFFF;
807 int error = -ENOMEM, i;
809 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
810 if (!port_info)
811 goto out;
812 memset(port_info, 0, sizeof(*port_info));
814 error = mptsas_sas_io_unit_pg0(ioc, port_info);
815 if (error)
816 goto out_free_port_info;
818 list_add_tail(&port_info->list, &ioc->sas_topology);
820 for (i = 0; i < port_info->num_phys; i++) {
821 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
822 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
823 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
825 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
826 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
827 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
828 port_info->phy_info[i].identify.phy_id =
829 port_info->phy_info[i].phy_id;
830 handle = port_info->phy_info[i].identify.handle;
832 if (port_info->phy_info[i].attached.handle) {
833 mptsas_sas_device_pg0(ioc,
834 &port_info->phy_info[i].attached,
835 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
836 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
837 port_info->phy_info[i].attached.handle);
840 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
841 &port_info->phy_info[i], *index);
842 (*index)++;
845 return 0;
847 out_free_port_info:
848 kfree(port_info);
849 out:
850 return error;
853 static int
854 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
856 struct mptsas_portinfo *port_info, *p;
857 int error = -ENOMEM, i, j;
859 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
860 if (!port_info)
861 goto out;
862 memset(port_info, 0, sizeof(*port_info));
864 error = mptsas_sas_expander_pg0(ioc, port_info,
865 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
866 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
867 if (error)
868 goto out_free_port_info;
870 *handle = port_info->handle;
872 list_add_tail(&port_info->list, &ioc->sas_topology);
873 for (i = 0; i < port_info->num_phys; i++) {
874 struct device *parent;
876 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
877 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
878 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
880 if (port_info->phy_info[i].identify.handle) {
881 mptsas_sas_device_pg0(ioc,
882 &port_info->phy_info[i].identify,
883 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
884 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
885 port_info->phy_info[i].identify.handle);
886 port_info->phy_info[i].identify.phy_id =
887 port_info->phy_info[i].phy_id;
890 if (port_info->phy_info[i].attached.handle) {
891 mptsas_sas_device_pg0(ioc,
892 &port_info->phy_info[i].attached,
893 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
894 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
895 port_info->phy_info[i].attached.handle);
899 * If we find a parent port handle this expander is
900 * attached to another expander, else it hangs of the
901 * HBA phys.
903 parent = &ioc->sh->shost_gendev;
904 list_for_each_entry(p, &ioc->sas_topology, list) {
905 for (j = 0; j < p->num_phys; j++) {
906 if (port_info->phy_info[i].identify.handle ==
907 p->phy_info[j].attached.handle)
908 parent = &p->phy_info[j].rphy->dev;
912 mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
913 (*index)++;
916 return 0;
918 out_free_port_info:
919 kfree(port_info);
920 out:
921 return error;
924 static void
925 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
927 u32 handle = 0xFFFF;
928 int index = 0;
930 mptsas_probe_hba_phys(ioc, &index);
931 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
935 static int
936 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
938 struct Scsi_Host *sh;
939 MPT_SCSI_HOST *hd;
940 MPT_ADAPTER *ioc;
941 unsigned long flags;
942 int sz, ii;
943 int numSGE = 0;
944 int scale;
945 int ioc_cap;
946 u8 *mem;
947 int error=0;
948 int r;
950 r = mpt_attach(pdev,id);
951 if (r)
952 return r;
954 ioc = pci_get_drvdata(pdev);
955 ioc->DoneCtx = mptsasDoneCtx;
956 ioc->TaskCtx = mptsasTaskCtx;
957 ioc->InternalCtx = mptsasInternalCtx;
959 /* Added sanity check on readiness of the MPT adapter.
961 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
962 printk(MYIOC_s_WARN_FMT
963 "Skipping because it's not operational!\n",
964 ioc->name);
965 return -ENODEV;
968 if (!ioc->active) {
969 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
970 ioc->name);
971 return -ENODEV;
974 /* Sanity check - ensure at least 1 port is INITIATOR capable
976 ioc_cap = 0;
977 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
978 if (ioc->pfacts[ii].ProtocolFlags &
979 MPI_PORTFACTS_PROTOCOL_INITIATOR)
980 ioc_cap++;
983 if (!ioc_cap) {
984 printk(MYIOC_s_WARN_FMT
985 "Skipping ioc=%p because SCSI Initiator mode "
986 "is NOT enabled!\n", ioc->name, ioc);
987 return 0;
990 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
991 if (!sh) {
992 printk(MYIOC_s_WARN_FMT
993 "Unable to register controller with SCSI subsystem\n",
994 ioc->name);
995 return -1;
998 spin_lock_irqsave(&ioc->FreeQlock, flags);
1000 /* Attach the SCSI Host to the IOC structure
1002 ioc->sh = sh;
1004 sh->io_port = 0;
1005 sh->n_io_port = 0;
1006 sh->irq = 0;
1008 /* set 16 byte cdb's */
1009 sh->max_cmd_len = 16;
1011 sh->max_id = ioc->pfacts->MaxDevices + 1;
1013 sh->transportt = mptsas_transport_template;
1015 sh->max_lun = MPT_LAST_LUN + 1;
1016 sh->max_channel = 0;
1017 sh->this_id = ioc->pfacts[0].PortSCSIID;
1019 /* Required entry.
1021 sh->unique_id = ioc->id;
1023 INIT_LIST_HEAD(&ioc->sas_topology);
1025 /* Verify that we won't exceed the maximum
1026 * number of chain buffers
1027 * We can optimize: ZZ = req_sz/sizeof(SGE)
1028 * For 32bit SGE's:
1029 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1030 * + (req_sz - 64)/sizeof(SGE)
1031 * A slightly different algorithm is required for
1032 * 64bit SGEs.
1034 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1035 if (sizeof(dma_addr_t) == sizeof(u64)) {
1036 numSGE = (scale - 1) *
1037 (ioc->facts.MaxChainDepth-1) + scale +
1038 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1039 sizeof(u32));
1040 } else {
1041 numSGE = 1 + (scale - 1) *
1042 (ioc->facts.MaxChainDepth-1) + scale +
1043 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1044 sizeof(u32));
1047 if (numSGE < sh->sg_tablesize) {
1048 /* Reset this value */
1049 dprintk((MYIOC_s_INFO_FMT
1050 "Resetting sg_tablesize to %d from %d\n",
1051 ioc->name, numSGE, sh->sg_tablesize));
1052 sh->sg_tablesize = numSGE;
1055 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1057 hd = (MPT_SCSI_HOST *) sh->hostdata;
1058 hd->ioc = ioc;
1060 /* SCSI needs scsi_cmnd lookup table!
1061 * (with size equal to req_depth*PtrSz!)
1063 sz = ioc->req_depth * sizeof(void *);
1064 mem = kmalloc(sz, GFP_ATOMIC);
1065 if (mem == NULL) {
1066 error = -ENOMEM;
1067 goto mptsas_probe_failed;
1070 memset(mem, 0, sz);
1071 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1073 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1074 ioc->name, hd->ScsiLookup, sz));
1076 /* Allocate memory for the device structures.
1077 * A non-Null pointer at an offset
1078 * indicates a device exists.
1079 * max_id = 1 + maximum id (hosts.h)
1081 sz = sh->max_id * sizeof(void *);
1082 mem = kmalloc(sz, GFP_ATOMIC);
1083 if (mem == NULL) {
1084 error = -ENOMEM;
1085 goto mptsas_probe_failed;
1088 memset(mem, 0, sz);
1089 hd->Targets = (VirtDevice **) mem;
1091 dprintk((KERN_INFO
1092 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1094 /* Clear the TM flags
1096 hd->tmPending = 0;
1097 hd->tmState = TM_STATE_NONE;
1098 hd->resetPending = 0;
1099 hd->abortSCpnt = NULL;
1101 /* Clear the pointer used to store
1102 * single-threaded commands, i.e., those
1103 * issued during a bus scan, dv and
1104 * configuration pages.
1106 hd->cmdPtr = NULL;
1108 /* Initialize this SCSI Hosts' timers
1109 * To use, set the timer expires field
1110 * and add_timer
1112 init_timer(&hd->timer);
1113 hd->timer.data = (unsigned long) hd;
1114 hd->timer.function = mptscsih_timer_expired;
1116 hd->mpt_pq_filter = mpt_pq_filter;
1117 ioc->sas_data.ptClear = mpt_pt_clear;
1119 if (ioc->sas_data.ptClear==1) {
1120 mptbase_sas_persist_operation(
1121 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1124 ddvprintk((MYIOC_s_INFO_FMT
1125 "mpt_pq_filter %x mpt_pq_filter %x\n",
1126 ioc->name,
1127 mpt_pq_filter,
1128 mpt_pq_filter));
1130 init_waitqueue_head(&hd->scandv_waitq);
1131 hd->scandv_wait_done = 0;
1132 hd->last_queue_full = 0;
1134 error = scsi_add_host(sh, &ioc->pcidev->dev);
1135 if (error) {
1136 dprintk((KERN_ERR MYNAM
1137 "scsi_add_host failed\n"));
1138 goto mptsas_probe_failed;
1141 mptsas_scan_sas_topology(ioc);
1143 return 0;
1145 mptsas_probe_failed:
1147 mptscsih_remove(pdev);
1148 return error;
1151 static void __devexit mptsas_remove(struct pci_dev *pdev)
1153 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1154 struct mptsas_portinfo *p, *n;
1156 sas_remove_host(ioc->sh);
1158 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1159 list_del(&p->list);
1160 kfree(p);
1163 mptscsih_remove(pdev);
1166 static struct pci_device_id mptsas_pci_table[] = {
1167 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1168 PCI_ANY_ID, PCI_ANY_ID },
1169 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1170 PCI_ANY_ID, PCI_ANY_ID },
1171 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1172 PCI_ANY_ID, PCI_ANY_ID },
1173 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1174 PCI_ANY_ID, PCI_ANY_ID },
1175 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1176 PCI_ANY_ID, PCI_ANY_ID },
1177 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1178 PCI_ANY_ID, PCI_ANY_ID },
1179 {0} /* Terminating entry */
1181 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1184 static struct pci_driver mptsas_driver = {
1185 .name = "mptsas",
1186 .id_table = mptsas_pci_table,
1187 .probe = mptsas_probe,
1188 .remove = __devexit_p(mptsas_remove),
1189 .shutdown = mptscsih_shutdown,
1190 #ifdef CONFIG_PM
1191 .suspend = mptscsih_suspend,
1192 .resume = mptscsih_resume,
1193 #endif
1196 static int __init
1197 mptsas_init(void)
1199 show_mptmod_ver(my_NAME, my_VERSION);
1201 mptsas_transport_template =
1202 sas_attach_transport(&mptsas_transport_functions);
1203 if (!mptsas_transport_template)
1204 return -ENODEV;
1206 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1207 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1208 mptsasInternalCtx =
1209 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1211 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1212 devtprintk((KERN_INFO MYNAM
1213 ": Registered for IOC event notifications\n"));
1216 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1217 dprintk((KERN_INFO MYNAM
1218 ": Registered for IOC reset notifications\n"));
1221 return pci_register_driver(&mptsas_driver);
1224 static void __exit
1225 mptsas_exit(void)
1227 pci_unregister_driver(&mptsas_driver);
1228 sas_release_transport(mptsas_transport_template);
1230 mpt_reset_deregister(mptsasDoneCtx);
1231 mpt_event_deregister(mptsasDoneCtx);
1233 mpt_deregister(mptsasInternalCtx);
1234 mpt_deregister(mptsasTaskCtx);
1235 mpt_deregister(mptsasDoneCtx);
1238 module_init(mptsas_init);
1239 module_exit(mptsas_exit);