aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/bfa/bfad_im.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa/bfad_im.c')
-rw-r--r--drivers/scsi/bfa/bfad_im.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 5b7cf539e50..678120b7046 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -554,7 +554,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
im_port->shost->transportt =
bfad_im_scsi_vport_transport_template;
- error = scsi_add_host(im_port->shost, dev);
+ error = scsi_add_host_with_dma(im_port->shost, dev, &bfad->pcidev->dev);
if (error) {
printk(KERN_WARNING "scsi_add_host failure %d\n", error);
goto out_fc_rel;
@@ -567,6 +567,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
out_fc_rel:
scsi_host_put(im_port->shost);
+ im_port->shost = NULL;
out_free_idr:
mutex_lock(&bfad_mutex);
idr_remove(&bfad_im_port_index, im_port->idr_id);
@@ -597,10 +598,12 @@ bfad_im_port_delete_handler(struct work_struct *work)
{
struct bfad_im_port_s *im_port =
container_of(work, struct bfad_im_port_s, port_delete_work);
+ struct bfad_s *bfad = im_port->bfad;
if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) {
im_port->flags |= BFAD_PORT_DELETE;
fc_vport_terminate(im_port->fc_vport);
+ atomic_dec(&bfad->wq_reqcnt);
}
}
@@ -633,8 +636,11 @@ bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port)
{
struct bfad_im_port_s *im_port = port->im_port;
- queue_work(bfad->im->drv_workq,
+ if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) {
+ atomic_inc(&bfad->wq_reqcnt);
+ queue_work(bfad->im->drv_workq,
&im_port->port_delete_work);
+ }
}
void
@@ -695,12 +701,27 @@ void
bfad_im_probe_undo(struct bfad_s *bfad)
{
if (bfad->im) {
+ while (atomic_read(&bfad->wq_reqcnt)) {
+ printk(KERN_INFO "bfa %s: waiting workq processing,"
+ " wq_reqcnt:%x\n", bfad->pci_name,
+ atomic_read(&bfad->wq_reqcnt));
+ schedule_timeout_uninterruptible(HZ);
+ }
bfad_os_destroy_workq(bfad->im);
kfree(bfad->im);
bfad->im = NULL;
}
}
+/**
+ * Call back function to handle IO redirection state change
+ */
+void
+bfa_cb_ioredirect_state_change(void *hcb_bfad, bfa_boolean_t ioredirect)
+{
+ /* Do nothing */
+}
+
struct Scsi_Host *
bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
{
@@ -1204,9 +1225,9 @@ int
bfad_os_get_linkup_delay(struct bfad_s *bfad)
{
- u8 nwwns = 0;
- wwn_t *wwns;
- int ldelay;
+ u8 nwwns = 0;
+ wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
+ int ldelay;
/*
* Querying for the boot target port wwns
@@ -1215,7 +1236,7 @@ bfad_os_get_linkup_delay(struct bfad_s *bfad)
* else => local boot machine set bfa_linkup_delay = 10
*/
- bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, &wwns);
+ bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, wwns);
if (nwwns > 0) {
/* If boot over SAN; linkup_delay = 30sec */