|
@@ -93,10 +93,11 @@ static int mptfcDoneCtx = -1;
|
|
static int mptfcTaskCtx = -1;
|
|
static int mptfcTaskCtx = -1;
|
|
static int mptfcInternalCtx = -1; /* Used only for internal commands */
|
|
static int mptfcInternalCtx = -1; /* Used only for internal commands */
|
|
|
|
|
|
-int mptfc_slave_alloc(struct scsi_device *device);
|
|
|
|
|
|
+static int mptfc_target_alloc(struct scsi_target *starget);
|
|
|
|
+static int mptfc_slave_alloc(struct scsi_device *sdev);
|
|
static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
|
|
static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
|
|
- void (*done)(struct scsi_cmnd *));
|
|
|
|
-
|
|
|
|
|
|
+ void (*done)(struct scsi_cmnd *));
|
|
|
|
+static void mptfc_target_destroy(struct scsi_target *starget);
|
|
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
|
|
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
|
|
static void __devexit mptfc_remove(struct pci_dev *pdev);
|
|
static void __devexit mptfc_remove(struct pci_dev *pdev);
|
|
|
|
|
|
@@ -107,10 +108,10 @@ static struct scsi_host_template mptfc_driver_template = {
|
|
.name = "MPT FC Host",
|
|
.name = "MPT FC Host",
|
|
.info = mptscsih_info,
|
|
.info = mptscsih_info,
|
|
.queuecommand = mptfc_qcmd,
|
|
.queuecommand = mptfc_qcmd,
|
|
- .target_alloc = mptscsih_target_alloc,
|
|
|
|
|
|
+ .target_alloc = mptfc_target_alloc,
|
|
.slave_alloc = mptfc_slave_alloc,
|
|
.slave_alloc = mptfc_slave_alloc,
|
|
.slave_configure = mptscsih_slave_configure,
|
|
.slave_configure = mptscsih_slave_configure,
|
|
- .target_destroy = mptscsih_target_destroy,
|
|
|
|
|
|
+ .target_destroy = mptfc_target_destroy,
|
|
.slave_destroy = mptscsih_slave_destroy,
|
|
.slave_destroy = mptscsih_slave_destroy,
|
|
.change_queue_depth = mptscsih_change_queue_depth,
|
|
.change_queue_depth = mptscsih_change_queue_depth,
|
|
.eh_abort_handler = mptscsih_abort,
|
|
.eh_abort_handler = mptscsih_abort,
|
|
@@ -347,15 +348,34 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+mptfc_remap_sdev(struct scsi_device *sdev, void *arg)
|
|
|
|
+{
|
|
|
|
+ VirtDevice *vdev;
|
|
|
|
+ VirtTarget *vtarget;
|
|
|
|
+ struct scsi_target *starget;
|
|
|
|
+
|
|
|
|
+ starget = scsi_target(sdev);
|
|
|
|
+ if (starget->hostdata == arg) {
|
|
|
|
+ vtarget = arg;
|
|
|
|
+ vdev = sdev->hostdata;
|
|
|
|
+ if (vdev) {
|
|
|
|
+ vdev->bus_id = vtarget->bus_id;
|
|
|
|
+ vdev->target_id = vtarget->target_id;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void
|
|
static void
|
|
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
|
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
|
{
|
|
{
|
|
struct fc_rport_identifiers rport_ids;
|
|
struct fc_rport_identifiers rport_ids;
|
|
struct fc_rport *rport;
|
|
struct fc_rport *rport;
|
|
struct mptfc_rport_info *ri;
|
|
struct mptfc_rport_info *ri;
|
|
- int match = 0;
|
|
|
|
- u64 port_name;
|
|
|
|
|
|
+ int new_ri = 1;
|
|
|
|
+ u64 pn;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ VirtTarget *vtarget;
|
|
|
|
|
|
if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
|
|
if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
|
|
return;
|
|
return;
|
|
@@ -363,14 +383,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
|
/* scan list looking for a match */
|
|
/* scan list looking for a match */
|
|
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
|
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
|
list_for_each_entry(ri, &ioc->fc_rports, list) {
|
|
list_for_each_entry(ri, &ioc->fc_rports, list) {
|
|
- port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
|
|
|
|
- if (port_name == rport_ids.port_name) { /* match */
|
|
|
|
|
|
+ pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
|
|
|
|
+ if (pn == rport_ids.port_name) { /* match */
|
|
list_move_tail(&ri->list, &ioc->fc_rports);
|
|
list_move_tail(&ri->list, &ioc->fc_rports);
|
|
- match = 1;
|
|
|
|
|
|
+ new_ri = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (!match) { /* allocate one */
|
|
|
|
|
|
+ if (new_ri) { /* allocate one */
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
|
ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
|
|
ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
|
|
if (!ri)
|
|
if (!ri)
|
|
@@ -382,40 +402,43 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
|
ri->pg0 = *pg0; /* add/update pg0 data */
|
|
ri->pg0 = *pg0; /* add/update pg0 data */
|
|
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
|
|
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
|
|
|
|
|
|
|
|
+ /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
|
|
if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
|
|
if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
|
|
ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
|
|
ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
|
- rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
|
|
|
|
|
|
+ rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
|
|
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
|
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
|
if (rport) {
|
|
if (rport) {
|
|
- if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
|
|
|
|
- ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
|
|
|
|
- ri->vdev = NULL;
|
|
|
|
- ri->rport = rport;
|
|
|
|
- *((struct mptfc_rport_info **)rport->dd_data) = ri;
|
|
|
|
- }
|
|
|
|
- rport->dev_loss_tmo = mptfc_dev_loss_tmo;
|
|
|
|
|
|
+ ri->rport = rport;
|
|
|
|
+ if (new_ri) /* may have been reset by user */
|
|
|
|
+ rport->dev_loss_tmo = mptfc_dev_loss_tmo;
|
|
|
|
+ *((struct mptfc_rport_info **)rport->dd_data) = ri;
|
|
/*
|
|
/*
|
|
* if already mapped, remap here. If not mapped,
|
|
* if already mapped, remap here. If not mapped,
|
|
- * slave_alloc will allocate vdev and map
|
|
|
|
|
|
+ * target_alloc will allocate vtarget and map,
|
|
|
|
+ * slave_alloc will fill in vdev from vtarget.
|
|
*/
|
|
*/
|
|
- if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
|
|
|
|
- ri->vdev->target_id = ri->pg0.CurrentTargetID;
|
|
|
|
- ri->vdev->bus_id = ri->pg0.CurrentBus;
|
|
|
|
- ri->vdev->vtarget->target_id = ri->vdev->target_id;
|
|
|
|
- ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
|
|
|
|
|
|
+ if (ri->starget) {
|
|
|
|
+ vtarget = ri->starget->hostdata;
|
|
|
|
+ if (vtarget) {
|
|
|
|
+ vtarget->target_id = pg0->CurrentTargetID;
|
|
|
|
+ vtarget->bus_id = pg0->CurrentBus;
|
|
|
|
+ starget_for_each_device(ri->starget,
|
|
|
|
+ vtarget,mptfc_remap_sdev);
|
|
|
|
+ }
|
|
|
|
+ ri->remap_needed = 0;
|
|
}
|
|
}
|
|
- #ifdef MPT_DEBUG
|
|
|
|
- printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
|
|
|
|
|
|
+ dfcprintk ((MYIOC_s_INFO_FMT
|
|
|
|
+ "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
|
|
"rport tid %d, tmo %d\n",
|
|
"rport tid %d, tmo %d\n",
|
|
- ioc->sh->host_no,
|
|
|
|
|
|
+ ioc->name,
|
|
|
|
+ oc->sh->host_no,
|
|
pg0->PortIdentifier,
|
|
pg0->PortIdentifier,
|
|
pg0->WWNN,
|
|
pg0->WWNN,
|
|
pg0->WWPN,
|
|
pg0->WWPN,
|
|
pg0->CurrentTargetID,
|
|
pg0->CurrentTargetID,
|
|
ri->rport->scsi_target_id,
|
|
ri->rport->scsi_target_id,
|
|
- ri->rport->dev_loss_tmo);
|
|
|
|
- #endif
|
|
|
|
|
|
+ ri->rport->dev_loss_tmo));
|
|
} else {
|
|
} else {
|
|
list_del(&ri->list);
|
|
list_del(&ri->list);
|
|
kfree(ri);
|
|
kfree(ri);
|
|
@@ -426,6 +449,65 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * OS entry point to allow for host driver to free allocated memory
|
|
|
|
+ * Called if no device present or device being unloaded
|
|
|
|
+ */
|
|
|
|
+static void
|
|
|
|
+mptfc_target_destroy(struct scsi_target *starget)
|
|
|
|
+{
|
|
|
|
+ struct fc_rport *rport;
|
|
|
|
+ struct mptfc_rport_info *ri;
|
|
|
|
+
|
|
|
|
+ rport = starget_to_rport(starget);
|
|
|
|
+ if (rport) {
|
|
|
|
+ ri = *((struct mptfc_rport_info **)rport->dd_data);
|
|
|
|
+ if (ri) /* better be! */
|
|
|
|
+ ri->starget = NULL;
|
|
|
|
+ }
|
|
|
|
+ if (starget->hostdata)
|
|
|
|
+ kfree(starget->hostdata);
|
|
|
|
+ starget->hostdata = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * OS entry point to allow host driver to alloc memory
|
|
|
|
+ * for each scsi target. Called once per device the bus scan.
|
|
|
|
+ * Return non-zero if allocation fails.
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+mptfc_target_alloc(struct scsi_target *starget)
|
|
|
|
+{
|
|
|
|
+ VirtTarget *vtarget;
|
|
|
|
+ struct fc_rport *rport;
|
|
|
|
+ struct mptfc_rport_info *ri;
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
|
|
|
|
+ if (!vtarget)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ starget->hostdata = vtarget;
|
|
|
|
+
|
|
|
|
+ rc = -ENODEV;
|
|
|
|
+ rport = starget_to_rport(starget);
|
|
|
|
+ if (rport) {
|
|
|
|
+ ri = *((struct mptfc_rport_info **)rport->dd_data);
|
|
|
|
+ if (ri) { /* better be! */
|
|
|
|
+ vtarget->target_id = ri->pg0.CurrentTargetID;
|
|
|
|
+ vtarget->bus_id = ri->pg0.CurrentBus;
|
|
|
|
+ ri->starget = starget;
|
|
|
|
+ ri->remap_needed = 0;
|
|
|
|
+ rc = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (rc != 0) {
|
|
|
|
+ kfree(vtarget);
|
|
|
|
+ starget->hostdata = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* OS entry point to allow host driver to alloc memory
|
|
* OS entry point to allow host driver to alloc memory
|
|
* for each scsi device. Called once per device the bus scan.
|
|
* for each scsi device. Called once per device the bus scan.
|
|
@@ -440,7 +522,6 @@ mptfc_slave_alloc(struct scsi_device *sdev)
|
|
VirtDevice *vdev;
|
|
VirtDevice *vdev;
|
|
struct scsi_target *starget;
|
|
struct scsi_target *starget;
|
|
struct fc_rport *rport;
|
|
struct fc_rport *rport;
|
|
- struct mptfc_rport_info *ri;
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
@@ -451,55 +532,44 @@ mptfc_slave_alloc(struct scsi_device *sdev)
|
|
|
|
|
|
hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
|
|
hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
|
|
|
|
|
|
- vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
|
|
|
|
|
|
+ vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
|
|
if (!vdev) {
|
|
if (!vdev) {
|
|
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
|
|
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
|
|
hd->ioc->name, sizeof(VirtDevice));
|
|
hd->ioc->name, sizeof(VirtDevice));
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
- memset(vdev, 0, sizeof(VirtDevice));
|
|
|
|
|
|
|
|
spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
|
|
spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
|
|
|
|
|
|
- if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
|
|
|
|
- spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
|
|
|
|
- kfree(vdev);
|
|
|
|
- return -ENODEV;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
sdev->hostdata = vdev;
|
|
sdev->hostdata = vdev;
|
|
starget = scsi_target(sdev);
|
|
starget = scsi_target(sdev);
|
|
vtarget = starget->hostdata;
|
|
vtarget = starget->hostdata;
|
|
|
|
+
|
|
if (vtarget->num_luns == 0) {
|
|
if (vtarget->num_luns == 0) {
|
|
|
|
+ vtarget->ioc_id = hd->ioc->id;
|
|
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
|
|
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
|
|
MPT_TARGET_FLAGS_VALID_INQUIRY;
|
|
MPT_TARGET_FLAGS_VALID_INQUIRY;
|
|
hd->Targets[sdev->id] = vtarget;
|
|
hd->Targets[sdev->id] = vtarget;
|
|
}
|
|
}
|
|
|
|
|
|
- vtarget->target_id = vdev->target_id;
|
|
|
|
- vtarget->bus_id = vdev->bus_id;
|
|
|
|
-
|
|
|
|
vdev->vtarget = vtarget;
|
|
vdev->vtarget = vtarget;
|
|
vdev->ioc_id = hd->ioc->id;
|
|
vdev->ioc_id = hd->ioc->id;
|
|
vdev->lun = sdev->lun;
|
|
vdev->lun = sdev->lun;
|
|
- vdev->target_id = ri->pg0.CurrentTargetID;
|
|
|
|
- vdev->bus_id = ri->pg0.CurrentBus;
|
|
|
|
-
|
|
|
|
- ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
|
|
|
|
- ri->vdev = vdev;
|
|
|
|
|
|
+ vdev->target_id = vtarget->target_id;
|
|
|
|
+ vdev->bus_id = vtarget->bus_id;
|
|
|
|
|
|
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
|
|
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
|
|
|
|
|
|
vtarget->num_luns++;
|
|
vtarget->num_luns++;
|
|
|
|
|
|
-#ifdef MPT_DEBUG
|
|
|
|
- printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
|
|
|
|
|
|
+ dfcprintk ((MYIOC_s_INFO_FMT
|
|
|
|
+ "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
|
|
"CurrentTargetID %d, %x %llx %llx\n",
|
|
"CurrentTargetID %d, %x %llx %llx\n",
|
|
- sdev->host->host_no,
|
|
|
|
- vtarget->num_luns,
|
|
|
|
- sdev->id, ri->pg0.CurrentTargetID,
|
|
|
|
- ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);
|
|
|
|
-#endif
|
|
|
|
|
|
+ ioc->name,
|
|
|
|
+ sdev->host->host_no,
|
|
|
|
+ vtarget->num_luns,
|
|
|
|
+ sdev->id, ri->pg0.CurrentTargetID,
|
|
|
|
+ ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -507,6 +577,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
|
|
static int
|
|
static int
|
|
mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
|
mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
|
{
|
|
{
|
|
|
|
+ struct mptfc_rport_info *ri;
|
|
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
|
|
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
|
|
int err;
|
|
int err;
|
|
|
|
|
|
@@ -516,6 +587,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
|
done(SCpnt);
|
|
done(SCpnt);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+ ri = *((struct mptfc_rport_info **)rport->dd_data);
|
|
|
|
+ if (unlikely(ri->remap_needed))
|
|
|
|
+ return SCSI_MLQUEUE_HOST_BUSY;
|
|
|
|
+
|
|
return mptscsih_qcmd(SCpnt,done);
|
|
return mptscsih_qcmd(SCpnt,done);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -591,16 +666,20 @@ mptfc_rescan_devices(void *arg)
|
|
|
|
|
|
ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
|
|
ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
|
|
MPT_RPORT_INFO_FLAGS_MISSING);
|
|
MPT_RPORT_INFO_FLAGS_MISSING);
|
|
|
|
+ ri->remap_needed = 1;
|
|
fc_remote_port_delete(ri->rport);
|
|
fc_remote_port_delete(ri->rport);
|
|
/*
|
|
/*
|
|
* remote port not really deleted 'cause
|
|
* remote port not really deleted 'cause
|
|
* binding is by WWPN and driver only
|
|
* binding is by WWPN and driver only
|
|
- * registers FCP_TARGETs
|
|
|
|
|
|
+ * registers FCP_TARGETs but cannot trust
|
|
|
|
+ * data structures.
|
|
*/
|
|
*/
|
|
- #ifdef MPT_DEBUG
|
|
|
|
- printk ("mptfc_rescan.%d: %llx deleted\n",
|
|
|
|
- ioc->sh->host_no, ri->pg0.WWPN);
|
|
|
|
- #endif
|
|
|
|
|
|
+ ri->rport = NULL;
|
|
|
|
+ dfcprintk ((MYIOC_s_INFO_FMT
|
|
|
|
+ "mptfc_rescan.%d: %llx deleted\n",
|
|
|
|
+ ioc->name,
|
|
|
|
+ ioc->sh->host_no,
|
|
|
|
+ ri->pg0.WWPN));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
|
|
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
|
|
@@ -872,9 +951,8 @@ mptfc_init(void)
|
|
}
|
|
}
|
|
|
|
|
|
error = pci_register_driver(&mptfc_driver);
|
|
error = pci_register_driver(&mptfc_driver);
|
|
- if (error) {
|
|
|
|
|
|
+ if (error)
|
|
fc_release_transport(mptfc_transport_template);
|
|
fc_release_transport(mptfc_transport_template);
|
|
- }
|
|
|
|
|
|
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
@@ -885,7 +963,8 @@ mptfc_init(void)
|
|
* @pdev: Pointer to pci_dev structure
|
|
* @pdev: Pointer to pci_dev structure
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
-static void __devexit mptfc_remove(struct pci_dev *pdev)
|
|
|
|
|
|
+static void __devexit
|
|
|
|
+mptfc_remove(struct pci_dev *pdev)
|
|
{
|
|
{
|
|
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
|
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
|
struct mptfc_rport_info *p, *n;
|
|
struct mptfc_rport_info *p, *n;
|