blob: dcdf0380be86e4dba183c86de0d404f33f3a62e8 [file] [log] [blame]
Christoph Hellwig0c33b272005-09-09 16:27:19 +02001/*
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.
5 *
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
8 * Copyright (c) 2005 Dell
9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/*
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.
15
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.
20
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.
31
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
40
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
44*/
45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
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>
53
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>
58
59#include "mptbase.h"
60#include "mptscsih.h"
61
62
63#define my_NAME "Fusion MPT SAS Host driver"
64#define my_VERSION MPT_LINUX_VERSION_COMMON
65#define MYNAM "mptsas"
66
67MODULE_AUTHOR(MODULEAUTHOR);
68MODULE_DESCRIPTION(my_NAME);
69MODULE_LICENSE("GPL");
70
71static int mpt_pq_filter;
72module_param(mpt_pq_filter, int, 0);
73MODULE_PARM_DESC(mpt_pq_filter,
74 "Enable peripheral qualifier filter: enable=1 "
75 "(default=0)");
76
77static int mpt_pt_clear;
78module_param(mpt_pt_clear, int, 0);
79MODULE_PARM_DESC(mpt_pt_clear,
80 "Clear persistency table: enable=1 "
81 "(default=MPTSCSIH_PT_CLEAR=0)");
82
83static int mptsasDoneCtx = -1;
84static int mptsasTaskCtx = -1;
85static int mptsasInternalCtx = -1; /* Used only for internal commands */
86
87
88/*
89 * SAS topology structures
90 *
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.
94 */
95
96struct 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 */
106};
107
108struct 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;
117};
118
119struct 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;
124};
125
Christoph Hellwigb5141122005-10-28 22:07:41 +0200126
127#ifdef SASDEBUG
128static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
129{
130 printk("---- IO UNIT PAGE 0 ------------\n");
131 printk("Handle=0x%X\n",
132 le16_to_cpu(phy_data->AttachedDeviceHandle));
133 printk("Controller Handle=0x%X\n",
134 le16_to_cpu(phy_data->ControllerDevHandle));
135 printk("Port=0x%X\n", phy_data->Port);
136 printk("Port Flags=0x%X\n", phy_data->PortFlags);
137 printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
138 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
139 printk("Controller PHY Device Info=0x%X\n",
140 le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
141 printk("DiscoveryStatus=0x%X\n",
142 le32_to_cpu(phy_data->DiscoveryStatus));
143 printk("\n");
144}
145
146static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
147{
148 __le64 sas_address;
149
150 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
151
152 printk("---- SAS PHY PAGE 0 ------------\n");
153 printk("Attached Device Handle=0x%X\n",
154 le16_to_cpu(pg0->AttachedDevHandle));
155 printk("SAS Address=0x%llX\n",
156 (unsigned long long)le64_to_cpu(sas_address));
157 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
158 printk("Attached Device Info=0x%X\n",
159 le32_to_cpu(pg0->AttachedDeviceInfo));
160 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
161 printk("Change Count=0x%X\n", pg0->ChangeCount);
162 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
163 printk("\n");
164}
165
166static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
167{
168 printk("---- SAS PHY PAGE 1 ------------\n");
169 printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
170 printk("Running Disparity Error Count=0x%x\n",
171 pg1->RunningDisparityErrorCount);
172 printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
173 printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
174 printk("\n");
175}
176
177static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
178{
179 __le64 sas_address;
180
181 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
182
183 printk("---- SAS DEVICE PAGE 0 ---------\n");
184 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
185 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
186 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
187 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
188 printk("Target ID=0x%X\n", pg0->TargetID);
189 printk("Bus=0x%X\n", pg0->Bus);
190 printk("PhyNum=0x%X\n", pg0->PhyNum);
191 printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus));
192 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
193 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
194 printk("Physical Port=0x%X\n", pg0->PhysicalPort);
195 printk("\n");
196}
197
198static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
199{
200 printk("---- SAS EXPANDER PAGE 1 ------------\n");
201
202 printk("Physical Port=0x%X\n", pg1->PhysicalPort);
203 printk("PHY Identifier=0x%X\n", pg1->Phy);
204 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
205 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
206 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
207 printk("Owner Device Handle=0x%X\n",
208 le16_to_cpu(pg1->OwnerDevHandle));
209 printk("Attached Device Handle=0x%X\n",
210 le16_to_cpu(pg1->AttachedDevHandle));
211}
212#else
213#define mptsas_print_phy_data(phy_data) do { } while (0)
214#define mptsas_print_phy_pg0(pg0) do { } while (0)
215#define mptsas_print_phy_pg1(pg1) do { } while (0)
216#define mptsas_print_device_pg0(pg0) do { } while (0)
217#define mptsas_print_expander_pg1(pg1) do { } while (0)
218#endif
219
220
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200221/*
222 * This is pretty ugly. We will be able to seriously clean it up
223 * once the DV code in mptscsih goes away and we can properly
224 * implement ->target_alloc.
225 */
226static int
227mptsas_slave_alloc(struct scsi_device *device)
228{
229 struct Scsi_Host *host = device->host;
230 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
231 struct sas_rphy *rphy;
232 struct mptsas_portinfo *p;
233 VirtDevice *vdev;
234 uint target = device->id;
235 int i;
236
237 if ((vdev = hd->Targets[target]) != NULL)
238 goto out;
239
240 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
241 if (!vdev) {
242 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
243 hd->ioc->name, sizeof(VirtDevice));
244 return -ENOMEM;
245 }
246
247 memset(vdev, 0, sizeof(VirtDevice));
248 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
249 vdev->ioc_id = hd->ioc->id;
250
251 rphy = dev_to_rphy(device->sdev_target->dev.parent);
252 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
253 for (i = 0; i < p->num_phys; i++) {
254 if (p->phy_info[i].attached.sas_address ==
255 rphy->identify.sas_address) {
256 vdev->target_id =
257 p->phy_info[i].attached.target;
258 vdev->bus_id = p->phy_info[i].attached.bus;
259 hd->Targets[device->id] = vdev;
260 goto out;
261 }
262 }
263 }
264
265 printk("No matching SAS device found!!\n");
266 kfree(vdev);
267 return -ENODEV;
268
269 out:
270 vdev->num_luns++;
271 device->hostdata = vdev;
272 return 0;
273}
274
275static struct scsi_host_template mptsas_driver_template = {
276 .proc_name = "mptsas",
277 .proc_info = mptscsih_proc_info,
278 .name = "MPT SPI Host",
279 .info = mptscsih_info,
280 .queuecommand = mptscsih_qcmd,
281 .slave_alloc = mptsas_slave_alloc,
282 .slave_configure = mptscsih_slave_configure,
283 .slave_destroy = mptscsih_slave_destroy,
284 .change_queue_depth = mptscsih_change_queue_depth,
285 .eh_abort_handler = mptscsih_abort,
286 .eh_device_reset_handler = mptscsih_dev_reset,
287 .eh_bus_reset_handler = mptscsih_bus_reset,
288 .eh_host_reset_handler = mptscsih_host_reset,
289 .bios_param = mptscsih_bios_param,
290 .can_queue = MPT_FC_CAN_QUEUE,
291 .this_id = -1,
292 .sg_tablesize = MPT_SCSI_SG_DEPTH,
293 .max_sectors = 8192,
294 .cmd_per_lun = 7,
295 .use_clustering = ENABLE_CLUSTERING,
296};
297
Christoph Hellwigb5141122005-10-28 22:07:41 +0200298static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
299{
300 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
301 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
302}
303
304static int mptsas_get_linkerrors(struct sas_phy *phy)
305{
306 MPT_ADAPTER *ioc = phy_to_ioc(phy);
307 ConfigExtendedPageHeader_t hdr;
308 CONFIGPARMS cfg;
309 SasPhyPage1_t *buffer;
310 dma_addr_t dma_handle;
311 int error;
312
313 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
314 hdr.ExtPageLength = 0;
315 hdr.PageNumber = 1 /* page number 1*/;
316 hdr.Reserved1 = 0;
317 hdr.Reserved2 = 0;
318 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
319 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
320
321 cfg.cfghdr.ehdr = &hdr;
322 cfg.physAddr = -1;
323 cfg.pageAddr = phy->identify.phy_identifier;
324 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
325 cfg.dir = 0; /* read */
326 cfg.timeout = 10;
327
328 error = mpt_config(ioc, &cfg);
329 if (error)
330 return error;
331 if (!hdr.ExtPageLength)
332 return -ENXIO;
333
334 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
335 &dma_handle);
336 if (!buffer)
337 return -ENOMEM;
338
339 cfg.physAddr = dma_handle;
340 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
341
342 error = mpt_config(ioc, &cfg);
343 if (error)
344 goto out_free_consistent;
345
346 mptsas_print_phy_pg1(buffer);
347
348 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
349 phy->running_disparity_error_count =
350 le32_to_cpu(buffer->RunningDisparityErrorCount);
351 phy->loss_of_dword_sync_count =
352 le32_to_cpu(buffer->LossDwordSynchCount);
353 phy->phy_reset_problem_count =
354 le32_to_cpu(buffer->PhyResetProblemCount);
355
356 out_free_consistent:
357 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
358 buffer, dma_handle);
359 return error;
360}
361
362
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200363static struct sas_function_template mptsas_transport_functions = {
Christoph Hellwigb5141122005-10-28 22:07:41 +0200364 .get_linkerrors = mptsas_get_linkerrors,
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200365};
366
367static struct scsi_transport_template *mptsas_transport_template;
368
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200369static int
370mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
371{
372 ConfigExtendedPageHeader_t hdr;
373 CONFIGPARMS cfg;
374 SasIOUnitPage0_t *buffer;
375 dma_addr_t dma_handle;
376 int error, i;
377
378 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
379 hdr.ExtPageLength = 0;
380 hdr.PageNumber = 0;
381 hdr.Reserved1 = 0;
382 hdr.Reserved2 = 0;
383 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
384 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
385
386 cfg.cfghdr.ehdr = &hdr;
387 cfg.physAddr = -1;
388 cfg.pageAddr = 0;
389 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
390 cfg.dir = 0; /* read */
391 cfg.timeout = 10;
392
393 error = mpt_config(ioc, &cfg);
394 if (error)
395 goto out;
396 if (!hdr.ExtPageLength) {
397 error = -ENXIO;
398 goto out;
399 }
400
401 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
402 &dma_handle);
403 if (!buffer) {
404 error = -ENOMEM;
405 goto out;
406 }
407
408 cfg.physAddr = dma_handle;
409 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
410
411 error = mpt_config(ioc, &cfg);
412 if (error)
413 goto out_free_consistent;
414
415 port_info->num_phys = buffer->NumPhys;
416 port_info->phy_info = kcalloc(port_info->num_phys,
417 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
418 if (!port_info->phy_info) {
419 error = -ENOMEM;
420 goto out_free_consistent;
421 }
422
423 for (i = 0; i < port_info->num_phys; i++) {
424 mptsas_print_phy_data(&buffer->PhyData[i]);
425 port_info->phy_info[i].phy_id = i;
426 port_info->phy_info[i].port_id =
427 buffer->PhyData[i].Port;
428 port_info->phy_info[i].negotiated_link_rate =
429 buffer->PhyData[i].NegotiatedLinkRate;
430 }
431
432 out_free_consistent:
433 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
434 buffer, dma_handle);
435 out:
436 return error;
437}
438
439static int
440mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
441 u32 form, u32 form_specific)
442{
443 ConfigExtendedPageHeader_t hdr;
444 CONFIGPARMS cfg;
445 SasPhyPage0_t *buffer;
446 dma_addr_t dma_handle;
447 int error;
448
449 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
450 hdr.ExtPageLength = 0;
451 hdr.PageNumber = 0;
452 hdr.Reserved1 = 0;
453 hdr.Reserved2 = 0;
454 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
455 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
456
457 cfg.cfghdr.ehdr = &hdr;
458 cfg.dir = 0; /* read */
459 cfg.timeout = 10;
460
461 /* Get Phy Pg 0 for each Phy. */
462 cfg.physAddr = -1;
463 cfg.pageAddr = form + form_specific;
464 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
465
466 error = mpt_config(ioc, &cfg);
467 if (error)
468 goto out;
469
470 if (!hdr.ExtPageLength) {
471 error = -ENXIO;
472 goto out;
473 }
474
475 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
476 &dma_handle);
477 if (!buffer) {
478 error = -ENOMEM;
479 goto out;
480 }
481
482 cfg.physAddr = dma_handle;
483 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
484
485 error = mpt_config(ioc, &cfg);
486 if (error)
487 goto out_free_consistent;
488
489 mptsas_print_phy_pg0(buffer);
490
491 phy_info->hw_link_rate = buffer->HwLinkRate;
492 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
493 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
494 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
495
496 out_free_consistent:
497 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
498 buffer, dma_handle);
499 out:
500 return error;
501}
502
503static int
504mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
505 u32 form, u32 form_specific)
506{
507 ConfigExtendedPageHeader_t hdr;
508 CONFIGPARMS cfg;
509 SasDevicePage0_t *buffer;
510 dma_addr_t dma_handle;
511 __le64 sas_address;
512 int error;
513
514 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
515 hdr.ExtPageLength = 0;
516 hdr.PageNumber = 0;
517 hdr.Reserved1 = 0;
518 hdr.Reserved2 = 0;
519 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
520 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
521
522 cfg.cfghdr.ehdr = &hdr;
523 cfg.pageAddr = form + form_specific;
524 cfg.physAddr = -1;
525 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
526 cfg.dir = 0; /* read */
527 cfg.timeout = 10;
528
529 error = mpt_config(ioc, &cfg);
530 if (error)
531 goto out;
532 if (!hdr.ExtPageLength) {
533 error = -ENXIO;
534 goto out;
535 }
536
537 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
538 &dma_handle);
539 if (!buffer) {
540 error = -ENOMEM;
541 goto out;
542 }
543
544 cfg.physAddr = dma_handle;
545 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
546
547 error = mpt_config(ioc, &cfg);
548 if (error)
549 goto out_free_consistent;
550
551 mptsas_print_device_pg0(buffer);
552
553 device_info->handle = le16_to_cpu(buffer->DevHandle);
554 device_info->phy_id = buffer->PhyNum;
555 device_info->port_id = buffer->PhysicalPort;
556 device_info->target = buffer->TargetID;
557 device_info->bus = buffer->Bus;
558 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
559 device_info->sas_address = le64_to_cpu(sas_address);
560 device_info->device_info =
561 le32_to_cpu(buffer->DeviceInfo);
562
563 out_free_consistent:
564 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
565 buffer, dma_handle);
566 out:
567 return error;
568}
569
570static int
571mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
572 u32 form, u32 form_specific)
573{
574 ConfigExtendedPageHeader_t hdr;
575 CONFIGPARMS cfg;
576 SasExpanderPage0_t *buffer;
577 dma_addr_t dma_handle;
578 int error;
579
580 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
581 hdr.ExtPageLength = 0;
582 hdr.PageNumber = 0;
583 hdr.Reserved1 = 0;
584 hdr.Reserved2 = 0;
585 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
586 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
587
588 cfg.cfghdr.ehdr = &hdr;
589 cfg.physAddr = -1;
590 cfg.pageAddr = form + form_specific;
591 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
592 cfg.dir = 0; /* read */
593 cfg.timeout = 10;
594
595 error = mpt_config(ioc, &cfg);
596 if (error)
597 goto out;
598
599 if (!hdr.ExtPageLength) {
600 error = -ENXIO;
601 goto out;
602 }
603
604 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
605 &dma_handle);
606 if (!buffer) {
607 error = -ENOMEM;
608 goto out;
609 }
610
611 cfg.physAddr = dma_handle;
612 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
613
614 error = mpt_config(ioc, &cfg);
615 if (error)
616 goto out_free_consistent;
617
618 /* save config data */
619 port_info->num_phys = buffer->NumPhys;
620 port_info->handle = le16_to_cpu(buffer->DevHandle);
621 port_info->phy_info = kcalloc(port_info->num_phys,
622 sizeof(struct mptsas_phyinfo),GFP_KERNEL);
623 if (!port_info->phy_info) {
624 error = -ENOMEM;
625 goto out_free_consistent;
626 }
627
628 out_free_consistent:
629 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
630 buffer, dma_handle);
631 out:
632 return error;
633}
634
635static int
636mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
637 u32 form, u32 form_specific)
638{
639 ConfigExtendedPageHeader_t hdr;
640 CONFIGPARMS cfg;
641 SasExpanderPage1_t *buffer;
642 dma_addr_t dma_handle;
643 int error;
644
645 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
646 hdr.ExtPageLength = 0;
647 hdr.PageNumber = 1;
648 hdr.Reserved1 = 0;
649 hdr.Reserved2 = 0;
650 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
651 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
652
653 cfg.cfghdr.ehdr = &hdr;
654 cfg.physAddr = -1;
655 cfg.pageAddr = form + form_specific;
656 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
657 cfg.dir = 0; /* read */
658 cfg.timeout = 10;
659
660 error = mpt_config(ioc, &cfg);
661 if (error)
662 goto out;
663
664 if (!hdr.ExtPageLength) {
665 error = -ENXIO;
666 goto out;
667 }
668
669 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
670 &dma_handle);
671 if (!buffer) {
672 error = -ENOMEM;
673 goto out;
674 }
675
676 cfg.physAddr = dma_handle;
677 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
678
679 error = mpt_config(ioc, &cfg);
680 if (error)
681 goto out_free_consistent;
682
683
684 mptsas_print_expander_pg1(buffer);
685
686 /* save config data */
Eric Moore024358e2005-10-21 20:56:36 +0200687 phy_info->phy_id = buffer->PhyIdentifier;
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200688 phy_info->port_id = buffer->PhysicalPort;
689 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
690 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
691 phy_info->hw_link_rate = buffer->HwLinkRate;
692 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
693 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
694
695
696 out_free_consistent:
697 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
698 buffer, dma_handle);
699 out:
700 return error;
701}
702
703static void
704mptsas_parse_device_info(struct sas_identify *identify,
705 struct mptsas_devinfo *device_info)
706{
707 u16 protocols;
708
709 identify->sas_address = device_info->sas_address;
710 identify->phy_identifier = device_info->phy_id;
711
712 /*
713 * Fill in Phy Initiator Port Protocol.
714 * Bits 6:3, more than one bit can be set, fall through cases.
715 */
716 protocols = device_info->device_info & 0x78;
717 identify->initiator_port_protocols = 0;
718 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
719 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
720 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
721 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
722 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
723 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
724 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
725 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
726
727 /*
728 * Fill in Phy Target Port Protocol.
729 * Bits 10:7, more than one bit can be set, fall through cases.
730 */
731 protocols = device_info->device_info & 0x780;
732 identify->target_port_protocols = 0;
733 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
734 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
735 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
736 identify->target_port_protocols |= SAS_PROTOCOL_STP;
737 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
738 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
739 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
740 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
741
742 /*
743 * Fill in Attached device type.
744 */
745 switch (device_info->device_info &
746 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
747 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
748 identify->device_type = SAS_PHY_UNUSED;
749 break;
750 case MPI_SAS_DEVICE_INFO_END_DEVICE:
751 identify->device_type = SAS_END_DEVICE;
752 break;
753 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
754 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
755 break;
756 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
757 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
758 break;
759 }
760}
761
762static int mptsas_probe_one_phy(struct device *dev,
Christoph Hellwigac01bbb2005-10-19 20:01:17 +0200763 struct mptsas_phyinfo *phy_info, int index, int local)
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200764{
765 struct sas_phy *port;
766 int error;
767
768 port = sas_phy_alloc(dev, index);
769 if (!port)
770 return -ENOMEM;
771
772 port->port_identifier = phy_info->port_id;
773 mptsas_parse_device_info(&port->identify, &phy_info->identify);
774
775 /*
776 * Set Negotiated link rate.
777 */
778 switch (phy_info->negotiated_link_rate) {
779 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
780 port->negotiated_linkrate = SAS_PHY_DISABLED;
781 break;
782 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
783 port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
784 break;
785 case MPI_SAS_IOUNIT0_RATE_1_5:
786 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
787 break;
788 case MPI_SAS_IOUNIT0_RATE_3_0:
789 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
790 break;
791 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
792 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
793 default:
794 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
795 break;
796 }
797
798 /*
799 * Set Max hardware link rate.
800 */
801 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
802 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
803 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
804 break;
805 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
806 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
807 break;
808 default:
809 break;
810 }
811
812 /*
813 * Set Max programmed link rate.
814 */
815 switch (phy_info->programmed_link_rate &
816 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
817 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
818 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
819 break;
820 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
821 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
822 break;
823 default:
824 break;
825 }
826
827 /*
828 * Set Min hardware link rate.
829 */
830 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
831 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
832 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
833 break;
834 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
835 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
836 break;
837 default:
838 break;
839 }
840
841 /*
842 * Set Min programmed link rate.
843 */
844 switch (phy_info->programmed_link_rate &
845 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
846 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
847 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
848 break;
849 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
850 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
851 break;
852 default:
853 break;
854 }
855
Christoph Hellwigac01bbb2005-10-19 20:01:17 +0200856 if (local)
857 port->local_attached = 1;
858
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200859 error = sas_phy_add(port);
860 if (error) {
861 sas_phy_free(port);
862 return error;
863 }
864
865 if (phy_info->attached.handle) {
866 struct sas_rphy *rphy;
867
868 rphy = sas_rphy_alloc(port);
869 if (!rphy)
870 return 0; /* non-fatal: an rphy can be added later */
871
872 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
873 error = sas_rphy_add(rphy);
874 if (error) {
875 sas_rphy_free(rphy);
876 return error;
877 }
878
879 phy_info->rphy = rphy;
880 }
881
882 return 0;
883}
884
885static int
886mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
887{
888 struct mptsas_portinfo *port_info;
889 u32 handle = 0xFFFF;
890 int error = -ENOMEM, i;
891
892 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
893 if (!port_info)
894 goto out;
895 memset(port_info, 0, sizeof(*port_info));
896
897 error = mptsas_sas_io_unit_pg0(ioc, port_info);
898 if (error)
899 goto out_free_port_info;
900
901 list_add_tail(&port_info->list, &ioc->sas_topology);
902
903 for (i = 0; i < port_info->num_phys; i++) {
904 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
905 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
906 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
907
908 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
909 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
910 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
Eric Moore024358e2005-10-21 20:56:36 +0200911 port_info->phy_info[i].identify.phy_id =
912 port_info->phy_info[i].phy_id;
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200913 handle = port_info->phy_info[i].identify.handle;
914
915 if (port_info->phy_info[i].attached.handle) {
916 mptsas_sas_device_pg0(ioc,
917 &port_info->phy_info[i].attached,
918 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
919 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
920 port_info->phy_info[i].attached.handle);
921 }
922
923 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
Christoph Hellwigac01bbb2005-10-19 20:01:17 +0200924 &port_info->phy_info[i], *index, 1);
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200925 (*index)++;
926 }
927
928 return 0;
929
930 out_free_port_info:
931 kfree(port_info);
932 out:
933 return error;
934}
935
936static int
937mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
938{
939 struct mptsas_portinfo *port_info, *p;
940 int error = -ENOMEM, i, j;
941
942 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
943 if (!port_info)
944 goto out;
945 memset(port_info, 0, sizeof(*port_info));
946
947 error = mptsas_sas_expander_pg0(ioc, port_info,
948 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
949 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
950 if (error)
951 goto out_free_port_info;
952
953 *handle = port_info->handle;
954
955 list_add_tail(&port_info->list, &ioc->sas_topology);
956 for (i = 0; i < port_info->num_phys; i++) {
957 struct device *parent;
958
959 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
960 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
961 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
962
963 if (port_info->phy_info[i].identify.handle) {
964 mptsas_sas_device_pg0(ioc,
965 &port_info->phy_info[i].identify,
966 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
967 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
968 port_info->phy_info[i].identify.handle);
Eric Moore024358e2005-10-21 20:56:36 +0200969 port_info->phy_info[i].identify.phy_id =
970 port_info->phy_info[i].phy_id;
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200971 }
972
973 if (port_info->phy_info[i].attached.handle) {
974 mptsas_sas_device_pg0(ioc,
975 &port_info->phy_info[i].attached,
976 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
977 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
978 port_info->phy_info[i].attached.handle);
979 }
980
981 /*
982 * If we find a parent port handle this expander is
983 * attached to another expander, else it hangs of the
984 * HBA phys.
985 */
986 parent = &ioc->sh->shost_gendev;
987 list_for_each_entry(p, &ioc->sas_topology, list) {
988 for (j = 0; j < p->num_phys; j++) {
989 if (port_info->phy_info[i].identify.handle ==
990 p->phy_info[j].attached.handle)
991 parent = &p->phy_info[j].rphy->dev;
992 }
993 }
994
Christoph Hellwigac01bbb2005-10-19 20:01:17 +0200995 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
996 *index, 0);
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200997 (*index)++;
998 }
999
1000 return 0;
1001
1002 out_free_port_info:
1003 kfree(port_info);
1004 out:
1005 return error;
1006}
1007
1008static void
1009mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1010{
1011 u32 handle = 0xFFFF;
1012 int index = 0;
1013
1014 mptsas_probe_hba_phys(ioc, &index);
1015 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1016 ;
1017}
1018
1019static int
1020mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1021{
1022 struct Scsi_Host *sh;
1023 MPT_SCSI_HOST *hd;
1024 MPT_ADAPTER *ioc;
1025 unsigned long flags;
1026 int sz, ii;
1027 int numSGE = 0;
1028 int scale;
1029 int ioc_cap;
1030 u8 *mem;
1031 int error=0;
1032 int r;
1033
1034 r = mpt_attach(pdev,id);
1035 if (r)
1036 return r;
1037
1038 ioc = pci_get_drvdata(pdev);
1039 ioc->DoneCtx = mptsasDoneCtx;
1040 ioc->TaskCtx = mptsasTaskCtx;
1041 ioc->InternalCtx = mptsasInternalCtx;
1042
1043 /* Added sanity check on readiness of the MPT adapter.
1044 */
1045 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1046 printk(MYIOC_s_WARN_FMT
1047 "Skipping because it's not operational!\n",
1048 ioc->name);
1049 return -ENODEV;
1050 }
1051
1052 if (!ioc->active) {
1053 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1054 ioc->name);
1055 return -ENODEV;
1056 }
1057
1058 /* Sanity check - ensure at least 1 port is INITIATOR capable
1059 */
1060 ioc_cap = 0;
1061 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1062 if (ioc->pfacts[ii].ProtocolFlags &
1063 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1064 ioc_cap++;
1065 }
1066
1067 if (!ioc_cap) {
1068 printk(MYIOC_s_WARN_FMT
1069 "Skipping ioc=%p because SCSI Initiator mode "
1070 "is NOT enabled!\n", ioc->name, ioc);
Moore, Eric Dean466544d2005-09-14 18:09:10 -06001071 return 0;
Christoph Hellwig0c33b272005-09-09 16:27:19 +02001072 }
1073
1074 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1075 if (!sh) {
1076 printk(MYIOC_s_WARN_FMT
1077 "Unable to register controller with SCSI subsystem\n",
1078 ioc->name);
1079 return -1;
1080 }
1081
1082 spin_lock_irqsave(&ioc->FreeQlock, flags);
1083
1084 /* Attach the SCSI Host to the IOC structure
1085 */
1086 ioc->sh = sh;
1087
1088 sh->io_port = 0;
1089 sh->n_io_port = 0;
1090 sh->irq = 0;
1091
1092 /* set 16 byte cdb's */
1093 sh->max_cmd_len = 16;
1094
1095 sh->max_id = ioc->pfacts->MaxDevices + 1;
1096
1097 sh->transportt = mptsas_transport_template;
1098
1099 sh->max_lun = MPT_LAST_LUN + 1;
1100 sh->max_channel = 0;
1101 sh->this_id = ioc->pfacts[0].PortSCSIID;
1102
1103 /* Required entry.
1104 */
1105 sh->unique_id = ioc->id;
1106
1107 INIT_LIST_HEAD(&ioc->sas_topology);
1108
1109 /* Verify that we won't exceed the maximum
1110 * number of chain buffers
1111 * We can optimize: ZZ = req_sz/sizeof(SGE)
1112 * For 32bit SGE's:
1113 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1114 * + (req_sz - 64)/sizeof(SGE)
1115 * A slightly different algorithm is required for
1116 * 64bit SGEs.
1117 */
1118 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1119 if (sizeof(dma_addr_t) == sizeof(u64)) {
1120 numSGE = (scale - 1) *
1121 (ioc->facts.MaxChainDepth-1) + scale +
1122 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1123 sizeof(u32));
1124 } else {
1125 numSGE = 1 + (scale - 1) *
1126 (ioc->facts.MaxChainDepth-1) + scale +
1127 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1128 sizeof(u32));
1129 }
1130
1131 if (numSGE < sh->sg_tablesize) {
1132 /* Reset this value */
1133 dprintk((MYIOC_s_INFO_FMT
1134 "Resetting sg_tablesize to %d from %d\n",
1135 ioc->name, numSGE, sh->sg_tablesize));
1136 sh->sg_tablesize = numSGE;
1137 }
1138
1139 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1140
1141 hd = (MPT_SCSI_HOST *) sh->hostdata;
1142 hd->ioc = ioc;
1143
1144 /* SCSI needs scsi_cmnd lookup table!
1145 * (with size equal to req_depth*PtrSz!)
1146 */
1147 sz = ioc->req_depth * sizeof(void *);
1148 mem = kmalloc(sz, GFP_ATOMIC);
1149 if (mem == NULL) {
1150 error = -ENOMEM;
1151 goto mptsas_probe_failed;
1152 }
1153
1154 memset(mem, 0, sz);
1155 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1156
1157 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1158 ioc->name, hd->ScsiLookup, sz));
1159
1160 /* Allocate memory for the device structures.
1161 * A non-Null pointer at an offset
1162 * indicates a device exists.
1163 * max_id = 1 + maximum id (hosts.h)
1164 */
1165 sz = sh->max_id * sizeof(void *);
1166 mem = kmalloc(sz, GFP_ATOMIC);
1167 if (mem == NULL) {
1168 error = -ENOMEM;
1169 goto mptsas_probe_failed;
1170 }
1171
1172 memset(mem, 0, sz);
1173 hd->Targets = (VirtDevice **) mem;
1174
1175 dprintk((KERN_INFO
1176 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1177
1178 /* Clear the TM flags
1179 */
1180 hd->tmPending = 0;
1181 hd->tmState = TM_STATE_NONE;
1182 hd->resetPending = 0;
1183 hd->abortSCpnt = NULL;
1184
1185 /* Clear the pointer used to store
1186 * single-threaded commands, i.e., those
1187 * issued during a bus scan, dv and
1188 * configuration pages.
1189 */
1190 hd->cmdPtr = NULL;
1191
1192 /* Initialize this SCSI Hosts' timers
1193 * To use, set the timer expires field
1194 * and add_timer
1195 */
1196 init_timer(&hd->timer);
1197 hd->timer.data = (unsigned long) hd;
1198 hd->timer.function = mptscsih_timer_expired;
1199
1200 hd->mpt_pq_filter = mpt_pq_filter;
1201 ioc->sas_data.ptClear = mpt_pt_clear;
1202
1203 if (ioc->sas_data.ptClear==1) {
1204 mptbase_sas_persist_operation(
1205 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1206 }
1207
1208 ddvprintk((MYIOC_s_INFO_FMT
1209 "mpt_pq_filter %x mpt_pq_filter %x\n",
1210 ioc->name,
1211 mpt_pq_filter,
1212 mpt_pq_filter));
1213
1214 init_waitqueue_head(&hd->scandv_waitq);
1215 hd->scandv_wait_done = 0;
1216 hd->last_queue_full = 0;
1217
1218 error = scsi_add_host(sh, &ioc->pcidev->dev);
1219 if (error) {
1220 dprintk((KERN_ERR MYNAM
1221 "scsi_add_host failed\n"));
1222 goto mptsas_probe_failed;
1223 }
1224
1225 mptsas_scan_sas_topology(ioc);
1226
1227 return 0;
1228
1229mptsas_probe_failed:
1230
1231 mptscsih_remove(pdev);
1232 return error;
1233}
1234
1235static void __devexit mptsas_remove(struct pci_dev *pdev)
1236{
1237 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1238 struct mptsas_portinfo *p, *n;
1239
1240 sas_remove_host(ioc->sh);
1241
1242 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1243 list_del(&p->list);
1244 kfree(p);
1245 }
1246
1247 mptscsih_remove(pdev);
1248}
1249
1250static struct pci_device_id mptsas_pci_table[] = {
1251 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1252 PCI_ANY_ID, PCI_ANY_ID },
1253 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1254 PCI_ANY_ID, PCI_ANY_ID },
1255 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1256 PCI_ANY_ID, PCI_ANY_ID },
1257 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1258 PCI_ANY_ID, PCI_ANY_ID },
1259 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1260 PCI_ANY_ID, PCI_ANY_ID },
1261 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1262 PCI_ANY_ID, PCI_ANY_ID },
1263 {0} /* Terminating entry */
1264};
1265MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1266
1267
1268static struct pci_driver mptsas_driver = {
1269 .name = "mptsas",
1270 .id_table = mptsas_pci_table,
1271 .probe = mptsas_probe,
1272 .remove = __devexit_p(mptsas_remove),
1273 .shutdown = mptscsih_shutdown,
1274#ifdef CONFIG_PM
1275 .suspend = mptscsih_suspend,
1276 .resume = mptscsih_resume,
1277#endif
1278};
1279
1280static int __init
1281mptsas_init(void)
1282{
1283 show_mptmod_ver(my_NAME, my_VERSION);
1284
1285 mptsas_transport_template =
1286 sas_attach_transport(&mptsas_transport_functions);
1287 if (!mptsas_transport_template)
1288 return -ENODEV;
1289
1290 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1291 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1292 mptsasInternalCtx =
1293 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1294
1295 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1296 devtprintk((KERN_INFO MYNAM
1297 ": Registered for IOC event notifications\n"));
1298 }
1299
1300 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1301 dprintk((KERN_INFO MYNAM
1302 ": Registered for IOC reset notifications\n"));
1303 }
1304
1305 return pci_register_driver(&mptsas_driver);
1306}
1307
1308static void __exit
1309mptsas_exit(void)
1310{
1311 pci_unregister_driver(&mptsas_driver);
1312 sas_release_transport(mptsas_transport_template);
1313
1314 mpt_reset_deregister(mptsasDoneCtx);
1315 mpt_event_deregister(mptsasDoneCtx);
1316
1317 mpt_deregister(mptsasInternalCtx);
1318 mpt_deregister(mptsasTaskCtx);
1319 mpt_deregister(mptsasDoneCtx);
1320}
1321
1322module_init(mptsas_init);
1323module_exit(mptsas_exit);