blob: 6512027bc69ad87ce3bba185671254e34d217273 [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,
763 struct mptsas_phyinfo *phy_info, int index)
764{
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
856 error = sas_phy_add(port);
857 if (error) {
858 sas_phy_free(port);
859 return error;
860 }
861
862 if (phy_info->attached.handle) {
863 struct sas_rphy *rphy;
864
865 rphy = sas_rphy_alloc(port);
866 if (!rphy)
867 return 0; /* non-fatal: an rphy can be added later */
868
869 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
870 error = sas_rphy_add(rphy);
871 if (error) {
872 sas_rphy_free(rphy);
873 return error;
874 }
875
876 phy_info->rphy = rphy;
877 }
878
879 return 0;
880}
881
882static int
883mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
884{
885 struct mptsas_portinfo *port_info;
886 u32 handle = 0xFFFF;
887 int error = -ENOMEM, i;
888
889 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
890 if (!port_info)
891 goto out;
892 memset(port_info, 0, sizeof(*port_info));
893
894 error = mptsas_sas_io_unit_pg0(ioc, port_info);
895 if (error)
896 goto out_free_port_info;
897
898 list_add_tail(&port_info->list, &ioc->sas_topology);
899
900 for (i = 0; i < port_info->num_phys; i++) {
901 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
902 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
903 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
904
905 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
906 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
907 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
Eric Moore024358e2005-10-21 20:56:36 +0200908 port_info->phy_info[i].identify.phy_id =
909 port_info->phy_info[i].phy_id;
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200910 handle = port_info->phy_info[i].identify.handle;
911
912 if (port_info->phy_info[i].attached.handle) {
913 mptsas_sas_device_pg0(ioc,
914 &port_info->phy_info[i].attached,
915 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
916 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
917 port_info->phy_info[i].attached.handle);
918 }
919
920 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
921 &port_info->phy_info[i], *index);
922 (*index)++;
923 }
924
925 return 0;
926
927 out_free_port_info:
928 kfree(port_info);
929 out:
930 return error;
931}
932
933static int
934mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
935{
936 struct mptsas_portinfo *port_info, *p;
937 int error = -ENOMEM, i, j;
938
939 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
940 if (!port_info)
941 goto out;
942 memset(port_info, 0, sizeof(*port_info));
943
944 error = mptsas_sas_expander_pg0(ioc, port_info,
945 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
946 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
947 if (error)
948 goto out_free_port_info;
949
950 *handle = port_info->handle;
951
952 list_add_tail(&port_info->list, &ioc->sas_topology);
953 for (i = 0; i < port_info->num_phys; i++) {
954 struct device *parent;
955
956 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
957 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
958 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
959
960 if (port_info->phy_info[i].identify.handle) {
961 mptsas_sas_device_pg0(ioc,
962 &port_info->phy_info[i].identify,
963 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
964 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
965 port_info->phy_info[i].identify.handle);
Eric Moore024358e2005-10-21 20:56:36 +0200966 port_info->phy_info[i].identify.phy_id =
967 port_info->phy_info[i].phy_id;
Christoph Hellwig0c33b272005-09-09 16:27:19 +0200968 }
969
970 if (port_info->phy_info[i].attached.handle) {
971 mptsas_sas_device_pg0(ioc,
972 &port_info->phy_info[i].attached,
973 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
974 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
975 port_info->phy_info[i].attached.handle);
976 }
977
978 /*
979 * If we find a parent port handle this expander is
980 * attached to another expander, else it hangs of the
981 * HBA phys.
982 */
983 parent = &ioc->sh->shost_gendev;
984 list_for_each_entry(p, &ioc->sas_topology, list) {
985 for (j = 0; j < p->num_phys; j++) {
986 if (port_info->phy_info[i].identify.handle ==
987 p->phy_info[j].attached.handle)
988 parent = &p->phy_info[j].rphy->dev;
989 }
990 }
991
992 mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
993 (*index)++;
994 }
995
996 return 0;
997
998 out_free_port_info:
999 kfree(port_info);
1000 out:
1001 return error;
1002}
1003
1004static void
1005mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1006{
1007 u32 handle = 0xFFFF;
1008 int index = 0;
1009
1010 mptsas_probe_hba_phys(ioc, &index);
1011 while (!mptsas_probe_expander_phys(ioc, &handle, &index))
1012 ;
1013}
1014
1015static int
1016mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1017{
1018 struct Scsi_Host *sh;
1019 MPT_SCSI_HOST *hd;
1020 MPT_ADAPTER *ioc;
1021 unsigned long flags;
1022 int sz, ii;
1023 int numSGE = 0;
1024 int scale;
1025 int ioc_cap;
1026 u8 *mem;
1027 int error=0;
1028 int r;
1029
1030 r = mpt_attach(pdev,id);
1031 if (r)
1032 return r;
1033
1034 ioc = pci_get_drvdata(pdev);
1035 ioc->DoneCtx = mptsasDoneCtx;
1036 ioc->TaskCtx = mptsasTaskCtx;
1037 ioc->InternalCtx = mptsasInternalCtx;
1038
1039 /* Added sanity check on readiness of the MPT adapter.
1040 */
1041 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1042 printk(MYIOC_s_WARN_FMT
1043 "Skipping because it's not operational!\n",
1044 ioc->name);
1045 return -ENODEV;
1046 }
1047
1048 if (!ioc->active) {
1049 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1050 ioc->name);
1051 return -ENODEV;
1052 }
1053
1054 /* Sanity check - ensure at least 1 port is INITIATOR capable
1055 */
1056 ioc_cap = 0;
1057 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
1058 if (ioc->pfacts[ii].ProtocolFlags &
1059 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1060 ioc_cap++;
1061 }
1062
1063 if (!ioc_cap) {
1064 printk(MYIOC_s_WARN_FMT
1065 "Skipping ioc=%p because SCSI Initiator mode "
1066 "is NOT enabled!\n", ioc->name, ioc);
Moore, Eric Dean466544d2005-09-14 18:09:10 -06001067 return 0;
Christoph Hellwig0c33b272005-09-09 16:27:19 +02001068 }
1069
1070 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
1071 if (!sh) {
1072 printk(MYIOC_s_WARN_FMT
1073 "Unable to register controller with SCSI subsystem\n",
1074 ioc->name);
1075 return -1;
1076 }
1077
1078 spin_lock_irqsave(&ioc->FreeQlock, flags);
1079
1080 /* Attach the SCSI Host to the IOC structure
1081 */
1082 ioc->sh = sh;
1083
1084 sh->io_port = 0;
1085 sh->n_io_port = 0;
1086 sh->irq = 0;
1087
1088 /* set 16 byte cdb's */
1089 sh->max_cmd_len = 16;
1090
1091 sh->max_id = ioc->pfacts->MaxDevices + 1;
1092
1093 sh->transportt = mptsas_transport_template;
1094
1095 sh->max_lun = MPT_LAST_LUN + 1;
1096 sh->max_channel = 0;
1097 sh->this_id = ioc->pfacts[0].PortSCSIID;
1098
1099 /* Required entry.
1100 */
1101 sh->unique_id = ioc->id;
1102
1103 INIT_LIST_HEAD(&ioc->sas_topology);
1104
1105 /* Verify that we won't exceed the maximum
1106 * number of chain buffers
1107 * We can optimize: ZZ = req_sz/sizeof(SGE)
1108 * For 32bit SGE's:
1109 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1110 * + (req_sz - 64)/sizeof(SGE)
1111 * A slightly different algorithm is required for
1112 * 64bit SGEs.
1113 */
1114 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1115 if (sizeof(dma_addr_t) == sizeof(u64)) {
1116 numSGE = (scale - 1) *
1117 (ioc->facts.MaxChainDepth-1) + scale +
1118 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1119 sizeof(u32));
1120 } else {
1121 numSGE = 1 + (scale - 1) *
1122 (ioc->facts.MaxChainDepth-1) + scale +
1123 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1124 sizeof(u32));
1125 }
1126
1127 if (numSGE < sh->sg_tablesize) {
1128 /* Reset this value */
1129 dprintk((MYIOC_s_INFO_FMT
1130 "Resetting sg_tablesize to %d from %d\n",
1131 ioc->name, numSGE, sh->sg_tablesize));
1132 sh->sg_tablesize = numSGE;
1133 }
1134
1135 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1136
1137 hd = (MPT_SCSI_HOST *) sh->hostdata;
1138 hd->ioc = ioc;
1139
1140 /* SCSI needs scsi_cmnd lookup table!
1141 * (with size equal to req_depth*PtrSz!)
1142 */
1143 sz = ioc->req_depth * sizeof(void *);
1144 mem = kmalloc(sz, GFP_ATOMIC);
1145 if (mem == NULL) {
1146 error = -ENOMEM;
1147 goto mptsas_probe_failed;
1148 }
1149
1150 memset(mem, 0, sz);
1151 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1152
1153 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1154 ioc->name, hd->ScsiLookup, sz));
1155
1156 /* Allocate memory for the device structures.
1157 * A non-Null pointer at an offset
1158 * indicates a device exists.
1159 * max_id = 1 + maximum id (hosts.h)
1160 */
1161 sz = sh->max_id * sizeof(void *);
1162 mem = kmalloc(sz, GFP_ATOMIC);
1163 if (mem == NULL) {
1164 error = -ENOMEM;
1165 goto mptsas_probe_failed;
1166 }
1167
1168 memset(mem, 0, sz);
1169 hd->Targets = (VirtDevice **) mem;
1170
1171 dprintk((KERN_INFO
1172 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1173
1174 /* Clear the TM flags
1175 */
1176 hd->tmPending = 0;
1177 hd->tmState = TM_STATE_NONE;
1178 hd->resetPending = 0;
1179 hd->abortSCpnt = NULL;
1180
1181 /* Clear the pointer used to store
1182 * single-threaded commands, i.e., those
1183 * issued during a bus scan, dv and
1184 * configuration pages.
1185 */
1186 hd->cmdPtr = NULL;
1187
1188 /* Initialize this SCSI Hosts' timers
1189 * To use, set the timer expires field
1190 * and add_timer
1191 */
1192 init_timer(&hd->timer);
1193 hd->timer.data = (unsigned long) hd;
1194 hd->timer.function = mptscsih_timer_expired;
1195
1196 hd->mpt_pq_filter = mpt_pq_filter;
1197 ioc->sas_data.ptClear = mpt_pt_clear;
1198
1199 if (ioc->sas_data.ptClear==1) {
1200 mptbase_sas_persist_operation(
1201 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
1202 }
1203
1204 ddvprintk((MYIOC_s_INFO_FMT
1205 "mpt_pq_filter %x mpt_pq_filter %x\n",
1206 ioc->name,
1207 mpt_pq_filter,
1208 mpt_pq_filter));
1209
1210 init_waitqueue_head(&hd->scandv_waitq);
1211 hd->scandv_wait_done = 0;
1212 hd->last_queue_full = 0;
1213
1214 error = scsi_add_host(sh, &ioc->pcidev->dev);
1215 if (error) {
1216 dprintk((KERN_ERR MYNAM
1217 "scsi_add_host failed\n"));
1218 goto mptsas_probe_failed;
1219 }
1220
1221 mptsas_scan_sas_topology(ioc);
1222
1223 return 0;
1224
1225mptsas_probe_failed:
1226
1227 mptscsih_remove(pdev);
1228 return error;
1229}
1230
1231static void __devexit mptsas_remove(struct pci_dev *pdev)
1232{
1233 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1234 struct mptsas_portinfo *p, *n;
1235
1236 sas_remove_host(ioc->sh);
1237
1238 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1239 list_del(&p->list);
1240 kfree(p);
1241 }
1242
1243 mptscsih_remove(pdev);
1244}
1245
1246static struct pci_device_id mptsas_pci_table[] = {
1247 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
1248 PCI_ANY_ID, PCI_ANY_ID },
1249 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
1250 PCI_ANY_ID, PCI_ANY_ID },
1251 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
1252 PCI_ANY_ID, PCI_ANY_ID },
1253 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
1254 PCI_ANY_ID, PCI_ANY_ID },
1255 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
1256 PCI_ANY_ID, PCI_ANY_ID },
1257 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
1258 PCI_ANY_ID, PCI_ANY_ID },
1259 {0} /* Terminating entry */
1260};
1261MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
1262
1263
1264static struct pci_driver mptsas_driver = {
1265 .name = "mptsas",
1266 .id_table = mptsas_pci_table,
1267 .probe = mptsas_probe,
1268 .remove = __devexit_p(mptsas_remove),
1269 .shutdown = mptscsih_shutdown,
1270#ifdef CONFIG_PM
1271 .suspend = mptscsih_suspend,
1272 .resume = mptscsih_resume,
1273#endif
1274};
1275
1276static int __init
1277mptsas_init(void)
1278{
1279 show_mptmod_ver(my_NAME, my_VERSION);
1280
1281 mptsas_transport_template =
1282 sas_attach_transport(&mptsas_transport_functions);
1283 if (!mptsas_transport_template)
1284 return -ENODEV;
1285
1286 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
1287 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
1288 mptsasInternalCtx =
1289 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1290
1291 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
1292 devtprintk((KERN_INFO MYNAM
1293 ": Registered for IOC event notifications\n"));
1294 }
1295
1296 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
1297 dprintk((KERN_INFO MYNAM
1298 ": Registered for IOC reset notifications\n"));
1299 }
1300
1301 return pci_register_driver(&mptsas_driver);
1302}
1303
1304static void __exit
1305mptsas_exit(void)
1306{
1307 pci_unregister_driver(&mptsas_driver);
1308 sas_release_transport(mptsas_transport_template);
1309
1310 mpt_reset_deregister(mptsasDoneCtx);
1311 mpt_event_deregister(mptsasDoneCtx);
1312
1313 mpt_deregister(mptsasInternalCtx);
1314 mpt_deregister(mptsasTaskCtx);
1315 mpt_deregister(mptsasDoneCtx);
1316}
1317
1318module_init(mptsas_init);
1319module_exit(mptsas_exit);