2 * linux/drivers/message/fusion/mptspi.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-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 #include "linux_compat.h" /* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h> /* for mdelay */
55 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
56 #include <linux/reboot.h> /* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.h>
59 #include <linux/raid_class.h>
61 #include <scsi/scsi.h>
62 #include <scsi/scsi_cmnd.h>
63 #include <scsi/scsi_device.h>
64 #include <scsi/scsi_host.h>
65 #include <scsi/scsi_tcq.h>
66 #include <scsi/scsi_transport.h>
67 #include <scsi/scsi_transport_spi.h>
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT SPI Host driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptspi"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
80 MODULE_VERSION(my_VERSION);
82 /* Command line args */
83 static int mpt_saf_te = MPTSCSIH_SAF_TE;
84 module_param(mpt_saf_te, int, 0);
85 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
87 static void mptspi_write_offset(struct scsi_target *, int);
88 static void mptspi_write_width(struct scsi_target *, int);
89 static int mptspi_write_spi_device_pg1(struct scsi_target *,
90 struct _CONFIG_PAGE_SCSI_DEVICE_1 *);
92 static struct scsi_transport_template *mptspi_transport_template = NULL;
94 static int mptspiDoneCtx = -1;
95 static int mptspiTaskCtx = -1;
96 static int mptspiInternalCtx = -1; /* Used only for internal commands */
99 * mptspi_setTargetNegoParms - Update the target negotiation
100 * parameters based on the the Inquiry data, adapter capabilities,
103 * @hd: Pointer to a SCSI Host Structure
104 * @vtarget: per target private data
109 mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
110 struct scsi_device *sdev)
112 SpiCfgData *pspi_data = &hd->ioc->spi_data;
113 int id = (int) target->id;
115 u8 width = MPT_NARROW;
116 u8 factor = MPT_ASYNC;
121 target->negoFlags = pspi_data->noQas;
123 if (sdev->scsi_level < SCSI_2) {
126 offset = pspi_data->maxSyncOffset;
127 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
129 if (scsi_device_wide(sdev))
132 if (scsi_device_sync(sdev)) {
133 factor = pspi_data->minSyncFactor;
134 if (!scsi_device_dt(sdev))
137 if (!scsi_device_ius(sdev) &&
138 !scsi_device_qas(sdev))
139 factor = MPT_ULTRA160;
141 factor = MPT_ULTRA320;
142 if (scsi_device_qas(sdev)) {
143 ddvprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
146 if (sdev->type == TYPE_TAPE &&
147 scsi_device_ius(sdev))
148 target->negoFlags |= MPT_TAPE_NEGO_IDP;
151 offset = pspi_data->maxSyncOffset;
153 /* If RAID, never disable QAS
154 * else if non RAID, do not disable
155 * QAS if bit 1 is set
156 * bit 1 QAS support, non-raid only
159 if (target->raidVolume == 1)
167 if (!sdev->tagged_supported)
168 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
170 /* Update tflags based on NVRAM settings. (SCSI only)
172 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
173 nvram = pspi_data->nvram[id];
174 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
177 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
180 /* Ensure factor is set to the
181 * maximum of: adapter, nvram, inquiry
184 if (nfactor < pspi_data->minSyncFactor )
185 nfactor = pspi_data->minSyncFactor;
187 factor = max(factor, nfactor);
188 if (factor == MPT_ASYNC)
199 /* Make sure data is consistent
201 if ((!width) && (factor < MPT_ULTRA2))
204 /* Save the data to the target structure.
206 target->minSyncFactor = factor;
207 target->maxOffset = offset;
208 target->maxWidth = width;
210 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
212 /* Disable unused features.
215 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
218 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
220 if ( factor > MPT_ULTRA320 )
223 if (noQas && (pspi_data->noQas == 0)) {
224 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
225 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
227 /* Disable QAS in a mixed configuration case
230 ddvprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
235 * mptspi_writeIOCPage4 - write IOC Page 4
236 * @hd: Pointer to a SCSI Host Structure
238 * @id: write IOC Page4 for this ID & Bus
240 * Return: -EAGAIN if unable to obtain a Message Frame
243 * Remark: We do not wait for a return, write pages sequentially.
246 mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
248 MPT_ADAPTER *ioc = hd->ioc;
250 IOCPage4_t *IOCPage4Ptr;
258 /* Get a MF for this command.
260 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
261 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
266 /* Set the request and the data pointers.
267 * Place data at end of MF.
269 pReq = (Config_t *)mf;
271 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
272 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
274 /* Complete the request frame (same for all requests).
276 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
278 pReq->ChainOffset = 0;
279 pReq->Function = MPI_FUNCTION_CONFIG;
280 pReq->ExtPageLength = 0;
281 pReq->ExtPageType = 0;
283 for (ii=0; ii < 8; ii++) {
284 pReq->Reserved2[ii] = 0;
287 IOCPage4Ptr = ioc->spi_data.pIocPg4;
288 dataDma = ioc->spi_data.IocPg4_dma;
289 ii = IOCPage4Ptr->ActiveSEP++;
290 IOCPage4Ptr->SEP[ii].SEPTargetID = id;
291 IOCPage4Ptr->SEP[ii].SEPBus = channel;
292 pReq->Header = IOCPage4Ptr->Header;
293 pReq->PageAddress = cpu_to_le32(id | (channel << 8 ));
295 /* Add a SGE to the config request.
297 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
298 (IOCPage4Ptr->Header.PageLength + ii) * 4;
300 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
302 ddvprintk((MYIOC_s_INFO_FMT
303 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
304 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel));
306 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
312 * mptspi_initTarget - Target, LUN alloc/free functionality.
313 * @hd: Pointer to MPT_SCSI_HOST structure
314 * @vtarget: per target private data
317 * NOTE: It's only SAFE to call this routine if data points to
318 * sane & valid STANDARD INQUIRY data!
320 * Allocate and initialize memory for this target.
325 mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
326 struct scsi_device *sdev)
329 /* Is LUN supported? If so, upper 2 bits will be 0
330 * in first byte of inquiry data.
332 if (sdev->inq_periph_qual != 0)
338 vtarget->type = sdev->type;
340 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
341 /* Treat all Processors as SAF-TE if
342 * command line option is set */
343 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
344 mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
345 }else if ((sdev->type == TYPE_PROCESSOR) &&
346 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
347 if (sdev->inquiry_len > 49 ) {
348 if (sdev->inquiry[44] == 'S' &&
349 sdev->inquiry[45] == 'A' &&
350 sdev->inquiry[46] == 'F' &&
351 sdev->inquiry[47] == '-' &&
352 sdev->inquiry[48] == 'T' &&
353 sdev->inquiry[49] == 'E' ) {
354 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
355 mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
359 mptspi_setTargetNegoParms(hd, vtarget, sdev);
363 * mptspi_is_raid - Determines whether target is belonging to volume
364 * @hd: Pointer to a SCSI HOST structure
365 * @id: target device id
373 mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
377 if (!hd->ioc->raid_data.pIocPg2)
380 if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes)
382 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
383 if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) {
393 static int mptspi_target_alloc(struct scsi_target *starget)
395 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
396 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
402 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
406 vtarget->ioc_id = hd->ioc->id;
407 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
408 vtarget->id = (u8)starget->id;
409 vtarget->channel = (u8)starget->channel;
410 vtarget->starget = starget;
411 starget->hostdata = vtarget;
413 if (starget->channel == 1) {
414 if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0)
416 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
417 /* The real channel for this device is zero */
418 vtarget->channel = 0;
419 /* The actual physdisknum (for RAID passthrough) */
420 vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0,
424 if (starget->channel == 0 &&
425 mptspi_is_raid(hd, starget->id)) {
426 vtarget->raidVolume = 1;
428 "RAID Volume @ channel=%d id=%d\n", starget->channel,
432 if (hd->ioc->spi_data.nvram &&
433 hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
434 u32 nvram = hd->ioc->spi_data.nvram[starget->id];
435 spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
436 spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
438 spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor;
439 spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth;
441 spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset;
443 spi_offset(starget) = 0;
444 mptspi_write_width(starget, 0);
450 mptspi_target_destroy(struct scsi_target *starget)
452 if (starget->hostdata)
453 kfree(starget->hostdata);
454 starget->hostdata = NULL;
457 static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
458 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
460 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
461 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
462 struct _MPT_ADAPTER *ioc = hd->ioc;
463 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0;
466 struct _x_config_parms cfg;
467 struct _CONFIG_PAGE_HEADER hdr;
470 /* No SPI parameters for RAID devices */
471 if (starget->channel == 0 &&
472 mptspi_is_raid(hd, starget->id))
475 size = ioc->spi_data.sdp0length * 4;
477 if (ioc->spi_data.sdp0length & 1)
482 pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL);
484 starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
488 memset(&hdr, 0, sizeof(hdr));
490 hdr.PageVersion = ioc->spi_data.sdp0version;
491 hdr.PageLength = ioc->spi_data.sdp0length;
493 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
495 memset(&cfg, 0, sizeof(cfg));
497 cfg.cfghdr.hdr = &hdr;
498 cfg.physAddr = pg0_dma;
499 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
501 cfg.pageAddr = starget->id;
503 if (mpt_config(ioc, &cfg)) {
504 starget_printk(KERN_ERR, starget, "mpt_config failed\n");
508 memcpy(pass_pg0, pg0, size);
511 dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma);
515 static u32 mptspi_getRP(struct scsi_target *starget)
519 nego |= spi_iu(starget) ? MPI_SCSIDEVPAGE1_RP_IU : 0;
520 nego |= spi_dt(starget) ? MPI_SCSIDEVPAGE1_RP_DT : 0;
521 nego |= spi_qas(starget) ? MPI_SCSIDEVPAGE1_RP_QAS : 0;
522 nego |= spi_hold_mcs(starget) ? MPI_SCSIDEVPAGE1_RP_HOLD_MCS : 0;
523 nego |= spi_wr_flow(starget) ? MPI_SCSIDEVPAGE1_RP_WR_FLOW : 0;
524 nego |= spi_rd_strm(starget) ? MPI_SCSIDEVPAGE1_RP_RD_STRM : 0;
525 nego |= spi_rti(starget) ? MPI_SCSIDEVPAGE1_RP_RTI : 0;
526 nego |= spi_pcomp_en(starget) ? MPI_SCSIDEVPAGE1_RP_PCOMP_EN : 0;
528 nego |= (spi_period(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD) & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
529 nego |= (spi_offset(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET) & MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
530 nego |= spi_width(starget) ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
535 static void mptspi_read_parameters(struct scsi_target *starget)
538 struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0;
540 mptspi_read_spi_device_pg0(starget, &pg0);
542 nego = le32_to_cpu(pg0.NegotiatedParameters);
544 spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0;
545 spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0;
546 spi_qas(starget) = (nego & MPI_SCSIDEVPAGE0_NP_QAS) ? 1 : 0;
547 spi_wr_flow(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WR_FLOW) ? 1 : 0;
548 spi_rd_strm(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RD_STRM) ? 1 : 0;
549 spi_rti(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RTI) ? 1 : 0;
550 spi_pcomp_en(starget) = (nego & MPI_SCSIDEVPAGE0_NP_PCOMP_EN) ? 1 : 0;
551 spi_hold_mcs(starget) = (nego & MPI_SCSIDEVPAGE0_NP_HOLD_MCS) ? 1 : 0;
552 spi_period(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
553 spi_offset(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
554 spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
558 mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
560 MpiRaidActionRequest_t *pReq;
563 /* Get and Populate a free Frame
565 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
566 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
570 pReq = (MpiRaidActionRequest_t *)mf;
572 pReq->Action = MPI_RAID_ACTION_QUIESCE_PHYS_IO;
574 pReq->Action = MPI_RAID_ACTION_ENABLE_PHYS_IO;
576 pReq->ChainOffset = 0;
577 pReq->Function = MPI_FUNCTION_RAID_ACTION;
579 pReq->VolumeBus = channel;
580 pReq->PhysDiskNum = 0;
583 pReq->ActionDataWord = 0; /* Reserved for this action */
585 mpt_add_sge((char *)&pReq->ActionDataSGE,
586 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
588 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action=%x channel=%d id=%d\n",
589 hd->ioc->name, pReq->Action, channel, id));
592 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
593 hd->scandv_wait_done = 0;
595 /* Save cmd pointer, for resource free if timeout or
600 add_timer(&hd->timer);
601 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
602 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
604 if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0))
610 static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
611 struct scsi_device *sdev)
613 VirtTarget *vtarget = scsi_target(sdev)->hostdata;
615 /* no DV on RAID devices */
616 if (sdev->channel == 0 &&
617 mptspi_is_raid(hd, sdev->id))
620 /* If this is a piece of a RAID, then quiesce first */
621 if (sdev->channel == 1 &&
622 mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) {
623 starget_printk(KERN_ERR, scsi_target(sdev),
624 "Integrated RAID quiesce failed\n");
630 if (sdev->channel == 1 &&
631 mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
632 starget_printk(KERN_ERR, scsi_target(sdev),
633 "Integrated RAID resume failed\n");
635 mptspi_read_parameters(sdev->sdev_target);
636 spi_display_xfer_agreement(sdev->sdev_target);
637 mptspi_read_parameters(sdev->sdev_target);
640 static int mptspi_slave_alloc(struct scsi_device *sdev)
642 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
645 struct scsi_target *starget;
647 if (sdev->channel == 1 &&
648 mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0)
651 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
653 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
654 hd->ioc->name, sizeof(VirtDevice));
658 vdev->lun = sdev->lun;
659 sdev->hostdata = vdev;
661 starget = scsi_target(sdev);
662 vtarget = starget->hostdata;
663 vdev->vtarget = vtarget;
666 if (sdev->channel == 1)
667 sdev->no_uld_attach = 1;
672 static int mptspi_slave_configure(struct scsi_device *sdev)
674 struct _MPT_SCSI_HOST *hd =
675 (struct _MPT_SCSI_HOST *)sdev->host->hostdata;
676 VirtTarget *vtarget = scsi_target(sdev)->hostdata;
677 int ret = mptscsih_slave_configure(sdev);
682 mptspi_initTarget(hd, vtarget, sdev);
684 if ((sdev->channel == 1 ||
685 !(mptspi_is_raid(hd, sdev->id))) &&
686 !spi_initial_dv(sdev->sdev_target))
687 mptspi_dv_device(hd, sdev);
693 mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
695 struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
696 VirtDevice *vdev = SCpnt->device->hostdata;
698 if (!vdev || !vdev->vtarget) {
699 SCpnt->result = DID_NO_CONNECT << 16;
704 if (SCpnt->device->channel == 1 &&
705 mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) {
706 SCpnt->result = DID_NO_CONNECT << 16;
711 return mptscsih_qcmd(SCpnt,done);
714 static void mptspi_slave_destroy(struct scsi_device *sdev)
716 struct scsi_target *starget = scsi_target(sdev);
717 VirtTarget *vtarget = starget->hostdata;
718 VirtDevice *vdevice = sdev->hostdata;
720 /* Will this be the last lun on a non-raid device? */
721 if (vtarget->num_luns == 1 && vdevice->configured_lun) {
722 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
725 pg1.RequestedParameters = 0;
727 pg1.Configuration = 0;
729 mptspi_write_spi_device_pg1(starget, &pg1);
732 mptscsih_slave_destroy(sdev);
735 static struct scsi_host_template mptspi_driver_template = {
736 .module = THIS_MODULE,
737 .proc_name = "mptspi",
738 .proc_info = mptscsih_proc_info,
739 .name = "MPT SPI Host",
740 .info = mptscsih_info,
741 .queuecommand = mptspi_qcmd,
742 .target_alloc = mptspi_target_alloc,
743 .slave_alloc = mptspi_slave_alloc,
744 .slave_configure = mptspi_slave_configure,
745 .target_destroy = mptspi_target_destroy,
746 .slave_destroy = mptspi_slave_destroy,
747 .change_queue_depth = mptscsih_change_queue_depth,
748 .eh_abort_handler = mptscsih_abort,
749 .eh_device_reset_handler = mptscsih_dev_reset,
750 .eh_bus_reset_handler = mptscsih_bus_reset,
751 .eh_host_reset_handler = mptscsih_host_reset,
752 .bios_param = mptscsih_bios_param,
753 .can_queue = MPT_SCSI_CAN_QUEUE,
755 .sg_tablesize = MPT_SCSI_SG_DEPTH,
758 .use_clustering = ENABLE_CLUSTERING,
761 static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
762 struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
764 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
765 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
766 struct _MPT_ADAPTER *ioc = hd->ioc;
767 struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
770 struct _x_config_parms cfg;
771 struct _CONFIG_PAGE_HEADER hdr;
774 /* don't allow updating nego parameters on RAID devices */
775 if (starget->channel == 0 &&
776 mptspi_is_raid(hd, starget->id))
779 size = ioc->spi_data.sdp1length * 4;
781 pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
783 starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
787 memset(&hdr, 0, sizeof(hdr));
789 hdr.PageVersion = ioc->spi_data.sdp1version;
790 hdr.PageLength = ioc->spi_data.sdp1length;
792 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
794 memset(&cfg, 0, sizeof(cfg));
796 cfg.cfghdr.hdr = &hdr;
797 cfg.physAddr = pg1_dma;
798 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
800 cfg.pageAddr = starget->id;
802 memcpy(pg1, pass_pg1, size);
804 pg1->Header.PageVersion = hdr.PageVersion;
805 pg1->Header.PageLength = hdr.PageLength;
806 pg1->Header.PageNumber = hdr.PageNumber;
807 pg1->Header.PageType = hdr.PageType;
809 if (mpt_config(ioc, &cfg)) {
810 starget_printk(KERN_ERR, starget, "mpt_config failed\n");
816 dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma);
820 static void mptspi_write_offset(struct scsi_target *starget, int offset)
822 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
831 if (spi_offset(starget) == -1)
832 mptspi_read_parameters(starget);
834 spi_offset(starget) = offset;
836 nego = mptspi_getRP(starget);
838 pg1.RequestedParameters = cpu_to_le32(nego);
840 pg1.Configuration = 0;
842 mptspi_write_spi_device_pg1(starget, &pg1);
845 static void mptspi_write_period(struct scsi_target *starget, int period)
847 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
856 if (spi_period(starget) == -1)
857 mptspi_read_parameters(starget);
862 } else if (period == 9) {
866 spi_period(starget) = period;
868 nego = mptspi_getRP(starget);
870 pg1.RequestedParameters = cpu_to_le32(nego);
872 pg1.Configuration = 0;
874 mptspi_write_spi_device_pg1(starget, &pg1);
877 static void mptspi_write_dt(struct scsi_target *starget, int dt)
879 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
882 if (spi_period(starget) == -1)
883 mptspi_read_parameters(starget);
885 if (!dt && spi_period(starget) < 10)
886 spi_period(starget) = 10;
888 spi_dt(starget) = dt;
890 nego = mptspi_getRP(starget);
893 pg1.RequestedParameters = cpu_to_le32(nego);
895 pg1.Configuration = 0;
897 mptspi_write_spi_device_pg1(starget, &pg1);
900 static void mptspi_write_iu(struct scsi_target *starget, int iu)
902 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
905 if (spi_period(starget) == -1)
906 mptspi_read_parameters(starget);
908 if (!iu && spi_period(starget) < 9)
909 spi_period(starget) = 9;
911 spi_iu(starget) = iu;
913 nego = mptspi_getRP(starget);
915 pg1.RequestedParameters = cpu_to_le32(nego);
917 pg1.Configuration = 0;
919 mptspi_write_spi_device_pg1(starget, &pg1);
922 #define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) \
923 static void mptspi_write_##parm(struct scsi_target *starget, int parm)\
925 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; \
928 spi_##parm(starget) = parm; \
930 nego = mptspi_getRP(starget); \
932 pg1.RequestedParameters = cpu_to_le32(nego); \
934 pg1.Configuration = 0; \
936 mptspi_write_spi_device_pg1(starget, &pg1); \
939 MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm)
940 MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow)
941 MPTSPI_SIMPLE_TRANSPORT_PARM(rti)
942 MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs)
943 MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en)
945 static void mptspi_write_qas(struct scsi_target *starget, int qas)
947 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
948 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
949 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
950 VirtTarget *vtarget = starget->hostdata;
953 if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) ||
954 hd->ioc->spi_data.noQas)
955 spi_qas(starget) = 0;
957 spi_qas(starget) = qas;
959 nego = mptspi_getRP(starget);
961 pg1.RequestedParameters = cpu_to_le32(nego);
963 pg1.Configuration = 0;
965 mptspi_write_spi_device_pg1(starget, &pg1);
968 static void mptspi_write_width(struct scsi_target *starget, int width)
970 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
975 if (spi_period(starget) < 10)
976 spi_period(starget) = 10;
979 spi_width(starget) = width;
981 nego = mptspi_getRP(starget);
983 pg1.RequestedParameters = cpu_to_le32(nego);
985 pg1.Configuration = 0;
987 mptspi_write_spi_device_pg1(starget, &pg1);
990 struct work_queue_wrapper {
991 struct work_struct work;
992 struct _MPT_SCSI_HOST *hd;
996 static void mpt_work_wrapper(struct work_struct *work)
998 struct work_queue_wrapper *wqw =
999 container_of(work, struct work_queue_wrapper, work);
1000 struct _MPT_SCSI_HOST *hd = wqw->hd;
1001 struct Scsi_Host *shost = hd->ioc->sh;
1002 struct scsi_device *sdev;
1003 int disk = wqw->disk;
1004 struct _CONFIG_PAGE_IOC_3 *pg3;
1008 mpt_findImVolumes(hd->ioc);
1009 pg3 = hd->ioc->raid_data.pIocPg3;
1013 shost_for_each_device(sdev,shost) {
1014 struct scsi_target *starget = scsi_target(sdev);
1015 VirtTarget *vtarget = starget->hostdata;
1017 /* only want to search RAID components */
1018 if (sdev->channel != 1)
1021 /* The id is the raid PhysDiskNum, even if
1022 * starget->id is the actual target address */
1023 if(vtarget->id != disk)
1026 starget_printk(KERN_INFO, vtarget->starget,
1027 "Integrated RAID requests DV of new device\n");
1028 mptspi_dv_device(hd, sdev);
1030 shost_printk(KERN_INFO, shost,
1031 "Integrated RAID detects new device %d\n", disk);
1032 scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1);
1036 static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
1038 struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
1041 shost_printk(KERN_ERR, hd->ioc->sh,
1042 "Failed to act on RAID event for physical disk %d\n",
1046 INIT_WORK(&wqw->work, mpt_work_wrapper);
1050 schedule_work(&wqw->work);
1054 mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1056 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1057 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
1059 if (hd && event == MPI_EVENT_INTEGRATED_RAID) {
1061 = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
1063 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
1064 int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
1065 mpt_dv_raid(hd, disk);
1068 return mptscsih_event_process(ioc, pEvReply);
1072 mptspi_deny_binding(struct scsi_target *starget)
1074 struct _MPT_SCSI_HOST *hd =
1075 (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
1076 return ((mptspi_is_raid(hd, starget->id)) &&
1077 starget->channel == 0) ? 1 : 0;
1080 static struct spi_function_template mptspi_transport_functions = {
1081 .get_offset = mptspi_read_parameters,
1082 .set_offset = mptspi_write_offset,
1084 .get_period = mptspi_read_parameters,
1085 .set_period = mptspi_write_period,
1087 .get_width = mptspi_read_parameters,
1088 .set_width = mptspi_write_width,
1090 .get_iu = mptspi_read_parameters,
1091 .set_iu = mptspi_write_iu,
1093 .get_dt = mptspi_read_parameters,
1094 .set_dt = mptspi_write_dt,
1096 .get_qas = mptspi_read_parameters,
1097 .set_qas = mptspi_write_qas,
1099 .get_wr_flow = mptspi_read_parameters,
1100 .set_wr_flow = mptspi_write_wr_flow,
1102 .get_rd_strm = mptspi_read_parameters,
1103 .set_rd_strm = mptspi_write_rd_strm,
1105 .get_rti = mptspi_read_parameters,
1106 .set_rti = mptspi_write_rti,
1108 .get_pcomp_en = mptspi_read_parameters,
1109 .set_pcomp_en = mptspi_write_pcomp_en,
1111 .get_hold_mcs = mptspi_read_parameters,
1112 .set_hold_mcs = mptspi_write_hold_mcs,
1114 .deny_binding = mptspi_deny_binding,
1117 /****************************************************************************
1118 * Supported hardware
1121 static struct pci_device_id mptspi_pci_table[] = {
1122 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
1123 PCI_ANY_ID, PCI_ANY_ID },
1124 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,
1125 PCI_ANY_ID, PCI_ANY_ID },
1126 {0} /* Terminating entry */
1128 MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
1132 * renegotiate for a given target
1135 mptspi_dv_renegotiate_work(struct work_struct *work)
1137 struct work_queue_wrapper *wqw =
1138 container_of(work, struct work_queue_wrapper, work);
1139 struct _MPT_SCSI_HOST *hd = wqw->hd;
1140 struct scsi_device *sdev;
1144 shost_for_each_device(sdev, hd->ioc->sh)
1145 mptspi_dv_device(hd, sdev);
1149 mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
1151 struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
1156 INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work);
1159 schedule_work(&wqw->work);
1163 * spi module reset handler
1166 mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1168 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
1171 rc = mptscsih_ioc_reset(ioc, reset_phase);
1173 if (reset_phase == MPT_IOC_POST_RESET)
1174 mptspi_dv_renegotiate(hd);
1181 * spi module resume handler
1184 mptspi_resume(struct pci_dev *pdev)
1186 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1187 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
1190 rc = mptscsih_resume(pdev);
1191 mptspi_dv_renegotiate(hd);
1197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1200 * mptspi_probe - Installs scsi devices per bus.
1201 * @pdev: Pointer to pci_dev structure
1203 * Returns 0 for success, non-zero for failure.
1207 mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1209 struct Scsi_Host *sh;
1212 unsigned long flags;
1220 if ((r = mpt_attach(pdev,id)) != 0)
1223 ioc = pci_get_drvdata(pdev);
1224 ioc->DoneCtx = mptspiDoneCtx;
1225 ioc->TaskCtx = mptspiTaskCtx;
1226 ioc->InternalCtx = mptspiInternalCtx;
1228 /* Added sanity check on readiness of the MPT adapter.
1230 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1231 printk(MYIOC_s_WARN_FMT
1232 "Skipping because it's not operational!\n",
1235 goto out_mptspi_probe;
1239 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1242 goto out_mptspi_probe;
1245 /* Sanity check - ensure at least 1 port is INITIATOR capable
1248 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1249 if (ioc->pfacts[ii].ProtocolFlags &
1250 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1255 printk(MYIOC_s_WARN_FMT
1256 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1261 sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
1264 printk(MYIOC_s_WARN_FMT
1265 "Unable to register controller with SCSI subsystem\n",
1268 goto out_mptspi_probe;
1271 spin_lock_irqsave(&ioc->FreeQlock, flags);
1273 /* Attach the SCSI Host to the IOC structure
1281 /* set 16 byte cdb's */
1282 sh->max_cmd_len = 16;
1284 /* Yikes! This is important!
1285 * Otherwise, by default, linux
1286 * only scans target IDs 0-7!
1287 * pfactsN->MaxDevices unreliable
1288 * (not supported in early
1289 * versions of the FW).
1290 * max_id = 1 + actual max id,
1291 * max_lun = 1 + actual last lun,
1294 sh->max_id = ioc->devices_per_bus;
1296 sh->max_lun = MPT_LAST_LUN + 1;
1298 * If RAID Firmware Detected, setup virtual channel
1300 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
1301 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
1302 sh->max_channel = 1;
1304 sh->max_channel = 0;
1305 sh->this_id = ioc->pfacts[0].PortSCSIID;
1309 sh->unique_id = ioc->id;
1311 /* Verify that we won't exceed the maximum
1312 * number of chain buffers
1313 * We can optimize: ZZ = req_sz/sizeof(SGE)
1315 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1316 * + (req_sz - 64)/sizeof(SGE)
1317 * A slightly different algorithm is required for
1320 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1321 if (sizeof(dma_addr_t) == sizeof(u64)) {
1322 numSGE = (scale - 1) *
1323 (ioc->facts.MaxChainDepth-1) + scale +
1324 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1327 numSGE = 1 + (scale - 1) *
1328 (ioc->facts.MaxChainDepth-1) + scale +
1329 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1333 if (numSGE < sh->sg_tablesize) {
1334 /* Reset this value */
1335 dprintk((MYIOC_s_INFO_FMT
1336 "Resetting sg_tablesize to %d from %d\n",
1337 ioc->name, numSGE, sh->sg_tablesize));
1338 sh->sg_tablesize = numSGE;
1341 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1343 hd = (MPT_SCSI_HOST *) sh->hostdata;
1346 /* SCSI needs scsi_cmnd lookup table!
1347 * (with size equal to req_depth*PtrSz!)
1349 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1350 if (!hd->ScsiLookup) {
1352 goto out_mptspi_probe;
1355 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1356 ioc->name, hd->ScsiLookup));
1358 /* Clear the TM flags
1361 hd->tmState = TM_STATE_NONE;
1362 hd->resetPending = 0;
1363 hd->abortSCpnt = NULL;
1365 /* Clear the pointer used to store
1366 * single-threaded commands, i.e., those
1367 * issued during a bus scan, dv and
1368 * configuration pages.
1372 /* Initialize this SCSI Hosts' timers
1373 * To use, set the timer expires field
1376 init_timer(&hd->timer);
1377 hd->timer.data = (unsigned long) hd;
1378 hd->timer.function = mptscsih_timer_expired;
1380 ioc->spi_data.Saf_Te = mpt_saf_te;
1382 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1383 ddvprintk((MYIOC_s_INFO_FMT
1387 ioc->spi_data.noQas = 0;
1389 init_waitqueue_head(&hd->scandv_waitq);
1390 hd->scandv_wait_done = 0;
1391 hd->last_queue_full = 0;
1393 /* Some versions of the firmware don't support page 0; without
1394 * that we can't get the parameters */
1395 if (hd->ioc->spi_data.sdp0length != 0)
1396 sh->transportt = mptspi_transport_template;
1398 error = scsi_add_host (sh, &ioc->pcidev->dev);
1400 dprintk((KERN_ERR MYNAM
1401 "scsi_add_host failed\n"));
1402 goto out_mptspi_probe;
1406 * issue internal bus reset
1408 if (ioc->spi_data.bus_reset)
1409 mptscsih_TMHandler(hd,
1410 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1418 mptscsih_remove(pdev);
1422 static struct pci_driver mptspi_driver = {
1424 .id_table = mptspi_pci_table,
1425 .probe = mptspi_probe,
1426 .remove = __devexit_p(mptscsih_remove),
1427 .shutdown = mptscsih_shutdown,
1429 .suspend = mptscsih_suspend,
1430 .resume = mptspi_resume,
1434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1436 * mptspi_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1438 * Returns 0 for success, non-zero for failure.
1443 show_mptmod_ver(my_NAME, my_VERSION);
1445 mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions);
1446 if (!mptspi_transport_template)
1449 mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
1450 mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
1451 mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
1453 if (mpt_event_register(mptspiDoneCtx, mptspi_event_process) == 0) {
1454 devtverboseprintk((KERN_INFO MYNAM
1455 ": Registered for IOC event notifications\n"));
1458 if (mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset) == 0) {
1459 dprintk((KERN_INFO MYNAM
1460 ": Registered for IOC reset notifications\n"));
1463 return pci_register_driver(&mptspi_driver);
1466 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1469 * mptspi_exit - Unregisters MPT adapter(s)
1474 pci_unregister_driver(&mptspi_driver);
1476 mpt_reset_deregister(mptspiDoneCtx);
1477 dprintk((KERN_INFO MYNAM
1478 ": Deregistered for IOC reset notifications\n"));
1480 mpt_event_deregister(mptspiDoneCtx);
1481 dprintk((KERN_INFO MYNAM
1482 ": Deregistered for IOC event notifications\n"));
1484 mpt_deregister(mptspiInternalCtx);
1485 mpt_deregister(mptspiTaskCtx);
1486 mpt_deregister(mptspiDoneCtx);
1487 spi_release_transport(mptspi_transport_template);
1490 module_init(mptspi_init);
1491 module_exit(mptspi_exit);